medium sized dollop
[vg.git] / src / vg / vg_platform.h
1 #ifndef VG_PLATFORM_H
2 #define VG_PLATFORM_H
3
4 #include "vg.h"
5
6 /* Copyright (C) 2021-2022 Harry Godden (hgn) - All Rights Reserved */
7
8 typedef unsigned int uint;
9
10 typedef int v2i[2];
11 typedef int v3i[3];
12 typedef int v4i[4];
13 typedef float v2f[2];
14 typedef float v3f[3];
15 typedef float v4f[4];
16 typedef v2f m2x2f[2];
17 typedef v3f m3x3f[3];
18 typedef v3f m4x3f[4];
19 typedef v4f m4x4f[4];
20 typedef v3f boxf[2];
21
22 // Resource types
23 typedef struct vg_tex2d vg_tex2d;
24
25 struct vg_achievement
26 {
27 int is_set;
28 const char *name;
29 };
30
31 #define vg_static_assert _Static_assert
32 #define vg_list_size( A ) (sizeof(A)/sizeof(A[0]))
33
34 #ifdef _WIN32
35 #include <windows.h>
36
37 /* TODO */
38
39 #else
40 #include <pthread.h>
41 #include <semaphore.h>
42
43 typedef sem_t vg_semaphore;
44 typedef pthread_mutex_t vg_mutex;
45
46 static int vg_semaphore_init( vg_semaphore *sem, u32 value )
47 {
48 if( !sem_init( sem, 0, value ) )
49 return 1;
50 else
51 return 0;
52 }
53
54 static int vg_semaphore_wait( vg_semaphore *sem )
55 {
56 if( !sem_wait( sem ) )
57 return 1;
58 else
59 return 0;
60 }
61
62 static int vg_semaphore_post( vg_semaphore *sem )
63 {
64 if( !sem_post( sem ) )
65 return 1;
66 else
67 return 0;
68 }
69
70 static void vg_semaphore_free( vg_semaphore *sem )
71 {
72 sem_destroy( sem );
73 }
74
75 static int vg_mutex_init( vg_mutex *mutex )
76 {
77 memset( mutex, 0, sizeof(vg_mutex) );
78 return 1;
79 }
80
81 static int vg_mutex_lock( vg_mutex *mutex )
82 {
83 if( !pthread_mutex_lock( mutex ) )
84 return 1;
85 else
86 return 0;
87 }
88
89 static int vg_mutex_unlock( vg_mutex *mutex )
90 {
91 if( !pthread_mutex_unlock( mutex ) )
92 return 1;
93 else
94 return 0;
95 }
96
97 static void vg_mutex_free( vg_mutex *mutex )
98 {
99
100 }
101
102 #endif
103
104
105 int vg_thread_run( void *pfunc, void *data )
106 {
107 #ifdef _WIN32
108 HANDLE hThread = CreateThread
109 (
110 NULL, /* Thread attributes */
111 0, /* Stack size (0 = use default) */
112 pfunc, /* Thread start address */
113 data, /* Parameter to pass to the thread */
114 0, /* Creation flags */
115 NULL /* Thread id */
116 );
117
118 if ( hThread == NULL )
119 {
120 /*
121 * Thread creation failed.
122 * More details can be retrieved by calling GetLastError()
123 */
124 return 1;
125 }
126 else
127 {
128 CloseHandle( hThread );
129 return 0;
130 }
131 #else
132 pthread_t hThread;
133 if( pthread_create( &hThread, NULL, pfunc, data ) )
134 {
135 return 1;
136 }
137 else
138 {
139 pthread_detach( hThread );
140 return 0;
141 }
142 #endif
143 }
144
145 static void vg_sleep_ms( long msec )
146 {
147 struct timespec ts;
148
149 ts.tv_sec = msec / 1000;
150 ts.tv_nsec = (msec % 1000) * 1000000;
151 nanosleep( &ts, &ts );
152 }
153
154 /* diff two timespecs in MS */
155 static double vg_time_diff( struct timespec start, struct timespec end )
156 {
157 double elapsed = 1000.0*end.tv_sec + 1e-6*end.tv_nsec
158 - (1000.0*start.tv_sec + 1e-6*start.tv_nsec);
159
160 return elapsed;
161 }
162
163 #define VG_MIN( A, B ) ((A)<(B)?(A):(B))
164 #define VG_MAX( A, B ) ((A)>(B)?(A):(B))
165
166 static void *buffer_reserve( void *buffer, u32 count, u32 *cap, u32 amount,
167 size_t emsize )
168 {
169 if( count+amount > *cap )
170 {
171 *cap = VG_MAX( (*cap)*2, (*cap)+amount );
172
173 return realloc( buffer, (*cap) * emsize );
174 }
175
176 return buffer;
177 }
178
179 static void *buffer_fix( void *buffer, u32 count, u32 *cap, size_t emsize )
180 {
181 *cap = count;
182 return realloc( buffer, (*cap) * emsize );
183 }
184
185 #endif