examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

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:
Msrc/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); } }