summaryrefslogtreecommitdiff
path: root/src/lzr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lzr.c')
-rw-r--r--src/lzr.c929
1 files changed, 0 insertions, 929 deletions
diff --git a/src/lzr.c b/src/lzr.c
deleted file mode 100644
index 7f3cfe0..0000000
--- a/src/lzr.c
+++ /dev/null
@@ -1,929 +0,0 @@
-/* Licensing information can be found at the end of the file. */
-#include "lzr.h"
-#include <SDL2/SDL.h>
-#ifdef LZR_ENABLE_GFX
-# include <SDL2/SDL2_gfxPrimitives.h>
-#endif
-#ifdef LZR_ENABLE_IMAGE
-# include <SDL2/SDL_image.h>
-#endif
-#ifdef LZR_ENABLE_MIXER
-# include <SDL2/SDL_mixer.h>
-#endif
-#ifdef LZR_ENABLE_DEVMODE
-# include <sys/stat.h>
-#endif
-#include <stdbool.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#define UNPACKED_COLOR color[0], color[1], color[2]
-#define UNPACKED_COLOR_RGBA color[0], color[1], color[2], color[3]
-#define SCODE_BIND_MENU SDL_SCANCODE_F1
-#define SCODE_FULLSCREEN SDL_SCANCODE_F11
-
-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 struct {
- SDL_Texture *tex;
- int width, height;
- char *path;
- long mtime;
-} images[LZR_MAX_IMAGES] = {0};
-static unsigned int color[4] = {0};
-static unsigned int map[LZR_BUTTON_COUNT] = {
- SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP,
- SDL_SCANCODE_DOWN, SDL_SCANCODE_X, SDL_SCANCODE_C};
-static bool input[LZR_BUTTON_COUNT] = {false};
-static SDL_Point *points = NULL;
-static uint64_t tick = 0;
-static int off_x = 0;
-static int off_y = 0;
-static float scale = 1.0;
-static int mouse_x = 0;
-static int mouse_y = 0;
-
-#ifdef LZR_ENABLE_MIXER
-static struct {
- Mix_Chunk *ptr;
-} sounds[LZR_MAX_SOUNDS] = {0};
-static Mix_Music *music = NULL;
-#endif
-
-static char *_lzrstrdup(const char *str)
-{
- char *const cpy = malloc(strlen(str) + 1);
- if (cpy == NULL)
- return NULL;
- strcpy(cpy, str);
- return cpy;
-}
-
-static int _scode_to_button(unsigned int scode)
-{
- for (int i = 0; i < LZR_BUTTON_MOUSE_L; i++)
- if (map[i] == scode)
- return i;
- return -1;
-}
-
-static void _draw_btn(SDL_Renderer *ren, int btn, int x, int y,
- unsigned int size)
-{
-#ifdef LZR_ENABLE_GFX
- const unsigned int size_2thirds = size * 2 / 3;
- switch (btn) {
- case LZR_BUTTON_LEFT:
- filledTrigonRGBA(ren, x - size / 2, y, x + size / 2,
- y + size_2thirds, x + size / 2,
- y - size_2thirds, 0, 0, 0, 255);
- break;
- case LZR_BUTTON_RIGHT:
- filledTrigonRGBA(ren, x + size / 2, y, x - size / 2,
- y + size_2thirds, x - size / 2,
- y - size_2thirds, 0, 0, 0, 255);
- break;
- case LZR_BUTTON_UP:
- filledTrigonRGBA(ren, x, y - size / 2, x - size_2thirds,
- y + size / 2, x + size_2thirds, y + size / 2,
- 0, 0, 0, 255);
- break;
- case LZR_BUTTON_DOWN:
- filledTrigonRGBA(ren, x, y + size / 2, x - size_2thirds,
- y - size / 2, x + size_2thirds, y - size / 2,
- 0, 0, 0, 255);
- break;
- case LZR_BUTTON_O:
- filledCircleRGBA(ren, x, y, size * 2 / 3, 0, 0, 0, 255);
- break;
- case LZR_BUTTON_X:
- thickLineRGBA(ren, x - size / 2, y - size / 2, x + size / 2,
- y + size / 2, size / 16 + 1, 0, 0, 0, 255);
- thickLineRGBA(ren, x + size / 2, y - size / 2, x - size / 2,
- y + size / 2, size / 16 + 1, 0, 0, 0, 255);
- break;
- default:
- break;
- }
-#else
- (void)ren, (void)btn, (void)x, (void)y, (void)size;
-#endif
-}
-
-static void _bind_menu(void)
-{
- SDL_Log("entering bind menu");
- SDL_Window *win = NULL;
- SDL_Renderer *ren = NULL;
- if (SDL_CreateWindowAndRenderer(256, 256, 0, &win, &ren) < 0) {
- SDL_Log("%s", SDL_GetError());
- return;
- }
- int btn = 0;
- SDL_Event e;
- while (btn < LZR_BUTTON_MOUSE_L) {
- while (SDL_PollEvent(&e)) {
- if (e.type != SDL_KEYDOWN || e.key.repeat ||
- e.key.keysym.scancode == SCODE_BIND_MENU ||
- e.key.keysym.scancode == SCODE_FULLSCREEN)
- continue;
- if (e.key.keysym.scancode == SDL_SCANCODE_ESCAPE ||
- e.type == SDL_QUIT)
- goto exit_bind_menu;
- LZR_ButtonBind(btn, e.key.keysym.scancode);
- btn++;
- }
- SDL_SetRenderDrawColor(ren, 220, 220, 200, 255);
- SDL_RenderClear(ren);
- SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
- _draw_btn(ren, btn, 128, 128, 104);
- SDL_RenderPresent(ren);
- sleep(0);
- }
-exit_bind_menu:
- SDL_DestroyRenderer(ren);
- SDL_DestroyWindow(win);
- SDL_Log("leaving bind menu");
-}
-
-int LZR_Init(LZR_Config cfg)
-{
- memcpy(&config, &cfg, sizeof(config));
- if (config.display_width == 0) {
- SDL_Log("display_width can't be 0");
- return -1;
- }
- if (config.display_height == 0) {
- SDL_Log("display_height can't be 0");
- return -1;
- }
- if (config.title == NULL) {
- SDL_Log("title is NULL, defaulting to 'LZR'");
- config.title = "LZR";
- }
- if (config.tile_size == 0)
- config.tile_size = 1;
- if (config.ratio <= 0.0)
- config.ratio = 1.0;
- else {
- const double ratio =
- (float)config.display_width / (float)config.display_height;
- config.ratio /= ratio;
- }
- if (SDL_Init(SDL_INIT_VIDEO) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
-#ifdef LZR_ENABLE_IMAGE
- if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) {
- SDL_Log("%s", IMG_GetError());
- return -1;
- }
-#endif
-#ifdef LZR_ENABLE_MIXER
- if (Mix_Init(MIX_INIT_FLAC) != MIX_INIT_FLAC) {
- SDL_Log("%s", Mix_GetError());
- return -1;
- }
- if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 8, 1024) < 0) {
- SDL_Log("%s", Mix_GetError());
- return -1;
- }
-#endif
- basepath = SDL_GetBasePath();
- if (basepath == NULL) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- const int dwidth = config.display_width * config.ratio;
- window = SDL_CreateWindow(config.title, SDL_WINDOWPOS_UNDEFINED,
- SDL_WINDOWPOS_UNDEFINED, dwidth,
- config.display_height, SDL_WINDOW_RESIZABLE);
- if (window == NULL) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
- if (renderer == NULL) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGB888,
- SDL_TEXTUREACCESS_TARGET,
- config.display_width, config.display_height);
- if (target == NULL) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- points =
- calloc(cfg.display_width * cfg.display_height, sizeof(SDL_Point));
- if (points == NULL) {
- SDL_Log("calloc failed");
- return -1;
- }
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, 0);
- if (config.target_fps) {
- min_dt = 1000 / config.target_fps;
- next_time = SDL_GetTicks64();
- }
- if (config.hide_cursor && SDL_ShowCursor(SDL_DISABLE) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- if (LZR_DrawSetColor(1.0f, 1.0f, 1.0f, 1.0f))
- return -1;
- return 0;
-}
-
-void LZR_Quit(void)
-{
-#ifdef LZR_ENABLE_MIXER
- for (int i = 0; i < LZR_MAX_SOUNDS; i++)
- if (sounds[i].ptr != NULL) {
- Mix_FreeChunk(sounds[i].ptr);
- sounds[i].ptr = NULL;
- }
- Mix_CloseAudio();
- Mix_Quit();
-#endif
- for (int i = 0; i < LZR_MAX_IMAGES; i++) {
- if (images[i].tex != NULL) {
- SDL_DestroyTexture(images[i].tex);
- images[i].tex = NULL;
- }
- if (images[i].path != NULL) {
- free(images[i].path);
- images[i].path = NULL;
- }
- }
- if (points != NULL) {
- free(points);
- points = NULL;
- }
- 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;
- }
-#ifdef LZR_ENABLE_IMAGE
- IMG_Quit();
-#endif
- SDL_Quit();
-}
-
-bool LZR_ShouldQuit(void)
-{
- return should_quit;
-}
-
-char *LZR_PathPrefix(const char *path)
-{
- if (path == NULL) {
- SDL_Log("path is NULL");
- return NULL;
- }
- if (basepath == NULL) {
- SDL_Log("basepath is NULL");
- return _lzrstrdup(path);
- }
- char *const buf = malloc(strlen(basepath) + strlen(path) + 1);
- if (buf == NULL) {
- SDL_Log("malloc failed");
- return NULL;
- }
- strcpy(buf, basepath);
- strcat(buf, path);
- return buf;
-}
-
-int LZR_ImageLoad(const char *path)
-{
- char *apath;
- long mtime = 0;
-#ifdef LZR_ENABLE_DEVMODE
- apath = LZR_PathPrefix(path);
- if (apath == NULL)
- return -1;
- struct stat st = {0};
- (void)stat(apath, &st); /* stat can fail safely */
- mtime = st.st_mtim.tv_nsec;
-#endif
- int i;
- for (i = 0; i < LZR_MAX_IMAGES; i++) {
- if (images[i].path != NULL &&
- strcmp(images[i].path, path) == 0) {
- if (mtime != images[i].mtime) {
- SDL_Log("reloading %d", i);
- break;
- }
- return i;
- }
- if (images[i].tex == NULL)
- break;
- }
- if (i >= LZR_MAX_IMAGES) {
- SDL_Log("reached image limit (%d)", LZR_MAX_IMAGES);
- return -1;
- }
- apath = LZR_PathPrefix(path);
- if (apath == NULL) {
- SDL_Log("LZR_PathPrefix failed");
- return -1;
- }
-#ifdef LZR_ENABLE_IMAGE
- SDL_Surface *const surf = IMG_Load(apath);
-#else
- SDL_Surface *const surf = SDL_LoadBMP(apath);
-#endif
- free(apath);
- if (surf == NULL) {
- SDL_Log("%s: %s", path, SDL_GetError());
- return -1;
- }
- SDL_Texture *const tex = SDL_CreateTextureFromSurface(renderer, surf);
- SDL_FreeSurface(surf);
- if (tex == NULL) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- if (images[i].tex != NULL)
- SDL_DestroyTexture(images[i].tex);
- images[i].tex = tex;
- images[i].mtime = mtime;
- if (SDL_SetTextureBlendMode(images[i].tex, SDL_BLENDMODE_BLEND) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- if (SDL_QueryTexture(tex, NULL, NULL, &images[i].width,
- &images[i].height)) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- if (images[i].path == NULL)
- images[i].path = _lzrstrdup(path);
- return i;
-}
-
-int LZR_SoundLoad(const char *path, float volume)
-{
-#ifdef LZR_ENABLE_MIXER
- int i;
- for (i = 0; i < LZR_MAX_SOUNDS; i++)
- if (sounds[i].ptr == NULL)
- break;
- if (i >= LZR_MAX_SOUNDS) {
- SDL_Log("reached sounds limit (%d)", LZR_MAX_SOUNDS);
- return -1;
- }
- char *const apath = LZR_PathPrefix(path);
- if (apath == NULL) {
- SDL_Log("LZR_PathPrefix failed");
- return -1;
- }
- Mix_Chunk *const chunk = Mix_LoadWAV(apath);
- free(apath);
- if (chunk == NULL) {
- SDL_Log("%s: %s", path, Mix_GetError());
- return -1;
- }
- Mix_VolumeChunk(chunk, volume);
- sounds[i].ptr = chunk;
- return i;
-#else
- (void)path, (void)volume;
- return -1;
-#endif
-}
-
-bool LZR_PollEvent(LZR_Event *e)
-{
- if (e == NULL) {
- SDL_Log("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;
- return true;
- case SDL_KEYDOWN: {
- if (!config.disable_bind_menu &&
- se.key.keysym.scancode == SCODE_BIND_MENU)
- _bind_menu();
- if (se.key.keysym.scancode == SCODE_FULLSCREEN)
- LZR_ToggleFullscreen();
- 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;
- return true;
- }
- case SDL_MOUSEBUTTONDOWN: {
- e->type = LZR_EVENT_BUTTON_DOWN;
- e->button = LZR_BUTTON_MOUSE_L + se.button.button - 1;
- e->x = se.button.x, e->y = se.button.y;
- LZR_ScreenTransform(&e->x, &e->y);
- mouse_x = e->x, mouse_y = e->y;
- if (e->button >= LZR_BUTTON_COUNT)
- continue;
- input[e->button] = true;
- return true;
- }
- 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;
- return true;
- }
- case SDL_MOUSEBUTTONUP: {
- e->type = LZR_EVENT_BUTTON_DOWN;
- e->button = LZR_BUTTON_MOUSE_L + se.button.button - 1;
- e->x = se.button.x, e->y = se.button.y;
- LZR_ScreenTransform(&e->x, &e->y);
- mouse_x = e->x, mouse_y = e->y;
- if (e->button >= LZR_BUTTON_COUNT)
- continue;
- input[e->button] = false;
- return true;
- }
- case SDL_MOUSEMOTION: {
- e->type = LZR_EVENT_MOUSE_MOVE;
- e->x = se.motion.x, e->y = se.motion.y;
- LZR_ScreenTransform(&e->x, &e->y);
- mouse_x = e->x, mouse_y = e->y;
- return true;
- }
- 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
- SDL_Log("%d button doesn't exist", btn);
- return false;
-}
-
-void LZR_ButtonBind(LZR_Button btn, unsigned int code)
-{
- if (btn < LZR_BUTTON_MOUSE_L && code != SCODE_BIND_MENU) {
- map[btn] = code;
- SDL_Log("bound key %s to button %u",
- SDL_GetScancodeName(map[btn]), btn);
- } else
- SDL_Log("button %u can't be remapped to key %s", btn,
- SDL_GetScancodeName(code));
-}
-
-int LZR_DrawBegin(void)
-{
- if (config.target_fps > 0)
- next_time += min_dt;
- if (SDL_SetRenderTarget(renderer, target) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
- SDL_RenderClear(renderer);
- return 0;
-}
-
-int LZR_DrawEnd(void)
-{
- if (SDL_SetRenderTarget(renderer, NULL)) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- LZR_DrawSetColor(0.0f, 0.0f, 0.0f, 1.0f);
- if (LZR_DrawClear()) {
- SDL_Log("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 width = config.display_width * config.ratio;
- const int height = config.display_height;
- const int ratio_w = win_w / width;
- const int ratio_h = win_h / height;
- scale = (ratio_w <= ratio_h) ? ratio_w : ratio_h;
- off_x = (win_w - width * scale) / 2;
- off_y = (win_h - height * scale) / 2;
- const SDL_Rect dest = {off_x, off_y, width * scale, height * scale};
- if (SDL_RenderCopyEx(renderer, target, NULL, &dest, 0.0, NULL, 0) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- SDL_RenderPresent(renderer);
- tick++;
- return 0;
-}
-
-int LZR_DrawSetColor(float r, float g, float b, float a)
-{
- 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;
- const unsigned int ua = (unsigned int)(a * 255) & 255;
- if (SDL_SetRenderDrawColor(renderer, ur, ug, ub, ua) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- color[0] = ur, color[1] = ug, color[2] = ub, color[3] = ua;
- return 0;
-}
-
-int LZR_DrawClear(void)
-{
- if (SDL_RenderClear(renderer) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- return 0;
-}
-
-int LZR_DrawPoint(int x, int y)
-{
- if (SDL_RenderDrawPoint(renderer, x, y) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- return 0;
-}
-
-int LZR_DrawPoints(int *x, int *y, int n)
-{
-
- if (n > (int)(config.display_width * config.display_height)) {
- SDL_Log("%d > %u", n,
- config.display_width * config.display_height);
- return -1;
- }
- for (int i = 0; i < n; i++) {
- points[i].x = x[i];
- points[i].y = y[i];
- }
- if (SDL_RenderDrawPoints(renderer, points, n) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- return 0;
-}
-
-int LZR_DrawLine(int x0, int y0, int x1, int y1)
-{
- if (SDL_RenderDrawLine(renderer, x0, y0, x1, y1) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- return 0;
-}
-
-int LZR_DrawRectangle(bool fill, int x, int y, int w, int h)
-{
- SDL_Rect rect = {x, y, w, h};
- if ((fill ? SDL_RenderFillRect : SDL_RenderDrawRect)(renderer, &rect)) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- return 0;
-}
-
-int LZR_DrawCircle(bool fill, int x, int y, int radius)
-{
-#ifdef LZR_ENABLE_GFX
- if ((fill ? filledCircleRGBA : circleRGBA)(renderer, x, y, radius,
- UNPACKED_COLOR_RGBA) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- return 0;
-#else
- (void)fill, (void)x, (void)y, (void)radius;
- SDL_Log("LZR GFX module is disabled");
- return -1;
-#endif
-}
-
-int LZR_DrawPolygon(bool fill, int *vx, int *vy, int n)
-{
-#ifdef LZR_ENABLE_GFX
- if (n > 32) {
- SDL_Log("%d > 32", n);
- return -1;
- }
- Sint16 x[32], y[32];
- for (int i = 0; i < n; i++)
- x[i] = vx[i], y[i] = vy[i];
- if ((fill ? filledPolygonRGBA : polygonRGBA)(renderer, x, y, n,
- UNPACKED_COLOR_RGBA) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- return 0;
-#else
- (void)fill, (void)vx, (void)vy, (void)n;
- SDL_Log("LZR GFX module is disabled");
- return -1;
-#endif
-}
-
-int LZR_DrawImage(int id, int x, int y)
-{
- if (id < 0) {
- SDL_Log("id is negative");
- return -1;
- }
- if (id >= LZR_MAX_IMAGES || images[id].tex == NULL) {
- SDL_Log("no image with id %d", id);
- return -1;
- }
- if (SDL_SetTextureColorMod(images[id].tex, UNPACKED_COLOR) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- if (SDL_SetTextureAlphaMod(images[id].tex, color[3]) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- const SDL_Rect dest = {x, y, images[id].width, images[id].height};
- if (SDL_RenderCopy(renderer, images[id].tex, NULL, &dest) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- return 0;
-}
-
-int LZR_DrawImageEx(int id, int x, int y, LZR_ImageDrawSettings stg)
-{
- if (id < 0) {
- SDL_Log("id is negative");
- return -1;
- }
- if (id >= LZR_MAX_IMAGES || images[id].tex == NULL) {
- SDL_Log("no image with id %d", id);
- return -1;
- }
- const int width = (stg.width > 0) ? stg.width : images[id].width;
- const int height = (stg.height > 0) ? stg.height : images[id].height;
- if (stg.center) {
- x -= stg.scale_x * width / 2;
- y -= stg.scale_y * height / 2;
- }
- 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, UNPACKED_COLOR) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- if (SDL_SetTextureAlphaMod(images[id].tex, color[3]) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- const int flip = (stg.flip_v ? SDL_FLIP_VERTICAL : 0) |
- (stg.flip_h ? SDL_FLIP_HORIZONTAL : 0);
- if (SDL_RenderCopyEx(renderer, images[id].tex, &src, &dst,
- stg.angle * 360.0, NULL, flip)) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- return 0;
-}
-
-int LZR_DrawTile(int id, int tile, int x, int y, double rot, int flip)
-{
- if (id < 0) {
- SDL_Log("id is negative");
- return -1;
- }
- if (id >= LZR_MAX_IMAGES || images[id].tex == NULL) {
- SDL_Log("no image with id %d", id);
- return -1;
- }
- if (tile < 0) {
- SDL_Log("tile is negative");
- return -1;
- }
- const int img_width = images[id].width / config.tile_size;
- const int img_height = images[id].height / config.tile_size;
- if (tile >= img_width * img_height) {
- SDL_Log("tile exceeds boundaries");
- return -1;
- }
- if (SDL_SetTextureColorMod(images[id].tex, UNPACKED_COLOR) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- if (SDL_SetTextureAlphaMod(images[id].tex, color[3]) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- SDL_Rect src;
- src.x = (tile % img_width) * config.tile_size;
- src.y = (tile / img_width) * config.tile_size;
- src.w = config.tile_size, src.h = config.tile_size;
- const SDL_Rect dst = {x, y, config.tile_size, config.tile_size};
- if (SDL_RenderCopyEx(renderer, images[id].tex, &src, &dst, rot, NULL,
- flip) < 0) {
- SDL_Log("%s", SDL_GetError());
- return -1;
- }
- return 0;
-}
-
-int LZR_PlaySound(int id)
-{
-#ifdef LZR_ENABLE_MIXER
- if (id < 0) {
- SDL_Log("id is negative");
- return -1;
- }
- if (id >= LZR_MAX_SOUNDS || sounds[id].ptr == NULL) {
- SDL_Log("no sound with id %d", id);
- return -1;
- }
- if (Mix_PlayChannel(-1, sounds[id].ptr, 0) < 0) {
- SDL_Log("%s", Mix_GetError());
- return -1;
- }
- return 0;
-#else
- (void)id;
- SDL_Log("LZR MIXER module is disabled");
- return -1;
-#endif
-}
-
-int LZR_SetMusicVolume(float volume)
-{
-#ifdef LZR_ENABLE_MIXER
- if (Mix_VolumeMusic(volume * MIX_MAX_VOLUME) < 0) {
- SDL_Log("%s", Mix_GetError());
- return -1;
- }
- return 0;
-#else
- (void)volume;
- SDL_Log("LZR MIXER module is disabled");
- return -1;
-#endif
-}
-
-int LZR_PlayMusic(const char *path, int loops)
-{
-#ifdef LZR_ENABLE_MIXER
- LZR_StopMusic();
- char *const apath = LZR_PathPrefix(path);
- if (apath == NULL) {
- SDL_Log("LZR_PathPrefix failed");
- return -1;
- }
- music = Mix_LoadMUS(apath);
- free(apath);
- if (music == NULL) {
- SDL_Log("%s: %s", path, Mix_GetError());
- return -1;
- }
- if (Mix_PlayMusic(music, loops) < 0) {
- SDL_Log("%s", Mix_GetError());
- return -1;
- }
- Mix_RewindMusic();
- return 0;
-#else
- (void)path, (void)loops;
- SDL_Log("LZR MIXER module is disabled");
- return -1;
-#endif
-}
-
-void LZR_StopMusic(void)
-{
-#ifdef LZR_ENABLE_MIXER
- if (Mix_PlayingMusic())
- Mix_HaltMusic();
- if (music != NULL) {
- Mix_FreeMusic(music);
- music = NULL;
- }
-#endif
-}
-
-void LZR_ToggleFullscreen(void)
-{
- static int fullscreen = 0;
- fullscreen = !fullscreen;
- SDL_SetWindowFullscreen(window,
- fullscreen * SDL_WINDOW_FULLSCREEN_DESKTOP);
-}
-
-uint64_t LZR_GetTick(void)
-{
- return tick;
-}
-
-void LZR_ScreenTransform(int *x, int *y)
-{
- if (scale == 0.0)
- return;
- if (x != NULL) {
- *x -= off_x;
- *x /= scale;
- }
- if (y != NULL) {
- *y -= off_y;
- *y /= scale;
- }
-}
-
-void LZR_MousePosition(int *x, int *y)
-{
- if (x != NULL)
- *x = mouse_x;
- if (y != NULL)
- *y = mouse_y;
-}
-
-/*
-** Copyright (c) 2022, 2023 kdx
-**
-** Permission is hereby granted, free of charge, to any person obtaining a copy
-** of this software and associated documentation files (the "Software"), to
-** deal in the Software without restriction, including without limitation the
-** rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-** sell copies of the Software, and to permit persons to whom the Software is
-** furnished to do so, subject to the following conditions:
-**
-** The above copyright notice and this permission notice shall be included in
-** all copies or substantial portions of the Software.
-**
-** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-** FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-** IN THE SOFTWARE.
-*/