From ea3aceeaf82b0b6ff91b5a9cac708014a316c2d9 Mon Sep 17 00:00:00 2001
From: Abdelrahman <said.abdelrahman89@gmail.com>
Date: Sun, 14 Jan 2024 19:30:04 +0000
Subject: [PATCH] Add window utilities

---
 include/window.h | 56 ++++++++++++++++++++++++++++++++++++
 src/window.c     | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 130 insertions(+)
 create mode 100644 include/window.h
 create mode 100644 src/window.c

diff --git a/include/window.h b/include/window.h
new file mode 100644
index 0000000..15d05eb
--- /dev/null
+++ b/include/window.h
@@ -0,0 +1,56 @@
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include "SDL_pixels.h"
+#include "aliases/aliases.h"
+#include <SDL2/SDL_render.h>
+#include <SDL2/SDL_video.h>
+#include <stdbool.h>
+
+typedef struct point point_t;
+typedef struct line line_t;
+typedef struct triangle triangle_t;
+typedef struct window window_t;
+
+struct point {
+  i32 x;
+  i32 y;
+};
+
+struct line {
+  point_t p0;
+  point_t p1;
+};
+
+struct triangle {
+  point_t p0;
+  point_t p1;
+  point_t p2;
+};
+
+struct window {
+  u64 width;
+  u64 height;
+  const char *title;
+  SDL_Window *window;
+  SDL_Renderer *renderer;
+};
+
+typedef struct colour colour_t;
+struct colour {
+  union {
+    u32 abgr;
+    SDL_Color colour;
+  };
+};
+
+bool init_window(window_t *wnd, const char *title, u64 width, u64 height);
+void cleanup_window(window_t *wnd);
+void clear_window(const window_t *wnd, colour_t colour);
+void swap_buffers(const window_t *wnd);
+void draw_point(const window_t *wnd, point_t p, colour_t colour);
+void draw_line(const window_t *wnd, const line_t *ln, colour_t colour);
+void draw_triangle(const window_t *wnd, const triangle_t *triangle,
+                   colour_t colour);
+
+#endif // !WINDOW_H
diff --git a/src/window.c b/src/window.c
new file mode 100644
index 0000000..4cfd1a8
--- /dev/null
+++ b/src/window.c
@@ -0,0 +1,74 @@
+#include "window.h"
+#include "SDL_render.h"
+#include "SDL_video.h"
+#include "aliases/aliases.h"
+#include <stdbool.h>
+
+bool init_window(window_t *wnd, const char *title, u64 width, u64 height) {
+  wnd->window =
+      SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
+                       width, height, SDL_WINDOW_SHOWN);
+  if (!(wnd->window)) {
+    return false;
+  }
+
+  wnd->renderer = SDL_CreateRenderer(
+      wnd->window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+  if (!(wnd->renderer)) {
+    cleanup_window(wnd);
+    return false;
+  }
+
+  wnd->title = title;
+  wnd->width = width;
+  wnd->height = height;
+
+  return true;
+}
+
+void cleanup_window(window_t *wnd) {
+  if (wnd->renderer) {
+    SDL_DestroyRenderer(wnd->renderer);
+    wnd->renderer = NULL;
+  }
+
+  if (wnd->window) {
+    SDL_DestroyWindow(wnd->window);
+    wnd->window = NULL;
+  }
+
+  wnd->width = wnd->height = 0;
+}
+
+void set_colour(const window_t *wnd, colour_t colour) {
+  SDL_SetRenderDrawColor(wnd->renderer, colour.colour.r, colour.colour.g,
+                         colour.colour.b, colour.colour.a);
+}
+
+void clear_window(const window_t *wnd, colour_t colour) {
+  set_colour(wnd, colour);
+  SDL_RenderClear(wnd->renderer);
+}
+
+void swap_buffers(const window_t *wnd) { SDL_RenderPresent(wnd->renderer); }
+
+void draw_point(const window_t *wnd, point_t p, colour_t colour) {
+  set_colour(wnd, colour);
+  SDL_RenderDrawPoint(wnd->renderer, p.x, p.y);
+}
+
+void draw_line(const window_t *wnd, const line_t *ln, colour_t colour) {
+  set_colour(wnd, colour);
+  SDL_RenderDrawLine(wnd->renderer, ln->p0.x, ln->p0.y, ln->p1.x, ln->p1.y);
+}
+
+void draw_triangle(const window_t *wnd, const triangle_t *triangle,
+                   colour_t colour) {
+  line_t ln0 = {triangle->p0, triangle->p1};
+  line_t ln1 = {triangle->p0, triangle->p2};
+  line_t ln2 = {triangle->p1, triangle->p2};
+
+  draw_line(wnd, &ln0, colour);
+  draw_line(wnd, &ln1, colour);
+  draw_line(wnd, &ln2, colour);
+}