A view is a collection of lists. This is useful for a shadow mapping pass that generates more than one shadow map. Each view would create lists of objects visible in one shadow map.
217 lines
6.4 KiB
C
217 lines
6.4 KiB
C
#ifndef RT_VOYAGE_H
|
|
#define RT_VOYAGE_H
|
|
|
|
/* basic types and macros */
|
|
|
|
#include <limits.h>
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#if defined(_MSC_VER) && !defined(RT_STATIC_LIB)
|
|
#define RT_DLLEXPORT __declspec(dllexport)
|
|
#define RT_DLLIMPORT __declspec(dllimport)
|
|
#else
|
|
#define RT_DLLEXPORT
|
|
#define RT_DLLIMPORT
|
|
#endif
|
|
|
|
#if defined(_MSC_VER)
|
|
#define RT_INLINE __forceinline
|
|
#elif defined(__GNUC__) || defined(__clang__)
|
|
#define RT_INLINE inline __attribute__((always_inline))
|
|
#endif
|
|
|
|
#define RT_UNUSED(x) ((void)sizeof((x)))
|
|
#define RT_ARRAY_COUNT(x) (sizeof((x)) / sizeof((x)[0]))
|
|
|
|
#define RT_RESTRICT_VALUE_TO_BOUNDS(v, lower, upper) \
|
|
(((v) < (lower)) ? (lower) : (((v) > (upper)) ? (upper) : (v)))
|
|
|
|
#define RT_MIN(a, b) (((a) < (b))?(a):(b))
|
|
#define RT_MAX(a, b) (((a) > (b))?(a):(b))
|
|
|
|
#define RT_KB(n) ((n)*1024U)
|
|
#define RT_MB(n) ((n)*1024U * 1024U)
|
|
#define RT_GB(n) ((n)*1024U * 1024U * 1024U)
|
|
|
|
#ifndef __cplusplus
|
|
#if defined(_MSC_VER)
|
|
/* For some reason _Thread_local does not work with vs2022,
|
|
* despite MS documentation claiming it should. */
|
|
#define RT_THREAD_LOCAL __declspec(thread)
|
|
#elif defined(__GNUC__) || defined(__clang__)
|
|
/* _Thread_local in C11-C17, thread_local in C23 */
|
|
#if __STDC_VERSION__ > 201710L
|
|
#define RT_THREAD_LOCAL thread_local
|
|
#elif __STDC_VERSION__ >= 201112L
|
|
#define RT_THREAD_LOCAL _Thread_local
|
|
#else
|
|
#error Versions older than C11 not supported.
|
|
#endif
|
|
#endif
|
|
#else
|
|
// C++ 11 supports thread_local
|
|
#if __cplusplus >= 201103L
|
|
#define RT_THREAD_LOCAL thread_local
|
|
#elif defined(_MSC_VER)
|
|
#define RT_THREAD_LOCAL __declspec(thread)
|
|
#else
|
|
#error Versions older than C++11 not supported.
|
|
#endif
|
|
#endif
|
|
|
|
/* Matches windows MAX_PATH */
|
|
#define RT_PATH_MAX 260
|
|
|
|
typedef unsigned int rt_result;
|
|
|
|
/* Default result codes */
|
|
enum {
|
|
RT_SUCCESS = 0,
|
|
RT_OUT_OF_MEMORY = 1,
|
|
RT_INVALID_VALUE = 2,
|
|
|
|
RT_CUSTOM_ERROR_START,
|
|
|
|
RT_UNKNOWN_ERROR = (rt_result)INT_MAX,
|
|
};
|
|
|
|
typedef struct {
|
|
const char *start;
|
|
unsigned int length;
|
|
} rt_text_span;
|
|
|
|
/* snprintf replacement.
|
|
* Always returns a zero terminated string.
|
|
*/
|
|
RT_DLLEXPORT int rtSPrint(char *dest, size_t n, const char *fmt, ...);
|
|
|
|
RT_DLLEXPORT int rtVSPrint(char *dest, size_t n, const char *fmt, va_list ap);
|
|
|
|
/* Returns results like strcmp():
|
|
* - If the first differing character is smaller in span than in cmp: < 0
|
|
* - If span and cmp are equal: 0
|
|
* - If the first differing character is greater in span than in cmp: > 0
|
|
* - If span.length is smaller than strlen(cmp): -1
|
|
* - If span.length is greater than strlen(cmp): 1
|
|
*/
|
|
RT_DLLEXPORT int rtCompareSpanToString(rt_text_span span, const char *cmp);
|
|
|
|
RT_DLLEXPORT void rtReportError(const char *subsystem, const char *fmt, ...);
|
|
|
|
RT_DLLEXPORT void rtLog(const char *subsystem, const char *fmt, ...);
|
|
|
|
#ifndef NDEBUG
|
|
#ifdef _MSC_VER
|
|
#define RT_DEBUGBREAK __debugbreak()
|
|
#elif defined(__clang__) && __has_builtin(__bultin_debugtrap)
|
|
#define RT_DEBUGBREAK __builtin_debugtrap()
|
|
#elif defined(__GNUC__)
|
|
#define RT_DEBUGBREAK __builtin_trap()
|
|
#endif
|
|
|
|
RT_DLLEXPORT int rtAssertHandler(const char *expr, const char *msg, const char *file, int line);
|
|
#define RT_ASSERT(x, msg) \
|
|
do { \
|
|
if (!(x)) { \
|
|
if (rtAssertHandler(#x, (msg), __FILE__, __LINE__) == 0) { \
|
|
RT_DEBUGBREAK; \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
#define RT_ASSERT_ALWAYS_EVAL(x, msg) RT_ASSERT(x, msg)
|
|
|
|
// Asserts if p is "false", evaluates to p
|
|
// NOTE that this will evaluate p multiple times!
|
|
#define RT_VERIFY(p) \
|
|
((!(p)) ? (rtAssertHandler(#p, "Verify failed", __FILE__, __LINE__), p) : p)
|
|
|
|
#else
|
|
#define RT_ASSERT(x, msg) RT_UNUSED(x)
|
|
#define RT_ASSERT_ALWAYS_EVAL(x, msg) (x)
|
|
#define RT_VERIFY(p) (p)
|
|
#endif
|
|
|
|
/* Makes it easier to search for unimplemented functions */
|
|
#define RT_NOT_IMPLEMENTED RT_ASSERT_ALWAYS_EVAL(0, "Not implemented.")
|
|
|
|
enum {
|
|
RT_INVALID_UNICODE = RT_CUSTOM_ERROR_START,
|
|
RT_INSUFFICIENT_BUFFER,
|
|
};
|
|
|
|
/* Returns RT_SUCCESS if the string was successfully converted,
|
|
* RT_INVALID_UNICODE if invalid unicode characters were encountered or
|
|
* RT_INSUFFICIENT_BUFFER if the provided output buffer is too small */
|
|
RT_DLLEXPORT rt_result rtUTF8ToWStr(const char *utf8, wchar_t *wstr, size_t len);
|
|
|
|
/* Returns RT_SUCCESS if the string was successfully converted,
|
|
* RT_INVALID_UNICODE if invalid unicode characters were encountered or
|
|
* RT_INSUFFICIENT_BUFFER if the provided output buffer is too small */
|
|
RT_DLLEXPORT rt_result rtWStrToUTF8(const wchar_t *wstr, char *utf8, size_t len);
|
|
|
|
/* Relative pointer */
|
|
typedef struct {
|
|
int32_t off;
|
|
} rt_relptr;
|
|
|
|
static RT_INLINE void *rtResolveRelptr(rt_relptr *ptr) {
|
|
if (ptr->off != 0) {
|
|
char *p = (char *)ptr;
|
|
return (void *)(p + (ptrdiff_t)ptr->off);
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
static RT_INLINE const void *rtResolveConstRelptr(const rt_relptr *ptr) {
|
|
if (ptr->off != 0) {
|
|
const char *p = (const char *)ptr;
|
|
return (const void *)(p + (ptrdiff_t)ptr->off);
|
|
} else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
static RT_INLINE void rtSetRelptr(rt_relptr *ptr, void *target) {
|
|
if (target) {
|
|
char *p = (char *)ptr, *t = (char *)target;
|
|
ptrdiff_t d = t - p;
|
|
ptr->off = (int32_t)d;
|
|
} else {
|
|
ptr->off = 0;
|
|
}
|
|
}
|
|
|
|
/* Bitfiddling functions */
|
|
|
|
/* Portable solution, On x64 using clzl is probably faster. */
|
|
static RT_INLINE uint32_t rtNextPowerOfTwo32(uint32_t v) {
|
|
v--;
|
|
v |= v >> 1;
|
|
v |= v >> 2;
|
|
v |= v >> 4;
|
|
v |= v >> 8;
|
|
v |= v >> 16;
|
|
v++;
|
|
return v;
|
|
}
|
|
|
|
/* Runtime init. Initializes basic systems.
|
|
* You need to call this, even if you build a CLI only app. */
|
|
RT_DLLEXPORT rt_result rtInitRuntime(void);
|
|
|
|
RT_DLLEXPORT void rtShutdownRuntime(void);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|