bsnes/snesreader/fex/blargg_common.h

207 lines
6.8 KiB
C
Raw Normal View History

Include all the code from the bsnes v068 tarball. byuu describes the changes since v067: This release officially introduces the accuracy and performance cores, alongside the previously-existing compatibility core. The accuracy core allows the most accurate SNES emulation ever seen, with every last processor running at the lowest possible clock synchronization level. The performance core allows slower computers the chance to finally use bsnes. It is capable of attaining 60fps in standard games even on an entry-level Intel Atom processor, commonly found in netbooks. The accuracy core is absolutely not meant for casual gaming at all. It is meant solely for getting as close to 100% perfection as possible, no matter the cost to speed. It should only be used for testing, development or debugging. The compatibility core is identical to bsnes v067 and earlier, but is now roughly 10% faster. This is the default and recommended core for casual gaming. The performance core contains an entirely new S-CPU core, with range-tested IRQs; and uses blargg's heavily-optimized S-DSP core directly. Although there are very minor accuracy tradeoffs to increase speed, I am confident that the performance core is still more accurate and compatible than any other SNES emulator. The S-CPU, S-SMP, S-DSP, SuperFX and SA-1 processors are all clock-based, just as in the accuracy and compatibility cores; and as always, there are zero game-specific hacks. Its compatibility is still well above 99%, running even the most challenging games flawlessly. If you have held off from using bsnes in the past due to its system requirements, please give the performance core a try. I think you will be impressed. I'm also not finished: I believe performance can be increased even further. I would also strongly suggest Windows Vista and Windows 7 users to take advantage of the new XAudio2 driver by OV2. Not only does it give you a performance boost, it also lowers latency and provides better sound by way of skipping an API emulation layer. Changelog: - Split core into three profiles: accuracy, compatibility and performance - Accuracy core now takes advantage of variable-bitlength integers (eg uint24_t) - Performance core uses a new S-CPU core, written from scratch for speed - Performance core uses blargg's snes_dsp library for S-DSP emulation - Binaries are now compiled using GCC 4.5 - Added a workaround in the SA-1 core for a bug in GCC 4.5+ - The clock-based S-PPU renderer has greatly improved OAM emulation; fixing Winter Gold and Megalomania rendering issues - Corrected pseudo-hires color math in the clock-based S-PPU renderer; fixing Super Buster Bros backgrounds - Fixed a clamping bug in the Cx4 16-bit triangle operation [Jonas Quinn]; fixing Mega Man X2 "gained weapon" star background effect - Updated video renderer to properly handle mixed-resolution screens with interlace enabled; fixing Air Strike Patrol level briefing screen - Added mightymo's 2010-08-19 cheat code pack - Windows port: added XAudio2 output support [OV2] - Source: major code restructuring; virtual base classes for processor - cores removed, build system heavily modified, etc.
2010-08-22 01:02:42 +00:00
// Sets up common environment for Shay Green's libraries.
// To change configuration options, modify blargg_config.h, not this file.
// File_Extractor 1.0.0
#ifndef BLARGG_COMMON_H
#define BLARGG_COMMON_H
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
typedef const char* blargg_err_t; // 0 on success, otherwise error string
// Success; no error
int const blargg_ok = 0;
// BLARGG_RESTRICT: equivalent to C99's restrict, where supported
#if __GNUC__ >= 3 || _MSC_VER >= 1100
#define BLARGG_RESTRICT __restrict
#else
#define BLARGG_RESTRICT
#endif
#if __cplusplus >= 199711
#define BLARGG_MUTABLE mutable
#else
#define BLARGG_MUTABLE
#endif
/* BLARGG_4CHAR('a','b','c','d') = 'abcd' (four character integer constant).
I don't just use 'abcd' because that's implementation-dependent. */
#define BLARGG_4CHAR( a, b, c, d ) \
((a&0xFF)*0x1000000 + (b&0xFF)*0x10000 + (c&0xFF)*0x100 + (d&0xFF))
/* BLARGG_STATIC_ASSERT( expr ): Generates compile error if expr is 0.
Can be used at file, function, or class scope. */
#ifdef _MSC_VER
// MSVC6 (_MSC_VER < 1300) __LINE__ fails when /Zl is specified
#define BLARGG_STATIC_ASSERT( expr ) \
void blargg_failed_( int (*arg) [2 / (int) !!(expr) - 1] )
#else
// Others fail when declaring same function multiple times in class,
// so differentiate them by line
#define BLARGG_STATIC_ASSERT( expr ) \
void blargg_failed_( int (*arg) [2 / !!(expr) - 1] [__LINE__] )
#endif
/* Pure virtual functions cause a vtable entry to a "called pure virtual"
error handler, requiring linkage to the C++ runtime library. This macro is
used in place of the "= 0", and simply expands to its argument. During
development, it expands to "= 0", allowing detection of missing overrides. */
#define BLARGG_PURE( def ) def
/* My code depends on ASCII anywhere a character or string constant is
compared with data read from a file, and anywhere file data is read and
treated as a string. */
#if '\n'!=0x0A || ' '!=0x20 || '0'!=0x30 || 'A'!=0x41 || 'a'!=0x61
#error "ASCII character set required"
#endif
/* My code depends on int being at least 32 bits. Almost everything these days
uses at least 32-bit ints, so it's hard to even find a system with 16-bit ints
to test with. The issue can't be gotten around by using a suitable blargg_int
everywhere either, because int is often converted to implicitly when doing
arithmetic on smaller types. */
#if UINT_MAX < 0xFFFFFFFF
#error "int must be at least 32 bits"
#endif
// In case compiler doesn't support these properly. Used rarely.
#define STATIC_CAST(T,expr) static_cast<T> (expr)
#define CONST_CAST( T,expr) const_cast<T> (expr)
// User configuration can override the above macros if necessary
#include "blargg_config.h"
/* BLARGG_DEPRECATED [_TEXT] for any declarations/text to be removed in a
future version. In GCC, we can let the compiler warn. In other compilers,
we strip it out unless BLARGG_LEGACY is true. */
#if BLARGG_LEGACY
// Allow old client code to work without warnings
#define BLARGG_DEPRECATED_TEXT( text ) text
#define BLARGG_DEPRECATED( text ) text
#elif __GNUC__ >= 4
// In GCC, we can mark declarations and let the compiler warn
#define BLARGG_DEPRECATED_TEXT( text ) text
#define BLARGG_DEPRECATED( text ) __attribute__ ((deprecated)) text
#else
// By default, deprecated items are removed, to avoid use in new code
#define BLARGG_DEPRECATED_TEXT( text )
#define BLARGG_DEPRECATED( text )
#endif
/* BOOST::int8_t, BOOST::int32_t, etc.
I used BOOST since I originally was going to allow use of the boost library
for prividing the definitions. If I'm defining them, they must be scoped or
else they could conflict with the standard ones at global scope. Even if
HAVE_STDINT_H isn't defined, I can't assume the typedefs won't exist at
global scope already. */
#if defined (HAVE_STDINT_H) || \
UCHAR_MAX != 0xFF || USHRT_MAX != 0xFFFF || UINT_MAX != 0xFFFFFFFF
#include <stdint.h>
#define BOOST
#else
struct BOOST
{
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
};
#endif
/* My code is not written with exceptions in mind, so either uses new (nothrow)
OR overrides operator new in my classes. The former is best since clients
creating objects will get standard exceptions on failure, but that causes it
to require the standard C++ library. So, when the client is using the C
interface, I override operator new to use malloc. */
// BLARGG_DISABLE_NOTHROW is put inside classes
#ifndef BLARGG_DISABLE_NOTHROW
// throw spec mandatory in ISO C++ if NULL can be returned
#if __cplusplus >= 199711 || __GNUC__ >= 3 || _MSC_VER >= 1300
#define BLARGG_THROWS_NOTHING throw ()
#else
#define BLARGG_THROWS_NOTHING
#endif
#define BLARGG_DISABLE_NOTHROW \
void* operator new ( size_t s ) BLARGG_THROWS_NOTHING { return malloc( s ); }\
void operator delete( void* p ) BLARGG_THROWS_NOTHING { free( p ); }
#define BLARGG_NEW new
#else
// BLARGG_NEW is used in place of new in library code
#include <new>
#define BLARGG_NEW new (std::nothrow)
#endif
class blargg_vector_ {
protected:
void* begin_;
size_t size_;
void init();
blargg_err_t resize_( size_t n, size_t elem_size );
public:
size_t size() const { return size_; }
void clear();
};
// Very lightweight vector for POD types (no constructor/destructor)
template<class T>
class blargg_vector : public blargg_vector_ {
union T_must_be_pod { T t; }; // fails if T is not POD
public:
blargg_vector() { init(); }
~blargg_vector() { clear(); }
blargg_err_t resize( size_t n ) { return resize_( n, sizeof (T) ); }
T* begin() { return static_cast<T*> (begin_); }
const T* begin() const { return static_cast<T*> (begin_); }
T* end() { return static_cast<T*> (begin_) + size_; }
const T* end() const { return static_cast<T*> (begin_) + size_; }
T& operator [] ( size_t n )
{
assert( n < size_ );
return static_cast<T*> (begin_) [n];
}
const T& operator [] ( size_t n ) const
{
assert( n < size_ );
return static_cast<T*> (begin_) [n];
}
};
// Callback function with user data.
// blargg_callback<T> set_callback; // for user, this acts like...
// void set_callback( T func, void* user_data = NULL ); // ...this
// To call function, do set_callback.f( .. set_callback.data ... );
template<class T>
struct blargg_callback
{
T f;
void* data;
blargg_callback() { f = NULL; }
void operator () ( T callback, void* user_data = NULL ) { f = callback; data = user_data; }
};
#ifndef _WIN32
// Not supported on any other platforms
#undef BLARGG_UTF8_PATHS
#endif
BLARGG_DEPRECATED( typedef signed int blargg_long; )
BLARGG_DEPRECATED( typedef unsigned int blargg_ulong; )
#if BLARGG_LEGACY
#define BOOST_STATIC_ASSERT BLARGG_STATIC_ASSERT
#endif
#endif