aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2022-09-06 01:29:58 +0200
committerkdx <kikoodx@paranoici.org>2022-09-06 01:58:14 +0200
commitc5f8f589f7fa12bac7b57db94a6dba3cf4e30a6a (patch)
tree274cccf852d22532fe47774743c605403f2a90d5
downloadlzr-c5f8f589f7fa12bac7b57db94a6dba3cf4e30a6a.tar.gz
initial commit
-rw-r--r--.clang-format9
-rw-r--r--Tupfile6
-rw-r--r--demo.c17
-rwxr-xr-xformat.sh2
-rw-r--r--lzr.c198
-rw-r--r--lzr.h25
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
diff --git a/Tupfile b/Tupfile
new file mode 100644
index 0000000..ffd6a55
--- /dev/null
+++ b/Tupfile
@@ -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
diff --git a/demo.c b/demo.c
new file mode 100644
index 0000000..baa4a3f
--- /dev/null
+++ b/demo.c
@@ -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
diff --git a/lzr.c b/lzr.c
new file mode 100644
index 0000000..34c626c
--- /dev/null
+++ b/lzr.c
@@ -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;
+}
diff --git a/lzr.h b/lzr.h
new file mode 100644
index 0000000..14893b5
--- /dev/null
+++ b/lzr.h
@@ -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