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