diff options
author | kdx <kikoodx@paranoici.org> | 2022-09-06 07:41:30 +0200 |
---|---|---|
committer | kdx <kikoodx@paranoici.org> | 2022-09-06 07:41:51 +0200 |
commit | a85d878031755ef21dfc45637dc4130bc40f3fc7 (patch) | |
tree | dafae0b2df05fcc78e2f669dfaa3bdac659c38bd | |
parent | 7163c10d4c0e887918f35ed82b25209f39a6bd2d (diff) | |
download | lzr-a85d878031755ef21dfc45637dc4130bc40f3fc7.tar.gz |
input & extended image draw
-rw-r--r-- | demo.c | 23 | ||||
-rw-r--r-- | lzr.c | 129 | ||||
-rw-r--r-- | lzr.h | 30 |
3 files changed, 164 insertions, 18 deletions
@@ -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(); @@ -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; } @@ -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 |