Skip to content

Commit b41f652

Browse files
Enhance gaming mode edge switching with vertical movement checks and configuration refinements.
1 parent 3f83640 commit b41f652

File tree

12 files changed

+251
-92
lines changed

12 files changed

+251
-92
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
build
22

33
.idea/
4+
.aider*

disk/disk.img

0 Bytes
Binary file not shown.

src/defaults.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ const config_t default_config = {
2323
.jump_threshold = JUMP_THRESHOLD,
2424

2525
.gaming_mode_on_boot = true,
26-
.gaming_edge_enabled = false,
27-
.gaming_edge_threshold = 500,
28-
.gaming_edge_window_ms = 500,
26+
.gaming_edge_enabled = false, // Global gaming edge switching disabled by default
2927

3028
.output = {
3129
[OUTPUT_A] = {
@@ -45,7 +43,10 @@ const config_t default_config = {
4543
.only_if_inactive = SCREENSAVER_A_ONLY_IF_INACTIVE,
4644
.idle_time_us = (uint64_t)SCREENSAVER_A_IDLE_TIME_SEC * 1000000,
4745
.max_time_us = (uint64_t)SCREENSAVER_A_MAX_TIME_SEC * 1000000,
48-
}
46+
},
47+
.gaming_edge_threshold = GAMING_EDGE_THRESHOLD,
48+
.gaming_edge_window_ms = GAMING_EDGE_WINDOW_MS,
49+
.gaming_edge_max_vertical = GAMING_EDGE_MAX_VERTICAL,
4950
},
5051
[OUTPUT_B] = {
5152
.number = OUTPUT_B,
@@ -64,7 +65,10 @@ const config_t default_config = {
6465
.only_if_inactive = SCREENSAVER_B_ONLY_IF_INACTIVE,
6566
.idle_time_us = (uint64_t)SCREENSAVER_B_IDLE_TIME_SEC * 1000000,
6667
.max_time_us = (uint64_t)SCREENSAVER_B_MAX_TIME_SEC * 1000000,
67-
}
68+
},
69+
.gaming_edge_threshold = GAMING_EDGE_THRESHOLD,
70+
.gaming_edge_window_ms = GAMING_EDGE_WINDOW_MS,
71+
.gaming_edge_max_vertical = GAMING_EDGE_MAX_VERTICAL,
6872
}
6973
}
7074
};

src/include/config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include "misc.h"
1616
#include "screen.h"
1717

18-
#define CURRENT_CONFIG_VERSION 10
18+
#define CURRENT_CONFIG_VERSION 9
1919

2020
/*==============================================================================
2121
* Configuration Data

src/include/screen.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,9 @@ typedef struct {
4848
uint8_t pos; // Screen position on this output
4949
uint8_t mouse_park_pos; // Where the mouse goes after switch
5050
screensaver_t screensaver; // Screensaver parameters for this output
51+
52+
// Gaming mode edge switching per output (except enabled flag which is global)
53+
uint32_t gaming_edge_threshold;
54+
uint32_t gaming_edge_window_ms;
55+
uint32_t gaming_edge_max_vertical; // M2aximum allowed vertical movement
5156
} output_t;

src/include/structs.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,7 @@ typedef struct {
8080
uint16_t jump_threshold;
8181

8282
uint8_t gaming_mode_on_boot;
83-
84-
uint8_t gaming_edge_enabled;
85-
uint16_t gaming_edge_threshold;
86-
uint16_t gaming_edge_window_ms;
83+
uint8_t gaming_edge_enabled; // Global enable for edge switching in gaming mode
8784

8885
output_t output[NUM_SCREENS];
8986
uint32_t _reserved;
@@ -151,7 +148,8 @@ typedef struct {
151148
bool digitizer_active; // True when digitizer Win/Mac workaround is active
152149

153150
/* Gaming mode edge switching state */
154-
int32_t gaming_edge_accum; // Accumulated movement toward edge in gaming mode
151+
uint32_t gaming_edge_accum; // Accumulated horizontal movement toward edge in gaming mode
152+
int32_t gaming_edge_vertical_accum; // Accumulated net vertical movement during edge detection (can be negative)
155153
uint64_t gaming_edge_last_reset; // Timestamp of last accumulator reset
156154

157155
/* Onboard LED blinky (provide feedback when e.g. mouse connected) */

src/include/user_config.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,27 @@
8282
/* Mouse acceleration */
8383
#define ENABLE_ACCELERATION 1
8484

85+
/**================================================== *
86+
* =========== Gaming Edge Switching ============== *
87+
* ================================================== *
88+
*
89+
* Gaming mode edge switching allows switching outputs in gaming mode
90+
* by moving the mouse toward the edge of the screen.
91+
*
92+
* GAMING_EDGE_THRESHOLD: [0-4294967295], accumulated horizontal movement needed
93+
* to trigger a switch (in mouse movement units)
94+
* GAMING_EDGE_WINDOW_MS: [0-4294967295], time window in milliseconds for
95+
* accumulating movement (max ~49 days)
96+
* GAMING_EDGE_MAX_VERTICAL: [0-4294967295], maximum allowed vertical movement
97+
* during edge detection (prevents accidental switches
98+
* when moving mouse diagonally)
99+
*
100+
* */
101+
102+
#define GAMING_EDGE_THRESHOLD 20000
103+
#define GAMING_EDGE_WINDOW_MS 1000
104+
#define GAMING_EDGE_MAX_VERTICAL 2000
105+
85106
/**================================================== *
86107
* ============== Screensaver Config ============== *
87108
* ================================================== *

src/mouse.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -321,14 +321,15 @@ mouse_report_t create_mouse_report(device_t *state, mouse_values_t *values) {
321321
return mouse_report;
322322
}
323323

324-
enum screen_pos_e check_gaming_edge_switch(device_t *state, int offset_x) {
324+
enum screen_pos_e check_gaming_edge_switch(device_t *state, int offset_x, int offset_y) {
325+
output_t *output = &state->config.output[state->active_output];
326+
325327
// Feature disabled - return early
326328
if (!state->config.gaming_edge_enabled || !state->gaming_mode)
327329
return NONE;
328330

329-
output_t *output = &state->config.output[state->active_output];
330331
uint64_t now = time_us_64();
331-
uint64_t window_us = state->config.gaming_edge_window_ms * 1000;
332+
uint64_t window_us = (uint64_t)output->gaming_edge_window_ms * 1000;
332333

333334
// Determine which direction would switch screens
334335
enum screen_pos_e switch_direction = (output->pos == LEFT) ? RIGHT : LEFT;
@@ -337,24 +338,42 @@ enum screen_pos_e check_gaming_edge_switch(device_t *state, int offset_x) {
337338
bool moving_toward_switch = (switch_direction == LEFT && offset_x < 0) ||
338339
(switch_direction == RIGHT && offset_x > 0);
339340

340-
// Reset accumulator if:
341+
// Reset accumulators if:
341342
// - Time window expired
342343
// - Moving in opposite direction
344+
// - Vertical movement exceeds maximum allowed
345+
bool reset_needed = false;
346+
343347
if ((now - state->gaming_edge_last_reset) > window_us || !moving_toward_switch) {
348+
reset_needed = true;
349+
}
350+
351+
// Update vertical accumulation
352+
state->gaming_edge_vertical_accum += offset_y;
353+
354+
uint32_t abs_vertical = (state->gaming_edge_vertical_accum < 0)
355+
? -(uint32_t)state->gaming_edge_vertical_accum
356+
: (uint32_t)state->gaming_edge_vertical_accum;
357+
if (abs_vertical > output->gaming_edge_max_vertical) {
358+
reset_needed = true;
359+
}
360+
if (reset_needed) {
344361
state->gaming_edge_accum = 0;
362+
state->gaming_edge_vertical_accum = 0;
345363
state->gaming_edge_last_reset = now;
346364

347365
// If not moving toward switch, return early
348366
if (!moving_toward_switch)
349367
return NONE;
350368
}
351369

352-
// Accumulate movement (use absolute value)
353-
state->gaming_edge_accum += abs(offset_x);
370+
// Accumulate horizontal movement (use absolute value)
371+
state->gaming_edge_accum += (uint32_t)abs(offset_x);
354372

355373
// Check if threshold exceeded
356-
if (state->gaming_edge_accum >= state->config.gaming_edge_threshold) {
374+
if (state->gaming_edge_accum >= output->gaming_edge_threshold) {
357375
state->gaming_edge_accum = 0;
376+
state->gaming_edge_vertical_accum = 0;
358377
state->gaming_edge_last_reset = now;
359378
return switch_direction;
360379
}
@@ -373,14 +392,15 @@ void process_mouse_report(uint8_t *raw_report, int len, uint8_t itf, hid_interfa
373392
enum screen_pos_e switch_direction = update_mouse_position(state, &values);
374393

375394
/* Check for gaming mode edge switching */
376-
if (state->gaming_mode && state->config.gaming_edge_enabled) {
395+
if (state->gaming_mode) {
377396
// Use the acceleration-adjusted offset from update_mouse_position
378397
output_t *current = &state->config.output[state->active_output];
379398
uint8_t reduce_speed = state->mouse_zoom ? MOUSE_ZOOM_SCALING_FACTOR : 0;
380399
float acceleration_factor = calculate_mouse_acceleration_factor(values.move_x, values.move_y);
381400
int offset_x = round(values.move_x * acceleration_factor * (current->speed_x >> reduce_speed));
401+
int offset_y = round(values.move_y * acceleration_factor * (current->speed_y >> reduce_speed));
382402

383-
switch_direction = check_gaming_edge_switch(state, offset_x);
403+
switch_direction = check_gaming_edge_switch(state, offset_x, offset_y);
384404
}
385405

386406
/* Create the report for the output PC based on the updated values */
@@ -432,4 +452,4 @@ void queue_mouse_report(mouse_report_t *report, device_t *state) {
432452
return;
433453

434454
queue_try_add(&state->mouse_queue, report);
435-
}
455+
}

src/protocol.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,14 @@ const field_map_t api_field_map[] = {
3030
{ 19, false, UINT8, 1, offsetof(device_t, config.output[0].screensaver.mode) },
3131
{ 20, false, UINT8, 1, offsetof(device_t, config.output[0].screensaver.only_if_inactive) },
3232

33-
/* Until we increase the payload size from 8 bytes, clamp to avoid exceeding the field size */
34-
{ 21, false, UINT64, 7, offsetof(device_t, config.output[0].screensaver.idle_time_us) },
35-
{ 22, false, UINT64, 7, offsetof(device_t, config.output[0].screensaver.max_time_us) },
33+
/* Screensaver idle and max times (64-bit values) */
34+
{ 21, false, UINT64, 8, offsetof(device_t, config.output[0].screensaver.idle_time_us) },
35+
{ 22, false, UINT64, 8, offsetof(device_t, config.output[0].screensaver.max_time_us) },
36+
37+
/* Gaming edge settings for Output A */
38+
{ 23, false, UINT32, 4, offsetof(device_t, config.output[0].gaming_edge_threshold) },
39+
{ 24, false, UINT32, 4, offsetof(device_t, config.output[0].gaming_edge_window_ms) },
40+
{ 25, false, UINT32, 4, offsetof(device_t, config.output[0].gaming_edge_max_vertical) },
3641

3742
/* Output B */
3843
{ 40, false, UINT32, 4, offsetof(device_t, config.output[1].number) },
@@ -46,8 +51,14 @@ const field_map_t api_field_map[] = {
4651
{ 48, false, UINT8, 1, offsetof(device_t, config.output[1].mouse_park_pos) },
4752
{ 49, false, UINT8, 1, offsetof(device_t, config.output[1].screensaver.mode) },
4853
{ 50, false, UINT8, 1, offsetof(device_t, config.output[1].screensaver.only_if_inactive) },
49-
{ 51, false, UINT64, 7, offsetof(device_t, config.output[1].screensaver.idle_time_us) },
50-
{ 52, false, UINT64, 7, offsetof(device_t, config.output[1].screensaver.max_time_us) },
54+
/* Screensaver idle and max times (64-bit values) */
55+
{ 51, false, UINT64, 8, offsetof(device_t, config.output[1].screensaver.idle_time_us) },
56+
{ 52, false, UINT64, 8, offsetof(device_t, config.output[1].screensaver.max_time_us) },
57+
58+
/* Gaming edge settings for Output B */
59+
{ 53, false, UINT32, 4, offsetof(device_t, config.output[1].gaming_edge_threshold) },
60+
{ 54, false, UINT32, 4, offsetof(device_t, config.output[1].gaming_edge_window_ms) },
61+
{ 55, false, UINT32, 4, offsetof(device_t, config.output[1].gaming_edge_max_vertical) },
5162

5263
/* Common config */
5364
{ 70, false, UINT32, 4, offsetof(device_t, config.version) },
@@ -60,8 +71,6 @@ const field_map_t api_field_map[] = {
6071
{ 77, false, UINT16, 2, offsetof(device_t, config.jump_threshold) },
6172
{ 83, false, UINT8, 1, offsetof(device_t, config.gaming_mode_on_boot) },
6273
{ 84, false, UINT8, 1, offsetof(device_t, config.gaming_edge_enabled) },
63-
{ 85, false, UINT16, 2, offsetof(device_t, config.gaming_edge_threshold) },
64-
{ 86, false, UINT16, 2, offsetof(device_t, config.gaming_edge_window_ms) },
6574

6675
/* Firmware */
6776
{ 78, true, UINT16, 2, offsetof(device_t, _running_fw.version) },

0 commit comments

Comments
 (0)