#ifndef PIXELDEFENSE_GAME_INPUT_H #define PIXELDEFENSE_GAME_INPUT_H #include #include #include #include "components.h" typedef enum InputType { INPUT_NONE, INPUT_BUILDING, INPUT_SELECTED_UNITS, INPUT_SELECTED_OBJECT, INPUT_SELECTED_BUILDING, } InputType; #define MOUSE_BUTTON_COUNT (MOUSE_BUTTON_BACK + 1) #define DRAG_THRESHOLD 5 #define BUTTON_COUNT (MOUSE_BUTTON_BACK + 1) typedef struct InputMapping { MouseButton primaryBtn; MouseButton secondaryBtn; //MouseButton mmb; MouseButton backBtn; MouseButton moveLeft; MouseButton moveRight; MouseButton moveUp; MouseButton moveDown; } InputMapping; typedef struct InputState { InputType state; InputMapping mapping; // Common Vector2 mouseDown; Vector2 mouseDownWorld; Vector2 mouse; Vector2 mouseWorld; f32 mouseDownElapsed[BUTTON_COUNT]; enum { CURSOR_NONE, CURSOR_COLLECT_WOOD, } cursor; // INPUT_BUILDING int building; bool buildingCanPlace; Vec2i buildingPos; Vec2i buildingSize; // SELECTED_UNITS Rectangle pickArea; // SELECTED_OBJECT // SELECTED_BUILDING // Other struct { /* Selected units * 1: Position * 2: Size * 3: UnitSelected */ ecs_query_t *selected; } queries; bool canUseMouse; bool canUseKeyboard; } InputState; static InputMapping inputDefaultMapping() { return (InputMapping) { .primaryBtn = MOUSE_BUTTON_LEFT, .secondaryBtn = MOUSE_BUTTON_RIGHT, .backBtn = KEY_ESCAPE, .moveLeft = KEY_W, .moveRight = KEY_D, .moveUp = KEY_UP, .moveDown = KEY_S }; } static void updateInputState(InputState *state, const Camera2D camera, const f32 dt) { for (i32 i = 0; i < BUTTON_COUNT; i++) { f32 *elapsed = &state->mouseDownElapsed[i]; if (IsMouseButtonDown(i)) *elapsed += dt; else if (IsMouseButtonUp(i) && !IsMouseButtonReleased(i)) *elapsed = 0; } const Vector2 mouse = GetMousePosition(); const Vector2 mouseWorld = GetScreenToWorld2D(mouse, camera); if (IsMouseButtonPressed(state->mapping.primaryBtn) || IsMouseButtonPressed(state->mapping.secondaryBtn)) { state->mouseDown = mouse; state->mouseDownWorld = mouseWorld; } state->mouse = mouse; state->mouseWorld = mouseWorld; } static f32 inputMouseDelta(const InputState *state) { Vector2 start = state->mouseDown; Vector2 end = state->mouse; f32 dst = Vector2DistanceSqr(start, end); return dst; } static bool isInputBtnDragged(const InputState *state, const MouseButton btn) { if (!IsMouseButtonDown(btn)) return false; return inputMouseDelta(state) >= DRAG_THRESHOLD; } static bool isInputBtnJustDragged(const InputState *state, const MouseButton btn) { if (!IsMouseButtonReleased(btn)) return false; return inputMouseDelta(state) >= DRAG_THRESHOLD; } static bool isInputBtnJustDown(const InputState *state, const MouseButton btn) { return IsMouseButtonPressed(btn) && inputMouseDelta(state) < DRAG_THRESHOLD; } static bool isInputBtnJustUp(const InputState *state, const MouseButton btn) { return IsMouseButtonReleased(btn) && inputMouseDelta(state) < DRAG_THRESHOLD; } static bool isInputBtnDown(const InputState *state, const MouseButton btn) { BZ_UNUSED(state); return IsMouseButtonDown(btn); } static bool isInputBtnUp(const InputState *state, const MouseButton btn) { BZ_UNUSED(state); return IsMouseButtonUp(btn); } extern ECS_COMPONENT_DECLARE(InputState); // defined in main.c #endif //PIXELDEFENSE_GAME_INPUT_H