Files
PixelDefense/game/input.h
2024-02-13 11:58:56 +01:00

156 lines
4.0 KiB
C

#ifndef PIXELDEFENSE_GAME_INPUT_H
#define PIXELDEFENSE_GAME_INPUT_H
#include <breeze.h>
#include <flecs.h>
#include <raymath.h>
#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 pauseBtn;
MouseButton moveLeft;
MouseButton moveRight;
MouseButton moveUp;
MouseButton moveDown;
} InputMapping;
typedef struct ToolTipCost {
bool active;
i32 costs[RES_COUNT];
} ToolTipCost;
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_COLLECT_GOLD,
CURSOR_FARM,
CURSOR_ATTACK
} cursor;
// INPUT_BUILDING
int building;
bool buildingCanPlace;
Vec2i buildingPos;
Vec2i buildingSize;
// SELECTED_UNITS
Rectangle pickArea;
i32 numUnits;
Vector2 *unitPlacePos;
// SELECTED_OBJECT
// SELECTED_BUILDING
// Other
ToolTipCost toolTipCost;
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,
.pauseBtn = KEY_P,
.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