commit 3a4d0747c840b3bf4c45c04d8d37b9475d00571e
parent 96869bcd12b762f473a74a53a9d33e460eea5a76
Author: Henry Wilson <henry@henryandlizzy.uk>
Date: Fri, 21 Jun 2024 01:00:23 +0100
sdl-gl: Mouse hover detection
Diffstat:
M | src/sdl-gl.cpp | | | 270 | +++++++++++-------------------------------------------------------------------- |
1 file changed, 36 insertions(+), 234 deletions(-)
diff --git a/src/sdl-gl.cpp b/src/sdl-gl.cpp
@@ -21,7 +21,7 @@ void initSDL(void)
{
int windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0)
+ if (SDL_Init(SDL_INIT_VIDEO) < 0)
errx(1, "Couldn't initialize SDL: %s\n", SDL_GetError());
window = SDL_CreateWindow("Pong", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, screen_width, screen_height, windowFlags);
@@ -36,16 +36,9 @@ void initSDL(void)
errx(1, "Failed to make OpenGL context current: %s", SDL_GetError());
}
-static struct rgb
+struct rgb
{
- unsigned char r,g,b;
-} player_colours[] = {
- {255,0,0},
- {0,255,0},
- {32,32,255},
- {192,192,0},
- {192,0,192},
- {0,192,255},
+ float r,g,b;
};
struct coord
@@ -61,24 +54,6 @@ struct coord
explicit operator bool() const { return x or y; }
};
-static struct player
-{
- SDL_GameController* controller;
- struct coord pos, vel;
- unsigned cooldown;
- int shooting;
- unsigned health;
-} players[ARRAY_SIZE(player_colours)];
-
-struct bullet
-{
- struct player* player;
- struct coord pos, vel, control;
- unsigned ttl;
-};
-
-struct bullet bullets[128];
-
int clamp(int v, int l, int h)
{
if (v < l)
@@ -88,22 +63,6 @@ int clamp(int v, int l, int h)
return v;
}
-void shoot(struct player* p)
-{
- p->cooldown = 30;
- for (unsigned i = 0; i < ARRAY_SIZE(bullets); ++i)
- {
- struct bullet* b = bullets + i;
- if (b->player)
- continue;
- b->player = p;
- b->ttl = 4*60;
- b->pos = p->pos;
- b->vel = p->vel*2;
- return;
- }
-}
-
int abs(int v)
{
return v < 0 ? -v : v;
@@ -117,102 +76,19 @@ int colliding(struct coord a, struct coord b, int r)
return a.x && a.y;
}
-void simulate(void)
-{
- for (unsigned i = 0; i < ARRAY_SIZE(bullets); ++i)
- {
- struct bullet* b = bullets + i;
- if (!b->player)
- continue;
- struct player* p = NULL;
- for (unsigned i = 0; i < ARRAY_SIZE(player_colours); ++i)
- {
- if (players + i == b->player)
- continue;
- if (!players[i].controller)
- continue;
- if (!colliding(players[i].pos, b->pos, (2 + 5 + players[i].health) << 13))
- continue;
- p = players + i;
- break;
- }
- if (!p)
- continue;
- p->health -= !!p->health;
- p->pos += b->vel * 10;
- b->player = NULL;
- }
-
- for (unsigned i = 0; i < ARRAY_SIZE(player_colours); ++i)
- {
- struct player* const p = players + i;
- if (!p->controller)
- continue;
- p->pos += p->vel;
- p->pos.x = clamp(p->pos.x, -(screen_width << 12), screen_width << 12);
- p->pos.y = clamp(p->pos.y, -(screen_height << 12), screen_height << 12);
- if (!p->cooldown)
- {
- if (p->shooting)
- shoot(p);
- }
- else
- --p->cooldown;
- }
- for (unsigned i = 0; i < ARRAY_SIZE(bullets); ++i)
- {
- struct bullet* b = bullets + i;
- if (!b->player)
- continue;
- b->pos += b->vel;
- if (b->ttl--)
- continue;
- b->player = NULL;
- }
-}
-
-void prepareScene(void)
-{
- for (unsigned i = 0; i < ARRAY_SIZE(bullets); ++i)
- {
- struct bullet const* b = bullets + i;
- if (!b->player)
- continue;
- // struct rgb c = player_colours[b->player - players];
- // coord pos{screen_width / 2 + (b->pos.x >> 13), screen_height / 2 + (b->pos.y >> 13)};
- // SDL_Rect rect{pos.x - 3, pos.y - 3, 6, 6};
- // SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 255);
- // SDL_RenderDrawRect(renderer, &rect);
- // if (auto vel = b->vel / 512)
- // SDL_RenderDrawLine(renderer, pos.x, pos.y, pos.x + vel.x, pos.y + vel.y);
- }
-
- for (unsigned i = 0; i < ARRAY_SIZE(player_colours); ++i)
- {
- struct player const* const p = players + i;
- // struct rgb const c = player_colours[i];
- if (!p->controller)
- continue;
- // SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 255);
- // int size = 5 + p->health;
- // coord pos{screen_width / 2 + (p->pos.x >> 13), screen_height / 2 + (p->pos.y >> 13)};
- // SDL_Rect rect{pos.x - size, pos.y - size, 2*size, 2*size};
- // SDL_RenderDrawRect(renderer, &rect);
- // ifu(auto vel = p->vel / 512)
- // SDL_RenderDrawLine(renderer, pos.x, pos.y, pos.x + vel.x, pos.y + vel.y);
- }
-}
-
struct point
{
float x = 0, y = 0;
- point operator -() { return {-x, -y}; };
- point operator *(float rhs) { return {x * rhs, y * rhs}; }
- point operator +(point rhs) { return {x + rhs.x, y + rhs.y}; }
- point operator -(point rhs) { return *this + -rhs; }
+ point operator -() const { return {-x, -y}; };
+ point operator *(float rhs) const { return {x * rhs, y * rhs}; }
+ point operator /(float rhs) const { return {x / rhs, y / rhs}; }
+ point operator +(point rhs) const { return {x + rhs.x, y + rhs.y}; }
+ point operator -(point rhs) const { return *this + -rhs; }
point& operator *=(float rhs) { return *this = *this * rhs; }
+ point& operator /=(float rhs) { return *this = *this / rhs; }
point& operator +=(point rhs) { return *this = *this + rhs; }
point& operator -=(point rhs) { return *this = *this - rhs; }
+ float magnitude_squared() const { return x*x + y*y; }
};
struct rotor
{
@@ -224,21 +100,41 @@ point operator *(point lhs, rotor rhs)
return {lhs.x * rhs.s - lhs.y * rhs.xy, lhs.x * rhs.xy + lhs.y * rhs.s};
}
+struct circle
+{
+ point pos;
+ float radius;
+
+ bool colliding(point p) const
+ {
+ return (pos - p).magnitude_squared() <= radius * radius;
+ }
+};
+
float scale = .5f;
point pan = {1, 0};
+point mouse_pos;
+
void presentScene(void)
{
static double turns = 0;
turns += 1./60/4;
rotor r = rotor::angle(turns);
static point const square[4] = {{-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
- static point const objs[] = {{0, 0}, {4, 0}, {0, 5}};
+ point objs[] = {{0, 0}, {4, 0}, {0, 5}};
+
float x_scale = (float)screen_height / screen_width;
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
+ circle mouse_area{mouse_pos, 1};
for (auto op : objs) {
+ if (mouse_area.colliding(op))
+ glColor3d(1,1,0);
+ else
+ glColor3d(.5,.5,.5);
+
glBegin(GL_TRIANGLE_STRIP);
for (auto& p : square) {
auto pp = (p * r + pan + op) * scale;
@@ -271,10 +167,12 @@ point drag_pos;
void mouse_motion(SDL_MouseMotionEvent& e)
{
- if (!drag)
- return;
auto world = mouse_to_screen(e.x, e.y) * (1/scale);
- pan = drag_pos + world;
+ if (drag)
+ {
+ pan = drag_pos + world;
+ }
+ mouse_pos = world - pan;
}
void mouse_button(SDL_MouseButtonEvent& e)
@@ -296,85 +194,6 @@ void wheel(SDL_MouseWheelEvent* e)
scale *= factor;
}
-void con_add(SDL_ControllerDeviceEvent* e)
-{
- char const* name = SDL_GameControllerNameForIndex(e->which);
- unsigned i = 0;
- for (i = 0; i < ARRAY_SIZE(players); ++i)
- if (!players[i].controller)
- goto allocated;
- printf("Controller %d '%s' has no free slot\n", e->which, name);
- return;
-allocated:
- players[i].controller = SDL_GameControllerOpen(i);
- SDL_GameControllerSetPlayerIndex(players[i].controller, i);
- players[i].vel = (struct coord){0, 0};
- players[i].pos = (struct coord){(((int)i-3)*100) << 13, 0};
- players[i].health = 10;
- printf("Controller %d %p '%s' added as player %d\n", e->which, players[i].controller, name, i);
-}
-
-void con_del(SDL_ControllerDeviceEvent* e)
-{
- SDL_GameController* c = SDL_GameControllerFromInstanceID(e->which);
- if (!c)
- {
- printf("Controller %d disconnected\n", e->which);
- return;
- }
-
- for (unsigned i = 0; i < ARRAY_SIZE(players); ++i)
- if (players[i].controller == c)
- {
- players[i].controller = NULL;
- printf("Controller %d %p disconnected, player %d removed\n", e->which, c, i);
- break;
- }
-
- SDL_GameControllerClose(c);
-}
-
-void button(SDL_ControllerButtonEvent* e)
-{
- SDL_GameController* c = SDL_GameControllerFromInstanceID(e->which);
- int pid = SDL_GameControllerGetPlayerIndex(c);
- if (pid < 0 || pid >= ARRAY_SSIZE(players))
- return;
-
- switch (e->button)
- {
- case SDL_CONTROLLER_BUTTON_A:
- players[pid].shooting = e->state;
- return;
- }
-
- if (e->state)
- printf("D[%d] P[%d] B[%u] %u\n", e->which, pid, e->button, e->state);
-
-}
-
-void axis(SDL_ControllerAxisEvent* e)
-{
- SDL_GameController* c = SDL_GameControllerFromInstanceID(e->which);
- int pid = SDL_GameControllerGetPlayerIndex(c);
- if (pid < 0 || pid >= ARRAY_SSIZE(players))
- return;
- struct player* p = players + pid;
- if (!p->controller)
- return;
- switch (e->axis)
- {
- case SDL_CONTROLLER_AXIS_LEFTX:
- p->vel.x = e->value >> 1;
- return;
- case SDL_CONTROLLER_AXIS_LEFTY:
- p->vel.y = e->value >> 1;
- return;
- default:
- printf("D[%d] P[%d] A[%u] %d\n", e->which, pid, e->axis, e->value);
- }
-}
-
void window_event(SDL_WindowEvent const* e)
{
switch (e->event)
@@ -410,20 +229,6 @@ void doInput()
case SDL_MOUSEWHEEL:
wheel(&event.wheel);
break;
- case SDL_CONTROLLERDEVICEADDED:
- con_add(&event.cdevice);
- break;
- case SDL_CONTROLLERDEVICEREMOVED:
- con_del(&event.cdevice);
- break;
- case SDL_CONTROLLERBUTTONDOWN:
- case SDL_CONTROLLERBUTTONUP:
- button(&event.cbutton);
- break;
-
- case SDL_CONTROLLERAXISMOTION:
- axis(&event.caxis);
- break;
case SDL_WINDOWEVENT:
window_event(&event.window);
@@ -442,9 +247,6 @@ int main()
for (;;)
{
doInput();
- simulate();
- prepareScene();
presentScene();
- //SDL_Delay(16);
}
}