Gama C Library
Gama C API Documentation
joystick.h
Go to the documentation of this file.
1/**
2 * @file widgets/joystick.h
3 * @brief Defines the theme and functionality for a virtual joystick widget.
4 *
5 * This file provides structures for customizing the appearance of an on-screen
6 * joystick and a function to render an interactive joystick that responds
7 * to mouse input, outputting its normalized position.
8 */
9#pragma once
10
11#include "../animate.h"
12#include "../draw.h"
13
14/**
15 * @brief Structure defining the visual theme for a joystick widget.
16 */
17typedef struct {
18 int enabled; /**< Whether the joystick is enabled for interaction (1) or disabled (0). */
19
20 double scale; /**< Overall joystick size scale when normal. */
21 gmColor background; /**< Background color of the joystick base circle when normal. */
22 gmColor border; /**< Border color of the joystick base circle when normal. */
23
24 struct {
25 double scale; /**< Scale factor of the joystick when focused/hovered. */
26 gmColor border; /**< Border color when focused/hovered. */
27 } focussed; /**< Theme properties when the joystick is focused or hovered. */
28
29 struct {
30 double scale; /**< Scale factor of the joystick when active (being dragged). */
31 gmColor border; /**< Border color when active. */
32 } active; /**< Theme properties when the joystick is active (mouse button down on it). */
33
34 gmColor knob; /**< Color of the joystick knob. */
35 gmColor knob_border; /**< Border color of the joystick knob. */
36
37 double border_width; /**< Width of the joystick base circle border. */
39
40/**
41 * @brief Global joystick theme instance with default values.
42 */
44 .enabled = 1,
45 .scale = 1.0,
46 .background = 0x3A2A3AE0,
47 .border = 0x7F4F7FFF,
48 .focussed = {.scale = 1.05, .border = 0xAA77AAFF},
49 .active = {.scale = 0.95, .border = 0x7F4F7FFF},
50 .knob = 0xAA77AAFF,
51 .knob_border = 0x6F3F6FFF,
52 .border_width = 0.01};
53
54/**
55 * @brief Creates and renders an animated joystick widget that can be
56 * manipulated with the mouse.
57 *
58 * This function draws a virtual joystick on screen, tracks mouse interaction,
59 * and outputs its normalized logical position. The visual knob position is
60 * animated smoothly.
61 *
62 * @param x The x-coordinate of the joystick's center.
63 * @param y The y-coordinate of the joystick's center.
64 * @param radius The radius of the joystick base circle.
65 * @param pos Pointer to a `gmPos` structure to store the joystick's logical
66 * position (normalized to -1.0 to 1.0 in X and Y).
67 * @param vpos Pointer to a `gmPos` structure for the animated visual knob
68 * position. If NULL, `pos` is used for both logical and visual position.
69 * @return 1 if the joystick is currently hovered over, 0 otherwise.
70 */
71int gm_joystick_anim(double x, double y, double radius, gmPos *pos,
72 gmPos *vpos) {
73
74 if (!gmwJoystick.enabled)
75 return 0;
76 if (vpos == NULL)
77 vpos = pos;
78
79 // Mouse vector relative to center
80 double dx = gm_mouse.position.x - x;
81 double dy = gm_mouse.position.y - y;
82
83 double dist = sqrt(dx * dx + dy * dy);
84
85 int hovered = dist <= radius;
86
87 int active = hovered && gm_mouse.down;
88
89 if (!gm_mouse.down) {
90 gm_anim_ease_out_cubic(&pos->x, 0, 0.1);
91 gm_anim_ease_out_cubic(&pos->y, 0, 0.1);
92 }
93
94 // Logical joystick position (-1..1)
95 double nx = 0.0, ny = 0.0;
96
97 if (active) {
98 if (dist > radius) {
99 dx = dx / dist * radius;
100 dy = dy / dist * radius;
101 }
102 nx = dx / radius;
103 ny = dy / radius;
104
105 pos->x = nx;
106 pos->y = ny;
107 }
108
109 // Animate knob smoothly to target pos->x/pos->y
110 gm_anim_ease_out_quad(&vpos->x, pos->x, 0.05);
111 gm_anim_ease_out_quad(&vpos->y, pos->y, 0.05);
112
113 // Draw joystick circle (border + background)
114 double draw_radius = radius * gmwJoystick.scale;
115 gm_draw_circle(x, y, draw_radius + gmwJoystick.border_width,
116 gmwJoystick.border);
117 gm_draw_circle(x, y, draw_radius, gmwJoystick.background);
118
119 // Draw knob
120 double knob_radius = draw_radius * 0.3; // 30% of radius
121 gm_draw_circle(x + vpos->x * draw_radius, y + vpos->y * draw_radius,
122 knob_radius + gmwJoystick.border_width,
123 gmwJoystick.knob_border);
125 x + vpos->x * draw_radius, y + vpos->y * draw_radius, knob_radius,
126 nx == 0 && ny == 0 ? gmwJoystick.knob & 0xEEEEFF44 : gmwJoystick.knob);
127
128 return hovered;
129}
130
131/**
132 * @brief Creates and renders a joystick widget that can be manipulated with the
133 * mouse (non-animated version).
134 *
135 * This is a simplified wrapper around `gm_joystick_anim` that does not use
136 * a separate visual position for animation, making the knob snap to position.
137 *
138 * @param x The x-coordinate of the joystick's center.
139 * @param y The y-coordinate of the joystick's center.
140 * @param radius The radius of the joystick base.
141 * @param pos Pointer to a `gmPos` structure to store the joystick's logical
142 * position (normalized to -1.0 to 1.0 in X and Y).
143 * @return 1 if the joystick is currently hovered over, 0 otherwise.
144 */
145int gmw_joystick(double x, double y, double radius, gmPos *pos) {
146 return gm_joystick_anim(x, y, radius, pos, NULL);
147}
Provides utility functions for animating numerical values using various easing effects.
void gm_anim_ease_out_cubic(double *value, double target, double t)
Animates a value towards a target with a cubic ease-out effect.
Definition animate.h:80
void gm_anim_ease_out_quad(double *value, const double target, double t)
Animates a value towards a target with a quadratic ease-out effect.
Definition animate.h:56
uint32_t gmColor
Type definition for color values, stored as a 32-bit unsigned integer. The color components are packe...
Definition color.h:13
Functions for drawing shapes, text, and images.
int32_t gm_draw_circle(double center_x, double center_y, double radius, gmColor c)
Draws a circle.
Definition draw.h:84
int gmw_joystick(double x, double y, double radius, gmPos *pos)
Creates and renders a joystick widget that can be manipulated with the mouse (non-animated version).
Definition joystick.h:145
gmwJoystickTheme gmwJoystick
Global joystick theme instance with default values.
Definition joystick.h:43
int gm_joystick_anim(double x, double y, double radius, gmPos *pos, gmPos *vpos)
Creates and renders an animated joystick widget that can be manipulated with the mouse.
Definition joystick.h:71
double sqrt(double x)
Calculates the square root of x.
Definition math.h:339
struct _gmMouse gm_mouse
Definition mouse.h:32
Represents a 2D position or vector.
Definition position.h:8
double x
Definition position.h:9
double y
Definition position.h:9
Structure defining the visual theme for a joystick widget.
Definition joystick.h:17
double border_width
Definition joystick.h:37
double scale
Definition joystick.h:20
gmColor background
Definition joystick.h:21
gmColor knob
Definition joystick.h:34
gmColor knob_border
Definition joystick.h:35
gmColor border
Definition joystick.h:22
int enabled
Definition joystick.h:18