From 2ef8f81d4e0cbdb4ce9c8e7eabc9c8b69459844d Mon Sep 17 00:00:00 2001 From: Pavel 'LEdoian' Turinsky Date: Sat, 21 Oct 2023 00:22:06 +0200 Subject: [PATCH] [WIP] C template --- C/lib.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ C/lib.h | 39 +++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 C/lib.c create mode 100644 C/lib.h diff --git a/C/lib.c b/C/lib.c new file mode 100644 index 0000000..655334b --- /dev/null +++ b/C/lib.c @@ -0,0 +1,76 @@ +#include "lib.h" + +static int actual_tile_size, actual_grid_height, actual_grid_width; +static bool was_init = false; + +static SDL_Window * window; +static SDL_Surface * win_surface; +static SDL_Surface * grid_sfc; + +void init(void) { + if (was_init) { + fprintf(stderr, "Cannot re-initialize.\n"); + abort(); // Life is tough, you do not deserve to handle this. + // Actually, crashing is the better behaviour in this caseā€¦ + } + was_init = true; + actual_tile_size = TILE_SIZE; + actual_grid_height = GRID_HEIGHT; + actual_grid_width = GRID_WIDTH; + + if (SDL_Init( SDL_INIT_VIDEO ) < 0) { + fprintf(stderr, "SDL_Init error: %s\n", SDL_GetError()); + abort(); + } + + grid = malloc(actual_grid_width * sizeof(color_t *)); + for (int i = 0; i < actual_grid_width; i++) { + grid[i] = malloc(actual_grid_height * sizeof(color_t)); + for (int j = 0; j < actual_grid_height; j++) grid[i][j] = (color_t) {0,0,0}; + } + + // TODO: Maybe add margins? + int winh = actual_tile_size * actual_grid_height; + int winw = actual_tile_size * actual_grid_width; + window = SDL_CreateWindow("Snake?", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, winw, winh, SDL_WINDOW_SHOWN); + if (window == NULL) { + fprintf(stderr, "Window broken: %s\n", SDL_GetError()); + abort(); + } + win_surface = SDL_GetWindowSurface(window); + + grid_sfc = SDL_CreateRGBSurface(0, winw, winh, 24, 0,0,0,0); + + // Ensure something is shown. + redraw(); +} + +void redraw(void) { + for (int x = 0; x < actual_grid_width; x++) { + for (int y = 0; y < actual_grid_height; y++) { + color_t c = grid[x][y]; + uint32_t color = (c.r << 24) + (c.g << 16) + (c.b << 8) + 0xFF /* alpha */; + SDL_Rect rect = {.x = x * actual_tile_size, .y = y * actual_tile_size, + .h = actual_tile_size, .w = actual_tile_size}; + SDL_FillRect(grid_sfc, &rect, color); + } + } +} + +char ** getkeys(int count) { + +} + +/* The simple stuff */ +void grid_set(int x, int y, color_t c) { + // FIXME: bounds checks! + grid[x][y] = c; +} + +color_t grid_get(int x, int y) { + return grid[x][y]; +} + +void wait(int msec) { + SDL_Delay(msec); +} diff --git a/C/lib.h b/C/lib.h new file mode 100644 index 0000000..8053efd --- /dev/null +++ b/C/lib.h @@ -0,0 +1,39 @@ +#pragma once +#include + +// Convenience: also get many stdlibs, so that we do not need to care in the program +#include +#include +#include +#include +#include + +typedef unsigned char byte; + +typedef struct color { + byte r; + byte g; + byte b; +} color_t; + +/* These are mutable, so that it is easy to change them from the code, before runing init() */ +int TILE_SIZE = 5; +int GRID_HEIGHT = 20; +int GRID_WIDTH = 20; + +color_t ** grid; + +/* We wrap SDL as a whole, so this is our API. */ +void init(void); +void redraw(void); +void wait(int msec); // Not a regular usleep, since we want SDL to still get inputs +char **getkeys(int count); // Get up to `count` keys pressed since last call. These are strings like 'a', 'shift', 'up', &c. + // We only report keydowns, and we report them in order they were pressed. +/* low-level Grid API */ +void grid_set(int x, int y, color_t color); +color_t grid_get(int x, int y); +// Of course, this is fourth quadrant, i.e. the origin is top left corner. + +/* I thought of providing a growing array here, but my implementation is too + * ugly (e.g. too many void pointers). Use reallocarray(3) instead, or just a + * regular array big enough. */