summaryrefslogtreecommitdiff
path: root/src/TZR.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/TZR.c')
-rw-r--r--src/TZR.c180
1 files changed, 141 insertions, 39 deletions
diff --git a/src/TZR.c b/src/TZR.c
index 150cf22..77ab2e0 100644
--- a/src/TZR.c
+++ b/src/TZR.c
@@ -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 */