1 module ecs_utils.utils; 2 3 extern(C): 4 5 import ecs_utils.math.vector; 6 7 enum PI = 3.141592653589793238462643383279502884197169399375105820; 8 9 extern(C) float sqrtf(float x) @nogc nothrow @system; 10 extern(C) float acosf(float x) @nogc nothrow @system; 11 extern(C) float sinf(float x) @nogc nothrow @system; 12 extern(C) float cosf(float x) @nogc nothrow @system; 13 extern(C) float powf(float x, float y) @nogc nothrow @system; 14 extern(C) float fabs(float x) @nogc nothrow @system; 15 extern(C) float log2f(float arg) @nogc nothrow @system; 16 17 18 int randomRange(int min, int max) nothrow @nogc @trusted 19 { 20 int range = max - min; 21 return rand() % range - min; 22 } 23 24 float randomf() nothrow @nogc @trusted 25 { 26 const float scale = 1.0 / 32_767.0; 27 return cast(float)(rand() & 0x007FFF) * scale; 28 } 29 30 /* 31 float randomRangef(float min, float max) 32 { 33 //int range = max - min; 34 return rand()%4096; 35 }*/ 36 37 float mix(float x, float y, float a) 38 { 39 //return x*a + y*(a-1); 40 //return x*a + y*a - y; 41 return x*(a+y) - y; 42 } 43 44 float rsqrt(float number) 45 { 46 long i; 47 float x2, y; 48 const float threehalfs = 1.5F; 49 50 x2 = number * 0.5F; 51 y = number; 52 i = * cast( long * ) &y; // evil floating point bit level hacking 53 i = 0x5f3759df - ( i >> 1 ); // what the fuck? 54 y = * cast( float * ) &i; 55 y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration 56 57 return y; 58 } 59 60 vec2 randomCircularSample() nothrow @nogc @trusted 61 { 62 float angle = 2 * PI * randomf; 63 float radius = sqrtf(randomf); 64 float s = sinf(angle); 65 float c = cosf(angle); 66 return vec2(c,s)*radius; 67 } 68 69 version(GNU) 70 { 71 public import core.stdc.stdio : printf; 72 pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) 73 { 74 return a; 75 } 76 } 77 else 78 { 79 extern(C) int printf(scope const char* format, ...) @nogc nothrow @system; 80 // public import std.array : staticArray; 81 pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a) 82 { 83 return a; 84 } 85 } 86 extern(C) int rand() nothrow @nogc @trusted; 87 88 version(D_BetterC) 89 { 90 version(LDC) 91 { 92 extern(C) bool _d_enter_cleanup(void*) 93 { 94 return true; 95 } 96 97 extern(C) void _d_leave_cleanup(void*) 98 { 99 100 } 101 102 extern(C) void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen, size_t elemsz) 103 { 104 import ldc.intrinsics : llvm_memcpy; 105 llvm_memcpy!size_t(dst, src, dstlen * elemsz, 0); 106 } 107 } 108 } 109 110 version(Android) 111 { 112 alias pthread_key_t = uint; 113 114 extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow; 115 extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow; 116 extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow; 117 extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow; 118 } 119 120 version(WebAssembly) 121 { 122 alias pthread_key_t = uint; 123 124 extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow; 125 extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow; 126 extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow; 127 extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow; 128 129 enum EMSCRIPTEN_RESULT_SUCCESS = 0; 130 enum EMSCRIPTEN_RESULT_DEFERRED = 1; 131 enum EMSCRIPTEN_RESULT_NOT_SUPPORTED = -1; 132 enum EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED = -2; 133 enum EMSCRIPTEN_RESULT_INVALID_TARGET = -3; 134 enum EMSCRIPTEN_RESULT_UNKNOWN_TARGET = -4; 135 enum EMSCRIPTEN_RESULT_INVALID_PARAM = -5; 136 enum EMSCRIPTEN_RESULT_FAILED = -6; 137 enum EMSCRIPTEN_RESULT_NO_DATA = -7; 138 enum EMSCRIPTEN_RESULT_TIMED_OUT = -8; 139 140 alias EMSCRIPTEN_FULLSCREEN_SCALE = int; 141 enum EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT = 0; 142 enum EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH = 1; 143 enum EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT = 2; 144 enum EMSCRIPTEN_FULLSCREEN_SCALE_CENTER = 3; 145 146 alias EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE = int; 147 enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE = 0; 148 enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF = 1; 149 enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF = 2; 150 151 alias EMSCRIPTEN_FULLSCREEN_FILTERING = int; 152 enum EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT = 0; 153 enum EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST = 1; 154 enum EMSCRIPTEN_FULLSCREEN_FILTERING_BILINEAR = 2; 155 156 alias em_canvasresized_callback_func = extern(C) bool function (int eventType, const void *reserved, void *userData); 157 158 struct EmscriptenFullscreenStrategy { 159 EMSCRIPTEN_FULLSCREEN_SCALE scaleMode; 160 EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE canvasResolutionScaleMode; 161 EMSCRIPTEN_FULLSCREEN_FILTERING filteringMode; 162 em_canvasresized_callback_func canvasResizedCallback; 163 void *canvasResizedCallbackUserData; 164 } 165 166 extern (C) const (char)* emscripten_result_to_string(int result) { 167 if (result == EMSCRIPTEN_RESULT_SUCCESS) return "EMSCRIPTEN_RESULT_SUCCESS"; 168 if (result == EMSCRIPTEN_RESULT_DEFERRED) return "EMSCRIPTEN_RESULT_DEFERRED"; 169 if (result == EMSCRIPTEN_RESULT_NOT_SUPPORTED) return "EMSCRIPTEN_RESULT_NOT_SUPPORTED"; 170 if (result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED) return "EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED"; 171 if (result == EMSCRIPTEN_RESULT_INVALID_TARGET) return "EMSCRIPTEN_RESULT_INVALID_TARGET"; 172 if (result == EMSCRIPTEN_RESULT_UNKNOWN_TARGET) return "EMSCRIPTEN_RESULT_UNKNOWN_TARGET"; 173 if (result == EMSCRIPTEN_RESULT_INVALID_PARAM) return "EMSCRIPTEN_RESULT_INVALID_PARAM"; 174 if (result == EMSCRIPTEN_RESULT_FAILED) return "EMSCRIPTEN_RESULT_FAILED"; 175 if (result == EMSCRIPTEN_RESULT_NO_DATA) return "EMSCRIPTEN_RESULT_NO_DATA"; 176 return "Unknown EMSCRIPTEN_RESULT!"; 177 } 178 179 extern (C) alias em_callback_func = void function(); 180 extern (C) alias em_arg_callback_func = void function(void*); 181 extern (C) void emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop); 182 extern (C) void emscripten_set_main_loop_arg(em_arg_callback_func func, void *arg, int fps, int simulate_infinite_loop); 183 extern (C) int emscripten_set_main_loop_timing(int mode, int value); 184 extern (C) void emscripten_cancel_main_loop(); 185 extern (C) int emscripten_request_fullscreen_strategy(const char *target, bool deferUntilInEventHandler, const EmscriptenFullscreenStrategy *fullscreenStrategy); 186 extern (C) int emscripten_enter_soft_fullscreen(const char *target, const EmscriptenFullscreenStrategy *fullscreenStrategy); 187 extern (C) void emscripten_main_thread_process_queued_calls(); 188 extern (C) void emscripten_pause_main_loop(); 189 extern (C) void emscripten_resume_main_loop(); 190 191 alias int time_t; 192 alias int clockid_t; 193 enum CLOCK_REALTIME = 0; 194 195 struct timespec 196 { 197 time_t tv_sec; 198 int tv_nsec; 199 } 200 201 extern(C) int clock_gettime(clockid_t, timespec*) @nogc nothrow @system; 202 203 struct Time 204 { 205 206 207 static long getUSecTime() 208 { 209 time_t time; 210 timespec spec; 211 212 clock_gettime(CLOCK_REALTIME, &spec); 213 214 //time = spec.tv_sec; 215 return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000;//time / 1000_000; 216 217 /*LARGE_INTEGER time, freq; 218 QueryPerformanceFrequency(&freq); 219 QueryPerformanceCounter(&time); 220 return time.QuadPart / (freq.QuadPart / 1000_000);*/ 221 } 222 } 223 } 224 else version(Windows) 225 { 226 import core.stdc.stdio : printf; 227 import core.sys.windows.windows; 228 struct Time 229 { 230 static long getUSecTime() 231 { 232 LARGE_INTEGER time, freq; 233 QueryPerformanceFrequency(&freq); 234 QueryPerformanceCounter(&time); 235 return time.QuadPart / (freq.QuadPart / 1000_000); 236 } 237 } 238 } 239 else version(Posix) 240 { 241 import core.stdc.stdio : printf; 242 import core.sys.posix.time; 243 struct Time 244 { 245 static long getUSecTime() 246 { 247 time_t time; 248 timespec spec; 249 250 clock_gettime(CLOCK_REALTIME, &spec); 251 252 //time = spec.tv_sec; 253 return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000;//time / 1000_000; 254 255 /*LARGE_INTEGER time, freq; 256 QueryPerformanceFrequency(&freq); 257 QueryPerformanceCounter(&time); 258 return time.QuadPart / (freq.QuadPart / 1000_000);*/ 259 } 260 } 261 }