// ============================================================================ // INPUT MANAGER IMPLEMENTATION // ============================================================================ // Processes touch and button inputs into InputEvent objects #include "input_manager.h" #include "pico/stdlib.h" #include "board_config.h" #include // External interrupt flags from basic1.cpp extern volatile bool touch_interrupt_flag; extern volatile bool touch_event_down; extern volatile bool button_key0_pressed; extern volatile bool button_key1_pressed; // GameConfig struct definition (matches basic1.cpp) struct GameConfig { uint32_t touch_debounce_ms; uint32_t button_debounce_ms; bool enable_gestures; bool enable_continuous_draw; bool debug_verbose; }; InputManager::InputManager(LowLevelTouch* touch, const GameConfig* config) : touch(touch), config(config) { } bool InputManager::has_touch() const { return touch != nullptr; } bool InputManager::has_buttons() const { #ifdef BUTTON_KEY0_PIN return true; #else return false; #endif } InputEvent InputManager::process_touch_input(uint32_t* last_time) { InputEvent event = {INPUT_NONE, 0, 0, 0, 0, 0, false}; // Check if touch interrupt flag is set if (!touch_interrupt_flag) { return event; // No touch event } printf("Processing touch: flag=%d, event_down=%d\n", touch_interrupt_flag, touch_event_down); // Don't clear the flag yet - we may still be processing continuous touch // Check if touch is active if (!touch_event_down) { // Touch released - reset timing for next touch touch_interrupt_flag = false; *last_time = 0; // Reset so next touch is treated as new touch-down event.type = INPUT_TOUCH_UP; event.valid = true; printf("Touch UP\n"); return event; } // Touch is down - check debounce timing uint32_t now = to_ms_since_boot(get_absolute_time()); if (now - *last_time < config->touch_debounce_ms) { return event; // Too soon, skip } // Read touch data TouchData touch_data; if (!touch || !touch->read_touch(&touch_data)) { // Clear flag even if read failed to prevent getting stuck touch_interrupt_flag = false; printf("Touch read FAILED\n"); return event; // Read failed } // Clear the interrupt flag after successfully reading touch data // This allows the next touch interrupt to be detected touch_interrupt_flag = false; printf("Touch DOWN at (%d,%d)\n", touch_data.points[0].x, touch_data.points[0].y); // Populate event structure event.x = touch_data.points[0].x; event.y = touch_data.points[0].y; event.pressure = touch_data.points[0].pressure; event.gesture_code = touch_data.gesture; event.valid = true; // Determine event type if (*last_time == 0) { event.type = INPUT_TOUCH_DOWN; } else { event.type = INPUT_TOUCH_MOVE; } // Handle gesture events if (config->enable_gestures && touch_data.gesture != 0) { event.type = INPUT_GESTURE; if (config->debug_verbose) { printf("Gesture: 0x%02X (%s)\n", event.gesture_code, get_gesture_name(event.gesture_code)); } } *last_time = now; return event; } InputEvent InputManager::process_button_input() { InputEvent event = {INPUT_NONE, 0, 0, 0, 0, 0, false}; #ifdef BUTTON_KEY0_PIN // Check KEY0 if (button_key0_pressed) { button_key0_pressed = false; sleep_ms(config->button_debounce_ms); if (gpio_get(BUTTON_KEY0_PIN) == 0) { // Verify still pressed event.type = INPUT_BUTTON_0; event.button_id = 0; event.valid = true; if (config->debug_verbose) { printf("Button KEY0 action triggered\n"); } return event; } } #ifdef BUTTON_KEY1_PIN // Check KEY1 if (button_key1_pressed) { button_key1_pressed = false; sleep_ms(config->button_debounce_ms); if (gpio_get(BUTTON_KEY1_PIN) == 0) { // Verify still pressed event.type = INPUT_BUTTON_1; event.button_id = 1; event.valid = true; if (config->debug_verbose) { printf("Button KEY1 action triggered\n"); } return event; } } #endif #endif return event; } const char* InputManager::get_gesture_name(uint8_t gesture_code) { switch(gesture_code) { case 0x10: return "Move Up"; case 0x14: return "Move Right"; case 0x18: return "Move Down"; case 0x1C: return "Move Left"; case 0x48: return "Zoom In"; case 0x49: return "Zoom Out"; default: return "Unknown"; } }