mirror of https://github.com/bsnes-emu/bsnes.git
Update to v082r25 release.
byuu says: Ryphecha fixed Gun Nac, it was some sort of problem with blank sprite address fetching messing with the MMC3 I've started on an XML parser for iNES-free loading, but it's pretty barebones right now. Only NROM-256 loads, and you have to make it a compile-time thing (so other games work for now.) Updated nall with nullptr stuff. nall/detect is now nall/intrinsic and has both #defines + static constants that can be used to detect the platform (allows for run-time platform checks where practical.) ruby has a Makefile now, that makes using it in other projects a lot easier
This commit is contained in:
parent
1d4f778176
commit
e8b1af0917
|
@ -25,7 +25,7 @@ namespace nall {
|
|||
|
||||
void reset() {
|
||||
if(pool) free(pool);
|
||||
pool = 0;
|
||||
pool = nullptr;
|
||||
poolsize = 0;
|
||||
buffersize = 0;
|
||||
}
|
||||
|
@ -85,10 +85,10 @@ namespace nall {
|
|||
memset(pool, 0, buffersize * sizeof(T));
|
||||
}
|
||||
|
||||
array() : pool(0), poolsize(0), buffersize(0) {
|
||||
array() : pool(nullptr), poolsize(0), buffersize(0) {
|
||||
}
|
||||
|
||||
array(std::initializer_list<T> list) : pool(0), poolsize(0), buffersize(0) {
|
||||
array(std::initializer_list<T> list) : pool(nullptr), poolsize(0), buffersize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ namespace nall {
|
|||
return *this;
|
||||
}
|
||||
|
||||
array(const array &source) : pool(0), poolsize(0), buffersize(0) {
|
||||
array(const array &source) : pool(nullptr), poolsize(0), buffersize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
|
@ -116,12 +116,12 @@ namespace nall {
|
|||
pool = source.pool;
|
||||
poolsize = source.poolsize;
|
||||
buffersize = source.buffersize;
|
||||
source.pool = 0;
|
||||
source.pool = nullptr;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(array &&source) : pool(0), poolsize(0), buffersize(0) {
|
||||
array(array &&source) : pool(nullptr), poolsize(0), buffersize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
#ifndef NALL_ATOI_HPP
|
||||
#define NALL_ATOI_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
//note: this header is intended to form the base for user-defined literals;
|
||||
//once they are supported by GCC. eg:
|
||||
//unsigned operator "" b(const char *s) { return binary(s); }
|
||||
//-> signed data = 1001b;
|
||||
//(0b1001 is nicer, but is not part of the C++ standard)
|
||||
|
||||
constexpr inline uintmax_t binary_(const char *s, uintmax_t sum = 0) {
|
||||
return (
|
||||
*s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') :
|
||||
sum
|
||||
);
|
||||
}
|
||||
|
||||
constexpr inline uintmax_t octal_(const char *s, uintmax_t sum = 0) {
|
||||
return (
|
||||
*s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') :
|
||||
sum
|
||||
);
|
||||
}
|
||||
|
||||
constexpr inline uintmax_t decimal_(const char *s, uintmax_t sum = 0) {
|
||||
return (
|
||||
*s >= '0' && *s <= '9' ? decimal_(s + 1, (sum * 10) + *s - '0') :
|
||||
sum
|
||||
);
|
||||
}
|
||||
|
||||
constexpr inline uintmax_t hex_(const char *s, uintmax_t sum = 0) {
|
||||
return (
|
||||
*s >= 'A' && *s <= 'F' ? hex_(s + 1, (sum << 4) | *s - 'A' + 10) :
|
||||
*s >= 'a' && *s <= 'f' ? hex_(s + 1, (sum << 4) | *s - 'a' + 10) :
|
||||
*s >= '0' && *s <= '9' ? hex_(s + 1, (sum << 4) | *s - '0') :
|
||||
sum
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
constexpr inline uintmax_t binary(const char *s) {
|
||||
return (
|
||||
*s == '0' && *(s + 1) == 'B' ? binary_(s + 2) :
|
||||
*s == '0' && *(s + 1) == 'b' ? binary_(s + 2) :
|
||||
*s == '%' ? binary_(s + 1) :
|
||||
binary_(s)
|
||||
);
|
||||
}
|
||||
|
||||
constexpr inline uintmax_t octal(const char *s) {
|
||||
return (
|
||||
octal_(s)
|
||||
);
|
||||
}
|
||||
|
||||
constexpr inline intmax_t integer(const char *s) {
|
||||
return (
|
||||
*s == '+' ? +decimal_(s + 1) :
|
||||
*s == '-' ? -decimal_(s + 1) :
|
||||
decimal_(s)
|
||||
);
|
||||
}
|
||||
|
||||
constexpr inline uintmax_t decimal(const char *s) {
|
||||
return (
|
||||
decimal_(s)
|
||||
);
|
||||
}
|
||||
|
||||
constexpr inline uintmax_t hex(const char *s) {
|
||||
return (
|
||||
*s == '0' && *(s + 1) == 'X' ? hex_(s + 2) :
|
||||
*s == '0' && *(s + 1) == 'x' ? hex_(s + 2) :
|
||||
*s == '$' ? hex_(s + 1) :
|
||||
hex_(s)
|
||||
);
|
||||
}
|
||||
|
||||
inline double fp(const char *s) {
|
||||
return atof(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -5,8 +5,7 @@
|
|||
#include <nall/stdint.hpp>
|
||||
|
||||
namespace nall {
|
||||
class base64 {
|
||||
public:
|
||||
struct base64 {
|
||||
static bool encode(char *&output, const uint8_t* input, unsigned inlength) {
|
||||
output = new char[inlength * 8 / 6 + 6]();
|
||||
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
#define NALL_BIT_HPP
|
||||
|
||||
namespace nall {
|
||||
constexpr inline unsigned binary(const char *s, unsigned sum = 0) {
|
||||
return s[0] == 0 ? sum : binary(s + 1, (sum << 1) | s[0] == '1');
|
||||
}
|
||||
|
||||
template<int bits> constexpr inline unsigned uclamp(const unsigned x) {
|
||||
enum { y = (1U << (bits - 1)) + ((1U << (bits - 1)) - 1) };
|
||||
return y + ((x - y) & -(x < y)); //min(x, y);
|
||||
|
|
|
@ -24,7 +24,7 @@ protected:
|
|||
struct Node {
|
||||
unsigned offset;
|
||||
Node *next;
|
||||
inline Node() : offset(0), next(0) {}
|
||||
inline Node() : offset(0), next(nullptr) {}
|
||||
inline ~Node() { if(next) delete next; }
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef NALL_COMPOSITOR_HPP
|
||||
#define NALL_COMPOSITOR_HPP
|
||||
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/intrinsics.hpp>
|
||||
|
||||
namespace nall {
|
||||
|
||||
|
@ -35,7 +35,7 @@ bool compositor::enable(bool status) {
|
|||
return true;
|
||||
}
|
||||
|
||||
#elif defined(PLATFORM_WIN)
|
||||
#elif defined(PLATFORM_WINDOWS)
|
||||
|
||||
bool compositor::enabled() {
|
||||
HMODULE module = GetModuleHandleW(L"dwmapi");
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace nall {
|
|||
else list[n].type = unknown_t;
|
||||
}
|
||||
|
||||
virtual bool load(const char *filename) {
|
||||
virtual bool load(const string &filename) {
|
||||
string data;
|
||||
if(data.readfile(filename) == true) {
|
||||
data.replace("\r", "");
|
||||
|
@ -100,7 +100,7 @@ namespace nall {
|
|||
}
|
||||
}
|
||||
|
||||
virtual bool save(const char *filename) const {
|
||||
virtual bool save(const string &filename) const {
|
||||
file fp;
|
||||
if(fp.open(filename, file::mode::write)) {
|
||||
for(unsigned i = 0; i < list.size(); i++) {
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef NALL_DETECT_HPP
|
||||
#define NALL_DETECT_HPP
|
||||
|
||||
/* Compiler detection */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define COMPILER_GCC
|
||||
#elif defined(_MSC_VER)
|
||||
#define COMPILER_VISUALC
|
||||
#endif
|
||||
|
||||
/* Platform detection */
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define PLATFORM_WIN
|
||||
#elif defined(__APPLE__)
|
||||
#define PLATFORM_OSX
|
||||
#elif defined(linux) || defined(__sun__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#define PLATFORM_X
|
||||
#endif
|
||||
|
||||
/* Endian detection */
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__) || defined(_M_IX86) || defined(_M_AMD64)
|
||||
#define ARCH_LSB
|
||||
#elif defined(__powerpc__) || defined(_M_PPC) || defined(__BIG_ENDIAN__)
|
||||
#define ARCH_MSB
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,11 +1,12 @@
|
|||
#ifndef NALL_DIRECTORY_HPP
|
||||
#define NALL_DIRECTORY_HPP
|
||||
|
||||
#include <nall/intrinsics.hpp>
|
||||
#include <nall/sort.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
#include <nall/windows/utf8.hpp>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
|
@ -22,7 +23,7 @@ struct directory {
|
|||
static lstring contents(const string &pathname, const string &pattern = "*");
|
||||
};
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
inline bool directory::exists(const string &pathname) {
|
||||
DWORD result = GetFileAttributes(utf16_t(pathname));
|
||||
if(result == INVALID_FILE_ATTRIBUTES) return false;
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
|
||||
//dynamic linking support
|
||||
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/intrinsics.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
#if defined(PLATFORM_X) || defined(PLATFORM_OSX)
|
||||
#include <dlfcn.h>
|
||||
#elif defined(PLATFORM_WIN)
|
||||
#elif defined(PLATFORM_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include <nall/windows/utf8.hpp>
|
||||
#endif
|
||||
|
@ -81,7 +81,7 @@ namespace nall {
|
|||
dlclose((void*)handle);
|
||||
handle = 0;
|
||||
}
|
||||
#elif defined(PLATFORM_WIN)
|
||||
#elif defined(PLATFORM_WINDOWS)
|
||||
inline bool library::open(const char *name, const char *path) {
|
||||
if(handle) close();
|
||||
string filepath(path, *path && !strend(path, "/") && !strend(path, "\\") ? "\\" : "", name, ".dll");
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef NALL_ENDIAN_HPP
|
||||
#define NALL_ENDIAN_HPP
|
||||
|
||||
#if !defined(ARCH_MSB)
|
||||
#include <nall/intrinsics.hpp>
|
||||
|
||||
#if defined(ENDIAN_LSB)
|
||||
//little-endian: uint8_t[] { 0x01, 0x02, 0x03, 0x04 } == 0x04030201
|
||||
#define order_lsb2(a,b) a,b
|
||||
#define order_lsb3(a,b,c) a,b,c
|
||||
|
@ -17,7 +19,7 @@
|
|||
#define order_msb6(a,b,c,d,e,f) f,e,d,c,b,a
|
||||
#define order_msb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a
|
||||
#define order_msb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a
|
||||
#else
|
||||
#elif defined(ENDIAN_MSB)
|
||||
//big-endian: uint8_t[] { 0x01, 0x02, 0x03, 0x04 } == 0x01020304
|
||||
#define order_lsb2(a,b) b,a
|
||||
#define order_lsb3(a,b,c) c,b,a
|
||||
|
@ -33,6 +35,8 @@
|
|||
#define order_msb6(a,b,c,d,e,f) a,b,c,d,e,f
|
||||
#define order_msb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g
|
||||
#define order_msb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h
|
||||
#else
|
||||
#error "Unknown endian. Please specify in nall/intrinsics.hpp"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,19 +36,19 @@ namespace nall {
|
|||
public:
|
||||
operator bool() const { return callback; }
|
||||
R operator()(P... p) const { return (*callback)(std::forward<P>(p)...); }
|
||||
void reset() { if(callback) { delete callback; callback = 0; } }
|
||||
void reset() { if(callback) { delete callback; callback = nullptr; } }
|
||||
|
||||
function& operator=(const function &source) {
|
||||
if(this != &source) {
|
||||
if(callback) { delete callback; callback = 0; }
|
||||
if(callback) { delete callback; callback = nullptr; }
|
||||
if(source.callback) callback = source.callback->copy();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
function(const function &source) : callback(0) { operator=(source); }
|
||||
function() : callback(0) {}
|
||||
function(void *function) : callback(0) { if(function) callback = new global((R (*)(P...))function); }
|
||||
function(const function &source) : callback(nullptr) { operator=(source); }
|
||||
function() : callback(nullptr) {}
|
||||
function(void *function) : callback(nullptr) { if(function) callback = new global((R (*)(P...))function); }
|
||||
function(R (*function)(P...)) { callback = new global(function); }
|
||||
template<typename C> function(R (C::*function)(P...), C *object) { callback = new member<C>(function, object); }
|
||||
template<typename C> function(R (C::*function)(P...) const, C *object) { callback = new member<C>((R (C::*)(P...))function, object); }
|
||||
|
|
|
@ -75,7 +75,7 @@ bool gzip::decompress(const uint8_t *data, unsigned size) {
|
|||
return inflate(this->data, this->size, data + p, size - p - 8);
|
||||
}
|
||||
|
||||
gzip::gzip() : data(0) {
|
||||
gzip::gzip() : data(nullptr) {
|
||||
}
|
||||
|
||||
gzip::~gzip() {
|
||||
|
|
|
@ -199,17 +199,17 @@ inline int codes(state *s, huffman *lencode, huffman *distcode) {
|
|||
symbol = decode(s, distcode);
|
||||
if(symbol < 0) return symbol;
|
||||
dist = dists[symbol] + bits(s, dext[symbol]);
|
||||
#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOO_FAR
|
||||
#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOO_FAR
|
||||
if(dist > s->outcnt) return -11;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if(s->out != 0) {
|
||||
if(s->outcnt + len > s->outlen) return 1;
|
||||
while(len--) {
|
||||
s->out[s->outcnt] =
|
||||
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOO_FAR
|
||||
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOO_FAR
|
||||
dist > s->outcnt ? 0 :
|
||||
#endif
|
||||
#endif
|
||||
s->out[s->outcnt - dist];
|
||||
s->outcnt++;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef NALL_INTRINSICS_HPP
|
||||
#define NALL_INTRINSICS_HPP
|
||||
|
||||
struct Intrinsics {
|
||||
enum class Compiler : unsigned { GCC, VisualC, Unknown };
|
||||
enum class Platform : unsigned { X, OSX, Windows, Unknown };
|
||||
enum class Endian : unsigned { LSB, MSB, Unknown };
|
||||
|
||||
static inline Compiler compiler();
|
||||
static inline Platform platform();
|
||||
static inline Endian endian();
|
||||
};
|
||||
|
||||
/* Compiler detection */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define COMPILER_GCC
|
||||
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::GCC; }
|
||||
#elif defined(_MSC_VER)
|
||||
#define COMPILER_VISUALC
|
||||
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::VisualC; }
|
||||
#else
|
||||
#define COMPILER_UNKNOWN
|
||||
Intrinsics::Compiler Intrinsics::compiler() { return Intrinsics::Compiler::Unknown; }
|
||||
#endif
|
||||
|
||||
/* Platform detection */
|
||||
|
||||
#if defined(linux) || defined(__sun__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#define PLATFORM_X
|
||||
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::X; }
|
||||
#elif defined(__APPLE__)
|
||||
#define PLATFORM_OSX
|
||||
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::OSX; }
|
||||
#elif defined(_WIN32)
|
||||
#define PLATFORM_WINDOWS
|
||||
#define PLATFORM_WIN
|
||||
Intrinsics::Platform Intrinsics::platform() { return Intrinsics::Platform::Windows; }
|
||||
#else
|
||||
#define PLATFORM_UNKNOWN
|
||||
|
||||
#endif
|
||||
|
||||
/* Endian detection */
|
||||
|
||||
#if defined(__i386__) || defined(__amd64__) || defined(_M_IX86) || defined(_M_AMD64)
|
||||
#define ENDIAN_LSB
|
||||
#define ARCH_LSB
|
||||
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::LSB; }
|
||||
#elif defined(__powerpc__) || defined(_M_PPC) || defined(__BIG_ENDIAN__)
|
||||
#define ENDIAN_MSB
|
||||
#define ARCH_MSB
|
||||
Intrinsics::Endian Intrinsics::endian() { return Intrinsics::Endian::MSB; }
|
||||
#else
|
||||
#define ENDIAN_UNKNOWN
|
||||
#define ARCH_UNKNOWN
|
||||
Intrinsics::Endian Intrinsics::endia() { return Intrinsics::Endian::Unknown; }
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -76,7 +76,7 @@ bool ips::apply() {
|
|||
}
|
||||
|
||||
delete[] data;
|
||||
data = 0;
|
||||
data = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ bool ips::modify(const string &filename) {
|
|||
return file::read(filename, modifyData, modifySize);
|
||||
}
|
||||
|
||||
ips::ips() : data(0), sourceData(0), modifyData(0) {
|
||||
ips::ips() : data(nullptr), sourceData(nullptr), modifyData(nullptr) {
|
||||
}
|
||||
|
||||
ips::~ips() {
|
||||
|
|
|
@ -25,7 +25,7 @@ protected:
|
|||
struct Node {
|
||||
unsigned offset;
|
||||
Node *next;
|
||||
inline Node() : offset(0), next(0) {}
|
||||
inline Node() : offset(0), next(nullptr) {}
|
||||
inline ~Node() { if(next) delete next; }
|
||||
} *tree[65536];
|
||||
|
||||
|
@ -34,7 +34,7 @@ protected:
|
|||
unsigned sourceSize;
|
||||
|
||||
public:
|
||||
inline lzss() : sourceData(0), sourceSize(0) {}
|
||||
inline lzss() : sourceData(nullptr), sourceSize(nullptr) {}
|
||||
};
|
||||
|
||||
void lzss::source(const uint8_t *data, unsigned size) {
|
||||
|
|
|
@ -413,7 +413,7 @@ void png::alphaTransform(uint32_t rgb) {
|
|||
}
|
||||
}
|
||||
|
||||
png::png() : data(0), rawData(0) {
|
||||
png::png() : data(nullptr), rawData(nullptr) {
|
||||
}
|
||||
|
||||
png::~png() {
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace nall {
|
|||
//priority queue implementation using binary min-heap array;
|
||||
//does not require normalize() function.
|
||||
//O(1) find (tick)
|
||||
//O(log n) insert (enqueue)
|
||||
//O(log n) append (enqueue)
|
||||
//O(log n) remove (dequeue)
|
||||
template<typename type_t> class priority_queue {
|
||||
public:
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
// readwrite<int> y;
|
||||
//};
|
||||
|
||||
//return types are const T& (byref) instead fo T (byval) to avoid major speed
|
||||
//return types are const T& (byref) instead of T (byval) to avoid major speed
|
||||
//penalties for objects with expensive copy constructors
|
||||
|
||||
//operator-> provides access to underlying object type:
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace nall {
|
|||
|
||||
void reset() {
|
||||
if(pool) free(pool);
|
||||
pool = 0;
|
||||
pool = nullptr;
|
||||
poolsize = 0;
|
||||
buffersize = 0;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ namespace nall {
|
|||
return false;
|
||||
}
|
||||
|
||||
template<typename... Args> reference_array(Args&... args) : pool(0), poolsize(0), buffersize(0) {
|
||||
template<typename... Args> reference_array(Args&... args) : pool(nullptr), poolsize(0), buffersize(0) {
|
||||
construct(args...);
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ namespace nall {
|
|||
pool = source.pool;
|
||||
poolsize = source.poolsize;
|
||||
buffersize = source.buffersize;
|
||||
source.pool = 0;
|
||||
source.pool = nullptr;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <initializer_list>
|
||||
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/atoi.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/sha256.hpp>
|
||||
|
|
|
@ -2,12 +2,11 @@
|
|||
#define NALL_STRING_BASE_HPP
|
||||
|
||||
namespace nall {
|
||||
class string;
|
||||
class lstring;
|
||||
struct string;
|
||||
struct lstring;
|
||||
template<typename T> inline const char* to_string(T);
|
||||
|
||||
class string {
|
||||
public:
|
||||
struct string {
|
||||
inline void reserve(unsigned);
|
||||
|
||||
template<typename... Args> inline string& assign(Args&&... args);
|
||||
|
@ -88,8 +87,7 @@ namespace nall {
|
|||
#endif
|
||||
};
|
||||
|
||||
class lstring : public linear_vector<string> {
|
||||
public:
|
||||
struct lstring : public linear_vector<string> {
|
||||
template<typename T> inline lstring& operator<<(T value);
|
||||
|
||||
inline optional<unsigned> find(const char*) const;
|
||||
|
@ -125,11 +123,6 @@ namespace nall {
|
|||
inline char* qstrlower(char *str);
|
||||
inline char* qstrupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t hex(const char *str);
|
||||
inline intmax_t integer(const char *str);
|
||||
inline uintmax_t decimal(const char *str);
|
||||
inline uintmax_t bin(const char *str);
|
||||
inline double fp(const char *str);
|
||||
|
||||
//math.hpp
|
||||
inline bool strint(const char *str, int &result);
|
||||
|
@ -170,7 +163,7 @@ namespace nall {
|
|||
template<unsigned length = 0, char padding = ' '> inline string decimal(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = ' '> inline string ldecimal(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string hex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string bin(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string binary(uintmax_t value);
|
||||
inline unsigned fp(char *str, double value);
|
||||
inline string fp(double value);
|
||||
|
||||
|
|
|
@ -60,86 +60,6 @@ char* strtr(char *dest, const char *before, const char *after) {
|
|||
return dest;
|
||||
}
|
||||
|
||||
uintmax_t hex(const char *str) {
|
||||
if(!str) return 0;
|
||||
uintmax_t result = 0;
|
||||
|
||||
//skip hex identifiers 0x and $, if present
|
||||
if(*str == '0' && (*(str + 1) == 'X' || *(str + 1) == 'x')) str += 2;
|
||||
else if(*str == '$') str++;
|
||||
|
||||
while(*str) {
|
||||
uint8_t x = *str++;
|
||||
if(x >= '0' && x <= '9') x -= '0';
|
||||
else if(x >= 'A' && x <= 'F') x -= 'A' - 10;
|
||||
else if(x >= 'a' && x <= 'f') x -= 'a' - 10;
|
||||
else break; //stop at first invalid character
|
||||
result = result * 16 + x;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
intmax_t integer(const char *str) {
|
||||
if(!str) return 0;
|
||||
intmax_t result = 0;
|
||||
bool negate = false;
|
||||
|
||||
//check for sign
|
||||
if(*str == '+') {
|
||||
negate = false;
|
||||
str++;
|
||||
} else if(*str == '-') {
|
||||
negate = true;
|
||||
str++;
|
||||
}
|
||||
|
||||
while(*str) {
|
||||
uint8_t x = *str++;
|
||||
if(x >= '0' && x <= '9') x -= '0';
|
||||
else break; //stop at first invalid character
|
||||
result = result * 10 + x;
|
||||
}
|
||||
|
||||
return !negate ? result : -result;
|
||||
}
|
||||
|
||||
uintmax_t decimal(const char *str) {
|
||||
if(!str) return 0;
|
||||
uintmax_t result = 0;
|
||||
|
||||
while(*str) {
|
||||
uint8_t x = *str++;
|
||||
if(x >= '0' && x <= '9') x -= '0';
|
||||
else break; //stop at first invalid character
|
||||
result = result * 10 + x;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uintmax_t bin(const char *str) {
|
||||
if(!str) return 0;
|
||||
uintmax_t result = 0;
|
||||
|
||||
//skip bin identifiers 0b and %, if present
|
||||
if(*str == '0' && (*(str + 1) == 'B' || *(str + 1) == 'b')) str += 2;
|
||||
else if(*str == '%') str++;
|
||||
|
||||
while(*str) {
|
||||
uint8_t x = *str++;
|
||||
if(x == '0' || x == '1') x -= '0';
|
||||
else break; //stop at first invalid character
|
||||
result = result * 2 + x;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double fp(const char *str) {
|
||||
return atof(str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -76,7 +76,7 @@ string& string::operator=(string &&source) {
|
|||
if(data) free(data);
|
||||
size = source.size;
|
||||
data = source.data;
|
||||
source.data = 0;
|
||||
source.data = nullptr;
|
||||
source.size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ string::string(string &&source) {
|
|||
if(&source == this) return;
|
||||
size = source.size;
|
||||
data = source.data;
|
||||
source.data = 0;
|
||||
source.data = nullptr;
|
||||
}
|
||||
|
||||
string::~string() {
|
||||
|
|
|
@ -193,7 +193,7 @@ template<unsigned length_, char padding> string hex(uintmax_t value) {
|
|||
return (const char*)result;
|
||||
}
|
||||
|
||||
template<unsigned length_, char padding> string bin(uintmax_t value) {
|
||||
template<unsigned length_, char padding> string binary(uintmax_t value) {
|
||||
char buffer[256];
|
||||
unsigned size = 0;
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace nall {
|
|||
for(unsigned i = 0; i < objectsize; i++) pool[i].~T();
|
||||
free(pool);
|
||||
}
|
||||
pool = 0;
|
||||
pool = nullptr;
|
||||
poolsize = 0;
|
||||
objectsize = 0;
|
||||
}
|
||||
|
@ -93,10 +93,10 @@ namespace nall {
|
|||
else resize(objectsize - count);
|
||||
}
|
||||
|
||||
linear_vector() : pool(0), poolsize(0), objectsize(0) {
|
||||
linear_vector() : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
}
|
||||
|
||||
linear_vector(std::initializer_list<T> list) : pool(0), poolsize(0), objectsize(0) {
|
||||
linear_vector(std::initializer_list<T> list) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ namespace nall {
|
|||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(const linear_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
linear_vector(const linear_vector<T> &source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
|
@ -123,12 +123,12 @@ namespace nall {
|
|||
pool = source.pool;
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.pool = nullptr;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(linear_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
linear_vector(linear_vector<T> &&source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
|
@ -174,7 +174,7 @@ namespace nall {
|
|||
for(unsigned i = 0; i < objectsize; i++) { if(pool[i]) delete pool[i]; }
|
||||
free(pool);
|
||||
}
|
||||
pool = 0;
|
||||
pool = nullptr;
|
||||
poolsize = 0;
|
||||
objectsize = 0;
|
||||
}
|
||||
|
@ -227,10 +227,10 @@ namespace nall {
|
|||
else resize(objectsize - count);
|
||||
}
|
||||
|
||||
pointer_vector() : pool(0), poolsize(0), objectsize(0) {
|
||||
pointer_vector() : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
}
|
||||
|
||||
pointer_vector(std::initializer_list<T> list) : pool(0), poolsize(0), objectsize(0) {
|
||||
pointer_vector(std::initializer_list<T> list) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
|
@ -247,7 +247,7 @@ namespace nall {
|
|||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(const pointer_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
pointer_vector(const pointer_vector<T> &source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
|
@ -257,12 +257,12 @@ namespace nall {
|
|||
pool = source.pool;
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.pool = nullptr;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(pointer_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
pointer_vector(pointer_vector<T> &&source) : pool(nullptr), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
#include "nrom.cpp"
|
||||
|
||||
unsigned Board::mirror(unsigned addr, unsigned size) const {
|
||||
unsigned base = 0;
|
||||
if(size) {
|
||||
unsigned mask = 1 << 23;
|
||||
while(addr >= size) {
|
||||
while(!(addr & mask)) mask >>= 1;
|
||||
addr -= mask;
|
||||
if(size > mask) {
|
||||
size -= mask;
|
||||
base += mask;
|
||||
}
|
||||
mask >>= 1;
|
||||
}
|
||||
base += addr;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
uint8 Board::prg_read(unsigned addr) {
|
||||
return prg.data[mirror(addr, prg.size)];
|
||||
}
|
||||
|
||||
void Board::prg_write(unsigned addr, uint8 data) {
|
||||
prg.data[mirror(addr, prg.size)] = data;
|
||||
}
|
||||
|
||||
uint8 Board::chr_read(unsigned addr) {
|
||||
return chr.data[mirror(addr, chr.size)];
|
||||
}
|
||||
|
||||
void Board::chr_write(unsigned addr, uint8 data) {
|
||||
chr.data[mirror(addr, chr.size)] = data;
|
||||
}
|
||||
|
||||
Board* Board::create(const string &xml, const uint8_t *data, unsigned size) {
|
||||
string type;
|
||||
string configuration;
|
||||
|
||||
xml_element document = xml_parse(xml);
|
||||
for(auto &head : document.element) {
|
||||
if(head.name == "cartridge") {
|
||||
for(auto &node : head.element) {
|
||||
if(node.name == "board") {
|
||||
configuration = node.content;
|
||||
for(auto &attr : node.attribute) {
|
||||
if(attr.name == "type") type = attr.parse();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Board *board = nullptr;
|
||||
if(type == "NES-NROM-256") board = new NROM;
|
||||
assert(board != nullptr);
|
||||
|
||||
for(auto &head : document.element) {
|
||||
if(head.name == "cartridge") {
|
||||
for(auto &node : head.element) {
|
||||
if(node.name == "board") {
|
||||
for(auto &leaf : node.element) {
|
||||
if(leaf.name == "prg") {
|
||||
for(auto &attr : leaf.attribute) {
|
||||
if(attr.name == "size") board->prg.size = decimal(attr.content);
|
||||
}
|
||||
}
|
||||
|
||||
if(leaf.name == "chr") {
|
||||
for(auto &attr : leaf.attribute) {
|
||||
if(attr.name == "size") board->chr.size = decimal(attr.content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
board->prg.data = new uint8[board->prg.size];
|
||||
memcpy(board->prg.data, data, board->prg.size);
|
||||
|
||||
board->chr.data = new uint8[board->chr.size];
|
||||
memcpy(board->chr.data, data + board->prg.size, board->chr.size);
|
||||
|
||||
board->configure({ "<board>\n", configuration, "</board>\n" });
|
||||
|
||||
return board;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
struct Board {
|
||||
unsigned mirror(unsigned addr, unsigned size) const;
|
||||
|
||||
virtual uint8 prg_read(unsigned addr);
|
||||
virtual void prg_write(unsigned addr, uint8 data);
|
||||
|
||||
virtual uint8 chr_read(unsigned addr);
|
||||
virtual void chr_write(unsigned addr, uint8 data);
|
||||
|
||||
virtual void configure(const string &xml) = 0;
|
||||
|
||||
static Board* create(const string &xml, const uint8_t *data, unsigned size);
|
||||
|
||||
struct Information {
|
||||
string type;
|
||||
} information;
|
||||
|
||||
struct Memory {
|
||||
uint8_t *data;
|
||||
unsigned size;
|
||||
};
|
||||
|
||||
Memory prg;
|
||||
Memory chr;
|
||||
};
|
|
@ -0,0 +1,47 @@
|
|||
struct NROM : Board {
|
||||
|
||||
struct Settings {
|
||||
enum class Mirror : unsigned { Horizontal, Vertical } mirror;
|
||||
} settings;
|
||||
|
||||
uint8 prg_read(unsigned addr) {
|
||||
if(addr & 0x8000) return Board::prg_read(addr);
|
||||
return cpu.mdr();
|
||||
}
|
||||
|
||||
void prg_write(unsigned addr, uint8 data) {
|
||||
}
|
||||
|
||||
uint8 chr_read(unsigned addr) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == Settings::Mirror::Horizontal) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_read(addr & 0x07ff);
|
||||
}
|
||||
return Board::chr_read(addr);
|
||||
}
|
||||
|
||||
void chr_write(unsigned addr, uint8 data) {
|
||||
if(addr & 0x2000) {
|
||||
if(settings.mirror == Settings::Mirror::Horizontal) addr = ((addr & 0x0800) >> 1) | (addr & 0x03ff);
|
||||
return ppu.ciram_write(addr, data);
|
||||
}
|
||||
return Board::chr_write(addr, data);
|
||||
}
|
||||
|
||||
void configure(const string &xml) {
|
||||
xml_element document = xml_parse(xml);
|
||||
for(auto &node : document.element) {
|
||||
if(node.name == "mirror") {
|
||||
for(auto &attr : node.attribute) {
|
||||
if(attr.name == "type") {
|
||||
if(attr.content == "horizontal") settings.mirror = Settings::Mirror::Horizontal;
|
||||
if(attr.content == "vertical" ) settings.mirror = Settings::Mirror::Vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
NROM nrom;
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
namespace NES {
|
||||
|
||||
#include "board/board.cpp"
|
||||
|
||||
//#define BOARD
|
||||
|
||||
Cartridge cartridge;
|
||||
|
||||
void Cartridge::Main() {
|
||||
|
@ -13,20 +17,31 @@ void Cartridge::main() {
|
|||
}
|
||||
|
||||
void Cartridge::load(const string &xml, const uint8_t *data, unsigned size) {
|
||||
#ifdef BOARD
|
||||
rom_size = size;
|
||||
rom_data = new uint8[rom_size];
|
||||
memcpy(rom_data, data, size);
|
||||
#else
|
||||
rom_size = size - 16;
|
||||
rom_data = new uint8[rom_size];
|
||||
memcpy(rom_data, data + 16, size - 16);
|
||||
#endif
|
||||
|
||||
#ifdef BOARD
|
||||
prg_size = 32768;
|
||||
chr_size = 8192;
|
||||
#else
|
||||
prg_size = data[4] * 0x4000;
|
||||
chr_size = data[5] * 0x2000;
|
||||
#endif
|
||||
|
||||
prg_data = new uint8[prg_size];
|
||||
memcpy(prg_data, data + 16, prg_size);
|
||||
memcpy(prg_data, rom_data, prg_size);
|
||||
|
||||
if(chr_size) {
|
||||
chr_ram = false;
|
||||
chr_data = new uint8[chr_size];
|
||||
memcpy(chr_data, data + 16 + prg_size, chr_size);
|
||||
memcpy(chr_data, rom_data + prg_size, chr_size);
|
||||
} else {
|
||||
chr_ram = true;
|
||||
chr_size = 0x2000;
|
||||
|
@ -48,9 +63,14 @@ void Cartridge::load(const string &xml, const uint8_t *data, unsigned size) {
|
|||
case 26: mapper = &Mapper::vrc6; Mapper::vrc6.abus_swap = 1; break;
|
||||
}
|
||||
|
||||
sha256 = nall::sha256(rom_data, rom_size);
|
||||
|
||||
#ifdef BOARD
|
||||
board = Board::create(xml, rom_data, rom_size);
|
||||
#endif
|
||||
|
||||
system.load();
|
||||
loaded = true;
|
||||
sha256 = nall::sha256(rom_data, rom_size);
|
||||
}
|
||||
|
||||
void Cartridge::unload() {
|
||||
|
@ -86,29 +106,33 @@ Cartridge::Cartridge() {
|
|||
}
|
||||
|
||||
uint8 Cartridge::prg_read(unsigned addr) {
|
||||
#ifdef BOARD
|
||||
return board->prg_read(addr);
|
||||
#endif
|
||||
return mapper->prg_read(addr);
|
||||
}
|
||||
|
||||
void Cartridge::prg_write(unsigned addr, uint8 data) {
|
||||
#ifdef BOARD
|
||||
return board->prg_write(addr, data);
|
||||
#endif
|
||||
return mapper->prg_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 Cartridge::chr_read(unsigned addr) {
|
||||
#ifdef BOARD
|
||||
return board->chr_read(addr);
|
||||
#endif
|
||||
return mapper->chr_read(addr);
|
||||
}
|
||||
|
||||
void Cartridge::chr_write(unsigned addr, uint8 data) {
|
||||
#ifdef BOARD
|
||||
return board->chr_write(addr, data);
|
||||
#endif
|
||||
return mapper->chr_write(addr, data);
|
||||
}
|
||||
|
||||
uint8 Cartridge::ciram_read(unsigned addr) {
|
||||
return mapper->ciram_read(addr);
|
||||
}
|
||||
|
||||
void Cartridge::ciram_write(unsigned addr, uint8 data) {
|
||||
return mapper->ciram_write(addr, data);
|
||||
}
|
||||
|
||||
void Cartridge::serialize(serializer &s) {
|
||||
if(chr_ram) s.array(chr_data, chr_size);
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include "board/board.hpp"
|
||||
|
||||
struct Cartridge : Processor, property<Cartridge> {
|
||||
static void Main();
|
||||
void main();
|
||||
|
@ -18,6 +20,7 @@ struct Cartridge : Processor, property<Cartridge> {
|
|||
Cartridge();
|
||||
|
||||
//privileged:
|
||||
Board *board;
|
||||
Mapper::Mapper *mapper;
|
||||
|
||||
uint8 prg_read(unsigned addr);
|
||||
|
@ -26,9 +29,6 @@ struct Cartridge : Processor, property<Cartridge> {
|
|||
uint8 chr_read(unsigned addr);
|
||||
void chr_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 ciram_read(unsigned addr);
|
||||
void ciram_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 *rom_data;
|
||||
unsigned rom_size;
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ namespace NES {
|
|||
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/dl.hpp>
|
||||
#include <nall/endian.hpp>
|
||||
#include <nall/file.hpp>
|
||||
|
|
|
@ -335,11 +335,11 @@ void PPU::raster_sprite() {
|
|||
return;
|
||||
}
|
||||
|
||||
raster.soam[raster.oam_counter].id = n;
|
||||
raster.soam[raster.oam_counter].y = y;
|
||||
raster.soam[raster.oam_counter].id = n;
|
||||
raster.soam[raster.oam_counter].y = oam[(n * 4) + 0];
|
||||
raster.soam[raster.oam_counter].tile = oam[(n * 4) + 1];
|
||||
raster.soam[raster.oam_counter].attr = oam[(n * 4) + 2];
|
||||
raster.soam[raster.oam_counter].x = oam[(n * 4) + 3];
|
||||
raster.soam[raster.oam_counter].x = oam[(n * 4) + 3];
|
||||
raster.oam_counter++;
|
||||
}
|
||||
|
||||
|
@ -357,7 +357,11 @@ void PPU::raster_scanline() {
|
|||
raster.oam_counter = 0;
|
||||
|
||||
for(unsigned n = 0; n < 8; n++) {
|
||||
raster.soam[n].id = 64;
|
||||
raster.soam[n].id = 64;
|
||||
raster.soam[n].y = 0xff;
|
||||
raster.soam[n].tile = 0xff;
|
||||
raster.soam[n].attr = 0xff;
|
||||
raster.soam[n].x = 0xff;
|
||||
raster.soam[n].tiledatalo = 0;
|
||||
raster.soam[n].tiledatahi = 0;
|
||||
}
|
||||
|
@ -420,10 +424,9 @@ void PPU::raster_scanline() {
|
|||
tick();
|
||||
tick();
|
||||
|
||||
unsigned spritey = raster.oam[sprite].y;
|
||||
unsigned spritey = (status.ly - raster.oam[sprite].y) & (sprite_height() - 1);
|
||||
if(raster.oam[sprite].attr & 0x80) spritey ^= (sprite_height() - 1);
|
||||
tileaddr += spritey + (spritey & 8);
|
||||
if(raster.oam[sprite].id == 64) tileaddr = status.sprite_addr;
|
||||
|
||||
raster.oam[sprite].tiledatalo = chr_load(tileaddr + 0);
|
||||
tick();
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
rubyflags := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c)
|
||||
rubyflags += $(if $(finstring .sdl,$(ruby)),`sdl-config --cflags`)
|
||||
|
||||
rubylink :=
|
||||
rubylink += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`)
|
||||
rubylink += $(if $(findstring video.direct3d,$(ruby)),-ld3d9)
|
||||
rubylink += $(if $(findstring video.directdraw,$(ruby)),-lddraw)
|
||||
rubylink += $(if $(findstring video.glx,$(ruby)),-lGL)
|
||||
rubylink += $(if $(findstring video.wgl,$(ruby)),-lopengl32)
|
||||
rubylink += $(if $(findstring video.xv,$(ruby)),-lXv)
|
||||
rubylink += $(if $(findstring audio.alsa,$(ruby)),-lasound)
|
||||
rubylink += $(if $(findstring audio.ao,$(ruby)),-lao)
|
||||
rubylink += $(if $(findstring audio.directsound,$(ruby)),-ldsound)
|
||||
rubylink += $(if $(findstring audio.pulseaudio,$(ruby)),-lpulse)
|
||||
rubylink += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple)
|
||||
rubylink += $(if $(findstring audio.xaudio2,$(ruby)),-lole32)
|
||||
rubylink += $(if $(findstring input.directinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
rubylink += $(if $(findstring input.rawinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
|
||||
ifeq ($(platform),x)
|
||||
rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal)
|
||||
else ifeq ($(platform),osx)
|
||||
rubylink += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL)
|
||||
else ifeq ($(platform),win)
|
||||
rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal32)
|
||||
endif
|
|
@ -11,8 +11,8 @@
|
|||
#include <nall/any.hpp>
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/input.hpp>
|
||||
#include <nall/intrinsics.hpp>
|
||||
#include <nall/sort.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
|
@ -24,8 +24,7 @@ namespace ruby {
|
|||
#include <ruby/audio.hpp>
|
||||
#include <ruby/input.hpp>
|
||||
|
||||
class VideoInterface {
|
||||
public:
|
||||
struct VideoInterface {
|
||||
void driver(const char *driver = "");
|
||||
const char* default_driver();
|
||||
const char* driver_list();
|
||||
|
@ -47,8 +46,7 @@ private:
|
|||
Video *p;
|
||||
};
|
||||
|
||||
class AudioInterface {
|
||||
public:
|
||||
struct AudioInterface {
|
||||
void driver(const char *driver = "");
|
||||
const char* default_driver();
|
||||
const char* driver_list();
|
||||
|
@ -68,8 +66,7 @@ private:
|
|||
Audio *p;
|
||||
};
|
||||
|
||||
class InputInterface {
|
||||
public:
|
||||
struct InputInterface {
|
||||
void driver(const char *driver = "");
|
||||
const char* default_driver();
|
||||
const char* driver_list();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#if defined(VIDEO_QTOPENGL)
|
||||
#include <QGLWidget>
|
||||
#if defined(PLATFORM_WIN)
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
#include <GL/glext.h>
|
||||
#endif
|
||||
#endif
|
||||
|
@ -19,7 +19,7 @@
|
|||
#elif defined(PLATFORM_OSX)
|
||||
#define __INTEL_COMPILER
|
||||
#include <Carbon/Carbon.h>
|
||||
#elif defined(PLATFORM_WIN)
|
||||
#elif defined(PLATFORM_WINDOWS)
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
|
|
@ -20,7 +20,6 @@ namespace SNES {
|
|||
#include <nall/algorithm.hpp>
|
||||
#include <nall/any.hpp>
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/dl.hpp>
|
||||
#include <nall/dsp.hpp>
|
||||
#include <nall/endian.hpp>
|
||||
|
|
|
@ -21,8 +21,6 @@ ifeq ($(platform),x)
|
|||
ruby := video.glx video.xv video.sdl
|
||||
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
||||
ruby += input.sdl input.x
|
||||
|
||||
link += $(if $(findstring audio.openal,$(ruby)),-lopenal)
|
||||
else ifeq ($(platform),osx)
|
||||
phoenix_compile = $(call compile,-DPHOENIX_QT)
|
||||
link +=
|
||||
|
@ -30,8 +28,6 @@ else ifeq ($(platform),osx)
|
|||
ruby :=
|
||||
ruby += audio.openal
|
||||
ruby += input.carbon
|
||||
|
||||
link += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL)
|
||||
else ifeq ($(platform),win)
|
||||
phoenix_compile = $(call compile,-DPHOENIX_WINDOWS)
|
||||
link +=
|
||||
|
@ -39,29 +35,11 @@ else ifeq ($(platform),win)
|
|||
ruby := video.direct3d video.wgl video.directdraw video.gdi
|
||||
ruby += audio.directsound audio.xaudio2
|
||||
ruby += input.rawinput input.directinput
|
||||
|
||||
link += $(if $(findstring audio.openal,$(ruby)),-lopenal32)
|
||||
endif
|
||||
|
||||
# ruby
|
||||
rubyflags := $(if $(finstring .sdl,$(ruby)),`sdl-config --cflags`)
|
||||
|
||||
link += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`)
|
||||
link += $(if $(findstring video.direct3d,$(ruby)),-ld3d9)
|
||||
link += $(if $(findstring video.directdraw,$(ruby)),-lddraw)
|
||||
link += $(if $(findstring video.glx,$(ruby)),-lGL)
|
||||
link += $(if $(findstring video.wgl,$(ruby)),-lopengl32)
|
||||
link += $(if $(findstring video.xv,$(ruby)),-lXv)
|
||||
link += $(if $(findstring audio.alsa,$(ruby)),-lasound)
|
||||
link += $(if $(findstring audio.ao,$(ruby)),-lao)
|
||||
link += $(if $(findstring audio.directsound,$(ruby)),-ldsound)
|
||||
link += $(if $(findstring audio.pulseaudio,$(ruby)),-lpulse)
|
||||
link += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple)
|
||||
link += $(if $(findstring audio.xaudio2,$(ruby)),-lole32)
|
||||
link += $(if $(findstring input.directinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
link += $(if $(findstring input.rawinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
|
||||
rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c)
|
||||
include ruby/Makefile
|
||||
link += $(rubylink)
|
||||
|
||||
# rules
|
||||
objects := $(ui_objects) $(objects)
|
||||
|
@ -78,7 +56,7 @@ obj/ui-settings.o: $(ui)/settings/settings.cpp $(call rwildcard,$(ui)/)
|
|||
obj/ui-tools.o: $(ui)/tools/tools.cpp $(call rwildcard,$(ui)/)
|
||||
|
||||
obj/ruby.o: ruby/ruby.cpp $(call rwildcard,ruby/*)
|
||||
$(call compile,$(rubydef) $(rubyflags))
|
||||
$(call compile,$(rubyflags))
|
||||
|
||||
obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*)
|
||||
$(phoenix_compile)
|
||||
|
@ -99,17 +77,15 @@ install:
|
|||
ifeq ($(platform),x)
|
||||
install -D -m 755 out/$(name) $(DESTDIR)$(prefix)/bin/$(name)
|
||||
mkdir -p ~/.config/$(name)
|
||||
install -D -m 644 data/$(name).png $(DESTDIR)$(prefix)/share/pixmaps/$(name).png
|
||||
install -D -m 644 data/$(name).desktop $(DESTDIR)$(prefix)/share/applications/$(name).desktop
|
||||
cp data/cheats.xml ~/.config/$(name)/cheats.xml
|
||||
chmod 777 ~/.config/$(name) ~/.config/$(name)/cheats.xml
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
ifeq ($(platform),x)
|
||||
rm $(DESTDIR)$(prefix)/bin/$(name)
|
||||
rm $(DESTDIR)$(prefix)/share/pixmaps/$(name).png
|
||||
rm $(DESTDIR)$(prefix)/share/applications/$(name).desktop
|
||||
endif
|
||||
|
||||
# install -D -m 644 data/$(name).png $(DESTDIR)$(prefix)/share/pixmaps/$(name).png
|
||||
# install -D -m 644 data/$(name).desktop $(DESTDIR)$(prefix)/share/applications/$(name).desktop
|
||||
# cp data/cheats.xml ~/.config/$(name)/cheats.xml
|
||||
# chmod 777 ~/.config/$(name) ~/.config/$(name)/cheats.xml
|
||||
|
||||
# rm $(DESTDIR)$(prefix)/share/pixmaps/$(name).png
|
||||
# rm $(DESTDIR)$(prefix)/share/applications/$(name).desktop
|
||||
|
|
|
@ -35,6 +35,7 @@ struct Application {
|
|||
|
||||
string basepath;
|
||||
string userpath;
|
||||
string path(const string &filename);
|
||||
|
||||
string title;
|
||||
string normalFont;
|
||||
|
|
|
@ -15,6 +15,8 @@ Config::Config() {
|
|||
attach(video.gammaRamp = true, "Video::GammaRamp");
|
||||
attach(video.fullScreenMode = 0, "Video::FullScreenMode");
|
||||
|
||||
attach(video.startFullScreen = false, "Video::StartFullScreen");
|
||||
|
||||
attach(audio.driver = "", "Audio::Driver");
|
||||
attach(audio.synchronize = true, "Audio::Synchronize");
|
||||
attach(audio.mute = false, "Audio::Mute");
|
||||
|
@ -37,10 +39,10 @@ Config::Config() {
|
|||
attach(snes.controllerPort1Device = 1, "SNES::Controller::Port1");
|
||||
attach(snes.controllerPort2Device = 0, "SNES::Controller::Port2");
|
||||
|
||||
load(string{ application->userpath, "settings.cfg" });
|
||||
save(string{ application->userpath, "settings.cfg" });
|
||||
load(application->path("settings.cfg"));
|
||||
save(application->path("settings.cfg"));
|
||||
}
|
||||
|
||||
Config::~Config() {
|
||||
save(string{ application->userpath, "settings.cfg" });
|
||||
save(application->path("settings.cfg"));
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ struct Config : public configuration {
|
|||
unsigned gamma;
|
||||
bool gammaRamp;
|
||||
unsigned fullScreenMode;
|
||||
|
||||
bool startFullScreen;
|
||||
} video;
|
||||
|
||||
struct Audio {
|
||||
|
|
|
@ -42,7 +42,7 @@ FileBrowser::FileBrowser() {
|
|||
fileList.onActivate = openButton.onTick = { &FileBrowser::fileListActivate, this };
|
||||
|
||||
filterModes[Mode::Default ] = { "Default", "", { "*" } };
|
||||
filterModes[Mode::NES ] = { "NES", "", { "*.nes" } };
|
||||
filterModes[Mode::NES ] = { "NES", "", { "*.fc", "*.nes" } };
|
||||
filterModes[Mode::SNES ] = { "SNES", "", { "*.sfc" } };
|
||||
filterModes[Mode::GameBoy ] = { "GameBoy", "", { "*.gb", "*.gbc" } };
|
||||
filterModes[Mode::Satellaview] = { "Satellaview", "", { "*.bs" } };
|
||||
|
@ -50,12 +50,12 @@ FileBrowser::FileBrowser() {
|
|||
mode = &filterModes[Mode::Default];
|
||||
|
||||
for(auto &mode : filterModes) config.attach(mode.path, mode.name);
|
||||
config.load(string{ application->userpath, "paths.cfg" });
|
||||
config.save(string{ application->userpath, "paths.cfg" });
|
||||
config.load(application->path("paths.cfg"));
|
||||
config.save(application->path("paths.cfg"));
|
||||
}
|
||||
|
||||
FileBrowser::~FileBrowser() {
|
||||
config.save(string{ application->userpath, "paths.cfg" });
|
||||
config.save(application->path("paths.cfg"));
|
||||
}
|
||||
|
||||
void FileBrowser::open(const string &title, unsigned requestedMode, function<void (string)> requestedCallback) {
|
||||
|
|
|
@ -325,7 +325,8 @@ void MainWindow::synchronize() {
|
|||
}
|
||||
|
||||
void MainWindow::setupVideoFilters() {
|
||||
lstring files = directory::files({ application->userpath, "filters/" }, "*.filter");
|
||||
lstring files = directory::files({ application->basepath, "filters/" }, "*.filter");
|
||||
if(files.size() == 0) directory::files({ application->userpath, "filters/" }, "*.filter");
|
||||
reference_array<RadioItem&> group;
|
||||
|
||||
settingsVideoFilterList = new RadioItem[files.size()];
|
||||
|
@ -351,7 +352,8 @@ void MainWindow::setupVideoFilters() {
|
|||
}
|
||||
|
||||
void MainWindow::setupVideoShaders() {
|
||||
lstring files = directory::files({ application->userpath, "shaders/" }, { "*.", config->video.driver, ".shader" });
|
||||
lstring files = directory::files({ application->basepath, "shaders/" }, { "*.", config->video.driver, ".shader" });
|
||||
if(files.size() == 0) files = directory::files({ application->userpath, "shaders/" }, { "*.", config->video.driver, ".shader" });
|
||||
reference_array<RadioItem&> group;
|
||||
|
||||
settingsVideoShaderList = new RadioItem[files.size()];
|
||||
|
|
|
@ -188,13 +188,13 @@ InputManager::InputManager() {
|
|||
inputList.append(userInterface);
|
||||
|
||||
for(unsigned n = 0; n < inputList.size(); n++) inputList[n].attach();
|
||||
config.load(string{ application->userpath, "input.cfg" });
|
||||
config.save(string{ application->userpath, "input.cfg" });
|
||||
config.load(application->path("input.cfg"));
|
||||
config.save(application->path("input.cfg"));
|
||||
for(unsigned n = 0; n < inputList.size(); n++) inputList[n].bind();
|
||||
|
||||
activeScancode = 0;
|
||||
}
|
||||
|
||||
InputManager::~InputManager() {
|
||||
config.save(string{ application->userpath, "input.cfg" });
|
||||
config.save(application->path("input.cfg"));
|
||||
}
|
||||
|
|
|
@ -20,7 +20,10 @@ bool InterfaceNES::loadCartridge(const string &filename) {
|
|||
interface->unloadCartridge();
|
||||
interface->baseName = nall::basename(filename);
|
||||
|
||||
NES::Interface::loadCartridge("", fp.data(), fp.size());
|
||||
string xml;
|
||||
xml.readfile({ interface->baseName, ".xml" });
|
||||
|
||||
NES::Interface::loadCartridge(xml, fp.data(), fp.size());
|
||||
fp.close();
|
||||
|
||||
if(NES::Interface::memorySize(NES::Interface::Memory::RAM) > 0) {
|
||||
|
|
|
@ -3,6 +3,14 @@
|
|||
Application *application = 0;
|
||||
nall::DSP dspaudio;
|
||||
|
||||
//allow files to exist in the same folder as binary;
|
||||
//otherwise default to home folder
|
||||
string Application::path(const string &filename) {
|
||||
string result = { basepath, filename };
|
||||
if(file::exists(result)) return result;
|
||||
return { userpath, filename };
|
||||
}
|
||||
|
||||
void Application::run() {
|
||||
inputManager->scan();
|
||||
|
||||
|
@ -26,14 +34,14 @@ Application::Application(int argc, char **argv) {
|
|||
{
|
||||
char path[PATH_MAX];
|
||||
auto unused = ::realpath(argv[0], path);
|
||||
basepath = path;
|
||||
basepath = dir(path);
|
||||
unused = ::userpath(path);
|
||||
userpath = path;
|
||||
#if defined(PLATFORM_WIN)
|
||||
userpath.append("batch/");
|
||||
#else
|
||||
userpath.append(".config/batch/");
|
||||
#endif
|
||||
if(Intrinsics::platform() == Intrinsics::Platform::Windows) {
|
||||
userpath.append("bsnes/");
|
||||
} else {
|
||||
userpath.append(".config/bsnes/");
|
||||
}
|
||||
mkdir(userpath, 0755);
|
||||
}
|
||||
config = new Config;
|
||||
|
@ -41,17 +49,12 @@ Application::Application(int argc, char **argv) {
|
|||
inputManager = new InputManager;
|
||||
utility = new Utility;
|
||||
|
||||
title = "bsnes v082.24";
|
||||
title = "bsnes v082.25";
|
||||
|
||||
#if defined(PLATFORM_WIN)
|
||||
normalFont = "Tahoma, 8";
|
||||
boldFont = "Tahoma, 8, Bold";
|
||||
titleFont = "Tahoma, 16, Bold";
|
||||
#else
|
||||
normalFont = "Sans, 8";
|
||||
boldFont = "Sans, 8, Bold";
|
||||
titleFont = "Sans, 16, Bold";
|
||||
#endif
|
||||
string fontFamily = Intrinsics::platform() == Intrinsics::Platform::Windows ? "Tahoma, " : "Sans, ";
|
||||
normalFont = { fontFamily, "8" };
|
||||
boldFont = { fontFamily, "8, Bold" };
|
||||
titleFont = { fontFamily, "16, Bold" };
|
||||
|
||||
windowManager = new WindowManager;
|
||||
mainWindow = new MainWindow;
|
||||
|
@ -91,6 +94,7 @@ Application::Application(int argc, char **argv) {
|
|||
input.set(Input::Handle, mainWindow->viewport.handle());
|
||||
input.init();
|
||||
|
||||
if(config->video.startFullScreen) utility->toggleFullScreen();
|
||||
if(argc == 2) interface->loadCartridge(argv[1]);
|
||||
|
||||
while(quit == false) {
|
||||
|
|
|
@ -40,7 +40,7 @@ AdvancedSettings::AdvancedSettings() {
|
|||
}
|
||||
|
||||
append(title, ~0, 0, 5);
|
||||
append(driverLabel, ~0, 0, 5);
|
||||
append(driverLabel, ~0, 0);
|
||||
append(driverLayout, ~0, 0, 5);
|
||||
driverLayout.append(videoLabel, 0, 0, 5);
|
||||
driverLayout.append(videoDriver, ~0, 0, 5);
|
||||
|
@ -48,7 +48,7 @@ AdvancedSettings::AdvancedSettings() {
|
|||
driverLayout.append(audioDriver, ~0, 0, 5);
|
||||
driverLayout.append(inputLabel, 0, 0, 5);
|
||||
driverLayout.append(inputDriver, ~0, 0);
|
||||
append(focusPolicyLabel, ~0, 0, 5);
|
||||
append(focusPolicyLabel, ~0, 0);
|
||||
append(focusPolicyLayout, ~0, 0, 5);
|
||||
focusPolicyLayout.append(focusPolicy[0], ~0, 0, 5);
|
||||
focusPolicyLayout.append(focusPolicy[1], ~0, 0, 5);
|
||||
|
|
|
@ -31,8 +31,8 @@ void WindowManager::loadGeometry() {
|
|||
for(auto &window : windowList) {
|
||||
config.attach(window.geometry, window.name);
|
||||
}
|
||||
config.load(string{ application->userpath, "geometry.cfg" });
|
||||
config.save(string{ application->userpath, "geometry.cfg" });
|
||||
config.load(application->path("geometry.cfg"));
|
||||
config.save(application->path("geometry.cfg"));
|
||||
for(auto &window : windowList) {
|
||||
window.window->setGeometry(geometry(window.geometry));
|
||||
}
|
||||
|
@ -42,5 +42,5 @@ void WindowManager::saveGeometry() {
|
|||
for(auto &window : windowList) {
|
||||
window.geometry = geometry(window.window->geometry());
|
||||
}
|
||||
config.save(string{ application->userpath, "geometry.cfg" });
|
||||
config.save(application->path("geometry.cfg"));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue