aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2022-09-06 04:07:19 +0200
committerkdx <kikoodx@paranoici.org>2022-09-06 04:21:13 +0200
commit7163c10d4c0e887918f35ed82b25209f39a6bd2d (patch)
tree82cd27db0b1354b6ead8b75f7db6ad424a051ac6
parentc5f8f589f7fa12bac7b57db94a6dba3cf4e30a6a (diff)
downloadlzr-7163c10d4c0e887918f35ed82b25209f39a6bd2d.tar.gz
load and draw image
-rw-r--r--coucou.bmpbin0 -> 16522 bytes
-rw-r--r--demo.c17
-rw-r--r--lzr.c99
-rw-r--r--lzr.h4
4 files changed, 106 insertions, 14 deletions
diff --git a/coucou.bmp b/coucou.bmp
new file mode 100644
index 0000000..db5399e
--- /dev/null
+++ b/coucou.bmp
Binary files differ
diff --git a/demo.c b/demo.c
index baa4a3f..6782dae 100644
--- a/demo.c
+++ b/demo.c
@@ -1,15 +1,32 @@
#include "lzr.h"
+#include <dx/log.h>
+#include <stdlib.h>
+#include <time.h>
int main(void)
{
LZR_Config cfg = {400, 224, 60, 16, "LZR demo"};
if (LZR_Init(cfg))
return 1;
+ srand(time(NULL));
+ const int limit = 1 + (rand() & 15);
+ for (int i = 0; i < limit; i++)
+ LZR_ImageLoad("coucou.bmp");
+ float darkness = 0.0f;
+ float dark_dir = 1.0f;
while (!LZR_ShouldQuit()) {
+ darkness += 0.01f * dark_dir;
+ if (darkness * dark_dir >= 0.5f) {
+ darkness = 0.5f * dark_dir;
+ dark_dir = -dark_dir;
+ }
LZR_CycleEvents();
LZR_DrawBegin();
LZR_DrawSetColor(0.9f, 0.9f, 0.8f);
LZR_DrawClear();
+ const float shade = 0.9 * (0.5f + darkness);
+ LZR_DrawSetColor(shade, shade, 0.0f);
+ LZR_DrawImage(0, 10, 20);
LZR_DrawEnd();
}
LZR_Quit();
diff --git a/lzr.c b/lzr.c
index 34c626c..231421c 100644
--- a/lzr.c
+++ b/lzr.c
@@ -15,6 +15,11 @@ 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 struct {
+ SDL_Texture *tex;
+ int width, height;
+} textures[LZR_MAX_IMAGES] = {0};
+static unsigned int color[3] = {0};
static char *_path_prefix(const char *path)
{
@@ -41,11 +46,11 @@ 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;
+ return -1;
}
if (config.display_height == 0) {
dx_log_error("display_height can't be 0");
- return 1;
+ return -1;
}
if (config.title == NULL) {
dx_log_warn("title is NULL, defaulting to 'LZR'");
@@ -56,31 +61,31 @@ int LZR_Init(LZR_Config cfg)
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
dx_log_error("%s", SDL_GetError());
- return 1;
+ return -1;
}
basepath = SDL_GetBasePath();
if (basepath == NULL) {
dx_log_error("%s", SDL_GetError());
- return 1;
+ 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;
+ return -1;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
dx_log_error("%s", SDL_GetError());
- return 1;
+ 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;
+ return -1;
}
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 0);
if (config.target_fps) {
@@ -92,6 +97,12 @@ int LZR_Init(LZR_Config cfg)
void LZR_Quit(void)
{
+ for (int i = 0; i < LZR_MAX_IMAGES; i++)
+ if (textures[i].tex != NULL) {
+ SDL_DestroyTexture(textures[i].tex);
+ textures[i].tex = NULL;
+ dx_log_trace("destroyed image %d", i);
+ }
if (target != NULL) {
SDL_DestroyTexture(target);
target = NULL;
@@ -116,6 +127,42 @@ bool LZR_ShouldQuit(void)
return should_quit;
}
+int LZR_ImageLoad(const char *path)
+{
+ int i;
+ for (i = 0; i < LZR_MAX_IMAGES; i++)
+ if (textures[i].tex == NULL)
+ break;
+ if (i >= LZR_MAX_IMAGES) {
+ dx_log_error("reached image limit (%d)", LZR_MAX_IMAGES);
+ return -1;
+ }
+ char *const apath = _path_prefix(path);
+ if (apath == NULL) {
+ dx_log_error("_path_prefix failed");
+ return -1;
+ }
+ SDL_Surface *const bmp = SDL_LoadBMP(apath);
+ dx_free(apath);
+ if (bmp == NULL) {
+ dx_log_error("%s: %s", path, SDL_GetError());
+ return -1;
+ }
+ SDL_Texture *const tex = SDL_CreateTextureFromSurface(renderer, bmp);
+ SDL_FreeSurface(bmp);
+ if (tex == NULL) {
+ dx_log_error("%s", SDL_GetError());
+ return -1;
+ }
+ textures[i].tex = tex;
+ if (SDL_QueryTexture(tex, NULL, NULL, &textures[i].width,
+ &textures[i].height)) {
+ dx_log_error("%s", SDL_GetError());
+ return -1;
+ }
+ return i;
+}
+
void LZR_CycleEvents(void)
{
SDL_Event e;
@@ -136,7 +183,7 @@ int LZR_DrawBegin(void)
next_time += min_dt;
if (SDL_SetRenderTarget(renderer, target) < 0) {
dx_log_error("%s", SDL_GetError());
- return 1;
+ return -1;
}
return 0;
}
@@ -145,12 +192,12 @@ int LZR_DrawEnd(void)
{
if (SDL_SetRenderTarget(renderer, NULL)) {
dx_log_error("%s", SDL_GetError());
- return 1;
+ return -1;
}
LZR_DrawSetColor(0.0f, 0.0f, 0.0f);
if (LZR_DrawClear()) {
dx_log_error("LZY_DrawClear failed");
- return 1;
+ return -1;
}
if (config.target_fps) {
const uint_least64_t cur_time = SDL_GetTicks64();
@@ -170,7 +217,7 @@ int LZR_DrawEnd(void)
config.display_height * scale};
if (SDL_RenderCopy(renderer, target, NULL, &dest) < 0) {
dx_log_error("%s", SDL_GetError());
- return 1;
+ return -1;
}
SDL_RenderPresent(renderer);
return 0;
@@ -181,10 +228,11 @@ 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)) {
+ if (SDL_SetRenderDrawColor(renderer, ur, ug, ub, 255) < 0) {
dx_log_error("%s", SDL_GetError());
- return 1;
+ return -1;
}
+ color[0] = ur, color[1] = ug, color[2] = ub;
return 0;
}
@@ -192,7 +240,30 @@ int LZR_DrawClear(void)
{
if (SDL_RenderClear(renderer) < 0) {
dx_log_error("%s", SDL_GetError());
- return 1;
+ return -1;
+ }
+ return 0;
+}
+
+int LZR_DrawImage(int id, int x, int y)
+{
+ if (id < 0) {
+ dx_log_error("id is negative");
+ return -1;
+ }
+ if (textures[id].tex == NULL) {
+ dx_log_error("no image with id %d", id);
+ return -1;
+ }
+ if (SDL_SetTextureColorMod(textures[id].tex, color[0], color[1],
+ color[2]) < 0) {
+ dx_log_error("%s", SDL_GetError());
+ return -1;
+ }
+ const SDL_Rect dest = {x, y, textures[id].width, textures[id].height};
+ if (SDL_RenderCopy(renderer, textures[id].tex, NULL, &dest) < 0) {
+ dx_log_error("%s", SDL_GetError());
+ return -1;
}
return 0;
}
diff --git a/lzr.h b/lzr.h
index 14893b5..c604bfd 100644
--- a/lzr.h
+++ b/lzr.h
@@ -2,6 +2,8 @@
#define LZR_H_
#include <stdbool.h>
+#define LZR_MAX_IMAGES 32
+
typedef struct LZR_Config {
unsigned int display_width;
unsigned int display_height;
@@ -14,6 +16,7 @@ int LZR_Init(LZR_Config cfg);
void LZR_Quit(void);
bool LZR_ShouldQuit(void);
void LZR_CycleEvents(void);
+int LZR_ImageLoad(const char *path);
int LZR_DrawBegin(void);
int LZR_DrawEnd(void);
int LZR_DrawSetColor(float r, float g, float b);
@@ -21,5 +24,6 @@ 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);
+int LZR_DrawImage(int id, int x, int y);
#endif