diff options
Diffstat (limited to 'src/TZR.c')
-rw-r--r-- | src/TZR.c | 180 |
1 files changed, 141 insertions, 39 deletions
@@ -4,6 +4,8 @@ #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <SDL2/SDL_log.h> +#include <SDL2/SDL_mixer.h> +#include <SDL2/SDL_mouse.h> #include <SDL2/SDL_render.h> #include <SDL2/SDL_rwops.h> #include <SDL2/SDL_scancode.h> @@ -58,8 +60,8 @@ static void TZR_RectFromSDLRect(TZR_Rect *dest, const SDL_Rect *src) } /* sources/globals.c */ -TZR_Config ___tzr_config = {0}; -TZR_Color ___tzr_color = {0, 0.0f, 0.0f, 0.0f, 1.0f}; +TZR_Config ___tzr_config = {}; +TZR_Color ___tzr_color = {0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; TZR_Resource *___tzr_resources = NULL; size_t ___tzr_resources_capacity = 0; size_t ___tzr_resources_size = 0; @@ -72,29 +74,38 @@ unsigned long ___tzr_min_dt = 0; int ___tzr_should_quit = 0; int ___tzr_mouse_x = 0; int ___tzr_mouse_y = 0; -const char *___tzr_command[___TZR_RES_COUNT] = {0}; -TZR_KeyState ___tzr_keystates[SDL_NUM_SCANCODES] = {0}; +TZR_KeyState ___tzr_keystates[SDL_NUM_SCANCODES] = {}; +TZR_KeyState ___tzr_mousestates[256] = {}; //doc says than mouse button is u8 +float ___tzr_scale = 1.0; +int ___tzr_off_x = 1.0; +int ___tzr_off_y = 1.0; /* sources/TZR_CycleEvents.c */ void +next_state(TZR_KeyState *keystate) +{ + switch (*keystate) { + case TZR_KEYSTATE_RELEASE: + case TZR_KEYSTATE_UP: + *keystate = TZR_KEYSTATE_UP; + break; + case TZR_KEYSTATE_PRESS: + case TZR_KEYSTATE_DOWN: + *keystate = TZR_KEYSTATE_DOWN; + break; + default: + break; + } +} + +void TZR_CycleEvents(void) { TZR_ResourcesWatch(); - for (int i = 0; i < SDL_NUM_SCANCODES; i++) { - TZR_KeyState *const keystate = &___tzr_keystates[i]; - switch (*keystate) { - case TZR_KEYSTATE_RELEASE: - case TZR_KEYSTATE_UP: - *keystate = TZR_KEYSTATE_UP; - break; - case TZR_KEYSTATE_PRESS: - case TZR_KEYSTATE_DOWN: - *keystate = TZR_KEYSTATE_DOWN; - break; - default: - break; - } - } + for (int i = 0; i < SDL_NUM_SCANCODES; i++) + next_state(&___tzr_keystates[i]); + for (int i = 0; i < 256; i++) + next_state(&___tzr_mousestates[i]); TZR_Event e; while (TZR_PollEvent(&e)) ; @@ -115,6 +126,10 @@ TZR_DestroyResource(TZR_Resource *res, int free_path) if (res->image.ptr != NULL) SDL_DestroyTexture(res->image.ptr); break; + case TZR_RES_SOUND: + if (res->sound.ptr != NULL) + Mix_FreeChunk(res->sound.ptr); + break; default: fprintf(stderr, "unknown resource type %u\n", res->type); break; @@ -160,6 +175,20 @@ TZR_DirectResourceLoad(TZR_Resource *res, const void *data, int size) } res->image.ptr = tex; } break; + case TZR_RES_SOUND: { + if (!___tzr_config.mixer) { + SDL_Log("audio mixer disabled, skip loading"); + return -1; + } + SDL_RWops *const rw = SDL_RWFromConstMem(data, size); + if (rw == NULL) + return sdl_error(-1); + Mix_Chunk *const chunk = Mix_LoadWAV_RW(rw, 0); + SDL_RWclose(rw); + if (chunk == NULL) + return sdl_error(-1); + res->sound.ptr = chunk; + } break; default: fprintf(stderr, "invalid type\n"); return -1; @@ -203,16 +232,16 @@ TZR_DrawEnd(void) const float ratio_w = win_w / (float)___tzr_config.width; const float ratio_h = win_h / (float)___tzr_config.height; - float scale = (ratio_w < ratio_h) ? ratio_w : ratio_h; - if (scale > 1.0f && ___tzr_config.pixel_perfect) - scale = (int)scale; - const int off_x = (win_w - ___tzr_config.width * scale) / 2; - const int off_y = (win_h - ___tzr_config.height * scale) / 2; + ___tzr_scale = (ratio_w < ratio_h) ? ratio_w : ratio_h; + if (___tzr_scale > 1.0f && ___tzr_config.pixel_perfect) + ___tzr_scale = (int)___tzr_scale; + ___tzr_off_x = (win_w - ___tzr_config.width * ___tzr_scale) / 2; + ___tzr_off_y = (win_h - ___tzr_config.height * ___tzr_scale) / 2; const SDL_Rect dest = { - off_x, - off_y, - ___tzr_config.width * scale, - ___tzr_config.height * scale + ___tzr_off_x, + ___tzr_off_y, + ___tzr_config.width * ___tzr_scale, + ___tzr_config.height * ___tzr_scale }; if (SDL_RenderCopy(___tzr_renderer, ___tzr_target, NULL, &dest) < 0) @@ -319,10 +348,15 @@ TZR_DrawPoint(int x, int y) /* sources/TZR_DrawRectangle.c */ int -TZR_DrawRectangle(bool fill, int x, int y, int w, int h) +_TZR_DrawRectangle(const TZR_DrawRectangleArgs *args) { - const SDL_Rect rect = { x, y, w, h }; - if (fill) { + const SDL_Rect rect = { + args->x - args->center * (args->w / 2), + args->y - args->center * (args->h / 2), + args->w, + args->h + }; + if (args->fill) { if (SDL_RenderFillRect(___tzr_renderer, &rect) < 0) return sdl_error(-1); } else { @@ -369,6 +403,17 @@ TZR_GetKeyState(int scancode) { return ___tzr_keystates[scancode]; } +/* sources/TZR_GetMousePosition.c */ + +void +TZR_GetMousePosition(int *x, int *y) +{ + if (x != NULL) + *x = ___tzr_mouse_x; + if (y != NULL) + *y = ___tzr_mouse_y; + TZR_ScreenTransform(x, y); +} /* sources/TZR_GetRawResource.c */ TZR_Raw * @@ -417,12 +462,17 @@ _sdl_error(void) int _TZR_Init(const TZR_Config *config) { + memcpy(&___tzr_config, config, sizeof(TZR_Config)); + if (SDL_Init(SDL_INIT_VIDEO) < 0) return _sdl_error(); if (IMG_Init(IMG_INIT_PNG) < 0) return _sdl_error(); + if (___tzr_config.mixer && Mix_Init(MIX_INIT_FLAC) != MIX_INIT_FLAC) { + SDL_Log("%s", Mix_GetError()); + ___tzr_config.mixer = false; + } - memcpy(&___tzr_config, config, sizeof(TZR_Config)); char *const basepath = SDL_GetBasePath(); if (basepath == NULL) return _sdl_error(); @@ -463,12 +513,19 @@ _TZR_Init(const TZR_Config *config) ___tzr_next_time = SDL_GetTicks64(); } - ___tzr_command[TZR_RES_RAW] = getenv("TZR_EDIT_RAW"); - if (___tzr_command[TZR_RES_RAW] == NULL) - ___tzr_command[TZR_RES_RAW] = "foot nvim"; - ___tzr_command[TZR_RES_IMAGE] = getenv("TZR_EDIT_IMAGE"); - if (___tzr_command[TZR_RES_IMAGE] == NULL) - ___tzr_command[TZR_RES_IMAGE] = "gimp"; + if (!___tzr_config.show_cursor) + SDL_ShowCursor(SDL_FALSE); + ___tzr_mouse_x = ___tzr_config.width / 2; + ___tzr_mouse_y = ___tzr_config.height / 2; + + /* Setup audio. */ + if (___tzr_config.mixer) { + if (Mix_OpenAudio(48000, MIX_DEFAULT_FORMAT, 8, 1024) < 0) { + sdl_error(0); + Mix_Quit(); + ___tzr_config.mixer = false; + } + } return 0; } /* sources/TZR_IsKeyDown.c */ @@ -514,6 +571,8 @@ deduce_type(const char *path) if (strcasecmp(path_extension, ".bmp") == 0 || strcasecmp(path_extension, ".png") == 0) return TZR_RES_IMAGE; + if (strcasecmp(path_extension, ".wav") == 0) + return TZR_RES_SOUND; return TZR_RES_RAW; } @@ -596,6 +655,27 @@ TZR_LoadResourceTyped(TZR_ResourceType type, const char *path) strcpy(res->path, path); return id; } +/* sources/TZR_PlaySound.c */ + +int +_TZR_PlaySound(const TZR_PlaySoundArgs *args) +{ + if (args->id == 0) { + fprintf(stderr, "args->id is 0\n"); + return -1; + } + + if (TZR_GetResourceType(args->id) != TZR_RES_SOUND) { + fprintf(stderr, "%u isn't a sound\n", args->id); + return -1; + } + + const __auto_type sound = &TZR_GetResourcePointer(args->id)->sound; + Mix_VolumeChunk(sound->ptr, args->volume * MIX_MAX_VOLUME); + if (Mix_PlayChannel(-1, sound->ptr, args->loop) < 0) + return sdl_error(-1); + return 0; +} /* sources/TZR_PollEvent.c */ int @@ -626,10 +706,12 @@ TZR_PollEvent(TZR_Event *e) case SDL_MOUSEBUTTONDOWN: ___tzr_mouse_x = se.button.x; ___tzr_mouse_y = se.button.y; + ___tzr_mousestates[se.button.button] = TZR_KEYSTATE_PRESS; break; case SDL_MOUSEBUTTONUP: ___tzr_mouse_x = se.button.x; ___tzr_mouse_y = se.button.y; + ___tzr_mousestates[se.button.button] = TZR_KEYSTATE_RELEASE; break; case SDL_MOUSEMOTION: ___tzr_mouse_x = se.motion.x; @@ -664,6 +746,10 @@ TZR_Quit(void) SDL_DestroyWindow(___tzr_window); ___tzr_window = NULL; } + if (___tzr_config.mixer) { + Mix_CloseAudio(); + Mix_Quit(); + } IMG_Quit(); SDL_Quit(); } @@ -715,6 +801,22 @@ TZR_ResourcesWatch(void) } } } +/* sources/TZR_ScreenTransform.c */ + +void +TZR_ScreenTransform(int *x, int *y) +{ + if (___tzr_scale == 0.0) + return; + if (x != NULL) { + *x -= ___tzr_off_x; + *x /= ___tzr_scale; + } + if (y != NULL) { + *y -= ___tzr_off_y; + *y /= ___tzr_scale; + } +} /* sources/TZR_ShouldQuit.c */ int @@ -723,4 +825,4 @@ TZR_ShouldQuit(void) return ___tzr_should_quit; } -/* commit hash: 8b92076145893cfdaf3e648e0324b163c1a6d28e */ +/* commit hash: e96c359a840974adea4d3d1d3445377f159ecdf0 */ |