partially done work on total source tree rework, separation of engine context and game context, generalization of renderer for different backends as well as web platform target
This commit is contained in:
167
include/twn_util.h
Normal file
167
include/twn_util.h
Normal file
@ -0,0 +1,167 @@
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include "twn_vec.h"
|
||||
#include "twn_engine_api.h"
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
#include <physfs.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <math.h>
|
||||
#include <stdnoreturn.h>
|
||||
|
||||
|
||||
/* */
|
||||
/* GENERAL UTILITIES */
|
||||
/* */
|
||||
|
||||
TWN_API void cry_impl(const char *file, const int line, const char *title, const char *text);
|
||||
#define CRY(title, text) cry_impl(__FILE__, __LINE__, title, text)
|
||||
#define CRY_SDL(title) cry_impl(__FILE__, __LINE__, title, SDL_GetError())
|
||||
#define CRY_PHYSFS(title) \
|
||||
cry_impl(__FILE__, __LINE__, title, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()))
|
||||
|
||||
|
||||
TWN_API void log_info(const char *restrict format, ...);
|
||||
TWN_API void log_critical(const char *restrict format, ...);
|
||||
TWN_API void log_warn(const char *restrict format, ...);
|
||||
|
||||
|
||||
/* for when there's absolutely no way to continue */
|
||||
TWN_API noreturn void die_abruptly(void);
|
||||
|
||||
|
||||
/* "critical" allocation functions which will log and abort() on failure. */
|
||||
/* if it is reasonable to handle this gracefully, use the standard versions. */
|
||||
/* the stb implementations will be configured to use these */
|
||||
TWN_API void *cmalloc(size_t size);
|
||||
TWN_API void *crealloc(void *ptr, size_t size);
|
||||
TWN_API void *ccalloc(size_t num, size_t size);
|
||||
|
||||
|
||||
/* DON'T FORGET ABOUT DOUBLE EVALUATION */
|
||||
/* YOU THINK YOU WON'T, AND THEN YOU DO */
|
||||
/* C23's typeof could fix it, so i will */
|
||||
/* leave them as macros to be replaced. */
|
||||
/* use the macro in tgmath.h for floats */
|
||||
#define MAX SDL_max
|
||||
#define MIN SDL_min
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327950288 /**< pi */
|
||||
#endif
|
||||
|
||||
/* multiply by these to convert degrees <---> radians */
|
||||
#define DEG2RAD (M_PI / 180)
|
||||
#define RAD2DEG (180 / M_PI)
|
||||
|
||||
/* TODO: this is why generics were invented. sorry, i'm tired today */
|
||||
TWN_API double clamp(double d, double min, double max);
|
||||
TWN_API float clampf(float f, float min, float max);
|
||||
TWN_API int clampi(int i, int min, int max);
|
||||
|
||||
/* sets buf_out to a pointer to a byte buffer which must be freed. */
|
||||
/* returns the size of this buffer. */
|
||||
TWN_API int64_t file_to_bytes(const char *path, unsigned char **buf_out);
|
||||
|
||||
/* returns a pointer to a string which must be freed */
|
||||
TWN_API char *file_to_str(const char *path);
|
||||
|
||||
|
||||
/* returns true if str ends with suffix */
|
||||
TWN_API TWN_API bool strends(const char *str, const char *suffix);
|
||||
|
||||
|
||||
/* */
|
||||
/* GAME LOGIC UTILITIES */
|
||||
/* */
|
||||
|
||||
/* 32-bit color data */
|
||||
typedef struct color {
|
||||
_Alignas(4)
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
uint8_t a;
|
||||
} t_color;
|
||||
|
||||
|
||||
/* a rectangle with the origin at the upper left (integer) */
|
||||
typedef struct rect {
|
||||
_Alignas(16)
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int32_t w;
|
||||
int32_t h;
|
||||
} t_rect;
|
||||
|
||||
|
||||
/* a rectangle with the origin at the upper left (floating point) */
|
||||
typedef struct frect {
|
||||
_Alignas(16)
|
||||
float x;
|
||||
float y;
|
||||
float w;
|
||||
float h;
|
||||
} t_frect;
|
||||
|
||||
|
||||
TWN_API bool intersect_rect(const t_rect *a, const t_rect *b, t_rect *result);
|
||||
|
||||
TWN_API bool intersect_frect(const t_frect *a, const t_frect *b, t_frect *result);
|
||||
|
||||
/* TODO: generics and specials (see m_to_fvec2() for an example)*/
|
||||
TWN_API t_frect to_frect(t_rect rect);
|
||||
|
||||
TWN_API t_fvec2 frect_center(t_frect rect);
|
||||
|
||||
|
||||
typedef struct matrix4 {
|
||||
t_fvec4 row[4];
|
||||
} t_matrix4;
|
||||
|
||||
|
||||
/* decrements an lvalue (which should be an int), stopping at 0 */
|
||||
/* meant for tick-based timers in game logic */
|
||||
/*
|
||||
* example:
|
||||
* tick_timer(&player->jump_air_timer);
|
||||
*/
|
||||
TWN_API void tick_timer(int *value);
|
||||
|
||||
/* decrements a floating point second-based timer, stopping at 0.0 */
|
||||
/* meant for poll based real time logic in game logic */
|
||||
/* note that it should be decremented only on the next tick after its creation */
|
||||
TWN_API void tick_ftimer(float *value);
|
||||
|
||||
/* same as `tick_ftimer` but instead of clamping it repeats */
|
||||
/* returns true if value was cycled */
|
||||
TWN_API bool repeat_ftimer(float *value, float at);
|
||||
|
||||
/* http://www.azillionmonkeys.com/qed/sqroot.html */
|
||||
static inline float fast_sqrt(float x)
|
||||
{
|
||||
union {
|
||||
float f;
|
||||
uint32_t u;
|
||||
} pun = {.f = x};
|
||||
|
||||
pun.u += 127 << 23;
|
||||
pun.u >>= 1;
|
||||
|
||||
return pun.f;
|
||||
}
|
||||
|
||||
|
||||
static inline t_fvec2 fast_cossine(float a) {
|
||||
const float s = sinf(a);
|
||||
return (t_fvec2){
|
||||
.x = fast_sqrt(1.0f - s * s) * (a >= (float)M_PI_2 && a < (float)(M_PI + M_PI_2) ? -1 : 1),
|
||||
.y = s
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user