From fbc5c101783533f90a3053671de5314c2c6a1c1a Mon Sep 17 00:00:00 2001 From: dawidg81 Date: Fri, 13 Feb 2026 10:13:59 +0100 Subject: Directory cleanup --- lib/graphics.cpp | 222 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 lib/graphics.cpp (limited to 'lib/graphics.cpp') diff --git a/lib/graphics.cpp b/lib/graphics.cpp new file mode 100644 index 0000000..827303e --- /dev/null +++ b/lib/graphics.cpp @@ -0,0 +1,222 @@ +#include "graphics.h" +#include + +#ifdef USE_SDL + +#include + +// Platform-specific window handle structure +struct WindowHandle { + SDL_Window* window; + SDL_Renderer* renderer; + bool shouldClose; + + WindowHandle() : window(nullptr), renderer(nullptr), shouldClose(false) {} +}; + +// Initialize SDL (called once) +static bool sdlInitialized = false; + +static void ensureSDLInit() { + if (!sdlInitialized) { + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + // Handle error - in production, use proper error handling + return; + } + sdlInitialized = true; + } +} + +WindowHandle* createWindow(const char* title, int width, int height) { + ensureSDLInit(); + + WindowHandle* handle = new WindowHandle(); + + handle->window = SDL_CreateWindow( + title, + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + width, + height, + SDL_WINDOW_SHOWN + ); + + if (!handle->window) { + delete handle; + return nullptr; + } + + handle->renderer = SDL_CreateRenderer( + handle->window, + -1, + SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC + ); + + if (!handle->renderer) { + SDL_DestroyWindow(handle->window); + delete handle; + return nullptr; + } + + // Enable alpha blending + SDL_SetRenderDrawBlendMode(handle->renderer, SDL_BLENDMODE_BLEND); + + return handle; +} + +void destroyWindow(WindowHandle* window) { + if (!window) return; + + if (window->renderer) { + SDL_DestroyRenderer(window->renderer); + } + + if (window->window) { + SDL_DestroyWindow(window->window); + } + + delete window; + + // Cleanup SDL if this was the last window + if (sdlInitialized) { + SDL_Quit(); + sdlInitialized = false; + } +} + +bool windowShouldClose(WindowHandle* window) { + if (!window) return true; + return window->shouldClose; +} + +void pollEvents(WindowHandle* window) { + if (!window) return; + + SDL_Event event; + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + window->shouldClose = true; + } + else if (event.type == SDL_KEYDOWN) { + if (event.key.keysym.sym == SDLK_ESCAPE) { + window->shouldClose = true; + } + } + } +} + +void swapBuffers(WindowHandle* window) { + if (!window || !window->renderer) return; + SDL_RenderPresent(window->renderer); +} + +void clearScreen(WindowHandle* window, const Color& color) { + if (!window || !window->renderer) return; + + SDL_SetRenderDrawColor(window->renderer, color.r, color.g, color.b, color.a); + SDL_RenderClear(window->renderer); +} + +void setDrawColor(WindowHandle* window, const Color& color) { + if (!window || !window->renderer) return; + SDL_SetRenderDrawColor(window->renderer, color.r, color.g, color.b, color.a); +} + +void drawLine(WindowHandle* window, int x1, int y1, int x2, int y2, const Color& color) { + if (!window || !window->renderer) return; + + setDrawColor(window, color); + SDL_RenderDrawLine(window->renderer, x1, y1, x2, y2); +} + +void drawRectangle(WindowHandle* window, int x, int y, int width, int height, const Color& color) { + if (!window || !window->renderer) return; + + SDL_Rect rect = {x, y, width, height}; + setDrawColor(window, color); + SDL_RenderDrawRect(window->renderer, &rect); +} + +void drawFilledRectangle(WindowHandle* window, int x, int y, int width, int height, const Color& color) { + if (!window || !window->renderer) return; + + SDL_Rect rect = {x, y, width, height}; + setDrawColor(window, color); + SDL_RenderFillRect(window->renderer, &rect); +} + +void drawPixel(WindowHandle* window, int x, int y, const Color& color) { + if (!window || !window->renderer) return; + + setDrawColor(window, color); + SDL_RenderDrawPoint(window->renderer, x, y); +} + +// Helper function for drawing circles using midpoint circle algorithm +void drawCircle(WindowHandle* window, int centerX, int centerY, int radius, const Color& color) { + if (!window || !window->renderer) return; + + setDrawColor(window, color); + + int x = 0; + int y = radius; + int d = 3 - 2 * radius; + + auto drawCirclePoints = [&](int xc, int yc, int x, int y) { + SDL_RenderDrawPoint(window->renderer, xc + x, yc + y); + SDL_RenderDrawPoint(window->renderer, xc - x, yc + y); + SDL_RenderDrawPoint(window->renderer, xc + x, yc - y); + SDL_RenderDrawPoint(window->renderer, xc - x, yc - y); + SDL_RenderDrawPoint(window->renderer, xc + y, yc + x); + SDL_RenderDrawPoint(window->renderer, xc - y, yc + x); + SDL_RenderDrawPoint(window->renderer, xc + y, yc - x); + SDL_RenderDrawPoint(window->renderer, xc - y, yc - x); + }; + + drawCirclePoints(centerX, centerY, x, y); + + while (y >= x) { + x++; + + if (d > 0) { + y--; + d = d + 4 * (x - y) + 10; + } else { + d = d + 4 * x + 6; + } + + drawCirclePoints(centerX, centerY, x, y); + } +} + +void drawFilledCircle(WindowHandle* window, int centerX, int centerY, int radius, const Color& color) { + if (!window || !window->renderer) return; + + setDrawColor(window, color); + + for (int y = -radius; y <= radius; y++) { + for (int x = -radius; x <= radius; x++) { + if (x * x + y * y <= radius * radius) { + SDL_RenderDrawPoint(window->renderer, centerX + x, centerY + y); + } + } + } +} + +void delay(uint32_t milliseconds) { + SDL_Delay(milliseconds); +} + +#endif // USE_SDL + +#ifdef USE_WIN32 +// Win32 implementation would go here +// For now, this is a placeholder +#error "Win32 backend not yet implemented" +#endif + +#ifdef USE_X11 +// X11 implementation would go here +// For now, this is a placeholder +#error "X11 backend not yet implemented" +#endif \ No newline at end of file -- cgit v1.2.3