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 }