now thats a lot of damage!
[vg.git] / src / vg / vg_platform.h
1 #ifndef VG_PLATFORM_H
2 #define VG_PLATFORM_H
3
4 #include "vg.h"
5 #include "vg_stdint.h"
6
7 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
8
9 typedef unsigned int uint;
10
11 typedef int v2i[2];
12 typedef int v3i[3];
13 typedef int v4i[4];
14 typedef float v2f[2];
15 typedef float v3f[3];
16 typedef float v4f[4];
17 typedef v2f m2x2f[2];
18 typedef v3f m3x3f[3];
19 typedef v3f m4x3f[4];
20 typedef v4f m4x4f[4];
21 typedef v3f boxf[2];
22
23 // Resource types
24 typedef struct vg_tex2d vg_tex2d;
25
26 struct vg_achievement
27 {
28 int is_set;
29 const char *name;
30 };
31
32 #ifndef VG_STATIC
33 #define VG_STATIC static
34 #endif
35
36 #define vg_static_assert _Static_assert
37 #define vg_list_size( A ) (sizeof(A)/sizeof(A[0]))
38 #define VG_MUST_USE_RESULT __attribute__((warn_unused_result))
39
40 #ifdef _WIN32_NO
41 #include <windows.h>
42
43 #ifdef I_THINK_THIS_IS_WHAT_MSCV_WANTS_BUT_HAVNT_TESTED_IT_YET
44
45 #define VG_DEPRECATED __declspec(deprecated)
46 #define VG_THREAD_LOCAL __declspec( thread )
47
48 #else /* MINGW-64 */
49
50 #define VG_THREAD_LOCAL __thread
51 #define VG_DEPRECATED __attribute__((deprecated))
52
53 #endif
54
55 typedef HANDLE vg_semaphore;
56 typedef HANDLE vg_mutex;
57 typedef u64 vg_timespec;
58
59 #else
60 #include <pthread.h>
61 #include <semaphore.h>
62
63 #define VG_DEPRECATED __attribute__((deprecated))
64 #define VG_THREAD_LOCAL __thread
65
66 typedef sem_t vg_semaphore;
67 typedef pthread_mutex_t vg_mutex;
68 typedef struct timespec vg_timespec;
69
70 #endif
71
72 VG_STATIC void vg_strncpy( const char *src, char *dst, u32 len )
73 {
74 for( u32 i=0; i<len; i++ )
75 {
76 dst[i] = src[i];
77
78 if( !src[i] )
79 break;
80 }
81 }
82
83 VG_STATIC void vg_fatal_exit_loop( const char *error );
84 VG_STATIC void vg_required( void *ptr, const char *path )
85 {
86 if( !ptr )
87 {
88 vg_fatal_exit_loop( path );
89 }
90 }
91
92 #define VG_REQUIRED_ASSET( TYPE, DECL, FN, PATH, ... ) \
93 TYPE DECL = FN( PATH,##__VA_ARGS__ ); \
94 vg_required( DECL, "Resource is required but failed to load: '" PATH "'" );
95
96 #if 0
97 VG_DEPRECATED
98 char *strcpy(char* destination, const char* source);
99 VG_DEPRECATED
100 char *strncpy(char *restrict dest, const char *restrict src, size_t n);
101 VG_DEPRECATED
102 char *strcat(char *restrict dest, const char *restrict src);
103 VG_DEPRECATED
104 char *strncat(char *restrict dest, const char *restrict src, size_t n);
105 #endif
106
107 #include <stdio.h>
108 #include <dirent.h>
109 #include <string.h>
110 #include <stdarg.h>
111 #include <ctype.h>
112 #include <math.h>
113 #include <assert.h>
114
115 VG_STATIC int vg_thread_run( void *pfunc, void *data );
116 VG_STATIC void vg_thread_exit(void);
117 VG_STATIC void vg_set_thread_name( const char *name );
118 VG_STATIC int vg_semaphore_init( vg_semaphore *sem, u32 value );
119 VG_STATIC int vg_semaphore_trywait( vg_semaphore *sem );
120 VG_STATIC int vg_semaphore_wait( vg_semaphore *sem );
121 VG_STATIC int vg_semaphore_post( vg_semaphore *sem );
122 VG_STATIC void vg_semaphore_free( vg_semaphore *sem );
123 VG_STATIC int vg_mutex_init( vg_mutex *mutex );
124 VG_STATIC int vg_mutex_lock( vg_mutex *mutex );
125 VG_STATIC int vg_mutex_unlock( vg_mutex *mutex );
126 VG_STATIC void vg_mutex_free( vg_mutex *mutex );
127 VG_STATIC void vg_sleep_ms( long msec );
128 VG_STATIC double vg_time_diff( vg_timespec start, vg_timespec end );
129
130 #ifdef _WIN32_NO
131
132 VG_STATIC int vg_thread_run( void *pfunc, void *data )
133 {
134 HANDLE hThread = CreateThread
135 (
136 NULL, /* Thread attributes */
137 0, /* Stack size (0 = use default) */
138 pfunc, /* Thread start address */
139 data, /* Parameter to pass to the thread */
140 0, /* Creation flags */
141 NULL /* Thread id */
142 );
143
144 if ( hThread == NULL )
145 {
146 /*
147 * Thread creation failed.
148 * More details can be retrieved by calling GetLastError()
149 */
150 return 1;
151 }
152 else
153 {
154 CloseHandle( hThread );
155 return 0;
156 }
157 }
158
159 VG_STATIC void vg_thread_exit(void)
160 {
161 ExitThread(0);
162 }
163
164 VG_STATIC void vg_set_thread_name( const char *name )
165 {
166 /* I believe this is a meaningless concept in windows */
167 }
168
169 VG_STATIC int vg_semaphore_init( vg_semaphore *sem, u32 value );
170 VG_STATIC int vg_semaphore_trywait( vg_semaphore *sem );
171 VG_STATIC int vg_semaphore_wait( vg_semaphore *sem );
172 VG_STATIC int vg_semaphore_post( vg_semaphore *sem );
173 VG_STATIC void vg_semaphore_free( vg_semaphore *sem );
174 VG_STATIC int vg_mutex_init( vg_mutex *mutex );
175 VG_STATIC int vg_mutex_lock( vg_mutex *mutex );
176 VG_STATIC int vg_mutex_unlock( vg_mutex *mutex );
177 VG_STATIC void vg_mutex_free( vg_mutex *mutex );
178 VG_STATIC void vg_sleep_ms( long msec );
179 VG_STATIC double vg_time_diff( vg_timespec start, vg_timespec end );
180
181 #else
182
183 VG_STATIC int vg_thread_run( void *pfunc, void *data )
184 {
185 pthread_t hThread;
186 if( pthread_create( &hThread, NULL, pfunc, data ) )
187 {
188 return 1;
189 }
190 else
191 {
192 pthread_detach( hThread );
193 return 0;
194 }
195 }
196
197
198 VG_STATIC void vg_thread_exit(void)
199 {
200 pthread_exit(NULL);
201 }
202
203 VG_STATIC void vg_set_thread_name( const char *name )
204 {
205 /* not defined but links?? */
206 #if 0
207 pthread_setname_np(pthread_self());
208 #endif
209 }
210
211 VG_STATIC int vg_semaphore_init( vg_semaphore *sem, u32 value )
212 {
213 return !sem_init( sem, 0, value );
214 }
215
216 VG_STATIC int vg_semaphore_trywait( vg_semaphore *sem )
217 {
218 return !sem_trywait( sem );
219 }
220
221 VG_STATIC int vg_semaphore_wait( vg_semaphore *sem )
222 {
223 return !sem_wait( sem );
224 }
225
226 VG_STATIC int vg_semaphore_post( vg_semaphore *sem )
227 {
228 return !sem_post( sem );
229 }
230
231 VG_STATIC void vg_semaphore_free( vg_semaphore *sem )
232 {
233 sem_destroy( sem );
234 }
235
236 VG_STATIC int vg_mutex_init( vg_mutex *mutex )
237 {
238 memset( mutex, 0, sizeof(vg_mutex) );
239 return 1;
240 }
241
242 VG_STATIC int vg_mutex_lock( vg_mutex *mutex )
243 {
244 if( !pthread_mutex_lock( mutex ) )
245 return 1;
246 else
247 return 0;
248 }
249
250 VG_STATIC int vg_mutex_unlock( vg_mutex *mutex )
251 {
252 if( !pthread_mutex_unlock( mutex ) )
253 return 1;
254 else
255 return 0;
256 }
257
258 VG_STATIC void vg_mutex_free( vg_mutex *mutex )
259 {
260
261 }
262
263 VG_STATIC void vg_sleep_ms( long msec )
264 {
265 struct timespec ts;
266
267 ts.tv_sec = msec / 1000;
268 ts.tv_nsec = (msec % 1000) * 1000000;
269 nanosleep( &ts, &ts );
270 }
271
272 /* diff two timespecs in MS */
273 VG_STATIC double vg_time_diff( struct timespec start, struct timespec end )
274 {
275 double elapsed = 1000.0*end.tv_sec + 1e-6*end.tv_nsec
276 - (1000.0*start.tv_sec + 1e-6*start.tv_nsec);
277
278 return elapsed;
279 }
280
281 #endif
282
283 #define VG_MIN( A, B ) ((A)<(B)?(A):(B))
284 #define VG_MAX( A, B ) ((A)>(B)?(A):(B))
285
286 #endif