aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2024-06-20 17:44:29 +0100
committerGitHub <noreply@github.com>2024-06-20 17:44:29 +0100
commit7237249d7d28bd754fa6d42e8697e7442b34c539 (patch)
tree1d991826e67c5c29c2d62589017c71e1c7c7528c /src
parentef4bf8202544a3be15516ec1d14757b61501377c (diff)
parent5d3ca03ab5ebdf40d78fe9e8c2551cf7af81bc8b (diff)
downloadhid-tmff2-7237249d7d28bd754fa6d42e8697e7442b34c539.tar.gz
hid-tmff2-7237249d7d28bd754fa6d42e8697e7442b34c539.zip
Merge pull request #105 from MmAaXx500/forcecorrect
Force effect corrections part1
Diffstat (limited to 'src')
-rw-r--r--src/tmt300rs/hid-tmt300rs.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/src/tmt300rs/hid-tmt300rs.c b/src/tmt300rs/hid-tmt300rs.c
index 24354ca..9b5d22d 100644
--- a/src/tmt300rs/hid-tmt300rs.c
+++ b/src/tmt300rs/hid-tmt300rs.c
@@ -344,6 +344,32 @@ static u8 damper_values[] = {
0x7f, 0x07
};
+static void t300rs_calculate_periodic_values(struct ff_effect *effect)
+{
+ struct ff_periodic_effect *periodic = &effect->u.periodic;
+ int16_t headroom;
+
+ effect->replay.length -= 1;
+
+ periodic->magnitude = (periodic->magnitude * fixp_sin16(effect->direction * 360 / 0x10000)) / 0x7fff;
+
+ if (periodic->magnitude < 0){
+ /* the wheel handles positive magnitudes only */
+ periodic->magnitude = -periodic->magnitude;
+
+ /* to give the expected result 180 deg is added to the phase */
+ periodic->phase = (periodic->phase + (0x10000 / 2)) % 0x10000;
+ }
+
+ /* the interval [0; 32677[ is used by the wheel for the [0; 360[ degree phase shift */
+ periodic->phase = periodic->phase * 32677 / 0x10000;
+
+ headroom = 0x7FFF - periodic->magnitude;
+ /* magnitude + offset cannot be outside the valid magnitude range, */
+ /* otherwise the wheel behaves incorrectly */
+ periodic->offset = clamp(periodic->offset, -headroom, headroom);
+}
+
int t300rs_send_buf(struct t300rs_device_entry *t300rs, u8 *send_buffer, size_t len)
{
int i;
@@ -636,6 +662,8 @@ static int t300rs_update_constant(struct t300rs_device_entry *t300rs,
int16_t level;
level = (constant.level * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff;
+ /* the Windows driver uses the range [-16385;16381] */
+ level = level / 2;
if ((constant.level != constant_old.level) || (effect.direction != old.direction)) {
@@ -832,26 +860,30 @@ static int t300rs_update_spring(struct t300rs_device_entry *t300rs,
return t300rs_update_damper(t300rs, state);
}
-
static int t300rs_update_periodic(struct t300rs_device_entry *t300rs,
struct tmff2_effect_state *state)
{
struct ff_effect effect = state->effect;
struct ff_effect old = state->old;
- struct ff_periodic_effect periodic = effect.u.periodic;
- struct ff_periodic_effect periodic_old = old.u.periodic;
struct __packed t300rs_packet_mod_periodic {
struct t300rs_packet_header header;
uint8_t attribute;
uint16_t value;
} *packet_mod_periodic = (struct t300rs_packet_mod_periodic *)t300rs->send_buffer;
+ struct ff_periodic_effect periodic, periodic_old;
int ret;
- int16_t magnitude, phase;
+ uint16_t phase;
+ int16_t magnitude;
- magnitude = (periodic.magnitude * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff;
+ t300rs_calculate_periodic_values(&effect);
+ periodic = effect.u.periodic;
+ magnitude = periodic.magnitude;
phase = periodic.phase;
+ t300rs_calculate_periodic_values(&old);
+ periodic_old = old.u.periodic;
+
if ((periodic.magnitude != periodic_old.magnitude)
|| (effect.direction != old.direction)) {
@@ -954,6 +986,8 @@ static int t300rs_upload_constant(struct t300rs_device_entry *t300rs,
int ret;
level = (constant.level * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff;
+ /* the Windows driver uses the range [-16385;16381] */
+ level = level / 2;
duration = effect.replay.length - 1;
offset = effect.replay.delay;
@@ -1127,7 +1161,6 @@ static int t300rs_upload_periodic(struct t300rs_device_entry *t300rs,
struct tmff2_effect_state *state)
{
struct ff_effect effect = state->effect;
- struct ff_periodic_effect periodic = state->effect.u.periodic;
struct __packed t300rs_packet_periodic {
struct t300rs_packet_header header;
uint16_t magnitude;
@@ -1140,19 +1173,20 @@ static int t300rs_upload_periodic(struct t300rs_device_entry *t300rs,
struct t300rs_packet_timing timing;
} *packet_periodic = (struct t300rs_packet_periodic *)t300rs->send_buffer;
+ struct ff_periodic_effect periodic;
int ret;
- uint16_t duration, period, offset, periodic_offset;
- int16_t phase, magnitude;
-
- duration = effect.replay.length - 1;
- magnitude = (periodic.magnitude * fixp_sin16(effect.direction * 360 / 0x10000)) / 0x7fff;
+ uint16_t duration, period, phase, offset, periodic_offset;
+ int16_t magnitude;
+ t300rs_calculate_periodic_values(&effect);
+ periodic = effect.u.periodic;
+ duration = effect.replay.length;
+ offset = effect.replay.delay;
+ magnitude = periodic.magnitude;
+ period = periodic.period;
phase = periodic.phase;
periodic_offset = periodic.offset;
- period = periodic.period;
- offset = effect.replay.delay;
-
t300rs_fill_header(&packet_periodic->header, effect.id, 0x6b);
packet_periodic->magnitude = cpu_to_le16(magnitude);