1 /* Copyright 2005 Guillaume Duhamel
2 Copyright 2005-2006 Theo Berkau
3
4 This file is part of Yabause.
5
6 Yabause is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 Yabause is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Yabause; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef CORE_H
22 #define CORE_H
23
24 #include <stdio.h>
25 #include <string.h>
26
27 #ifndef ALIGNED
28 #ifdef _MSC_VER
29 #define ALIGNED(x) __declspec(align(x))
30 #else
31 #define ALIGNED(x) __attribute__((aligned(x)))
32 #endif
33 #endif
34
35 #ifndef STDCALL
36 #ifdef _MSC_VER
37 #define STDCALL __stdcall
38 #else
39 #define STDCALL
40 #endif
41 #endif
42
43 #ifndef FASTCALL
44 #ifdef __MINGW32__
45 #define FASTCALL __attribute__((fastcall))
46 #elif defined (__i386__)
47 #define FASTCALL __attribute__((regparm(3)))
48 #else
49 #define FASTCALL
50 #endif
51 #endif
52
53 /* When building multiple arches on OS X you must use the compiler-
54 provided endian flags instead of the one provided by autoconf */
55 #if defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__)
56 #undef WORDS_BIGENDIAN
57 #ifdef __BIG_ENDIAN__
58 #define WORDS_BIGENDIAN
59 #endif
60 #endif
61
62
63 #ifndef INLINE
64 #ifdef _MSC_VER
65 #define INLINE _inline
66 #else
67 #define INLINE inline
68 #endif
69 #endif
70
71 #ifdef GEKKO
72 /* Wii have both stdint.h and "yabause" definitions of fixed
73 size types */
74 #include <gccore.h>
75 typedef unsigned long pointer;
76
77 #else /* ! GEKKO */
78
79 #ifdef HAVE_STDINT_H
80
81 #include <stdint.h>
82 typedef uint8_t u8;
83 typedef int8_t s8;
84 typedef uint16_t u16;
85 typedef int16_t s16;
86 typedef uint32_t u32;
87 typedef int32_t s32;
88 typedef uint64_t u64;
89 typedef int64_t s64;
90 typedef uintptr_t pointer;
91
92 #else // !HAVE_STDINT_H
93
94 typedef unsigned char u8;
95 typedef unsigned short u16;
96
97 typedef signed char s8;
98 typedef signed short s16;
99
100 #if defined(__LP64__)
101 // Generic 64-bit
102 typedef unsigned int u32;
103 typedef unsigned long u64;
104 typedef unsigned long pointer;
105
106 typedef signed int s32;
107 typedef signed long s64;
108
109 #elif defined(_MSC_VER)
110 typedef unsigned long u32;
111 typedef unsigned __int64 u64;
112 typedef unsigned long long u64;
113 #ifdef _WIN64
114 typedef __int64 pointer;
115 #else
116 typedef unsigned long pointer;
117 #endif
118
119 typedef signed long s32;
120 typedef __int64 s64;
121 typedef signed long long s64;
122
123 #else
124 // 32-bit Linux GCC/MINGW/etc.
125 typedef unsigned long u32;
126 typedef unsigned long long u64;
127 typedef unsigned long pointer;
128
129 typedef signed long s32;
130 typedef signed long long s64;
131 #endif
132
133 #endif // !HAVE_STDINT_H
134
135 #endif // !GEKKO
136
137 typedef struct {
138 unsigned int size;
139 unsigned int done;
140 } IOCheck_struct;
141
ywrite(IOCheck_struct * check,void * ptr,size_t size,size_t nmemb,FILE * stream)142 static INLINE void ywrite(IOCheck_struct * check, void * ptr, size_t size, size_t nmemb, FILE * stream) {
143 check->done += (unsigned int)fwrite(ptr, size, nmemb, stream);
144 check->size += (unsigned int)nmemb;
145 }
146
yread(IOCheck_struct * check,void * ptr,size_t size,size_t nmemb,FILE * stream)147 static INLINE void yread(IOCheck_struct * check, void * ptr, size_t size, size_t nmemb, FILE * stream) {
148 check->done += (unsigned int)fread(ptr, size, nmemb, stream);
149 check->size += (unsigned int)nmemb;
150 }
151
StateWriteHeader(FILE * fp,const char * name,int version)152 static INLINE int StateWriteHeader(FILE *fp, const char *name, int version) {
153 IOCheck_struct check = { 0, 0 };
154 fprintf(fp, "%s", name);
155 check.done = 0;
156 check.size = 0;
157 ywrite(&check, (void *)&version, sizeof(version), 1, fp);
158 ywrite(&check, (void *)&version, sizeof(version), 1, fp); // place holder for size
159 return (check.done == check.size) ? ftell(fp) : -1;
160 }
161
StateFinishHeader(FILE * fp,int offset)162 static INLINE int StateFinishHeader(FILE *fp, int offset) {
163 IOCheck_struct check = { 0, 0 };
164 int size = 0;
165 size = ftell(fp) - offset;
166 fseek(fp, offset - 4, SEEK_SET);
167 check.done = 0;
168 check.size = 0;
169 ywrite(&check, (void *)&size, sizeof(size), 1, fp); // write true size
170 fseek(fp, 0, SEEK_END);
171 return (check.done == check.size) ? (size + 12) : -1;
172 }
173
StateCheckRetrieveHeader(FILE * fp,const char * name,int * version,int * size)174 static INLINE int StateCheckRetrieveHeader(FILE *fp, const char *name, int *version, int *size) {
175 char id[4];
176 size_t ret;
177
178 if ((ret = fread((void *)id, 1, 4, fp)) != 4)
179 return -1;
180
181 if (strncmp(name, id, 4) != 0)
182 return -2;
183
184 if ((ret = fread((void *)version, 4, 1, fp)) != 1)
185 return -1;
186
187 if (fread((void *)size, 4, 1, fp) != 1)
188 return -1;
189
190 return 0;
191 }
192
193 //////////////////////////////////////////////////////////////////////////////
194
195 // Terrible, but I'm not sure how to do the equivalent in inline
196 #ifdef HAVE_C99_VARIADIC_MACROS
197 #define AddString(s, ...) \
198 { \
199 sprintf(s, __VA_ARGS__); \
200 s += strlen(s); \
201 }
202 #else
203 #define AddString(s, r...) \
204 { \
205 sprintf(s, ## r); \
206 s += strlen(s); \
207 }
208 #endif
209
210 //////////////////////////////////////////////////////////////////////////////
211
212 #ifdef HAVE_LIBMINI18N
213 #include "mini18n.h"
214 #else
215 #ifndef _
216 #define _(a) (a)
217 #endif
218 #endif
219
220 //////////////////////////////////////////////////////////////////////////////
221
222 /* Minimum/maximum values */
223
224 #undef MIN
225 #undef MAX
226 #define MIN(a,b) ((a) < (b) ? (a) : (b))
227 #define MAX(a,b) ((a) > (b) ? (a) : (b))
228
229 //////////////////////////////////////////////////////////////////////////////
230
231 /*
232 * BSWAP16(x) swaps two bytes in a 16-bit value (AABB -> BBAA) or adjacent
233 * bytes in a 32-bit value (AABBCCDD -> BBAADDCC).
234 *
235 * BSWAP32(x) reverses four bytes in a 32-bit value (AABBCCDD -> DDCCBBAA).
236 *
237 * WSWAP32(x) swaps two 16-bit words in a 32-bit value (AABBCCDD -> CCDDAABB).
238 *
239 * Any of these can be left undefined if there is no platform-specific
240 * optimization for them; the defaults below will then be used instead.
241 */
242
243 #ifdef PSP
244 # define BSWAP16(x) ((typeof(x)) __builtin_allegrex_wsbh((x)))
245 # define BSWAP16L(x) BSWAP16(x)
246 # define BSWAP32(x) ((typeof(x)) __builtin_allegrex_wsbw((x)))
247 # define WSWAP32(x) ((typeof(x)) __builtin_allegrex_rotr((x), 16))
248 #endif
249
250 #ifdef __GNUC__
251 #ifdef HAVE_BUILTIN_BSWAP16
252 # define BSWAP16(x) ((__builtin_bswap16((x) >> 16) << 16) | __builtin_bswap16((x)))
253 # define BSWAP16L(x) (__builtin_bswap16((x)))
254 #endif
255 #ifdef HAVE_BUILTIN_BSWAP32
256 # define BSWAP32(x) (__builtin_bswap32((x)))
257 #endif
258 #endif
259
260 #ifdef _MSC_VER
261 # define BSWAP16(x) ((_byteswap_ushort((x) >> 16) << 16) | _byteswap_ushort((x)))
262 # define BSWAP16L(x) (_byteswap_ushort((x)))
263 # define BSWAP32(x) (_byteswap_ulong((x)))
264 # define WSWAP32(x) (_lrotr((x), 16))
265 #endif
266
267 /* Defaults: */
268
269 #ifndef BSWAP16
270 # define BSWAP16(x) (((u32)(x)>>8 & 0x00FF00FF) | ((u32)(x) & 0x00FF00FF) << 8)
271 #endif
272 #ifndef BSWAP16L
273 # define BSWAP16L(x) (((u16)(x)>>8 & 0xFF) | ((u16)(x) & 0xFF) << 8)
274 #endif
275 #ifndef BSWAP32
276 # define BSWAP32(x) ((u32)(x)>>24 | ((u32)(x)>>8 & 0xFF00) | ((u32)(x) & 0xFF00)<<8 | (u32)(x)<<24)
277 #endif
278 #ifndef WSWAP32
279 # define WSWAP32(x) ((u32)(x)>>16 | (u32)(x)<<16)
280 #endif
281
282 //////////////////////////////////////////////////////////////////////////////
283
284 #ifdef __GNUC__
285
286 #define UNUSED __attribute ((unused))
287
288 #ifdef DEBUG
289 #define USED_IF_DEBUG
290 #else
291 #define USED_IF_DEBUG __attribute ((unused))
292 #endif
293
294 #ifdef SMPC_DEBUG
295 #define USED_IF_SMPC_DEBUG
296 #else
297 #define USED_IF_SMPC_DEBUG __attribute ((unused))
298 #endif
299
300 /* LIKELY(x) indicates that x is likely to be true (nonzero);
301 * UNLIKELY(x) indicates that x is likely to be false (zero).
302 * Use like: "if (UNLIKELY(a < b)) {...}" */
303 #define LIKELY(x) (__builtin_expect(!!(x), 1))
304 #define UNLIKELY(x) (__builtin_expect(!!(x), 0))
305
306 #else
307
308 #define UNUSED
309 #define USED_IF_DEBUG
310 #define USED_IF_SMPC_DEBUG
311 #define LIKELY(x) (x)
312 #define UNLIKELY(x) (x)
313
314 #endif
315
316 #ifdef USE_16BPP
317 typedef u16 pixel_t;
318 #else
319 typedef u32 pixel_t;
320 #endif
321
322 #ifdef _MSC_VER
323 #define snprintf sprintf_s
324 #endif
325
326 #endif
327