// Sets up common environment for Shay Green's libraries.1// To change configuration options, modify blargg_config.h, not this file.23// File_Extractor 1.0.04#ifndef BLARGG_COMMON_H5#define BLARGG_COMMON_H67#include <stdlib.h>8#include <stdint.h>9#include <assert.h>10#include <limits.h>1112typedef const char* blargg_err_t; // 0 on success, otherwise error string1314#ifdef _WIN3215typedef wchar_t blargg_wchar_t;16#else17typedef uint16_t blargg_wchar_t;18#endif1920inline size_t blargg_wcslen( const blargg_wchar_t* str )21{22size_t length = 0;23while ( *str++ ) length++;24return length;25}2627// Success; no error28blargg_err_t const blargg_ok = 0;2930// BLARGG_RESTRICT: equivalent to C99's restrict, where supported31#if __GNUC__ >= 3 || _MSC_VER >= 110032#define BLARGG_RESTRICT __restrict33#else34#define BLARGG_RESTRICT35#endif3637#if __cplusplus >= 19971138#define BLARGG_MUTABLE mutable39#else40#define BLARGG_MUTABLE41#endif4243/* BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant).44I don't just use 'abcd' because that's implementation-dependent. */45#define BLARGG_4CHAR( a, b, c, d ) \46((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF))4748/* BLARGG_STATIC_ASSERT( expr ): Generates compile error if expr is 0.49Can be used at file, function, or class scope. */50#ifdef _MSC_VER51// MSVC6 (_MSC_VER < 1300) __LINE__ fails when /Zl is specified52#define BLARGG_STATIC_ASSERT( expr ) \53void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )54#else55// Others fail when declaring same function multiple times in class,56// so differentiate them by line57#define BLARGG_STATIC_ASSERT( expr ) \58void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )59#endif6061/* Pure virtual functions cause a vtable entry to a "called pure virtual"62error handler, requiring linkage to the C++ runtime library. This macro is63used in place of the "= 0", and simply expands to its argument. During64development, it expands to "= 0", allowing detection of missing overrides. */65#define BLARGG_PURE( def ) def6667/* My code depends on ASCII anywhere a character or string constant is68compared with data read from a file, and anywhere file data is read and69treated as a string. */70#if '\n'!=0x0A || ' '!=0x20 || '0'!=0x30 || 'A'!=0x41 || 'a'!=0x6171#error "ASCII character set required"72#endif7374/* My code depends on int being at least 32 bits. Almost everything these days75uses at least 32-bit ints, so it's hard to even find a system with 16-bit ints76to test with. The issue can't be gotten around by using a suitable blargg_int77everywhere either, because int is often converted to implicitly when doing78arithmetic on smaller types. */79#if UINT_MAX < 0xFFFFFFFF80#error "int must be at least 32 bits"81#endif8283// In case compiler doesn't support these properly. Used rarely.84#define STATIC_CAST(T,expr) static_cast<T> (expr)85#define CONST_CAST( T,expr) const_cast<T> (expr)8687// User configuration can override the above macros if necessary88#include "blargg_config.h"8990/* BLARGG_DEPRECATED [_TEXT] for any declarations/text to be removed in a91future version. In GCC, we can let the compiler warn. In other compilers,92we strip it out unless BLARGG_LEGACY is true. */93#if BLARGG_LEGACY94// Allow old client code to work without warnings95#define BLARGG_DEPRECATED_TEXT( text ) text96#define BLARGG_DEPRECATED( text ) text97#elif __GNUC__ >= 498// In GCC, we can mark declarations and let the compiler warn99#define BLARGG_DEPRECATED_TEXT( text ) text100#define BLARGG_DEPRECATED( text ) __attribute__ ((deprecated)) text101#else102// By default, deprecated items are removed, to avoid use in new code103#define BLARGG_DEPRECATED_TEXT( text )104#define BLARGG_DEPRECATED( text )105#endif106107/* BOOST::int8_t, BOOST::int32_t, etc.108I used BOOST since I originally was going to allow use of the boost library109for prividing the definitions. If I'm defining them, they must be scoped or110else they could conflict with the standard ones at global scope. Even if111HAVE_STDINT_H isn't defined, I can't assume the typedefs won't exist at112global scope already. */113#if defined (HAVE_STDINT_H) || \114UCHAR_MAX != 0xFF || USHRT_MAX != 0xFFFF || UINT_MAX != 0xFFFFFFFF115#include <stdint.h>116#define BOOST117#else118struct BOOST119{120typedef signed char int8_t;121typedef unsigned char uint8_t;122typedef short int16_t;123typedef unsigned short uint16_t;124typedef int int32_t;125typedef unsigned int uint32_t;126typedef __int64 int64_t;127typedef unsigned __int64 uint64_t;128};129#endif130131/* My code is not written with exceptions in mind, so either uses new (nothrow)132OR overrides operator new in my classes. The former is best since clients133creating objects will get standard exceptions on failure, but that causes it134to require the standard C++ library. So, when the client is using the C135interface, I override operator new to use malloc. */136137// BLARGG_DISABLE_NOTHROW is put inside classes138#ifndef BLARGG_DISABLE_NOTHROW139// throw spec mandatory in ISO C++ if NULL can be returned140#if __cplusplus >= 199711 || __GNUC__ >= 3 || _MSC_VER >= 1300141#define BLARGG_THROWS_NOTHING throw ()142#else143#define BLARGG_THROWS_NOTHING144#endif145146#define BLARGG_DISABLE_NOTHROW \147void* operator new ( size_t s ) BLARGG_THROWS_NOTHING { return malloc( s ); }\148void operator delete( void* p ) BLARGG_THROWS_NOTHING { free( p ); }149150#define BLARGG_NEW new151#else152// BLARGG_NEW is used in place of new in library code153#include <new>154#define BLARGG_NEW new (std::nothrow)155#endif156157class blargg_vector_ {158protected:159void* begin_;160size_t size_;161void init();162blargg_err_t resize_( size_t n, size_t elem_size );163public:164size_t size() const { return size_; }165void clear();166};167168// Very lightweight vector for POD types (no constructor/destructor)169template<class T>170class blargg_vector : public blargg_vector_ {171union T_must_be_pod { T t; }; // fails if T is not POD172public:173blargg_vector() { init(); }174~blargg_vector() { clear(); }175176blargg_err_t resize( size_t n ) { return resize_( n, sizeof (T) ); }177178T* begin() { return static_cast<T*> (begin_); }179const T* begin() const { return static_cast<T*> (begin_); }180181T* end() { return static_cast<T*> (begin_) + size_; }182const T* end() const { return static_cast<T*> (begin_) + size_; }183184T& operator [] ( size_t n )185{186assert( n < size_ );187return static_cast<T*> (begin_) [n];188}189190const T& operator [] ( size_t n ) const191{192assert( n < size_ );193return static_cast<T*> (begin_) [n];194}195};196197// Callback function with user data.198// blargg_callback<T> set_callback; // for user, this acts like...199// void set_callback( T func, void* user_data = NULL ); // ...this200// To call function, do set_callback.f( .. set_callback.data ... );201template<class T>202struct blargg_callback203{204T f;205void* data;206blargg_callback() { f = NULL; }207void operator () ( T callback, void* user_data = NULL ) { f = callback; data = user_data; }208};209210BLARGG_DEPRECATED( typedef signed int blargg_long; )211BLARGG_DEPRECATED( typedef unsigned int blargg_ulong; )212#if BLARGG_LEGACY213#define BOOST_STATIC_ASSERT BLARGG_STATIC_ASSERT214#endif215216#endif217218219