module ecs_utils.utils; extern(C): import ecs_utils.math.vector; enum PI = 3.141592653589793238462643383279502884197169399375105820; extern(C) float sqrtf(float x) @nogc nothrow @system; extern(C) float acosf(float x) @nogc nothrow @system; extern(C) float sinf(float x) @nogc nothrow @system; extern(C) float cosf(float x) @nogc nothrow @system; extern(C) float powf(float x, float y) @nogc nothrow @system; extern(C) float fabs(float x) @nogc nothrow @system; int randomRange(int min, int max) nothrow @nogc @trusted { int range = max - min; return rand() % range - min; } float randomf() nothrow @nogc @trusted { const float scale = 1.0 / 32_767.0; return cast(float)(rand() & 0x007FFF) * scale; } /* float randomRangef(float min, float max) { //int range = max - min; return rand()%4096; }*/ float mix(float x, float y, float a) { //return x*a + y*(a-1); //return x*a + y*a - y; return x*(a+y) - y; } float rsqrt(float number) { long i; float x2, y; const float threehalfs = 1.5F; x2 = number * 0.5F; y = number; i = * cast( long * ) &y; // evil floating point bit level hacking i = 0x5f3759df - ( i >> 1 ); // what the fuck? y = * cast( float * ) &i; y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration return y; } vec2 randomCircularSample() nothrow @nogc @trusted { float angle = 2 * PI * randomf; float radius = sqrtf(randomf); float s = sinf(angle); float c = cosf(angle); return vec2(c,s)*radius; } version(GNU) { public import core.stdc.stdio : printf; pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) { return a; } } else { extern(C) int printf(scope const char* format, ...) @nogc nothrow @system; public import std.array : staticArray; } extern(C) int rand() nothrow @nogc @trusted; version(D_BetterC) { version(LDC) { extern(C) bool _d_enter_cleanup(void*) { return true; } extern(C) void _d_leave_cleanup(void*) { } extern(C) void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen, size_t elemsz) { import ldc.intrinsics : llvm_memcpy; llvm_memcpy!size_t(dst, src, dstlen * elemsz, 0); } } } version(Android) { alias pthread_key_t = uint; extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow; extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow; extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow; extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow; } version(WebAssembly) { alias pthread_key_t = uint; extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow; extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow; extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow; extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow; enum EMSCRIPTEN_RESULT_SUCCESS = 0; enum EMSCRIPTEN_RESULT_DEFERRED = 1; enum EMSCRIPTEN_RESULT_NOT_SUPPORTED = -1; enum EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED = -2; enum EMSCRIPTEN_RESULT_INVALID_TARGET = -3; enum EMSCRIPTEN_RESULT_UNKNOWN_TARGET = -4; enum EMSCRIPTEN_RESULT_INVALID_PARAM = -5; enum EMSCRIPTEN_RESULT_FAILED = -6; enum EMSCRIPTEN_RESULT_NO_DATA = -7; enum EMSCRIPTEN_RESULT_TIMED_OUT = -8; alias EMSCRIPTEN_FULLSCREEN_SCALE = int; enum EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT = 0; enum EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH = 1; enum EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT = 2; enum EMSCRIPTEN_FULLSCREEN_SCALE_CENTER = 3; alias EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE = int; enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE = 0; enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF = 1; enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF = 2; alias EMSCRIPTEN_FULLSCREEN_FILTERING = int; enum EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT = 0; enum EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST = 1; enum EMSCRIPTEN_FULLSCREEN_FILTERING_BILINEAR = 2; alias em_canvasresized_callback_func = extern(C) bool function (int eventType, const void *reserved, void *userData); struct EmscriptenFullscreenStrategy { EMSCRIPTEN_FULLSCREEN_SCALE scaleMode; EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE canvasResolutionScaleMode; EMSCRIPTEN_FULLSCREEN_FILTERING filteringMode; em_canvasresized_callback_func canvasResizedCallback; void *canvasResizedCallbackUserData; } extern (C) const (char)* emscripten_result_to_string(int result) { if (result == EMSCRIPTEN_RESULT_SUCCESS) return "EMSCRIPTEN_RESULT_SUCCESS"; if (result == EMSCRIPTEN_RESULT_DEFERRED) return "EMSCRIPTEN_RESULT_DEFERRED"; if (result == EMSCRIPTEN_RESULT_NOT_SUPPORTED) return "EMSCRIPTEN_RESULT_NOT_SUPPORTED"; if (result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED) return "EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED"; if (result == EMSCRIPTEN_RESULT_INVALID_TARGET) return "EMSCRIPTEN_RESULT_INVALID_TARGET"; if (result == EMSCRIPTEN_RESULT_UNKNOWN_TARGET) return "EMSCRIPTEN_RESULT_UNKNOWN_TARGET"; if (result == EMSCRIPTEN_RESULT_INVALID_PARAM) return "EMSCRIPTEN_RESULT_INVALID_PARAM"; if (result == EMSCRIPTEN_RESULT_FAILED) return "EMSCRIPTEN_RESULT_FAILED"; if (result == EMSCRIPTEN_RESULT_NO_DATA) return "EMSCRIPTEN_RESULT_NO_DATA"; return "Unknown EMSCRIPTEN_RESULT!"; } extern (C) alias em_callback_func = void function(); extern (C) alias em_arg_callback_func = void function(void*); extern (C) void emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop); extern (C) void emscripten_set_main_loop_arg(em_arg_callback_func func, void *arg, int fps, int simulate_infinite_loop); extern (C) int emscripten_set_main_loop_timing(int mode, int value); extern (C) void emscripten_cancel_main_loop(); extern (C) int emscripten_request_fullscreen_strategy(const char *target, bool deferUntilInEventHandler, const EmscriptenFullscreenStrategy *fullscreenStrategy); extern (C) int emscripten_enter_soft_fullscreen(const char *target, const EmscriptenFullscreenStrategy *fullscreenStrategy); extern (C) void emscripten_main_thread_process_queued_calls(); extern (C) void emscripten_pause_main_loop(); extern (C) void emscripten_resume_main_loop(); alias int time_t; alias int clockid_t; enum CLOCK_REALTIME = 0; struct timespec { time_t tv_sec; int tv_nsec; } extern(C) int clock_gettime(clockid_t, timespec*) @nogc nothrow @system; struct Time { static long getUSecTime() { time_t time; timespec spec; clock_gettime(CLOCK_REALTIME, &spec); //time = spec.tv_sec; return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000;//time / 1000_000; /*LARGE_INTEGER time, freq; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&time); return time.QuadPart / (freq.QuadPart / 1000_000);*/ } } } else version(Windows) { import core.stdc.stdio : printf; import core.sys.windows.windows; struct Time { static long getUSecTime() { LARGE_INTEGER time, freq; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&time); return time.QuadPart / (freq.QuadPart / 1000_000); } } } else version(Posix) { import core.stdc.stdio : printf; import core.sys.posix.time; struct Time { static long getUSecTime() { time_t time; timespec spec; clock_gettime(CLOCK_REALTIME, &spec); //time = spec.tv_sec; return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000;//time / 1000_000; /*LARGE_INTEGER time, freq; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&time); return time.QuadPart / (freq.QuadPart / 1000_000);*/ } } }