-
Notifications
You must be signed in to change notification settings - Fork 20
/
common.h
136 lines (106 loc) · 2.92 KB
/
common.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
* gbsplay is a Gameboy sound player
*
* 2003-2021 (C) by Tobias Diedrich <[email protected]>
*
* Licensed under GNU GPL v1 or, at your option, any later version.
*/
#ifndef _COMMON_H_
#define _COMMON_H_
#include <inttypes.h>
#include <stddef.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <math.h>
#include "config.h"
typedef uint64_t cycles_t;
/* mingw64 also defines __MINGW32__ in addition to __MINGW64__ */
#ifdef __MINGW32__
#define HAVE_MINGW 1
#endif
#ifndef true
#define true (0==0)
#define false (!true)
#endif
#define UNUSED(x) (void)(x)
#define WARN_N(n, ...) { \
static long ctr = n; \
if (ctr) { \
ctr--; \
fprintf(stderr, __VA_ARGS__); \
} \
}
#define WARN_ONCE(...) WARN_N(1, __VA_ARGS__)
#define CONTAINER_OF(ptr, type, member) \
((type *)((void *)(ptr) - offsetof(type, member)))
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
#define TEXTDOMAIN "gbsplay"
#define N_(x) x
#define C0HZ 16.35
#define C0MIDI 12
#define C6GBRAW 1923 /* First note in gameboy startup sound, 1048.576Hz (3.4 cents too high) */
#define C6GB (2048 - C6GBRAW)
#define C6MIDI 84 /* 1046.50Hz in equal temperament */
/* wave channel produces half the frequency */
#define FREQ(x,ch) (131072. / ((x)<<((ch)>1)))
#define FREQTONOTE(f) (lround(log2((f)/C0HZ)*12)+C0MIDI)
#define NOTE(x,ch) FREQTONOTE(FREQ(x,ch))
#if USE_I18N == 1
# include <locale.h>
# include <libintl.h>
# if GBS_PRESERVE_TEXTDOMAIN == 1
static inline char* _(const char* const msgid)
{
char *olddomain = textdomain(NULL);
char *olddir = bindtextdomain(olddomain, NULL);
char *res;
bindtextdomain(TEXTDOMAIN, LOCALE_PREFIX);
res = dgettext(TEXTDOMAIN, msgid);
bindtextdomain(olddomain, olddir);
return res;
}
# else
static inline char* _(const char* const msgid)
{
return gettext(msgid);
}
static inline void i18n_init(void)
{
if (setlocale(LC_ALL, "") == NULL) {
fprintf(stderr, "setlocale() failed\n");
}
if (bindtextdomain(TEXTDOMAIN, LOCALE_PREFIX) == NULL) {
fprintf(stderr, "bindtextdomain() failed: %s\n", strerror(errno));
}
if (textdomain(TEXTDOMAIN) == NULL) {
fprintf(stderr, "textdomain() failed: %s\n", strerror(errno));
}
}
# endif
#else
# define _(x) (x)
static inline void i18n_init(void) {}
#endif
#if !defined(__BYTE_ORDER__) || !defined(__ORDER_LITTLE_ENDIAN__) || !defined(__ORDER_BIG_ENDIAN__)
#error Unsupported compiler
#endif
#if __BYTE_ORDER__ != 1234 && __BYTE_ORDER__ != 4321
#error Unexpected endian value __BYTE_ORDER__
#endif
#if __ORDER_LITTLE_ENDIAN__ != 1234
#error Unexpected endian value
#endif
#if __ORDER_BIG_ENDIAN__ != 4321
#error Unexpected endian value
#endif
#define GBS_BYTE_ORDER __BYTE_ORDER__
#define GBS_ORDER_LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
#define GBS_ORDER_BIG_ENDIAN __ORDER_BIG_ENDIAN__
static inline long is_le_machine() {
return __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__;
}
static inline long is_be_machine() {
return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__;
}
#endif