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 <ranma+gbsplay@tdiedrich.de>
*
* 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 && ENABLE_TEST != 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
|