aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2022-09-06 07:41:30 +0200
committerkdx <kikoodx@paranoici.org>2022-09-06 07:41:51 +0200
commita85d878031755ef21dfc45637dc4130bc40f3fc7 (patch)
treedafae0b2df05fcc78e2f669dfaa3bdac659c38bd
parent7163c10d4c0e887918f35ed82b25209f39a6bd2d (diff)
downloadlzr-a85d878031755ef21dfc45637dc4130bc40f3fc7.tar.gz
input & extended image draw
-rw-r--r--demo.c23
-rw-r--r--lzr.c129
-rw-r--r--lzr.h30
3 files changed, 164 insertions, 18 deletions
diff --git a/demo.c b/demo.c
index 6782dae..0a95626 100644
--- a/demo.c
+++ b/demo.c
@@ -1,5 +1,6 @@
#include "lzr.h"
#include <dx/log.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
@@ -14,19 +15,39 @@ int main(void)
LZR_ImageLoad("coucou.bmp");
float darkness = 0.0f;
float dark_dir = 1.0f;
+ int x = 10;
+ int y = 20;
+ LZR_ImageDrawSettings stg = {0, 0, -1, -1, 1.0, 1.0, 0.0, false, false};
while (!LZR_ShouldQuit()) {
darkness += 0.01f * dark_dir;
if (darkness * dark_dir >= 0.5f) {
darkness = 0.5f * dark_dir;
dark_dir = -dark_dir;
}
+ if (LZR_ButtonDown(LZR_BUTTON_LEFT)) {
+ stg.flip_h = true;
+ x--;
+ }
+ if (LZR_ButtonDown(LZR_BUTTON_RIGHT)) {
+ stg.flip_h = false;
+ x++;
+ }
+ if (LZR_ButtonDown(LZR_BUTTON_UP)) {
+ stg.flip_v = true;
+ y--;
+ }
+ if (LZR_ButtonDown(LZR_BUTTON_DOWN)) {
+ stg.flip_v = false;
+ y++;
+ }
+ stg.angle = darkness * 20;
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_DrawImageEx(0, x, y, &stg);
LZR_DrawEnd();
}
LZR_Quit();
diff --git a/lzr.c b/lzr.c
index 231421c..b2b13b4 100644
--- a/lzr.c
+++ b/lzr.c
@@ -1,5 +1,7 @@
#include "lzr.h"
#include <SDL2/SDL.h>
+#include <SDL2/SDL_error.h>
+#include <SDL2/SDL_render.h>
#include <dx/log.h>
#include <dx/mem.h>
#include <dx/str.h>
@@ -18,8 +20,9 @@ static bool should_quit = false;
static struct {
SDL_Texture *tex;
int width, height;
-} textures[LZR_MAX_IMAGES] = {0};
+} images[LZR_MAX_IMAGES] = {0};
static unsigned int color[3] = {0};
+static bool input[LZR_BUTTON_COUNT] = {false};
static char *_path_prefix(const char *path)
{
@@ -41,6 +44,17 @@ static char *_path_prefix(const char *path)
return buf;
}
+static int _scode_to_button(unsigned int scode)
+{
+ static const unsigned int map[LZR_BUTTON_COUNT] = {
+ SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP,
+ SDL_SCANCODE_DOWN, SDL_SCANCODE_X, SDL_SCANCODE_C};
+ for (int i = 0; i < LZR_BUTTON_COUNT; i++)
+ if (map[i] == scode)
+ return i;
+ return -1;
+}
+
int LZR_Init(LZR_Config cfg)
{
memcpy(&config, &cfg, sizeof(config));
@@ -98,9 +112,9 @@ 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;
+ if (images[i].tex != NULL) {
+ SDL_DestroyTexture(images[i].tex);
+ images[i].tex = NULL;
dx_log_trace("destroyed image %d", i);
}
if (target != NULL) {
@@ -131,7 +145,7 @@ int LZR_ImageLoad(const char *path)
{
int i;
for (i = 0; i < LZR_MAX_IMAGES; i++)
- if (textures[i].tex == NULL)
+ if (images[i].tex == NULL)
break;
if (i >= LZR_MAX_IMAGES) {
dx_log_error("reached image limit (%d)", LZR_MAX_IMAGES);
@@ -154,27 +168,65 @@ int LZR_ImageLoad(const char *path)
dx_log_error("%s", SDL_GetError());
return -1;
}
- textures[i].tex = tex;
- if (SDL_QueryTexture(tex, NULL, NULL, &textures[i].width,
- &textures[i].height)) {
+ images[i].tex = tex;
+ if (SDL_QueryTexture(tex, NULL, NULL, &images[i].width,
+ &images[i].height)) {
dx_log_error("%s", SDL_GetError());
return -1;
}
return i;
}
-void LZR_CycleEvents(void)
+bool LZR_PollEvent(LZR_Event *e)
{
- SDL_Event e;
- while (SDL_PollEvent(&e)) {
- switch (e.type) {
+ if (e == NULL) {
+ dx_log_error("e is NULL");
+ return false;
+ }
+ SDL_Event se;
+ while (SDL_PollEvent(&se)) {
+ switch (se.type) {
case SDL_QUIT:
+ e->type = LZR_EVENT_QUIT;
should_quit = true;
- break;
+ return true;
+ case SDL_KEYDOWN: {
+ const int b = _scode_to_button(se.key.keysym.scancode);
+ if (se.key.repeat || b < 0)
+ break;
+ e->type = LZR_EVENT_BUTTON_DOWN;
+ e->button = b;
+ input[b] = true;
+ } break;
+ case SDL_KEYUP: {
+ const int b = _scode_to_button(se.key.keysym.scancode);
+ if (b < 0)
+ break;
+ e->type = LZR_EVENT_BUTTON_UP;
+ e->button = b;
+ input[b] = false;
+ } break;
default:
break;
}
}
+ return false;
+}
+
+void LZR_CycleEvents(void)
+{
+ LZR_Event e;
+ while (LZR_PollEvent(&e))
+ ;
+}
+
+bool LZR_ButtonDown(LZR_Button btn)
+{
+ if (btn >= 0 && btn < LZR_BUTTON_COUNT)
+ return input[btn];
+ else
+ dx_log_warn("%d button doesn't exist", btn);
+ return false;
}
int LZR_DrawBegin(void)
@@ -251,17 +303,60 @@ int LZR_DrawImage(int id, int x, int y)
dx_log_error("id is negative");
return -1;
}
- if (textures[id].tex == NULL) {
+ if (id >= LZR_MAX_IMAGES || images[id].tex == NULL) {
+ dx_log_error("no image with id %d", id);
+ return -1;
+ }
+ const SDL_Rect dest = {x, y, images[id].width, images[id].height};
+ if (SDL_RenderCopy(renderer, images[id].tex, NULL, &dest) < 0) {
+ dx_log_error("%s", SDL_GetError());
+ return -1;
+ }
+ return 0;
+}
+
+int LZR_DrawImageEx(int id, int x, int y, const LZR_ImageDrawSettings *stg)
+{
+ if (id < 0) {
+ dx_log_error("id is negative");
+ return -1;
+ }
+ if (id >= LZR_MAX_IMAGES || images[id].tex == NULL) {
dx_log_error("no image with id %d", id);
return -1;
}
- if (SDL_SetTextureColorMod(textures[id].tex, color[0], color[1],
+ const int width = (stg->width > 0) ? stg->width : images[id].width;
+ const int height = (stg->height > 0) ? stg->height : images[id].height;
+ SDL_Rect src = {stg->ix, stg->iy, width, height};
+ SDL_Rect dst = {x, y, width * stg->scale_x, height * stg->scale_y};
+ if (stg->ix < 0) {
+ src.w += stg->ix;
+ dst.x = 0 - stg->ix;
+ dst.w += stg->ix;
+ }
+ if (stg->iy < 0) {
+ src.y = 0 - stg->iy;
+ src.h += stg->iy;
+ dst.y -= stg->iy;
+ dst.h += stg->iy;
+ }
+ if (stg->ix + width > images[id].width) {
+ src.w = images[id].width - stg->ix;
+ dst.w = images[id].width - stg->ix;
+ }
+ if (stg->iy + height > images[id].height) {
+ src.h = images[id].height - stg->iy;
+ dst.h = images[id].height - stg->iy;
+ }
+ if (SDL_SetTextureColorMod(images[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) {
+ const int flip = (stg->flip_h ? SDL_FLIP_VERTICAL : 0) |
+ (stg->flip_v ? SDL_FLIP_HORIZONTAL : 0);
+ if (SDL_RenderCopyEx(renderer, images[id].tex, &src, &dst, stg->angle,
+ NULL, flip)) {
dx_log_error("%s", SDL_GetError());
return -1;
}
diff --git a/lzr.h b/lzr.h
index c604bfd..01d0f74 100644
--- a/lzr.h
+++ b/lzr.h
@@ -12,10 +12,39 @@ typedef struct LZR_Config {
const char *title;
} LZR_Config;
+typedef enum LZR_EventType {
+ LZR_EVENT_QUIT,
+ LZR_EVENT_BUTTON_DOWN,
+ LZR_EVENT_BUTTON_UP,
+} LZR_EventType;
+
+typedef enum LZR_Button {
+ LZR_BUTTON_LEFT,
+ LZR_BUTTON_RIGHT,
+ LZR_BUTTON_UP,
+ LZR_BUTTON_DOWN,
+ LZR_BUTTON_O,
+ LZR_BUTTON_X,
+ LZR_BUTTON_COUNT
+} LZR_Button;
+
+typedef struct LZR_Event {
+ LZR_EventType type;
+ LZR_Button button;
+} LZR_Event;
+
+typedef struct LZR_ImageDrawSettings {
+ int ix, iy, width, height;
+ double scale_x, scale_y, angle;
+ bool flip_v, flip_h;
+} LZR_ImageDrawSettings;
+
int LZR_Init(LZR_Config cfg);
void LZR_Quit(void);
bool LZR_ShouldQuit(void);
+bool LZR_PollEvent(LZR_Event *e);
void LZR_CycleEvents(void);
+bool LZR_ButtonDown(LZR_Button);
int LZR_ImageLoad(const char *path);
int LZR_DrawBegin(void);
int LZR_DrawEnd(void);
@@ -25,5 +54,6 @@ 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);
+int LZR_DrawImageEx(int id, int x, int y, const LZR_ImageDrawSettings *stg);
#endif