#include "window/window.h" #include "c_cpp_aliases/aliases.h" #include #include #include #include #include #include #define NORMALISED_MIN -1.0f #define NORMALISED_MAX 1.0f u32 colour_to_u32(colour_t colour); u32 index_from_coordinates(window_t *wnd, u32 x, u32 y); i32 denormalise(f32 value, u32 max); void set_screen_pixel(window_t *wnd, u32 x, u32 y, colour_t colour); bool init_window(window_t *wnd, u64 width, u64 height, const char *title) { if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { printf("Failed to initialise SDL: %s\n", SDL_GetError()); return false; } wnd->window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0); if (!(wnd->window)) { printf("Failed to create window: %s\n", SDL_GetError()); close_window(wnd); return false; } wnd->front_buffer = SDL_GetWindowSurface(wnd->window); if (!(wnd->front_buffer)) { printf("Failed to get front buffer: %s\n", SDL_GetError()); close_window(wnd); return false; } wnd->back_buffer = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_ABGR32); if (!(wnd->back_buffer)) { printf("Failed to create back buffer: %s\n", SDL_GetError()); close_window(wnd); return false; } wnd->width = width; wnd->height = height; wnd->title = title; return true; } void close_window(window_t *wnd) { if (wnd) { wnd->width = 0; wnd->height = 0; wnd->title = ""; if (wnd->window) { SDL_DestroyWindow(wnd->window); wnd->window = NULL; } if (wnd->back_buffer) { SDL_FreeSurface(wnd->back_buffer); wnd->back_buffer = NULL; } } SDL_Quit(); } void clear_window(window_t *wnd, colour_t colour) { SDL_LockSurface(wnd->back_buffer); u32 c = colour_to_u32(colour); u32 *pixels = (u32 *)(wnd->back_buffer->pixels); u32 count = wnd->back_buffer->w * wnd->back_buffer->h; for (u32 i = 0; i < count; ++i) { pixels[i] = c; } SDL_UnlockSurface(wnd->back_buffer); } void set_pixel(window_t *wnd, f32 x, f32 y, colour_t colour) { i32 screen_x = denormalise(x, wnd->width); i32 screen_y = denormalise(-y, wnd->height); if (screen_x < 0 || screen_y < 0) { return; } SDL_LockSurface(wnd->back_buffer); set_screen_pixel(wnd, screen_x, screen_y, colour); SDL_UnlockSurface(wnd->back_buffer); } void swap_buffers(window_t *wnd) { SDL_BlitSurface(wnd->back_buffer, NULL, wnd->front_buffer, NULL); SDL_UpdateWindowSurface(wnd->window); } u32 colour_to_u32(colour_t colour) { return ((u32)(colour.r) << 24) | ((u32)(colour.g) << 16) | ((u32)(colour.b) << 8) | (u32)(colour.a); } u32 index_from_coordinates(window_t *wnd, u32 x, u32 y) { return y * wnd->width + x; } i32 denormalise(f32 value, u32 max) { if (max == 0 || value < NORMALISED_MIN || value >= NORMALISED_MAX) { return -1; } return (i32)(((value - NORMALISED_MIN) * max) / (NORMALISED_MAX - NORMALISED_MIN)); } void set_screen_pixel(window_t *wnd, u32 x, u32 y, colour_t colour) { u32 index = index_from_coordinates(wnd, x, y); u32 c = colour_to_u32(colour); u32 *pixels = (u32 *)(wnd->back_buffer->pixels); pixels[index] = c; }