From e8b1af09179e43618b1b787c2f6774679e724f03 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Thu, 29 Sep 2011 22:08:22 +1000 Subject: [PATCH] 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 --- bsnes/nall/array.hpp | 12 ++-- bsnes/nall/atoi.hpp | 88 ++++++++++++++++++++++++++++ bsnes/nall/base64.hpp | 3 +- bsnes/nall/bit.hpp | 4 -- bsnes/nall/bps/delta.hpp | 2 +- bsnes/nall/compositor.hpp | 4 +- bsnes/nall/config.hpp | 4 +- bsnes/nall/detect.hpp | 30 ---------- bsnes/nall/directory.hpp | 5 +- bsnes/nall/dl.hpp | 6 +- bsnes/nall/endian.hpp | 8 ++- bsnes/nall/function.hpp | 10 ++-- bsnes/nall/gzip.hpp | 2 +- bsnes/nall/inflate.hpp | 8 +-- bsnes/nall/intrinsics.hpp | 60 +++++++++++++++++++ bsnes/nall/ips.hpp | 4 +- bsnes/nall/lzss.hpp | 4 +- bsnes/nall/png.hpp | 2 +- bsnes/nall/priorityqueue.hpp | 2 +- bsnes/nall/property.hpp | 2 +- bsnes/nall/reference_array.hpp | 6 +- bsnes/nall/string.hpp | 1 + bsnes/nall/string/base.hpp | 17 ++---- bsnes/nall/string/convert.hpp | 80 ------------------------- bsnes/nall/string/core.hpp | 4 +- bsnes/nall/string/utility.hpp | 2 +- bsnes/nall/vector.hpp | 24 ++++---- bsnes/nes/cartridge/board/board.cpp | 90 +++++++++++++++++++++++++++++ bsnes/nes/cartridge/board/board.hpp | 25 ++++++++ bsnes/nes/cartridge/board/nrom.cpp | 47 +++++++++++++++ bsnes/nes/cartridge/cartridge.cpp | 46 +++++++++++---- bsnes/nes/cartridge/cartridge.hpp | 6 +- bsnes/nes/nes.hpp | 1 - bsnes/nes/ppu/ppu.cpp | 15 +++-- bsnes/ruby/Makefile | 26 +++++++++ bsnes/ruby/ruby.hpp | 11 ++-- bsnes/ruby/ruby_impl.cpp | 4 +- bsnes/snes/snes.hpp | 1 - bsnes/ui/Makefile | 42 +++----------- bsnes/ui/base.hpp | 1 + bsnes/ui/config/config.cpp | 8 ++- bsnes/ui/config/config.hpp | 2 + bsnes/ui/general/file-browser.cpp | 8 +-- bsnes/ui/general/main-window.cpp | 6 +- bsnes/ui/input/input.cpp | 6 +- bsnes/ui/interface/nes.cpp | 5 +- bsnes/ui/main.cpp | 36 +++++++----- bsnes/ui/settings/advanced.cpp | 4 +- bsnes/ui/window/window.cpp | 6 +- 49 files changed, 511 insertions(+), 279 deletions(-) create mode 100755 bsnes/nall/atoi.hpp delete mode 100755 bsnes/nall/detect.hpp create mode 100755 bsnes/nall/intrinsics.hpp create mode 100755 bsnes/nes/cartridge/board/board.cpp create mode 100755 bsnes/nes/cartridge/board/board.hpp create mode 100755 bsnes/nes/cartridge/board/nrom.cpp create mode 100755 bsnes/ruby/Makefile diff --git a/bsnes/nall/array.hpp b/bsnes/nall/array.hpp index b9fb6699..96061660 100755 --- a/bsnes/nall/array.hpp +++ b/bsnes/nall/array.hpp @@ -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 list) : pool(0), poolsize(0), buffersize(0) { + array(std::initializer_list 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)); } diff --git a/bsnes/nall/atoi.hpp b/bsnes/nall/atoi.hpp new file mode 100755 index 00000000..cec3e72d --- /dev/null +++ b/bsnes/nall/atoi.hpp @@ -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 diff --git a/bsnes/nall/base64.hpp b/bsnes/nall/base64.hpp index ee59c1be..a0afd8b1 100755 --- a/bsnes/nall/base64.hpp +++ b/bsnes/nall/base64.hpp @@ -5,8 +5,7 @@ #include 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](); diff --git a/bsnes/nall/bit.hpp b/bsnes/nall/bit.hpp index b1f24573..67a35ad6 100755 --- a/bsnes/nall/bit.hpp +++ b/bsnes/nall/bit.hpp @@ -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 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); diff --git a/bsnes/nall/bps/delta.hpp b/bsnes/nall/bps/delta.hpp index a3af047c..6cee56a3 100755 --- a/bsnes/nall/bps/delta.hpp +++ b/bsnes/nall/bps/delta.hpp @@ -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; } }; diff --git a/bsnes/nall/compositor.hpp b/bsnes/nall/compositor.hpp index 6d5c46c9..ff6a6ea6 100755 --- a/bsnes/nall/compositor.hpp +++ b/bsnes/nall/compositor.hpp @@ -1,7 +1,7 @@ #ifndef NALL_COMPOSITOR_HPP #define NALL_COMPOSITOR_HPP -#include +#include 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"); diff --git a/bsnes/nall/config.hpp b/bsnes/nall/config.hpp index 99aaee08..0c6602df 100755 --- a/bsnes/nall/config.hpp +++ b/bsnes/nall/config.hpp @@ -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++) { diff --git a/bsnes/nall/detect.hpp b/bsnes/nall/detect.hpp deleted file mode 100755 index 85122fbd..00000000 --- a/bsnes/nall/detect.hpp +++ /dev/null @@ -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 diff --git a/bsnes/nall/directory.hpp b/bsnes/nall/directory.hpp index fbd1e93e..31ca1e05 100755 --- a/bsnes/nall/directory.hpp +++ b/bsnes/nall/directory.hpp @@ -1,11 +1,12 @@ #ifndef NALL_DIRECTORY_HPP #define NALL_DIRECTORY_HPP +#include #include #include #include -#if defined(_WIN32) +#if defined(PLATFORM_WINDOWS) #include #else #include @@ -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; diff --git a/bsnes/nall/dl.hpp b/bsnes/nall/dl.hpp index c697958c..3bd7d4d2 100755 --- a/bsnes/nall/dl.hpp +++ b/bsnes/nall/dl.hpp @@ -3,14 +3,14 @@ //dynamic linking support -#include +#include #include #include #include #if defined(PLATFORM_X) || defined(PLATFORM_OSX) #include -#elif defined(PLATFORM_WIN) +#elif defined(PLATFORM_WINDOWS) #include #include #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"); diff --git a/bsnes/nall/endian.hpp b/bsnes/nall/endian.hpp index 40d15633..1f834b5b 100755 --- a/bsnes/nall/endian.hpp +++ b/bsnes/nall/endian.hpp @@ -1,7 +1,9 @@ #ifndef NALL_ENDIAN_HPP #define NALL_ENDIAN_HPP -#if !defined(ARCH_MSB) +#include + +#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 diff --git a/bsnes/nall/function.hpp b/bsnes/nall/function.hpp index 35b76881..ca574b8c 100755 --- a/bsnes/nall/function.hpp +++ b/bsnes/nall/function.hpp @@ -36,19 +36,19 @@ namespace nall { public: operator bool() const { return callback; } R operator()(P... p) const { return (*callback)(std::forward

(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 function(R (C::*function)(P...), C *object) { callback = new member(function, object); } template function(R (C::*function)(P...) const, C *object) { callback = new member((R (C::*)(P...))function, object); } diff --git a/bsnes/nall/gzip.hpp b/bsnes/nall/gzip.hpp index 635d3277..8f5d206b 100755 --- a/bsnes/nall/gzip.hpp +++ b/bsnes/nall/gzip.hpp @@ -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() { diff --git a/bsnes/nall/inflate.hpp b/bsnes/nall/inflate.hpp index c989e3f1..cbbf6d29 100755 --- a/bsnes/nall/inflate.hpp +++ b/bsnes/nall/inflate.hpp @@ -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++; } diff --git a/bsnes/nall/intrinsics.hpp b/bsnes/nall/intrinsics.hpp new file mode 100755 index 00000000..45d25eb2 --- /dev/null +++ b/bsnes/nall/intrinsics.hpp @@ -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 diff --git a/bsnes/nall/ips.hpp b/bsnes/nall/ips.hpp index 87c7de25..3071d038 100755 --- a/bsnes/nall/ips.hpp +++ b/bsnes/nall/ips.hpp @@ -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() { diff --git a/bsnes/nall/lzss.hpp b/bsnes/nall/lzss.hpp index 147e1e62..521b36c6 100755 --- a/bsnes/nall/lzss.hpp +++ b/bsnes/nall/lzss.hpp @@ -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) { diff --git a/bsnes/nall/png.hpp b/bsnes/nall/png.hpp index 025044b2..a39c85c5 100755 --- a/bsnes/nall/png.hpp +++ b/bsnes/nall/png.hpp @@ -413,7 +413,7 @@ void png::alphaTransform(uint32_t rgb) { } } -png::png() : data(0), rawData(0) { +png::png() : data(nullptr), rawData(nullptr) { } png::~png() { diff --git a/bsnes/nall/priorityqueue.hpp b/bsnes/nall/priorityqueue.hpp index 7104e791..443eac21 100755 --- a/bsnes/nall/priorityqueue.hpp +++ b/bsnes/nall/priorityqueue.hpp @@ -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 class priority_queue { public: diff --git a/bsnes/nall/property.hpp b/bsnes/nall/property.hpp index 6fd33acd..665afcad 100755 --- a/bsnes/nall/property.hpp +++ b/bsnes/nall/property.hpp @@ -22,7 +22,7 @@ // readwrite 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: diff --git a/bsnes/nall/reference_array.hpp b/bsnes/nall/reference_array.hpp index 1095dbd0..b01ae8c0 100755 --- a/bsnes/nall/reference_array.hpp +++ b/bsnes/nall/reference_array.hpp @@ -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 reference_array(Args&... args) : pool(0), poolsize(0), buffersize(0) { + template 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; } diff --git a/bsnes/nall/string.hpp b/bsnes/nall/string.hpp index f8d1cc1d..3dcd53fa 100755 --- a/bsnes/nall/string.hpp +++ b/bsnes/nall/string.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include diff --git a/bsnes/nall/string/base.hpp b/bsnes/nall/string/base.hpp index bca5fb10..bb82872d 100755 --- a/bsnes/nall/string/base.hpp +++ b/bsnes/nall/string/base.hpp @@ -2,12 +2,11 @@ #define NALL_STRING_BASE_HPP namespace nall { - class string; - class lstring; + struct string; + struct lstring; template inline const char* to_string(T); - class string { - public: + struct string { inline void reserve(unsigned); template inline string& assign(Args&&... args); @@ -88,8 +87,7 @@ namespace nall { #endif }; - class lstring : public linear_vector { - public: + struct lstring : public linear_vector { template inline lstring& operator<<(T value); inline optional 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 inline string decimal(uintmax_t value); template inline string ldecimal(uintmax_t value); template inline string hex(uintmax_t value); - template inline string bin(uintmax_t value); + template inline string binary(uintmax_t value); inline unsigned fp(char *str, double value); inline string fp(double value); diff --git a/bsnes/nall/string/convert.hpp b/bsnes/nall/string/convert.hpp index 49be73c5..114d991b 100755 --- a/bsnes/nall/string/convert.hpp +++ b/bsnes/nall/string/convert.hpp @@ -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 diff --git a/bsnes/nall/string/core.hpp b/bsnes/nall/string/core.hpp index e2af4eea..d5c4e0d6 100755 --- a/bsnes/nall/string/core.hpp +++ b/bsnes/nall/string/core.hpp @@ -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() { diff --git a/bsnes/nall/string/utility.hpp b/bsnes/nall/string/utility.hpp index ad5653fe..485f528b 100755 --- a/bsnes/nall/string/utility.hpp +++ b/bsnes/nall/string/utility.hpp @@ -193,7 +193,7 @@ template string hex(uintmax_t value) { return (const char*)result; } -template string bin(uintmax_t value) { +template string binary(uintmax_t value) { char buffer[256]; unsigned size = 0; diff --git a/bsnes/nall/vector.hpp b/bsnes/nall/vector.hpp index ee6041a3..681d595f 100755 --- a/bsnes/nall/vector.hpp +++ b/bsnes/nall/vector.hpp @@ -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 list) : pool(0), poolsize(0), objectsize(0) { + linear_vector(std::initializer_list 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 &source) : pool(0), poolsize(0), objectsize(0) { + linear_vector(const linear_vector &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 &&source) : pool(0), poolsize(0), objectsize(0) { + linear_vector(linear_vector &&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 list) : pool(0), poolsize(0), objectsize(0) { + pointer_vector(std::initializer_list 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 &source) : pool(0), poolsize(0), objectsize(0) { + pointer_vector(const pointer_vector &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 &&source) : pool(0), poolsize(0), objectsize(0) { + pointer_vector(pointer_vector &&source) : pool(nullptr), poolsize(0), objectsize(0) { operator=(std::move(source)); } diff --git a/bsnes/nes/cartridge/board/board.cpp b/bsnes/nes/cartridge/board/board.cpp new file mode 100755 index 00000000..435725cf --- /dev/null +++ b/bsnes/nes/cartridge/board/board.cpp @@ -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({ "\n", configuration, "\n" }); + + return board; +} diff --git a/bsnes/nes/cartridge/board/board.hpp b/bsnes/nes/cartridge/board/board.hpp new file mode 100755 index 00000000..9530c51d --- /dev/null +++ b/bsnes/nes/cartridge/board/board.hpp @@ -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; +}; diff --git a/bsnes/nes/cartridge/board/nrom.cpp b/bsnes/nes/cartridge/board/nrom.cpp new file mode 100755 index 00000000..4af8eff9 --- /dev/null +++ b/bsnes/nes/cartridge/board/nrom.cpp @@ -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; diff --git a/bsnes/nes/cartridge/cartridge.cpp b/bsnes/nes/cartridge/cartridge.cpp index f568c800..44434355 100755 --- a/bsnes/nes/cartridge/cartridge.cpp +++ b/bsnes/nes/cartridge/cartridge.cpp @@ -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); diff --git a/bsnes/nes/cartridge/cartridge.hpp b/bsnes/nes/cartridge/cartridge.hpp index 3ed45b05..f22df099 100755 --- a/bsnes/nes/cartridge/cartridge.hpp +++ b/bsnes/nes/cartridge/cartridge.hpp @@ -1,3 +1,5 @@ +#include "board/board.hpp" + struct Cartridge : Processor, property { static void Main(); void main(); @@ -18,6 +20,7 @@ struct Cartridge : Processor, property { Cartridge(); //privileged: + Board *board; Mapper::Mapper *mapper; uint8 prg_read(unsigned addr); @@ -26,9 +29,6 @@ struct Cartridge : Processor, property { 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; diff --git a/bsnes/nes/nes.hpp b/bsnes/nes/nes.hpp index 7b71ea8e..171d0edc 100755 --- a/bsnes/nes/nes.hpp +++ b/bsnes/nes/nes.hpp @@ -19,7 +19,6 @@ namespace NES { #include #include -#include #include #include #include diff --git a/bsnes/nes/ppu/ppu.cpp b/bsnes/nes/ppu/ppu.cpp index 0d201211..05db6258 100755 --- a/bsnes/nes/ppu/ppu.cpp +++ b/bsnes/nes/ppu/ppu.cpp @@ -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(); diff --git a/bsnes/ruby/Makefile b/bsnes/ruby/Makefile new file mode 100755 index 00000000..1231bcd5 --- /dev/null +++ b/bsnes/ruby/Makefile @@ -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 diff --git a/bsnes/ruby/ruby.hpp b/bsnes/ruby/ruby.hpp index f6198d02..a8b08227 100755 --- a/bsnes/ruby/ruby.hpp +++ b/bsnes/ruby/ruby.hpp @@ -11,8 +11,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -24,8 +24,7 @@ namespace ruby { #include #include -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(); diff --git a/bsnes/ruby/ruby_impl.cpp b/bsnes/ruby/ruby_impl.cpp index ac517a1f..aca0e7af 100755 --- a/bsnes/ruby/ruby_impl.cpp +++ b/bsnes/ruby/ruby_impl.cpp @@ -7,7 +7,7 @@ #if defined(VIDEO_QTOPENGL) #include - #if defined(PLATFORM_WIN) + #if defined(PLATFORM_WINDOWS) #include #endif #endif @@ -19,7 +19,7 @@ #elif defined(PLATFORM_OSX) #define __INTEL_COMPILER #include -#elif defined(PLATFORM_WIN) +#elif defined(PLATFORM_WINDOWS) #define _WIN32_WINNT 0x0501 #include #endif diff --git a/bsnes/snes/snes.hpp b/bsnes/snes/snes.hpp index 70f2e000..cca2bf1c 100755 --- a/bsnes/snes/snes.hpp +++ b/bsnes/snes/snes.hpp @@ -20,7 +20,6 @@ namespace SNES { #include #include #include -#include #include #include #include diff --git a/bsnes/ui/Makefile b/bsnes/ui/Makefile index 9d39cd6b..31e1a7e4 100755 --- a/bsnes/ui/Makefile +++ b/bsnes/ui/Makefile @@ -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 diff --git a/bsnes/ui/base.hpp b/bsnes/ui/base.hpp index 8a86ff50..52c066d7 100755 --- a/bsnes/ui/base.hpp +++ b/bsnes/ui/base.hpp @@ -35,6 +35,7 @@ struct Application { string basepath; string userpath; + string path(const string &filename); string title; string normalFont; diff --git a/bsnes/ui/config/config.cpp b/bsnes/ui/config/config.cpp index e33ebe50..bcbc8076 100755 --- a/bsnes/ui/config/config.cpp +++ b/bsnes/ui/config/config.cpp @@ -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")); } diff --git a/bsnes/ui/config/config.hpp b/bsnes/ui/config/config.hpp index 482424b5..d8ffc3a6 100755 --- a/bsnes/ui/config/config.hpp +++ b/bsnes/ui/config/config.hpp @@ -12,6 +12,8 @@ struct Config : public configuration { unsigned gamma; bool gammaRamp; unsigned fullScreenMode; + + bool startFullScreen; } video; struct Audio { diff --git a/bsnes/ui/general/file-browser.cpp b/bsnes/ui/general/file-browser.cpp index 365a8236..d8be1ead 100755 --- a/bsnes/ui/general/file-browser.cpp +++ b/bsnes/ui/general/file-browser.cpp @@ -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 requestedCallback) { diff --git a/bsnes/ui/general/main-window.cpp b/bsnes/ui/general/main-window.cpp index 9757d996..e4b8e31d 100755 --- a/bsnes/ui/general/main-window.cpp +++ b/bsnes/ui/general/main-window.cpp @@ -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 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 group; settingsVideoShaderList = new RadioItem[files.size()]; diff --git a/bsnes/ui/input/input.cpp b/bsnes/ui/input/input.cpp index 02724ff1..a7d62dcb 100755 --- a/bsnes/ui/input/input.cpp +++ b/bsnes/ui/input/input.cpp @@ -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")); } diff --git a/bsnes/ui/interface/nes.cpp b/bsnes/ui/interface/nes.cpp index 3d46b150..608a02bd 100755 --- a/bsnes/ui/interface/nes.cpp +++ b/bsnes/ui/interface/nes.cpp @@ -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) { diff --git a/bsnes/ui/main.cpp b/bsnes/ui/main.cpp index 91ce9222..e496a0f7 100755 --- a/bsnes/ui/main.cpp +++ b/bsnes/ui/main.cpp @@ -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) { diff --git a/bsnes/ui/settings/advanced.cpp b/bsnes/ui/settings/advanced.cpp index f797f0c6..2066abaf 100755 --- a/bsnes/ui/settings/advanced.cpp +++ b/bsnes/ui/settings/advanced.cpp @@ -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); diff --git a/bsnes/ui/window/window.cpp b/bsnes/ui/window/window.cpp index f867bc0c..dec01b68 100755 --- a/bsnes/ui/window/window.cpp +++ b/bsnes/ui/window/window.cpp @@ -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")); }