Skip to content

Commit 8f48288

Browse files
committed
Add tilt support to DFT processor
1 parent b9a1f1f commit 8f48288

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

src/daemon/config.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,15 @@ static int parse_conf(void *user, const char *c_section, const char *c_name, con
117117
if (section == "DFT" && name == "FreqMinMag")
118118
config->dft_freq_min_mag = std::stoi(value);
119119

120+
if (section == "DFT" && name == "TiltMinMag")
121+
config->dft_tilt_min_mag = std::stoi(value);
122+
123+
if (section == "DFT" && name == "TiltDistance")
124+
config->dft_tilt_distance = std::stof(value);
125+
126+
if (section == "DFT" && name == "TipDistance")
127+
config->dft_tip_distance = std::stof(value);
128+
120129
return 1;
121130
}
122131

src/daemon/config.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class Config {
3939
f32 dft_position_exp = -0.7;
4040
u16 dft_button_min_mag = 1000;
4141
u16 dft_freq_min_mag = 10000;
42+
u16 dft_tilt_min_mag = 10000;
43+
f32 dft_tilt_distance = 6;
44+
f32 dft_tip_distance = 2;
4245

4346
i16 vendor;
4447
i16 product;

src/daemon/dft.cpp

+42-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ static f64 iptsd_dft_interpolate_frequency(const Context &ctx, const ipts::DftWi
130130
static void iptsd_dft_handle_position(Context &ctx, const ipts::DftWindow &dft,
131131
ipts::StylusData &stylus)
132132
{
133-
if (dft.rows <= 0) {
133+
if (dft.rows <= 1) {
134134
iptsd_dft_lift(stylus);
135135
return;
136136
}
@@ -161,6 +161,47 @@ static void iptsd_dft_handle_position(Context &ctx, const ipts::DftWindow &dft,
161161
if (ctx.config.invert_y)
162162
y = 1 - y;
163163

164+
if (dft.x[1].magnitude > ctx.config.dft_tilt_min_mag &&
165+
dft.y[1].magnitude > ctx.config.dft_tilt_min_mag) {
166+
167+
// calculate tilt angle from relative position of secondary transmitter
168+
169+
auto [pxt, xt] = iptsd_dft_interpolate_position(ctx, dft.x[1]);
170+
auto [pyt, yt] = iptsd_dft_interpolate_position(ctx, dft.y[1]);
171+
172+
if (pxt && pyt) {
173+
174+
xt /= dft.dim.width - 1;
175+
yt /= dft.dim.height - 1;
176+
177+
if (ctx.config.invert_x)
178+
xt = 1 - xt;
179+
180+
if (ctx.config.invert_y)
181+
yt = 1 - yt;
182+
183+
xt -= x;
184+
yt -= y;
185+
186+
if (ctx.config.dft_tip_distance) {
187+
// correct tip position using tilt data
188+
auto r = ctx.config.dft_tip_distance / ctx.config.dft_tilt_distance;
189+
x -= xt * r;
190+
y -= yt * r;
191+
}
192+
193+
xt *= ctx.config.width / (ctx.config.dft_tilt_distance * 10);
194+
yt *= ctx.config.height / (ctx.config.dft_tilt_distance * 10);
195+
196+
auto azm = std::max(0., std::fmod(std::atan2(-yt, xt) / M_PI + 2, 2)) * 18000;
197+
auto alt = (.5 - std::acos(std::min(1., std::hypot(xt, yt))) / M_PI) * 18000;
198+
stylus.azimuth = gsl::narrow<u16>(std::round(azm));
199+
stylus.altitude = gsl::narrow<u16>(std::round(alt));
200+
201+
}
202+
203+
}
204+
164205
x = std::round(std::clamp(x, 0.0, 1.0) * IPTS_MAX_X);
165206
y = std::round(std::clamp(y, 0.0, 1.0) * IPTS_MAX_Y);
166207

0 commit comments

Comments
 (0)