aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-10-08 21:21:52 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2023-10-08 21:21:52 +0300
commit3027994d340f09892efa08e22c1f2e1ae6d7010d (patch)
tree0676e7e8be81700622921d1d1b5e793d768226da /docs
parent4445da64240e9d5867dfdfefed6052586fb1148b (diff)
downloadhid-tmff2-3027994d340f09892efa08e22c1f2e1ae6d7010d.tar.gz
hid-tmff2-3027994d340f09892efa08e22c1f2e1ae6d7010d.zip
docs: mostly tweak structure and formatting
+ Still have to check that everything renders properly on GitHub.
Diffstat (limited to 'docs')
-rw-r--r--docs/CONTRIBUTING.md122
-rw-r--r--docs/DRIVER.md49
-rw-r--r--docs/FFBEFFECTS.md558
-rw-r--r--docs/INTEGRATION.md6
-rw-r--r--docs/STRUCTURE.md42
-rw-r--r--docs/effects/FFBEFFECTS_T248.md7
-rw-r--r--docs/effects/FFBEFFECTS_T300RS.md541
7 files changed, 746 insertions, 579 deletions
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index db937a1..46b8b26 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -1,50 +1,110 @@
# Contributing
-## Overview
-This file contains general contributing information. This project is seeking for help from people who can contribute. If you have a wheel that's not on the list, but suspect it might fit into the driver, please feel free to open up an issue about it.
+## Overview This file contains general contributing information.
+
+This project is seeking for help from people who can contribute. If you have a
+wheel that's not on the list, but suspect it might fit into the driver, please
+feel free to open up an issue about it.
Currently open requests for wheels:
-- [T500 RS](https://github.com/Kimplul/hid-tmff2/issues/18)
-- [T818](https://github.com/Kimplul/hid-tmff2/issues/58)
-- [T-GT II](https://github.com/Kimplul/hid-tmff2/issues/55)
-- [T128P](https://github.com/Kimplul/hid-tmff2/issues/67)
++ [T500 RS](https://github.com/Kimplul/hid-tmff2/issues/18)
++ [T818](https://github.com/Kimplul/hid-tmff2/issues/58)
++ [T-GT II](https://github.com/Kimplul/hid-tmff2/issues/55)
++ [T128P](https://github.com/Kimplul/hid-tmff2/issues/67)
Other documents available are linked here:
-- [FFBEffects-T300RS](./FFBEffects-T300RS.md): Force Feedback Effects example for T300RS
-- [FFBEffects-T248](./FFBEffects-T248.md): Force Feedback Effects example for T248
-- [Structure](https://github.com/Kimplul/hid-tmff2/wiki#structure-of-the-thrustmaster-device-stack): Structure of Thrustmaster device stack
-- [TO-DO](./TODO.md): TO-DO list for maintainers
++ [FFBEEFFECTS](./FFBEFFECTS.md):
+ Force feedback effects example for T300RS and compatible wheels
-## How to add in support for a new T-series wheel?
-Should probably not be too often that you need this info, but essentially use wireshark like in the previous example, but spin up a Windows virtual machine and install the Thrustmaster drivers on to it, and pass the device to the virtual machine. I prefer to use `qemu` with `virt-manager` as a frontend. With the wheel working under Windows, install [fedit.exe](https://gimx.fr/download/b882e209a0ac023d03abbf560dfc3f25fe6367ca/fedit.zip) and methodically go through all effects the device supports and compare the USB packets the driver sends out. You should be able to build up a table of what each value in the USB packet means, see [FFBEffects-T300RS.md](./FFBEffects-T300RS.md) for an example of what I found out about the T300.
++ [STRUCTURE](./STRUCTURE.md):
+ Structure of Thrustmaster device stack
+
++ [TODO](./TODO.md):
+ TO-DO list for maintainers
## How to capture what effects a game sends to the driver?
-Use ffbwrap from ffbtools: [github:berarma/ffbtools](https://github.com/berarma/ffbtools)
-The documentation gives good examples, but tl;dr; For steam, insert the following into a game's launch options:
+
+Use ffbwrap from ffbtools:
+[github:berarma/ffbtools](https://github.com/berarma/ffbtools)
+
+The documentation gives good examples, but tl;dr; For steam, insert the following
+into a game's launch options:
+
```shell
-$ ffbwrap --logger=/home/$USER/game.log /dev/input/by-id/usb-Thrustmaster_Thrustmaster_T300RS_Racing_wheel-event-joystick -- %command%
+ffbwrap --logger=/home/$USER/game.log /dev/input/by-id/usb-Thrustmaster_Thrustmaster_T300RS_Racing_wheel-event-joystick -- %command%
```
-This will create a file called `game.log` (with additional timestamp) in your home directory. Preferably change the name to suit the game, but you do you.
-> **NOTE:** Most fixes presented in the documentation are more or less obsolete by now, but the tool is still very useful for logging purposes.
+This will create a file called `game.log` (with additional timestamp) in your
+home directory. Preferably change the name to suit the game, but you do you.
+
+> **NOTE:** Most fixes presented in the documentation are more or less obsolete
+> by now, but the tool is still very useful for logging purposes.
## How to capture what USB packets the driver sends to the device?
-I'd recommend [wireshark](https://www.wireshark.org/)
-Usb capture setup is fairly straightforward: [wireshark/CaptureSetup](https://wiki.wireshark.org/CaptureSetup/USB#linux)
+I'd recommend
+[wireshark](https://www.wireshark.org/)
+
+Usb capture setup is fairly straightforward:
+[wireshark/CaptureSetup](https://wiki.wireshark.org/CaptureSetup/USB#linux)
+
+Here's what I typically do when starting a capture:
+
++ Run `sudo modprobe usbmon`. This will load a kernel module that allows
+ Wireshark to read the USB packets.
+
++ Open wireshark with root privileges. There are some ways to allow wireshark to
+ access the packets with regular user privileges, I just haven't bothered with
+ it.
-Here's what I typically do when starting capturing:
++ Select `usbmon0` from the view that opens up by default.
+
++ The screen will quickly fill up with noise from other devices connected to the
+ computer, so you will have to filter out the noise.
+
++ Run `lsusb` in a terminal. Look for the T300 in the list, you should see
+ something like `Bus 001 Device 006: ID 044f:b66e ThrustMaster, Inc.
+ Thrustmaster T300RS Racing wheel`
+
++ From the previous command, the Bus and Device fields can be used to filter
+ out only packets from/to the device. To see all packets coming from the
+ wheel, add in a filter `usb.src ~ "1\.6\..*"`, where `1` is in this case
+ from the `Bus` field and `6` from the `Device` field. To see all packets
+ being sent to the device, use `usb.dst`.
+
++ This data is probably also filled with a lot of cruft. Data to/from
+ endpoint 2 is button state info, which is probably unnecessary. To see FFB
+ data being sent to the device, use endpoint 1, i.e. `usb.dst == "1.6.1"`.
+ `~` is a Perl-compliant regex operator, whereas `==` just matches the string
+ directly. To see both data coming from the device and going to it, use
+ `usb.dst == "..." || usb.src == "..."`.
+
++ There is also endpoint 0, `usb.src == "1.6.0"` but it doesn't seem to be
+ used for much.
+
++ Use the three buttons in the top left of the screen to start, stop and restart
+ captures.
+
++ Do whatever you want with the device, packets should automatically be
+ captured. When you want to save your capture to a file, stop the recording and
+ go to `File > Export Specified Packets` and make sure `Displayed` is selected.
+ This will apply the filter you've been using, and will only include the packets
+ that are visible in Wireshark, i.e. it applies the filter you've specified.
+
+> **NOTE:** Every time you unplug and replug your wheel, its `Device` field will
+> probably change.
+
+## How to add in support for a new T-series wheel?
-- Run `sudo modprobe usbmon`. This will load a kernel module that allows Wireshark to read the USB packets.
-- Open wireshark with root privileges. There are some ways to allow wireshark to access the packets with regular user privileges, I just haven't bothered with it.
-- Select `usbmon0` from the view that opens up by default.
-- The screen will quickly fill up with noise from other devices connected to the computer, so you will have to filter out the noise.
- - Run `lsusb` in a terminal. Look for the T300 in the list, you should see something like `Bus 001 Device 006: ID 044f:b66e ThrustMaster, Inc. Thrustmaster T300RS Racing wheel`
- - From the previous command, the Bus and Device fields can be used to filter out only packets from/to the device. To see all packets coming from the wheel, add in a filter `usb.src ~ "1\.6\..*"`, where `1` is in this case from the `Bus` field and `6` from the `Device` field. To see all packets coming from the device, use `usb.dst`.
- - This data is probably also filled with a lot of cruft. Data to/from endpoint 2 is button state info, which is probably unnecessary. To see FFB data being sent to the device, use endpoint 1, i.e. `usb.dst == "1.6.1"`. `~` is a Perl-compliant regex operator, whereas `==` just matches the string directly. To see both data coming from the device and going to it, use `usb.dst == "..." || usb.src == "..."`.
- - There is also endpoint 0, `usb.src == "1.6.0"` but it doesn't seem to be used for much.
-- Use the three buttons in the top left of the screen to start, stop and restart captures.
-- Do whatever you want with the device, packets should automatically be captured. When you want to save your capture to a file, stop the recording and go to `File > Export Specified Packets` and make sure `Displayed` is selected. This will apply the filter you've been using, and will only include the packets that are visible in Wireshark, i.e. it applies the filter you've specified.
+Should probably not be too often that you need this info, but essentially use
+wireshark like in the previous example, but spin up a Windows virtual machine
+and install the Thrustmaster drivers on to it, and pass the device to the
+virtual machine. I prefer to use `qemu` with `virt-manager` as a frontend.
-> **NOTE:** Every time you unplug and replug your wheel, its `Device` field will probably change.
+With the wheel working under Windows, install
+[fedit.exe](https://gimx.fr/download/b882e209a0ac023d03abbf560dfc3f25fe6367ca/fedit.zip)
+and methodically go through all effects the device supports and compare the USB
+packets the driver sends out. You should be able to build up a table of what
+each value in the USB packet means, see [FFBEFFECTS.md](./FFBEFFECTS.md)
+for an example of what I found out about the T300.
diff --git a/docs/DRIVER.md b/docs/DRIVER.md
new file mode 100644
index 0000000..053ee41
--- /dev/null
+++ b/docs/DRIVER.md
@@ -0,0 +1,49 @@
+There are some reports that games will work better with the Thrustmaster Windows
+drivers installed.
+
+# Installing the Windows drivers inside a proton prefix
+
+1. Install [protontricks](https://github.com/Matoking/protontricks).
+
+2. Download the
+ [Thrustmaster drivers](https://support.thrustmaster.com/en/product/t300rs-en/).
+
+3. Look up the ID of your game with `protontricks -s NAME`. For example:
+ ```shell
+ $ protontricks -s Dirt
+ Found the following games:
+ DiRT 3 Complete Edition (321040)
+ DiRT 4 (421020)
+ DiRT Rally (310560)
+ DiRT Rally 2.0 (690790)
+
+ To run Protontricks for the chosen game, run: $ protontricks APPID COMMAND
+
+ NOTE: A game must be launched at least once before Protontricks can find the
+ game.
+ ```
+
+4. Run the driver installer with protontricks.
+ ```shell
+ protontricks -c 'wine ~/Downloads/DRIVER_INSTALL_EXE' APPID
+ ```
+
+ Dirt 4 for example:
+ ```shell
+ protontricks -c 'wine ~/Downloads/2022_TTRS_1.exe' 421020
+ ```
+
+Note that `protontricks` may change the working directory, so relative paths may
+end up not working as expected.
+
+# Installing the Windows drivers manually
+
+Assuming you've already downloaded the installer:
+
+```shell
+WINE_PREFIX=/path/to/prefix wine ./DRIVER_INSTALL_EXE
+```
+
+[Lutris](https://lutris.net/) is an excellent way to keep track of which
+non-steam games exist in which prefixes, and allows you to run executables in
+prefixes from a GUI if that's more your thing.
diff --git a/docs/FFBEFFECTS.md b/docs/FFBEFFECTS.md
new file mode 100644
index 0000000..e2b3edc
--- /dev/null
+++ b/docs/FFBEFFECTS.md
@@ -0,0 +1,558 @@
+# Force Feedback Effects - Thrustmaster T300RS and compatible
+
+Here I will gather all info I can find out about the different force feedback
+effects and their USB commands. All values seem to be little-endian.
+
+Also, general note, it seems like some effects are affected by the direction of
+the force, denoted by `***`. As far as I can tell, `fade_level` and
+`attack_level` values are calculated by mapping the `u16` into `s16` and taking
+the absolute value, and after that multiplying by the direction.
+
+A full list of wheels that use USB packets in the format documented here is yet
+to be determined, but at least T300, T248 and TX seem to use it. Each wheel may
+have model specific peculiarities, though.
+
+> **NOTE:** All values are examples of actual commands that I captured on the
+> USB interface, not the only available ones.
+
+## GENERAL
+### Playing
+```
+ 60 00 - standard header
+ 01 - ID
+ 89 - playing options
+ 01 - play
+ 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+### Stopping/removing (why are they rolled into one?)
+```
+ 60 00 - standard header
+ 01 - ID
+ 89 - playing options
+ 00 - stop
+ 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+## Open:
+```
+ 60 01 - standard header?
+ 04 - ?
+ 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ (this command doesn't appear every time, odd)
+ 60 12 - ?
+ bf 04 00 00 03 b7 1e - ? /* wow, this is different on different wheels? */
+ 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ 60 01 - ?
+ 05 - ?
+ 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+## Close:
+```
+ 60 01 - standard header?
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+## Rotation angle:
+```
+ 60 08 - header plus settings?
+ 11 - set rotation angle
+ 55 d5 - angle (between ff ff and 7b 09, one degree is roughly 3c)
+ 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+## FF_AUTOCENTER:
+```
+ 60 08 - header plus settings?
+ 03 - set autocenter force
+ 8f 02 - force (between ff ff and 00 00)
+ 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+## FF_GAIN:
+```
+ 60 02 - header plus gain?
+ bf - gain (between ff and 00)
+ 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+## FF_CONSTANT
+### Initialization
+```
+ 60 00 - standard header
+ 01 - ID
+ 6a - new constant effect(?)
+ fe ff - strength ***
+ 00 00 - attack_length
+ 00 00 - attack_level ***
+ 00 00 - fade_length
+ 00 00 - fade_level ***
+ 00 4f - ?
+ f7 17 - time in milliseconds, unsigned
+ 00 00
+ 07 00 - offset from start(?)
+ 00 ff ff - end of new effect(?)
+ 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+### Modifying (For dynamic updating of effects)
+
+#### Direction: ``N/A``
+
+#### Constant force:
+```
+ 60 00 - standard header
+ 01 - ID
+ 0a - modify constant force
+ 05 16 - constant force ***
+ 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+#### Envelope:
+```
+ 60 00 - standard header
+ 01 - ID
+ 31 - modify envelope
+ 84 - ID of envelope attribute ( attack_level 82,
+ attack_length 81,
+ fade_level 88,
+ fade_length 84 )
+ 63 04 - value attribute should be set to ?***?
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+#### Duration:
+```
+ 60 00 - standard header
+ 01 - ID
+ 49 00 41 - modify timing?
+ 6c 20 - length in milliseconds
+ 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+#### Offset: `N/A`
+
+## FF_RAMP
+
+Ramps seem to follow triangle wave parameters.
+
+### Init:
+```
+ 60 00 - standard header
+ 01 - ID
+ 6b - new ramp effect
+ f6 7f - difference ***
+ fe ff - level? *** (level = (if end_level > start_level, end_level, else
+ start_level) - difference?) (signed)
+ 00 00
+ f7 17 - time
+ 00 80 - some kind of marker
+ 00 00 - attack_length
+ f6 7f - attack_level ***
+ 00 00 - fade_length
+ f6 7f - fade_level***
+ 04 - invert (going "down", 05, going "up", 04)
+ 4f
+ f7 17 - time again?
+ 00 00
+ 00 00 - offset
+ 00 ff ff - end of init
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+### Modifying:
+```
+ 60 00 - standard header
+ 01 - ID
+ 0e - ???
+ 03 - ramp?
+ e3 04 - difference?
+ 7d 75 - "level"?
+ 05 - ????
+ 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+#### Envelope:
+```
+ 60 00 - standard header
+ 01 - ID
+ 31 - modify envelope
+ 84 - ID of envelope attribute ( attack_level 82,
+ attack_length 81,
+ fade_level 88,
+ fade_length 84 )
+ 63 04 - value attribute should be set to
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+#### Duration:
+```
+ 60 00
+ 01 - ID
+ 4e - ?
+ 08 - ?
+ 01 00 - time in milliseconds
+ 05 - ?
+ 41 - ?
+ 01 00 - time in milliseconds
+ 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+#### Offset: `N/A`
+
+## FF_SPRING:
+### Init:
+```
+ 60 00 - standard header
+ 01 - ID
+ 64 - new conditional effect
+ fc 7f - positive coefficient (right?)
+ fc 7f - negative coefficient (left?)
+ fe ff - deadband (left?) (deadband + offset) (fe ff means no deadband)
+ fe ff - deadband (right?) (deadband + offset)
+ a6 6a a6 6a fe ff fe ff fe ff fe ff df 58 a6 6a 06 - some weird hard-coded
+ values to do with springs?
+
+ 4f
+ f7 17 - duration
+ 00 00
+ 00 00 - offset
+ 00 ff ff - end of init
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+### Modifying:
+Same as below (FF_DAMPER + FF_FRICTION + FF_INERTIA)
+
+## FF_DAMPER + FF_FRICTION + FF_INERTIA:
+### Init:
+```
+ 60 00 - standard header
+ 02 -ID
+ 64 - new conditional effect
+ fc 7f - positive coefficient (right?)
+ fc 7f - negative coefficient (left?)
+ fe ff - deadband (left?) (deadband + offset) (fe ff means no deadband)
+ fe ff - deadband (right?) (deadband + offset)
+ fc 7f fc 7f fe ff fe ff fe ff fe ff fc 7f fc 7f 07 - some weird hard-coded
+ values to do with friction?
+ 4f
+ f7 17 - duration
+ 00 00
+ 00 00 - offset
+ 00 ff ff - end of init
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+### Modifying:
+```
+ positive coefficient:
+ 60 00
+ 02 - ID
+ 0e 41
+ 64 35 - value, signed (between 00 00 and 01 80?)
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ negative coefficient:
+ 60 00
+ 02 - ID
+ 0e 42
+ 64 35 - value, signed (between 00 00 and ff 7f?)
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ deadband/offset:
+ 60 00
+ 02 - ID
+ 0e 4c
+ 64 35 - deadband (right?) (deadband + offset) (fe ff means no deadband)
+ 00 00 - deadband (left?) (deadband + offset)
+ 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+### Duration:
+```
+ 60 00 - standard header
+ 01 - ID
+ 49 06 41 - modify timing?
+ 6c 20 - length in milliseconds
+ 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+### Offset: `N/A`
+
+## FF_PERIODIC:
+### Init
+```
+ 60 00 - standard header
+ 01 - ID
+ 6b - new periodic effect
+ 00 00 - magnitude ***
+ fe ff - offset (up/down)
+ 00 00 - phase (left/right)
+ e8 03 - period
+ 00 80
+ 00 00 - attack_length
+ 00 00 - attack_level ***
+ 00 00 - fade_length
+ 00 00 - fade_level ***
+ 01 - type of periodic ( square 01,
+ sine 03,
+ triangle 02,
+ sawtooth down 05,
+ sawtooth up 04 )
+ 4f
+ f7 17 - duration
+ 00 00
+ 00 00 - offset
+ 00 ff ff - end of init
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+### Modifying:
+```
+ magnitude:
+ 60 00
+ 02 - ID
+ 0e 01
+ 64 35 - value, signed (between 00 00 and ff 7f?)
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ offset of effect:
+ 60 00
+ 02 - ID
+ 0e 02
+ 64 35 - value, signed (between 00 00 and ff 7f?)
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ phase:
+ 60 00
+ 02 - ID
+ 0e 04
+ 64 35 - value, signed (between 80 01 and ff 7f?)
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ period:
+ 60 00
+ 02 - ID
+ 0e 08
+ 64 35 - value, signed (between 00 00 and I guess ff 7f?) (max value in
+ wireshark is 0d 07, but I don't know if that's a driver or program issue)
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+```
+
+### Envelope:
+```
+ 60 00 - standard header
+ 01 - ID
+ 31 - modify envelope
+ 84 - ID of envelope attribute ( attack_level 82,
+ attack_length 81,
+ fade_level 88,
+ fade_length 84 )
+ 63 04 - value attribute should be set to
+ 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+
+### Duration:
+```
+ Square:
+ 60 00
+ 01 - ID
+ 49 - ?
+ 01 - Effect type
+ 41 - ?
+ 4e 0c - Time in milliseconds
+ 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ Sine:
+ 60 00
+ 01 - ID
+ 49 - ?
+ 03 - Effect type
+ 41 - ?
+ ec 13 - Time in milliseconds
+ 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ Triangle:
+ 60 00
+ 01 - ID
+ 49 - ?
+ 02 - Effect type
+ 41 - ?
+ 4e 0c - Time in milliseconds
+ 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ Sawtooth up:
+ 60 00
+ 01 - ID
+ 49 - ?
+ 04 - Effect type
+ 41 - ?
+ 4e 0c - Time in milliseconds
+ 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+
+ Sawtooth down:
+ 60 00
+ 01 - ID
+ 49 - ?
+ 05 - Effect type
+ 41 - ?
+ ec 13 - Time in milliseconds
+ 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+```
+### Offset: `N/A ?`
+
+## PS4 Input `rdesc`
+```
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 226 /* wheel */
+ ff00.0021 = 125 /* wheel */
+ ff00.0021 = 255 /* gas */
+ ff00.0021 = 255 /* gas */
+ ff00.0021 = 255 /* brake */
+ ff00.0021 = 255 /* brake */
+ ff00.0021 = 255 /* clutch */
+ ff00.0021 = 255 /* clutch */
+ ff00.0021 = 0
+ ff00.0021 = 255
+ ff00.0021 = 255
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+ ff00.0021 = 0
+```
diff --git a/docs/INTEGRATION.md b/docs/INTEGRATION.md
new file mode 100644
index 0000000..bcdb9f4
--- /dev/null
+++ b/docs/INTEGRATION.md
@@ -0,0 +1,6 @@
+Some distros require more complicated installation methods than what's outlined
+in the README. This page is intended to collect information about the topic.
+
+# NixOS
+
+See https://github.com/Kimplul/hid-tmff2/issues/71.
diff --git a/docs/STRUCTURE.md b/docs/STRUCTURE.md
new file mode 100644
index 0000000..e7778ba
--- /dev/null
+++ b/docs/STRUCTURE.md
@@ -0,0 +1,42 @@
+# Structure of the Thrustmaster device 'stack'
+
++ `hid-tmff`
+
+Driver for older Thrustmaster wheels, has existed in the Kernel for a long time
+and I have nothing to with it.
+
++ `hid-thrustmaster`
+
+Driver for initializing newer Thrustmaster wheels, initially added in version
+5.13. Essentially `hid-tminit`, with some modifications to better fit into the
+kernel.
+
++ `hid-tminit`
+
+Driver for initializing newer Thrustmaster wheels, currently maintained over at
+https://github.com/scarburato/hid-tminit.
+
+All newer Thrustmaster wheels initially identify themselves as `Thrustmaster FFB
+Wheel`, and it is up to the `hid-tminit` driver to boot the wheel into its
+correct designation, after which the corresponding driver can take over. No FFB
+takes place while this driver is active.
+
++ `hid-tmff-new`
+
+Active driver module for different wheels, responsible for handling FFB.
+At the moment only supports T300 RS and T248. Note that the T300 RS has a number
+of different modes, of which PS3, PS4, and PS3 F1 (advanced) mode are known to
+work (at least on some systems, please open up any issues you encounter.)
+
++ `hid-tmff2`
+
+Name of this projects, initially I intended to write `hid-tmff` but for newer
+wheels, hence the name. Because of some slight weirdness in the Kernel build
+configuration, I couldn't use `hid-tmff2` as the module name, so I chose
+`hid-tmff-new`.
+
+I don't know exactly which wheels are 'newer' and which are 'older', but at
+least T150/T248/T300/T500 are in the 'newer' category.
+
+Note that the T150 already has a driver in a separate module
+(https://github.com/scarburato/t150_driver).
diff --git a/docs/effects/FFBEFFECTS_T248.md b/docs/effects/FFBEFFECTS_T248.md
deleted file mode 100644
index f43fb55..0000000
--- a/docs/effects/FFBEFFECTS_T248.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Force Feedback Effects - Thrustmaster T248
-
-## Open:
-Identical to [T300RS](./FFBEFFECTST300RS)
-
-## Close:
-Identical to [T300RS](./FFBEFFECTST300RS)
diff --git a/docs/effects/FFBEFFECTS_T300RS.md b/docs/effects/FFBEFFECTS_T300RS.md
deleted file mode 100644
index f076ec7..0000000
--- a/docs/effects/FFBEFFECTS_T300RS.md
+++ /dev/null
@@ -1,541 +0,0 @@
-# Force Feedback Effects - Thrustmaster T300RS (incl. PS3/PS4 modes)
-Here I will gather all info I can find out about the different force feedback effects and their USB commands. All values seem to be little-endian. Also, general note, it seems like some effects are affected by the direction of the force, denoted by `***`. As far as I can tell, `fade_level` and `attack_level` values are calculated by mapping the `u16` into `s16` and taking the absolute value, and after that multiplying by the direction.
-
-> **NOTE:** All values are examples of actual commands that I captured on the USB interface, not the only available ones.
-
-
-## GENERAL
-### Playing
-```
- 60 00 - standard header
- 01 - ID
- 89 - playing options
- 01 - play
- 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-### Stopping/removing (why are they rolled into one?)
-```
- 60 00 - standard header
- 01 - ID
- 89 - playing options
- 00 - stop
- 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-## Open:
-```
- 60 01 - standard header?
- 04 - ?
- 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- (this command doesn't appear every time, odd)
- 60 12 - ?
- bf 04 00 00 03 b7 1e - ? /* wow, this is different on different wheels? */
- 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- 60 01 - ?
- 05 - ?
- 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-## Close:
-```
- 60 01 - standard header?
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-## Rotation angle:
-```
- 60 08 - header plus settings?
- 11 - set rotation angle
- 55 d5 - angle (between ff ff and 7b 09, one degree is roughly 3c)
- 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-## FF_AUTOCENTER:
-```
- 60 08 - header plus settings?
- 03 - set autocenter force
- 8f 02 - force (between ff ff and 00 00)
- 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-## FF_GAIN:
-```
- 60 02 - header plus gain?
- bf - gain (between ff and 00)
- 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-## FF_CONSTANT
-### Initialization
-```
- 60 00 - standard header
- 01 - ID
- 6a - new constant effect(?)
- fe ff - strength ***
- 00 00 - attack_length
- 00 00 - attack_level ***
- 00 00 - fade_length
- 00 00 - fade_level ***
- 00 4f - ?
- f7 17 - time in milliseconds, unsigned
- 00 00
- 07 00 - offset from start(?)
- 00 ff ff - end of new effect(?)
- 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-### Modifying (For dynamic updating of effects)
-
-#### Direction: ``N/A``
-
-#### Constant force:
-```
-60 00 - standard header
-01 - ID
-0a - modify constant force
-05 16 - constant force ***
-00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-#### Envelope:
-```
-60 00 - standard header
-01 - ID
- 31 - modify envelope
-84 - ID of envelope attribute ( attack_level 82,
- attack_length 81,
- fade_level 88,
- fade_length 84 )
- 63 04 - value attribute should be set to ?***?
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-#### Duration:
-```
- 60 00 - standard header
- 01 - ID
- 49 00 41 - modify timing?
- 6c 20 - length in milliseconds
- 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-#### Offset: `N/A`
-
-## FF_RAMP
-(Why on earth is it this difficult to figure out how a ramp works?)
-### Init:
-```
- 60 00 - standard header
- 01 - ID
- 6b - new ramp effect
- f6 7f - difference ***
- fe ff - level? *** (level = (if end_level > start_level, end_level, else
- start_level) - difference?) (signed)
- 00 00
- f7 17 - time
- 00 80 - some kind of marker
- 00 00 - attack_length
- f6 7f - attack_level ***
- 00 00 - fade_length
- f6 7f - fade_level***
- 04 - invert (going "down", 05, going "up", 04)
- 4f
- f7 17 - time again?
- 00 00
- 00 00 - offset
- 00 ff ff - end of init
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-### Modifying:
-(Sweet baby jesus. I'll figure this out later ``Ramp(?)``)
-```
- 60 00 - standard header
- 01 - ID
- 0e - ???
- 03 - ramp?
- e3 04 - difference?
- 7d 75 - "level"?
- 05 - ????
- 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-#### Envelope:
-```
- 60 00 - standard header
- 01 - ID
- 31 - modify envelope
- 84 - ID of envelope attribute ( attack_level 82,
- attack_length 81,
- fade_level 88,
- fade_length 84 )
- 63 04 - value attribute should be set to
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-#### Duration:
-```
- 60 00
- 01 - ID
- 4e - ?
- 08 - ?
- 01 00 - time in milliseconds
- 05 - ?
- 41 - ?
- 01 00 - time in milliseconds
- 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-#### Offset: `N/A`
-
-## FF_SPRING:
-### Init:
-```
- 60 00 - standard header
- 01 - ID
- 64 - new conditional effect
- fc 7f - positive coefficient (right?)
- fc 7f - negative coefficient (left?)
- fe ff - deadband (left?) (deadband + offset) (fe ff means no deadband)
- fe ff - deadband (right?) (deadband + offset)
- a6 6a a6 6a fe ff fe ff fe ff fe ff df 58 a6 6a 06 - some weird hard-coded
- values to do with springs?
-
- 4f
- f7 17 - duration
- 00 00
- 00 00 - offset
- 00 ff ff - end of init
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-### Modifying:
-Same as below (FF_DAMPER + FF_FRICTION + FF_INERTIA)
-
-## FF_DAMPER + FF_FRICTION + FF_INERTIA:
-### Init:
-```
- 60 00 - standard header
- 02 -ID
- 64 - new conditional effect
- fc 7f - positive coefficient (right?)
- fc 7f - negative coefficient (left?)
- fe ff - deadband (left?) (deadband + offset) (fe ff means no deadband)
- fe ff - deadband (right?) (deadband + offset)
- fc 7f fc 7f fe ff fe ff fe ff fe ff fc 7f fc 7f 07 - some weird hard-coded
- values to do with friction?
- 4f
- f7 17 - duration
- 00 00
- 00 00 - offset
- 00 ff ff - end of init
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-### Modifying:
-```
- positive coefficient:
- 60 00
- 02 - ID
- 0e 41
- 64 35 - value, signed (between 00 00 and 01 80?)
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- negative coefficient:
- 60 00
- 02 - ID
- 0e 42
- 64 35 - value, signed (between 00 00 and ff 7f?)
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- deadband/offset:
- 60 00
- 02 - ID
- 0e 4c
- 64 35 - deadband (right?) (deadband + offset) (fe ff means no deadband)
- 00 00 - deadband (left?) (deadband + offset)
- 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-### Duration:
-```
- 60 00 - standard header
- 01 - ID
- 49 06 41 - modify timing?
- 6c 20 - length in milliseconds
- 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-### Offset: `N/A`
-
-## FF_PERIODIC:
-### Init
-```
- 60 00 - standard header
- 01 - ID
- 6b - new periodic effect
- 00 00 - magnitude ***
- fe ff - offset (up/down)
- 00 00 - phase (left/right)
- e8 03 - period
- 00 80
- 00 00 - attack_length
- 00 00 - attack_level ***
- 00 00 - fade_length
- 00 00 - fade_level ***
- 01 - type of periodic ( square 01,
- sine 03,
- triangle 02,
- sawtooth down 05,
- sawtooth up 04 )
- 4f
- f7 17 - duration
- 00 00
- 00 00 - offset
- 00 ff ff - end of init
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-### Modifying:
-```
- magnitude:
- 60 00
- 02 - ID
- 0e 01
- 64 35 - value, signed (between 00 00 and ff 7f?)
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- offset of effect:
- 60 00
- 02 - ID
- 0e 02
- 64 35 - value, signed (between 00 00 and ff 7f?)
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- phase:
- 60 00
- 02 - ID
- 0e 04
- 64 35 - value, signed (between 80 01 and ff 7f?)
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- period:
- 60 00
- 02 - ID
- 0e 08
- 64 35 - value, signed (between 00 00 and I guess ff 7f?) (max value in
- wireshark is 0d 07, but I don't know if that's a driver or program issue)
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
-```
-
-### Envelope:
-```
- 60 00 - standard header
- 01 - ID
- 31 - modify envelope
- 84 - ID of envelope attribute ( attack_level 82,
- attack_length 81,
- fade_level 88,
- fade_length 84 )
- 63 04 - value attribute should be set to
- 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-
-### Duration:
-```
- Square:
- 60 00
- 01 - ID
- 49 - ?
- 01 - Effect type
- 41 - ?
- 4e 0c - Time in milliseconds
- 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- Sine:
- 60 00
- 01 - ID
- 49 - ?
- 03 - Effect type
- 41 - ?
- ec 13 - Time in milliseconds
- 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- Triangle:
- 60 00
- 01 - ID
- 49 - ?
- 02 - Effect type
- 41 - ?
- 4e 0c - Time in milliseconds
- 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- Sawtooth up:
- 60 00
- 01 - ID
- 49 - ?
- 04 - Effect type
- 41 - ?
- 4e 0c - Time in milliseconds
- 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-
- Sawtooth down:
- 60 00
- 01 - ID
- 49 - ?
- 05 - Effect type
- 41 - ?
- ec 13 - Time in milliseconds
- 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
-```
-### Offset: `N/A ?`
-
-## PS4 Input
-```
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 226 /* wheel */
-ff00.0021 = 125 /* wheel */
-ff00.0021 = 255 /* gas */
-ff00.0021 = 255 /* gas */
-ff00.0021 = 255 /* brake */
-ff00.0021 = 255 /* brake */
-ff00.0021 = 255 /* clutch */
-ff00.0021 = 255 /* clutch */
-ff00.0021 = 0
-ff00.0021 = 255
-ff00.0021 = 255
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-ff00.0021 = 0
-```