diff options
author | kdx <kikoodx@paranoici.org> | 2022-09-06 01:29:58 +0200 |
---|---|---|
committer | kdx <kikoodx@paranoici.org> | 2022-09-06 01:58:14 +0200 |
commit | c5f8f589f7fa12bac7b57db94a6dba3cf4e30a6a (patch) | |
tree | 274cccf852d22532fe47774743c605403f2a90d5 | |
download | lzr-c5f8f589f7fa12bac7b57db94a6dba3cf4e30a6a.tar.gz |
initial commit
-rw-r--r-- | .clang-format | 9 | ||||
-rw-r--r-- | Tupfile | 6 | ||||
-rw-r--r-- | demo.c | 17 | ||||
-rwxr-xr-x | format.sh | 2 | ||||
-rw-r--r-- | lzr.c | 198 | ||||
-rw-r--r-- | lzr.h | 25 |
6 files changed, 257 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..d749f15 --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: LLVM +IndentWidth: 8 +UseTab: AlignWithSpaces +BreakBeforeBraces: Linux +AllowShortIfStatementsOnASingleLine: Never +AllowShortFunctionsOnASingleLine: None +IndentCaseLabels: false +ColumnLimit: 80 +AlignConsecutiveMacros: true @@ -0,0 +1,6 @@ +CFLAGS = -Wall -Wextra -std=c99 -pedantic `sdl2-config --cflags` +LDFLAGS = -ldx `sdl2-config --libs` + +.gitignore +: foreach *.c |> gcc $(CFLAGS) -c -o %o %f |> %B.o +: *.o |> gcc -o %o %f $(LDFLAGS) |> lzr @@ -0,0 +1,17 @@ +#include "lzr.h" + +int main(void) +{ + LZR_Config cfg = {400, 224, 60, 16, "LZR demo"}; + if (LZR_Init(cfg)) + return 1; + while (!LZR_ShouldQuit()) { + LZR_CycleEvents(); + LZR_DrawBegin(); + LZR_DrawSetColor(0.9f, 0.9f, 0.8f); + LZR_DrawClear(); + LZR_DrawEnd(); + } + LZR_Quit(); + return 0; +} diff --git a/format.sh b/format.sh new file mode 100755 index 0000000..067309e --- /dev/null +++ b/format.sh @@ -0,0 +1,2 @@ +#!/bin/sh +clang-format -style=file -verbose -i *.c *.h @@ -0,0 +1,198 @@ +#include "lzr.h" +#include <SDL2/SDL.h> +#include <dx/log.h> +#include <dx/mem.h> +#include <dx/str.h> +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + +static LZR_Config config = {0}; +static char *basepath = NULL; +static SDL_Window *window = NULL; +static SDL_Renderer *renderer = NULL; +static SDL_Texture *target = NULL; +static uint_least64_t next_time = 0; +static uint_least64_t min_dt = 0; +static bool should_quit = false; + +static char *_path_prefix(const char *path) +{ + if (path == NULL) { + dx_log_error("path is NULL"); + return NULL; + } + if (basepath == NULL) { + dx_log_warn("basepath is NULL"); + return dx_strdup(path); + } + char *const buf = dx_alloc(strlen(basepath) + strlen(path) + 1); + if (buf == NULL) { + dx_log_error("dx_alloc failed"); + return NULL; + } + dx_strcpy(buf, basepath); + dx_strcat(buf, path); + return buf; +} + +int LZR_Init(LZR_Config cfg) +{ + memcpy(&config, &cfg, sizeof(config)); + if (config.display_width == 0) { + dx_log_error("display_width can't be 0"); + return 1; + } + if (config.display_height == 0) { + dx_log_error("display_height can't be 0"); + return 1; + } + if (config.title == NULL) { + dx_log_warn("title is NULL, defaulting to 'LZR'"); + config.title = "LZR"; + } + if (config.tile_size == 0) + config.tile_size = 1; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + dx_log_error("%s", SDL_GetError()); + return 1; + } + basepath = SDL_GetBasePath(); + if (basepath == NULL) { + dx_log_error("%s", SDL_GetError()); + return 1; + } + window = SDL_CreateWindow(config.title, SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, config.display_width, + config.display_height, SDL_WINDOW_RESIZABLE); + if (window == NULL) { + dx_log_error("%s", SDL_GetError()); + return 1; + } + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + if (renderer == NULL) { + dx_log_error("%s", SDL_GetError()); + return 1; + } + target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB888, + SDL_TEXTUREACCESS_TARGET, + config.display_width, config.display_height); + if (target == NULL) { + dx_log_error("%s", SDL_GetError()); + return 1; + } + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 0); + if (config.target_fps) { + min_dt = 1000 / config.target_fps; + next_time = SDL_GetTicks64(); + } + return 0; +} + +void LZR_Quit(void) +{ + if (target != NULL) { + SDL_DestroyTexture(target); + target = NULL; + } + if (renderer != NULL) { + SDL_DestroyRenderer(renderer); + renderer = NULL; + } + if (window != NULL) { + SDL_DestroyWindow(window); + window = NULL; + } + if (basepath != NULL) { + SDL_free(basepath); + basepath = NULL; + } + SDL_Quit(); +} + +bool LZR_ShouldQuit(void) +{ + return should_quit; +} + +void LZR_CycleEvents(void) +{ + SDL_Event e; + while (SDL_PollEvent(&e)) { + switch (e.type) { + case SDL_QUIT: + should_quit = true; + break; + default: + break; + } + } +} + +int LZR_DrawBegin(void) +{ + if (config.target_fps > 0) + next_time += min_dt; + if (SDL_SetRenderTarget(renderer, target) < 0) { + dx_log_error("%s", SDL_GetError()); + return 1; + } + return 0; +} + +int LZR_DrawEnd(void) +{ + if (SDL_SetRenderTarget(renderer, NULL)) { + dx_log_error("%s", SDL_GetError()); + return 1; + } + LZR_DrawSetColor(0.0f, 0.0f, 0.0f); + if (LZR_DrawClear()) { + dx_log_error("LZY_DrawClear failed"); + return 1; + } + if (config.target_fps) { + const uint_least64_t cur_time = SDL_GetTicks64(); + if (next_time <= cur_time) + next_time = cur_time; + else + SDL_Delay(next_time - cur_time); + } + int win_w, win_h; + SDL_GetWindowSize(window, &win_w, &win_h); + const int ratio_w = win_w / config.display_width; + const int ratio_h = win_h / config.display_height; + const int scale = (ratio_w <= ratio_h) ? ratio_w : ratio_h; + const int off_x = (win_w - config.display_width * scale) / 2; + const int off_y = (win_h - config.display_height * scale) / 2; + const SDL_Rect dest = {off_x, off_y, config.display_width * scale, + config.display_height * scale}; + if (SDL_RenderCopy(renderer, target, NULL, &dest) < 0) { + dx_log_error("%s", SDL_GetError()); + return 1; + } + SDL_RenderPresent(renderer); + return 0; +} + +int LZR_DrawSetColor(float r, float g, float b) +{ + const unsigned int ur = (unsigned int)(r * 255) & 255; + const unsigned int ug = (unsigned int)(g * 255) & 255; + const unsigned int ub = (unsigned int)(b * 255) & 255; + if (SDL_SetRenderDrawColor(renderer, ur, ug, ub, 255)) { + dx_log_error("%s", SDL_GetError()); + return 1; + } + return 0; +} + +int LZR_DrawClear(void) +{ + if (SDL_RenderClear(renderer) < 0) { + dx_log_error("%s", SDL_GetError()); + return 1; + } + return 0; +} @@ -0,0 +1,25 @@ +#ifndef LZR_H_ +#define LZR_H_ +#include <stdbool.h> + +typedef struct LZR_Config { + unsigned int display_width; + unsigned int display_height; + unsigned int target_fps; + unsigned int tile_size; + const char *title; +} LZR_Config; + +int LZR_Init(LZR_Config cfg); +void LZR_Quit(void); +bool LZR_ShouldQuit(void); +void LZR_CycleEvents(void); +int LZR_DrawBegin(void); +int LZR_DrawEnd(void); +int LZR_DrawSetColor(float r, float g, float b); +int LZR_DrawClear(void); +int LZR_DrawPoint(int x, int y); +int LZR_DrawLine(int x0, int y0, int x1, int y1); +int LZR_DrawRect(bool fill, int x, int y, int w, int h); + +#endif |