Reduce touch overhead and cap frame rate at 24 FPS
This commit is contained in:
@@ -722,13 +722,13 @@ int main()
|
|||||||
|
|
||||||
printf("\nEntering reactive game loop (Core 0 - input & logic)\n");
|
printf("\nEntering reactive game loop (Core 0 - input & logic)\n");
|
||||||
printf("Display refreshes handled by Core 1\n");
|
printf("Display refreshes handled by Core 1\n");
|
||||||
printf("Frame rate limited to 30 FPS (33.3ms per frame)\n\n");
|
printf("Frame rate limited to 24 FPS (41.7ms per frame)\n\n");
|
||||||
|
|
||||||
Game* current_game = nullptr;
|
Game* current_game = nullptr;
|
||||||
uint32_t game_start_time = 0;
|
uint32_t game_start_time = 0;
|
||||||
|
|
||||||
// Frame rate limiting (30 FPS = 33.33ms per frame)
|
// Frame rate limiting (24 FPS = 41.67ms per frame)
|
||||||
const uint32_t TARGET_FRAME_TIME_MS = 33; // 1000ms / 30fps ≈ 33ms
|
const uint32_t TARGET_FRAME_TIME_MS = 42; // 1000ms / 24fps ≈ 41.7ms
|
||||||
uint32_t last_frame_time = 0;
|
uint32_t last_frame_time = 0;
|
||||||
|
|
||||||
bool needs_refresh = false; // Track if screen needs redraw
|
bool needs_refresh = false; // Track if screen needs redraw
|
||||||
@@ -990,7 +990,7 @@ int main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Redraw and queue async refresh on Core 1 (with 30 FPS limiting)
|
// 4. Redraw and queue async refresh on Core 1 (with 24 FPS limiting)
|
||||||
if (needs_refresh || pending_refresh) {
|
if (needs_refresh || pending_refresh) {
|
||||||
// Check frame rate limiting
|
// Check frame rate limiting
|
||||||
uint32_t current_time = to_ms_since_boot(get_absolute_time());
|
uint32_t current_time = to_ms_since_boot(get_absolute_time());
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ static bool ft6336u_read_reg(uint8_t reg, uint8_t *value) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add delay after write, before read (like Arduino library does)
|
// Short settle time between register address write and read.
|
||||||
sleep_us(10000); // 10ms delay
|
// 10ms here heavily throttles touch sampling during hold/move.
|
||||||
|
sleep_us(100); // 0.1ms
|
||||||
|
|
||||||
result = i2c_read_blocking(g_config->i2c, FT6336U_ADDR, value, 1, false);
|
result = i2c_read_blocking(g_config->i2c, FT6336U_ADDR, value, 1, false);
|
||||||
if (result == 1) {
|
if (result == 1) {
|
||||||
@@ -50,8 +51,9 @@ static bool ft6336u_read_regs(uint8_t reg, uint8_t *buf, size_t len) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add delay after write, before read (like Arduino library does)
|
// Short settle time between register address write and read.
|
||||||
sleep_us(10000); // 10ms delay
|
// 10ms here heavily throttles touch sampling during hold/move.
|
||||||
|
sleep_us(100); // 0.1ms
|
||||||
|
|
||||||
result = i2c_read_blocking(g_config->i2c, FT6336U_ADDR, buf, len, false);
|
result = i2c_read_blocking(g_config->i2c, FT6336U_ADDR, buf, len, false);
|
||||||
if (result == (int)len) {
|
if (result == (int)len) {
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ bool InputManager::has_buttons() const {
|
|||||||
|
|
||||||
InputEvent InputManager::process_touch_input(uint32_t* last_time) {
|
InputEvent InputManager::process_touch_input(uint32_t* last_time) {
|
||||||
InputEvent event = {INPUT_NONE, 0, 0, 0, 0, 0, false};
|
InputEvent event = {INPUT_NONE, 0, 0, 0, 0, 0, false};
|
||||||
|
const uint32_t now = to_ms_since_boot(get_absolute_time());
|
||||||
|
static constexpr uint32_t ACTIVE_TOUCH_SAMPLE_INTERVAL_MS = 8;
|
||||||
|
|
||||||
// Process immediately on IRQ, and continue sampling while a touch is active.
|
// Process immediately on IRQ, and continue sampling while a touch is active.
|
||||||
// Some controllers only IRQ on edge transitions, so move events require polling.
|
// Some controllers only IRQ on edge transitions, so move events require polling.
|
||||||
@@ -47,16 +49,26 @@ InputEvent InputManager::process_touch_input(uint32_t* last_time) {
|
|||||||
return event; // No touch event
|
return event; // No touch event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// While a touch session is active, avoid reading touch hardware every loop
|
||||||
|
// iteration. IRQ edges (down/up) still bypass this throttle for responsiveness.
|
||||||
|
if (!touch_interrupt_flag && *last_time != 0) {
|
||||||
|
uint32_t elapsed = now - last_touch_sample_ms;
|
||||||
|
if (elapsed < ACTIVE_TOUCH_SAMPLE_INTERVAL_MS) {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Always validate via controller state instead of relying on edge flag alone.
|
// Always validate via controller state instead of relying on edge flag alone.
|
||||||
// Edge chatter can flip touch_event_down without a real touch transition.
|
// Edge chatter can flip touch_event_down without a real touch transition.
|
||||||
TouchData touch_data;
|
TouchData touch_data;
|
||||||
if (!touch || !touch->read_touch(&touch_data)) {
|
if (!touch || !touch->read_touch(&touch_data)) {
|
||||||
|
last_touch_sample_ms = now;
|
||||||
touch_interrupt_flag = false;
|
touch_interrupt_flag = false;
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_touch_sample_ms = now;
|
||||||
touch_interrupt_flag = false;
|
touch_interrupt_flag = false;
|
||||||
uint32_t now = to_ms_since_boot(get_absolute_time());
|
|
||||||
|
|
||||||
// No active touch points: require consecutive empty reads before release to
|
// No active touch points: require consecutive empty reads before release to
|
||||||
// avoid false TOUCH_UP events from transient controller jitter.
|
// avoid false TOUCH_UP events from transient controller jitter.
|
||||||
@@ -65,6 +77,7 @@ InputEvent InputManager::process_touch_input(uint32_t* last_time) {
|
|||||||
no_touch_samples++;
|
no_touch_samples++;
|
||||||
if (no_touch_samples >= 2) {
|
if (no_touch_samples >= 2) {
|
||||||
*last_time = 0;
|
*last_time = 0;
|
||||||
|
last_touch_sample_ms = 0;
|
||||||
no_touch_samples = 0;
|
no_touch_samples = 0;
|
||||||
event.type = INPUT_TOUCH_UP;
|
event.type = INPUT_TOUCH_UP;
|
||||||
event.valid = true;
|
event.valid = true;
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
LowLevelTouch* touch;
|
LowLevelTouch* touch;
|
||||||
const GameConfig* config;
|
const GameConfig* config;
|
||||||
|
// Last time we sampled touch over I2C while a touch session is active.
|
||||||
|
uint32_t last_touch_sample_ms = 0;
|
||||||
// Consecutive touch_count==0 samples while a touch session is active.
|
// Consecutive touch_count==0 samples while a touch session is active.
|
||||||
// Used to suppress false TOUCH_UP events from transient touch controller jitter.
|
// Used to suppress false TOUCH_UP events from transient touch controller jitter.
|
||||||
uint8_t no_touch_samples = 0;
|
uint8_t no_touch_samples = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user