diff options
Diffstat (limited to 'inc/TZR.h')
-rw-r--r-- | inc/TZR.h | 476 |
1 files changed, 476 insertions, 0 deletions
diff --git a/inc/TZR.h b/inc/TZR.h new file mode 100644 index 0000000..20e81cb --- /dev/null +++ b/inc/TZR.h @@ -0,0 +1,476 @@ +/* Licensing information can be found at the end of the file. */ +#pragma once +#ifdef __EMSCRIPTEN__ +#include <emscripten.h> +#endif +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef TZR_SOLOUD +#include "soloud_c.h" +#endif +#include <limits.h> +#include <SDL2/SDL_gamecontroller.h> +#include <SDL2/SDL_main.h> +#include <SDL2/SDL_mixer.h> +#include <SDL2/SDL_mouse.h> +#include <SDL2/SDL_render.h> +#include <SDL2/SDL_scancode.h> +#include <stdbool.h> +#include <stddef.h> + +/* headers/TZR_types.h */ + +enum TZR_ResourceType { + TZR_RES_RAW, + TZR_RES_IMAGE, + TZR_RES_SOUND, + ___TZR_RES_COUNT +}; + +enum TZR_EventType { + TZR_EV_QUIT, + TZR_EV_KEYDOWN, + TZR_EV_KEYUP +}; + +enum TZR_KeyState { + TZR_KEYSTATE_UP, + TZR_KEYSTATE_DOWN, + TZR_KEYSTATE_RELEASE, + TZR_KEYSTATE_PRESS +}; + +enum TZR_MixerFlags { + TZR_MIXER_OFF, + TZR_MIXER_ON, + TZR_MIXER_FLAC +}; + +typedef unsigned int TZR_Uint; +typedef struct TZR_Config TZR_Config; +typedef struct TZR_Point TZR_Point; +typedef struct TZR_Color TZR_Color; +typedef struct TZR_Rect TZR_Rect; +typedef enum TZR_ResourceType TZR_ResourceType; +typedef struct TZR_Raw TZR_Raw; +typedef struct TZR_Image TZR_Image; +typedef struct TZR_Sound TZR_Sound; +typedef struct TZR_Resource TZR_Resource; +typedef enum TZR_EventType TZR_EventType; +typedef struct TZR_Event TZR_Event; +typedef struct TZR_Music TZR_Music; +typedef struct TZR_DrawImageArgs TZR_DrawImageArgs; +typedef struct TZR_DrawRectangleArgs TZR_DrawRectangleArgs; +typedef struct TZR_PlaySoundArgs TZR_PlaySoundArgs; +typedef enum TZR_KeyState TZR_KeyState; +typedef struct TZR_Joystick TZR_Joystick; + +struct TZR_Config { + int _; + int width; + int height; + int scale; + int target_fps; + bool pixel_perfect; + bool hd_render; + bool scale_linear; + bool show_cursor; + unsigned int mixer; + const char *basepath; + const char *title; +}; + +struct TZR_Point { + int x; + int y; +}; + +struct TZR_Color { + int _; + float r; + float g; + float b; + float a; +}; + +struct TZR_Rect { + TZR_Point from; + TZR_Point to; +}; + +struct TZR_Raw { + void *data; + size_t size; +}; + +struct TZR_Image { + int width; + int height; + SDL_Texture *ptr; +}; + +#ifdef TZR_SOLOUD +struct TZR_Sound { + Wav *ptr; +}; +#else +struct TZR_Sound { + Mix_Chunk *ptr; +}; +#endif + +struct TZR_Resource { + TZR_ResourceType type; + char *path; /* allocated and freed by TZR; can be NULL */ + long mtime; + union { + TZR_Raw raw; /* raw file data */ + TZR_Image image; + TZR_Sound sound; + }; +}; + +struct TZR_Event { + TZR_EventType type; + int button; +}; + +struct TZR_DrawImageArgs { + int _; + TZR_Uint id; + int x; + int y; + int ix; + int iy; + int w; + int h; + float r; + float sx; + float sy; + bool center; + bool flip_x; + bool flip_y; +}; + +struct TZR_DrawRectangleArgs { + int _; + int x; + int y; + int w; + int h; + bool fill; + bool center; +}; + +struct TZR_PlaySoundArgs { + int _; + TZR_Uint id; + int loop; + float volume; +}; + +struct TZR_Joystick +{ + SDL_GameController *ptr; + float leftx; + float lefty; + float rightx; + float righty; +}; +/* headers/TZR_globals.h */ + +extern TZR_Config ___tzr_config; +extern TZR_Color ___tzr_color; +extern TZR_Resource *___tzr_resources; +extern size_t ___tzr_resources_capacity; +extern size_t ___tzr_resources_size; +extern SDL_Window *___tzr_window; +extern SDL_Renderer *___tzr_renderer; +extern SDL_Texture *___tzr_target; +extern unsigned long ___tzr_tick; +extern unsigned long ___tzr_next_time; +extern unsigned long ___tzr_min_dt; +extern int ___tzr_should_quit; +extern int ___tzr_mouse_x; +extern int ___tzr_mouse_y; +extern TZR_KeyState ___tzr_keystates[SDL_NUM_SCANCODES]; +extern TZR_KeyState ___tzr_mousestates[256]; +extern TZR_KeyState ___tzr_joystates[SDL_CONTROLLER_BUTTON_MAX]; +extern float ___tzr_scale; +extern int ___tzr_off_x; +extern int ___tzr_off_y; +extern Mix_Music *___tzr_music; +extern TZR_Joystick *___tzr_joysticks; +extern size_t ___tzr_joysticks_capacity; +extern size_t ___tzr_joysticks_size; +extern SDL_BlendMode ___tzr_blendmode; + +#ifdef TZR_SOLOUD +extern Soloud ___tzr_soloud; +#endif +/* headers/TZR_resource.h */ + +#define TZR_RES TZR_LoadResource + +/* Return 0 on error. */ +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +TZR_Uint TZR_LoadResourceFromMemory(TZR_ResourceType type, const void *data, int size); +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +TZR_Uint TZR_LoadResourceTyped(TZR_ResourceType type, const char *path); + +/* Return 0 on error; try to autodetect resource type from file extension. */ +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +TZR_Uint TZR_LoadResource(const char *path); + +/* Doesn't handle invalid ID. Pointer might get invalidated by resource + * creation calls, use with caution. */ +TZR_Resource *TZR_GetResourcePointer(TZR_Uint id); + +/* Doesn't handle invalid ID. Pointer might get invalidated by resource + * creation calls, use with caution. */ +TZR_Raw *TZR_GetRawResource(TZR_Uint id); + +/* Doesn't handle invalid ID. */ +TZR_ResourceType TZR_GetResourceType(TZR_Uint id); + +/* Doesn't handle invalid ID. */ +const char *TZR_GetResourcePath(TZR_Uint id); + +/* Doesn't handle invalid ID. */ +int TZR_GetImageWidth(TZR_Uint id); + +/* Doesn't handle invalid ID. */ +int TZR_GetImageHeight(TZR_Uint id); + +/* Reload ressource. Returns -1 on error and doesn't apply changes. */ +int TZR_ReloadResource(TZR_Uint id); + +/* Watch for changes on managed resources and hotreload if appropriate. */ +void TZR_ResourcesWatch(void); + +/* Used internaly. */ +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +int TZR_DirectResourceLoad(TZR_Resource *res, const void *data, int size); +void TZR_DestroyResource(TZR_Resource *res, int free_path); +/* headers/TZR_sound.h */ + +#define TZR_PlaySound(...) ({ const TZR_PlaySoundArgs ____arg = { \ + .id=0, .loop=0, .volume=1.0f, ._=0, __VA_ARGS__ }; \ + _TZR_PlaySound(&____arg); }) +#ifdef TZR_PARANOID +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +#endif +int _TZR_PlaySound(const TZR_PlaySoundArgs *args); + +/* Return -1 on error. */ +int TZR_PlayMusic(const char *path, int loop); + +void TZR_StopMusic(void); +/* headers/TZR_events.h */ + +/* Write event data to `e`. Return 0 when event queue is empty. */ +int TZR_PollEvent(TZR_Event *e); + +/* Drain queued events with TZR_PollEvent and call TZR_ResourcesWatch. */ +void TZR_CycleEvents(void); +/* headers/TZR_render.h */ + +/* All draw calls should happen between TZR_DrawBegin and TZR_DrawEnd. + * Return -1 on error. */ +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +int TZR_DrawBegin(void); + +/* Return -1 on error. */ +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +int TZR_DrawEnd(void); + +/* Return -1 on error. */ +#define TZR_DrawSetColor(...) ({ const TZR_Color ____arg = { \ + .r=-1.0f, .g=-1.0f, .b=-1.0f, .a=-1.0f, ._=0, __VA_ARGS__ }; \ + _TZR_DrawSetColor(&____arg); }) +#ifdef TZR_PARANOID +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +#endif +int _TZR_DrawSetColor(const TZR_Color *color); + +/* Return -1 on error. */ +#ifdef TZR_PARANOID +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +#endif +int TZR_DrawSetColor8(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + +/* Return -1 on error. */ +#ifdef TZR_PARANOID +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +#endif +int TZR_DrawClear(void); + +/* Return -1 on error. Draw point on `x`;`y` in the framebuffer. */ +#ifdef TZR_PARANOID +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +#endif +int TZR_DrawPoint(int x, int y); + +/* Return -1 on error. Draw line between `x0`;`y0` and `x1`;`y1` in the + * framebuffer. */ +#ifdef TZR_PARANOID +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +#endif +int TZR_DrawLine(int x0, int y0, int x1, int y1); + +/* Return -1 on error. Draw rectangle at `x`;`y` position of size `w`x`h` in the + * framebuffer. */ +#define TZR_DrawRectangle(...) ({ const TZR_DrawRectangleArgs ____arg = { \ + .x=0, .y=0, .w=0, .h=0, .fill=false, .center=false, ._=0, __VA_ARGS__ }; \ + _TZR_DrawRectangle(&____arg); }) +#ifdef TZR_PARANOID +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +#endif +int _TZR_DrawRectangle(const TZR_DrawRectangleArgs *args); + +/* Return -1 on error. Draw texture ressource `id` at `x`;`y` position of + * the framebuffer. */ +#define TZR_DrawImage(...) ({ const TZR_DrawImageArgs ____arg = { \ + .x=0, .y=0, .ix=0, .iy=0, .w=INT_MIN, .h=INT_MIN, .r=0.0f, .sx=1.0f, \ + .sy=1.0f, .center=false, .flip_x=false, .flip_y=false, ._=0, \ + __VA_ARGS__ }; \ + _TZR_DrawImage(&____arg); }) +#ifdef TZR_PARANOID +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +#endif +int _TZR_DrawImage(const TZR_DrawImageArgs *args); + +void TZR_ScreenTransform(int *x, int *y); + +#ifdef TZR_PARANOID +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +#endif +int TZR_BlendMode(SDL_BlendMode mode); +/* headers/TZR_keystate.h */ + +TZR_KeyState TZR_GetKeyState(int scancode); +bool TZR_IsKeyDown(int scancode); +bool TZR_IsKeyUp(int scancode); +bool TZR_IsKeyReleased(int scancode); +bool TZR_IsKeyPressed(int scancode); +/* headers/TZR_mouse.h */ + +/* `x` and `y` are out values and nullable. */ +void TZR_MouseGetPosition(int *x, int *y); + +TZR_KeyState TZR_MouseGetState(uint8_t button); +bool TZR_MouseDown(uint8_t button); +bool TZR_MouseUp(uint8_t button); +bool TZR_MouseReleased(uint8_t button); +bool TZR_MousePressed(uint8_t button); +/* headers/TZR_joystick.h */ + +TZR_KeyState TZR_JoystickGetState(uint8_t button); +bool TZR_JoystickDown(uint8_t button); +bool TZR_JoystickUp(uint8_t button); +bool TZR_JoystickReleased(uint8_t button); +bool TZR_JoystickPressed(uint8_t button); +float TZR_JoystickLeftX(void); +float TZR_JoystickLeftY(void); +float TZR_JoystickRightX(void); +float TZR_JoystickRightY(void); +/* headers/TZR.h */ + +/* TZR manages all loaded resources internally and tries to avoid duplicate. + * A resource can be loaded multiple times if asked, identification doesn't rely + * on filepath. In doubt, use TZR_LoadResource ONCE per asset and store the ID. + * Resources are exposed as ID instead of pointer, as a future proof measure in + * case TZR needs to rearrange memory at runtime in the future. */ + +#define TZR_Init(...) ({ const TZR_Config ____arg = { \ + .width=256, \ + .height=224, \ + .scale=2, \ + .target_fps=60, \ + .pixel_perfect=true, \ + .hd_render=false, \ + .scale_linear=false, \ + .show_cursor=false, \ + .mixer=TZR_MIXER_ON, \ + .basepath=NULL, \ + .title="TZR", \ + ._=0, __VA_ARGS__ }; \ + _TZR_Init(&____arg); }) + +/* Should be called only once before usage of any other function unless + * otherwise specified. On error this calls TZR_Quit and returns -1. + * `config` will be duplicated internally and can be safely discarded. */ +#if __STDC_VERSION__ > 201710L +[[nodiscard]] +#endif +int _TZR_Init(const TZR_Config *config); + +/* Destroy and free everything created by TZR. */ +void TZR_Quit(void); + +/* Return non-zero value when a quit event has been received. */ +int TZR_ShouldQuit(void); + +int TZR_MainLoop(int (*main_loop)(void *udata), void *udata); + +unsigned long TZR_GetTick(void); + +void TZR_ToggleFullscreen(void); + +#ifdef __cplusplus +} +#endif +/* +** Copyright (c) 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. +*/ +/* commit hash: ae4af8c1f825d904eaea3be5cdf02e097e30a30f */ |