Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Implementing FFB support #27

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

Ultrawipf
Copy link

@Ultrawipf Ultrawipf commented Oct 24, 2024

This change adds full FFB packet parsing into python dicts using callback functions and the missing FFB related functions from the vJoy sdk.

Solves issue #17

A helper class for receiving and translating C style structs to python dicts using integrated vJoy functions was added in sdk.py.
If preferred it may be possible to split some functionality into sdk and vjoydevice as it did require some higher level processing.

Using different or the same callbacks per device is possible. The callbacks are stored by rID and called based on the source.
Multiple FFB devices are supported.
Parsed FFB data is can be parsed into dicts.

Info: This has not yet been extensively used yet but all reports have been tested and verified and should contain valid data.

Note: _wrapper.py was not touched. It seems like this file is not in use anymore. Possibly delete the whole file?
The duplicated SetBtn function was also deleted.

Example usage:

j = pyvjoy.VJoyDevice(1)

class EffMan(pyvjoy.FFB_Effect_Manager):
     
    def update_ctrl_cb(self,ctrl):
        print("Control",ctrl)

    def update_effect_op_cb(self,enabled,idx):
        print(f"Effect {idx} state change {enabled}")
    
    def update_effect_cb(self,data,idx):
        print("Data",data)

    def update_condition_cb(self,data,idx):
        print("cond",data)
    def update_constant_cb(self,data,idx):
        print("CF",data["Magnitude"])

effectManager1 = EffMan()


if j.ffb_supported():
    print("J1 support")
    effectManager1.ffb_register_callback(j)


time.sleep(100)
print("End")

For testing "fedit.exe" or the iracing wheelcheck tool can be used.
The sdk callback returns parsed structs and a packet type (previously directly as a dict but that might be too restrictive).

A dict of the packet can be generated using a static helper function ffb_packet_to_dict(packet,packettype) which can then directly update an effect dict if a block index is present and returns the dict and an effect block index.

An effect block index of 0 means that this packet does not address a specific effect and must be treated as a global control report.

Note: vjoy only seems to return block index 1 for all effects even if multiple effects are in use. This is problematic as it would only work well with a single effect.
From version 2.2.x on of the BrunnerInnovation fork (https://github.com/BrunnerInnovation/vJoy) it uses the effect block index correctly allowing multiple effects to be used.

Type is one of the newly added "PT_" constants.

Valid packet names generated by the ffb_packet_to_dict to function are:

  • ctrl : device control report. Enable or disable actuators.
  • effect: Set effect report. Changes effect parameters.
  • ramp: Ramp report. Changes parameters of a ramp effect.
  • effop: Effect operation. Enables or disables a specific effect.
  • period: Period effect report. Changes periodic effects.
  • cond: Conditional effect report. Changes conditional effects.
  • envelope: Envelope report.
  • neweff: New effect report. Called when a new effect is created at EffectBlockIndex.
  • const: Constant force report. Changes magnitude of constant force effects.
  • gain: Changes total gain of device.
  • blkfree: Block free report. Deletes an effect from EffectBlockIndex.

The FFB_Effect_Manager helper class makes the effect management easy by keeping track of effect states internally and splitting reports into separate callbacks that can be implemented in a custom version like in the example snippet.

In the default implementation it also keeps track of all the latest effect states in the internal self.effects list per block index.

@Ultrawipf Ultrawipf marked this pull request as ready for review January 5, 2025 20:22
@Ultrawipf
Copy link
Author

Keeping this open for some time until I need to update the master source branch.

If there is no reply it is getting closed and a fork will remain with the new features.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant