mirror of https://github.com/bsnes-emu/bsnes.git
Update to bsnes v065r03 release.
Polishing work. My dlopen wrapper accepts an optional path argument now, and the basename setting is universal instead of just for MSU1, so serial-based games can load in a dynamic client library directly. Still need to update snesserver to accept another argument for the program library name to load. Upped the serial polling frequency to 8x UART speed per blargg. And a very tricky change, I updated nall/string to remove sprint(). At first, I used: string name = string() << path << basename << ".msu"; I then improved upon that with: string name = sprint(path, basename, ".msu"); Tonight I went ahead and finished this by taking advantage of variadic templates for the constructor itself. Very tricky because my conversion functions created new strings to copy data into, which would create an infinite loop; then of course I also had to leave the copy constructor behind even after this. So the end result is the following: string name(path, basename, ".msu"); Oh, and I found a typo in MSU1, it wasn't using the proper extension when loading a save state for the data file.
This commit is contained in:
parent
20b44ddfd1
commit
dce3e61f06
|
@ -3,9 +3,9 @@
|
|||
|
||||
//dynamic linking support
|
||||
|
||||
#include <string.h>
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
#if defined(PLATFORM_X) || defined(PLATFORM_OSX)
|
||||
|
@ -18,7 +18,7 @@
|
|||
namespace nall {
|
||||
struct library {
|
||||
bool opened() const { return handle; }
|
||||
bool open(const char*);
|
||||
bool open(const char*, const char* = "");
|
||||
void* sym(const char*);
|
||||
void close();
|
||||
|
||||
|
@ -33,20 +33,10 @@ namespace nall {
|
|||
};
|
||||
|
||||
#if defined(PLATFORM_X)
|
||||
inline bool library::open(const char *name) {
|
||||
inline bool library::open(const char *name, const char *path) {
|
||||
if(handle) close();
|
||||
char *t = new char[strlen(name) + 256];
|
||||
strcpy(t, "lib");
|
||||
strcat(t, name);
|
||||
strcat(t, ".so");
|
||||
handle = (uintptr_t)dlopen(t, RTLD_LAZY);
|
||||
if(!handle) {
|
||||
strcpy(t, "/usr/local/lib/lib");
|
||||
strcat(t, name);
|
||||
strcat(t, ".so");
|
||||
handle = (uintptr_t)dlopen(t, RTLD_LAZY);
|
||||
}
|
||||
delete[] t;
|
||||
handle = (uintptr_t)dlopen(string(path, *path && !strend(path, "/") ? "/" : "", "lib", name, ".so"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".so"), RTLD_LAZY);
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -61,20 +51,10 @@ namespace nall {
|
|||
handle = 0;
|
||||
}
|
||||
#elif defined(PLATFORM_OSX)
|
||||
inline bool library::open(const char *name) {
|
||||
inline bool library::open(const char *name, const char *path) {
|
||||
if(handle) close();
|
||||
char *t = new char[strlen(name) + 256];
|
||||
strcpy(t, "lib");
|
||||
strcat(t, name);
|
||||
strcat(t, ".dylib");
|
||||
handle = (uintptr_t)dlopen(t, RTLD_LAZY);
|
||||
if(!handle) {
|
||||
strcpy(t, "/usr/local/lib/lib");
|
||||
strcat(t, name);
|
||||
strcat(t, ".dylib");
|
||||
handle = (uintptr_t)dlopen(t, RTLD_LAZY);
|
||||
}
|
||||
delete[] t;
|
||||
handle = (uintptr_t)dlopen(string(path, *path && !strend(path, "/") ? "/" : "", "lib", name, ".dylib"), RTLD_LAZY);
|
||||
if(!handle) handle = (uintptr_t)dlopen(string("/usr/local/lib/lib", name, ".dylib"), RTLD_LAZY);
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -89,13 +69,10 @@ namespace nall {
|
|||
handle = 0;
|
||||
}
|
||||
#elif defined(PLATFORM_WIN)
|
||||
inline bool library::open(const char *name) {
|
||||
inline bool library::open(const char *name, const char *path) {
|
||||
if(handle) close();
|
||||
char *t = new char[strlen(name) + 8];
|
||||
strcpy(t, name);
|
||||
strcat(t, ".dll");
|
||||
handle = (uintptr_t)LoadLibraryW(utf16_t(t));
|
||||
delete[] t;
|
||||
string filepath(path, *path && !strend(path, "/") && !strend(path, "\\") ? "\\" : "", name, ".dll");
|
||||
handle = (uintptr_t)LoadLibraryW(utf16_t(filepath));
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -110,7 +87,7 @@ namespace nall {
|
|||
handle = 0;
|
||||
}
|
||||
#else
|
||||
inline bool library::open(const char*) { return false; }
|
||||
inline bool library::open(const char*, const char*) { return false; }
|
||||
inline void* library::sym(const char*) { return 0; }
|
||||
inline void library::close() {}
|
||||
#endif
|
||||
|
|
|
@ -23,10 +23,12 @@
|
|||
#include <direct.h>
|
||||
#include <shlobj.h>
|
||||
#undef interface
|
||||
#define dllexport __declspec(dllexport)
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/stat.h>
|
||||
#define dllexport
|
||||
#endif
|
||||
|
||||
//==================
|
||||
|
|
|
@ -21,6 +21,11 @@ namespace nall {
|
|||
|
||||
inline string& assign(const char*);
|
||||
inline string& append(const char*);
|
||||
inline string& append(bool);
|
||||
inline string& append(signed int value);
|
||||
inline string& append(unsigned int value);
|
||||
inline string& append(double value);
|
||||
|
||||
template<typename T> inline string& operator= (T value);
|
||||
template<typename T> inline string& operator<<(T value);
|
||||
|
||||
|
@ -38,8 +43,7 @@ namespace nall {
|
|||
inline string& operator=(const string&);
|
||||
inline string& operator=(string&&);
|
||||
|
||||
inline string();
|
||||
inline string(const char*);
|
||||
template<typename... Args> inline string(Args... args);
|
||||
inline string(const string&);
|
||||
inline string(string&&);
|
||||
inline ~string();
|
||||
|
@ -129,7 +133,6 @@ namespace nall {
|
|||
inline string strdouble(double value);
|
||||
|
||||
//variadic.hpp
|
||||
template<typename... Args> inline string sprint(Args... args);
|
||||
template<typename... Args> inline void print(Args... args);
|
||||
};
|
||||
|
||||
|
|
|
@ -29,6 +29,11 @@ string& string::append(const char *s) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
string& string::append(bool value) { append(value ? "true" : "false"); return *this; }
|
||||
string& string::append(signed int value) { append(strsigned(value)); return *this; }
|
||||
string& string::append(unsigned int value) { append(strunsigned(value)); return *this; }
|
||||
string& string::append(double value) { append(strdouble(value)); return *this; }
|
||||
|
||||
string::operator const char*() const {
|
||||
return data;
|
||||
}
|
||||
|
@ -63,15 +68,20 @@ string& string::operator=(string &&source) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
string::string() {
|
||||
static void istring(string &output) {
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static void istring(string &output, T value, Args... args) {
|
||||
output.append(value);
|
||||
istring(output, args...);
|
||||
}
|
||||
|
||||
template<typename... Args> string::string(Args... args) {
|
||||
size = 64;
|
||||
data = (char*)malloc(size + 1);
|
||||
*data = 0;
|
||||
}
|
||||
|
||||
string::string(const char *value) {
|
||||
size = strlen(value);
|
||||
data = strdup(value);
|
||||
istring(*this, args...);
|
||||
}
|
||||
|
||||
string::string(const string &value) {
|
||||
|
@ -86,7 +96,7 @@ string::string(string &&source) {
|
|||
}
|
||||
|
||||
string::~string() {
|
||||
free(data);
|
||||
if(data) free(data);
|
||||
}
|
||||
|
||||
bool string::readfile(const char *filename) {
|
||||
|
|
|
@ -3,23 +3,8 @@
|
|||
|
||||
namespace nall {
|
||||
|
||||
static void isprint(string &output) {
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static void isprint(string &output, T value, Args... args) {
|
||||
output << to_string<T>(value);
|
||||
isprint(output, args...);
|
||||
}
|
||||
|
||||
template<typename... Args> inline string sprint(Args... args) {
|
||||
string output;
|
||||
isprint(output, args...);
|
||||
return output;
|
||||
}
|
||||
|
||||
template<typename... Args> inline void print(Args... args) {
|
||||
printf("%s", (const char*)sprint(args...));
|
||||
printf("%s", (const char*)string(args...));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@ public:
|
|||
Version2,
|
||||
};
|
||||
|
||||
//assigned externally to point to file-system datafiles (msu1 and serial)
|
||||
//example: "/path/to/filename.sfc" would set this to "/path/to/filename"
|
||||
readwrite<string> basename;
|
||||
|
||||
readonly<bool> loaded;
|
||||
readonly<unsigned> crc32;
|
||||
readonly<string> sha256;
|
||||
|
|
|
@ -125,7 +125,7 @@ bool Cheat::encode(string &s, unsigned addr, uint8 data, Type type) {
|
|||
char t[16];
|
||||
|
||||
if(type == Type::ProActionReplay) {
|
||||
s = sprint(strhex<6>(addr), strhex<2>(data));
|
||||
s = string(strhex<6>(addr), strhex<2>(data));
|
||||
return true;
|
||||
} else if(type == Type::GameGenie) {
|
||||
unsigned r = addr;
|
||||
|
@ -141,7 +141,7 @@ bool Cheat::encode(string &s, unsigned addr, uint8 data, Type type) {
|
|||
| (!!(r & 0x080000) << 5) | (!!(r & 0x040000) << 4)
|
||||
| (!!(r & 0x020000) << 3) | (!!(r & 0x010000) << 2)
|
||||
| (!!(r & 0x000800) << 1) | (!!(r & 0x000400) << 0);
|
||||
s = sprint(strhex<2>(data), strhex<2>(addr >> 16), "-", strhex<4>(addr & 0xffff));
|
||||
s = string(strhex<2>(data), strhex<2>(addr >> 16), "-", strhex<4>(addr & 0xffff));
|
||||
strtr(s, "0123456789abcdef", "df4709156bc8a23e");
|
||||
return true;
|
||||
} else {
|
||||
|
|
|
@ -49,7 +49,7 @@ void MSU1::enable() {
|
|||
audio.coprocessor_frequency(44100.0);
|
||||
|
||||
if(datafile.open()) datafile.close();
|
||||
datafile.open(string() << basename << ".msu", file::mode_read);
|
||||
datafile.open(string() << cartridge.basename() << ".msu", file::mode_read);
|
||||
}
|
||||
|
||||
void MSU1::power() {
|
||||
|
@ -125,7 +125,7 @@ void MSU1::mmio_write(unsigned addr, uint8 data) {
|
|||
if(audiofile.open()) audiofile.close();
|
||||
char track[16];
|
||||
sprintf(track, "-%u", mmio.audio_track);
|
||||
if(audiofile.open(string() << basename << track << ".wav", file::mode_read)) {
|
||||
if(audiofile.open(string() << cartridge.basename() << track << ".wav", file::mode_read)) {
|
||||
audiofile.seek(mmio.audio_offset = 58); //skip WAV header
|
||||
}
|
||||
mmio.audio_busy = false;
|
||||
|
@ -143,8 +143,4 @@ void MSU1::mmio_write(unsigned addr, uint8 data) {
|
|||
}
|
||||
}
|
||||
|
||||
void MSU1::base(const string& name) {
|
||||
basename = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,11 +10,9 @@ public:
|
|||
uint8 mmio_read(unsigned addr);
|
||||
void mmio_write(unsigned addr, uint8 data);
|
||||
|
||||
void base(const string &name);
|
||||
void serialize(serializer&);
|
||||
|
||||
private:
|
||||
string basename;
|
||||
file datafile;
|
||||
file audiofile;
|
||||
|
||||
|
|
|
@ -11,14 +11,14 @@ void MSU1::serialize(serializer &s) {
|
|||
s.integer(mmio.audio_play);
|
||||
|
||||
if(datafile.open()) datafile.close();
|
||||
if(datafile.open(string() << basename << ".msun", file::mode_read)) {
|
||||
if(datafile.open(string() << cartridge.basename() << ".msu", file::mode_read)) {
|
||||
datafile.seek(mmio.data_offset);
|
||||
}
|
||||
|
||||
if(audiofile.open()) audiofile.close();
|
||||
char track[16];
|
||||
sprintf(track, "-%u", mmio.audio_track);
|
||||
if(audiofile.open(string() << basename << track << ".wav", file::mode_read)) {
|
||||
if(audiofile.open(string() << cartridge.basename() << track << ".wav", file::mode_read)) {
|
||||
audiofile.seek(mmio.audio_offset);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,16 +5,16 @@ namespace SNES {
|
|||
|
||||
Serial serial;
|
||||
|
||||
static void snesserial_tick(unsigned clocks) { serial.add_clocks(clocks); }
|
||||
static void snesserial_tick(unsigned clocks) { serial.add_clocks(clocks * 8); }
|
||||
static uint8 snesserial_read() { return serial.read(); }
|
||||
static void snesserial_write(uint8 data) { serial.write(data); }
|
||||
|
||||
void Serial::enter() {
|
||||
scheduler.clock.cop_freq = cartridge.serial_baud_rate() * 4;
|
||||
scheduler.clock.cop_freq = cartridge.serial_baud_rate() * 8; //over-sample for edge detection
|
||||
latch = 0;
|
||||
add_clocks(256 * 4);
|
||||
add_clocks(256 * 8); //warm-up
|
||||
if(snesserial_main) snesserial_main(snesserial_tick, snesserial_read, snesserial_write);
|
||||
while(true) add_clocks(scheduler.clock.cop_freq);
|
||||
while(true) add_clocks(scheduler.clock.cop_freq); //snesserial_main() fallback
|
||||
}
|
||||
|
||||
void Serial::add_clocks(unsigned clocks) {
|
||||
|
@ -25,11 +25,11 @@ void Serial::add_clocks(unsigned clocks) {
|
|||
uint8 Serial::read() {
|
||||
while(cpu.joylatch() == 0) add_clocks(1);
|
||||
while(cpu.joylatch() == 1) add_clocks(1);
|
||||
add_clocks(2);
|
||||
add_clocks(4);
|
||||
|
||||
uint8 data = 0;
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
add_clocks(4);
|
||||
add_clocks(8);
|
||||
data = (cpu.joylatch() << 7) | (data >> 1);
|
||||
}
|
||||
|
||||
|
@ -38,16 +38,16 @@ uint8 Serial::read() {
|
|||
|
||||
void Serial::write(uint8 data) {
|
||||
latch = 1;
|
||||
add_clocks(4);
|
||||
add_clocks(8);
|
||||
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
latch = (data & 0x01) ^ 1;
|
||||
latch = (data & 1) ^ 1;
|
||||
data >>= 1;
|
||||
add_clocks(4);
|
||||
add_clocks(8);
|
||||
}
|
||||
|
||||
latch = 0;
|
||||
add_clocks(4);
|
||||
add_clocks(8);
|
||||
}
|
||||
|
||||
void Serial::init() {
|
||||
|
@ -55,7 +55,9 @@ void Serial::init() {
|
|||
|
||||
void Serial::enable() {
|
||||
if(opened()) close();
|
||||
if(open("snesserial")) {
|
||||
string name = notdir(cartridge.basename());
|
||||
string path = dir(cartridge.basename());
|
||||
if(open(name, path)) {
|
||||
snesserial_main = sym("snesserial_main");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@ bool CPUDebugger::property(unsigned id, string &name, string &value) {
|
|||
unsigned n = 0;
|
||||
|
||||
//internal
|
||||
if(id == n++) { name = "S-CPU MDR"; value = sprint("0x", strhex<2>(mdr())); return true; }
|
||||
if(id == n++) { name = "S-CPU MDR"; value = string("0x", strhex<2>(mdr())); return true; }
|
||||
|
||||
//$2181-2183
|
||||
if(id == n++) { name = "$2181-$2183"; value = ""; return true; }
|
||||
if(id == n++) { name = "WRAM Address"; value = sprint("0x", strhex<6>(wram_address())); return true; }
|
||||
if(id == n++) { name = "WRAM Address"; value = string("0x", strhex<6>(wram_address())); return true; }
|
||||
|
||||
//$4016
|
||||
if(id == n++) { name = "$4016"; value = ""; return true; }
|
||||
|
@ -23,39 +23,39 @@ bool CPUDebugger::property(unsigned id, string &name, string &value) {
|
|||
|
||||
//$4201
|
||||
if(id == n++) { name = "$4201"; value = ""; return true; }
|
||||
if(id == n++) { name = "PIO"; value = sprint("0x", strhex<2>(pio_bits())); return true; }
|
||||
if(id == n++) { name = "PIO"; value = string("0x", strhex<2>(pio_bits())); return true; }
|
||||
|
||||
//$4202
|
||||
if(id == n++) { name = "$4202"; value = ""; return true; }
|
||||
if(id == n++) { name = "Multiplicand"; value = sprint("0x", strhex<2>(multiplicand())); return true; }
|
||||
if(id == n++) { name = "Multiplicand"; value = string("0x", strhex<2>(multiplicand())); return true; }
|
||||
|
||||
//$4203
|
||||
if(id == n++) { name = "$4203"; value = ""; return true; }
|
||||
if(id == n++) { name = "Multiplier"; value = sprint("0x", strhex<2>(multiplier())); return true; }
|
||||
if(id == n++) { name = "Multiplier"; value = string("0x", strhex<2>(multiplier())); return true; }
|
||||
|
||||
//$4204-$4205
|
||||
if(id == n++) { name = "$4204-$4205"; value = ""; return true; }
|
||||
if(id == n++) { name = "Dividend"; value = sprint("0x", strhex<4>(dividend())); return true; }
|
||||
if(id == n++) { name = "Dividend"; value = string("0x", strhex<4>(dividend())); return true; }
|
||||
|
||||
//$4206
|
||||
if(id == n++) { name = "$4206"; value = ""; return true; }
|
||||
if(id == n++) { name = "Divisor"; value = sprint("0x", strhex<2>(divisor())); return true; }
|
||||
if(id == n++) { name = "Divisor"; value = string("0x", strhex<2>(divisor())); return true; }
|
||||
|
||||
//$4207-$4208
|
||||
if(id == n++) { name = "$4207-$4208"; value = ""; return true; }
|
||||
if(id == n++) { name = "H-Time"; value = sprint("0x", strhex<4>(htime())); return true; }
|
||||
if(id == n++) { name = "H-Time"; value = string("0x", strhex<4>(htime())); return true; }
|
||||
|
||||
//$4209-$420a
|
||||
if(id == n++) { name = "$4209-$420a"; value = ""; return true; }
|
||||
if(id == n++) { name = "V-Time"; value = sprint("0x", strhex<4>(vtime())); return true; }
|
||||
if(id == n++) { name = "V-Time"; value = string("0x", strhex<4>(vtime())); return true; }
|
||||
|
||||
//$420b
|
||||
if(id == n++) { name = "$420b"; value = ""; return true; }
|
||||
if(id == n++) { name = "DMA Enable"; value = sprint("0x", strhex<2>(dma_enable())); return true; }
|
||||
if(id == n++) { name = "DMA Enable"; value = string("0x", strhex<2>(dma_enable())); return true; }
|
||||
|
||||
//$420c
|
||||
if(id == n++) { name = "$420c"; value = ""; return true; }
|
||||
if(id == n++) { name = "HDMA Enable"; value = sprint("0x", strhex<2>(hdma_enable())); return true; }
|
||||
if(id == n++) { name = "HDMA Enable"; value = string("0x", strhex<2>(hdma_enable())); return true; }
|
||||
|
||||
//$420d
|
||||
if(id == n++) { name = "$420d"; value = ""; return true; }
|
||||
|
@ -72,25 +72,25 @@ bool CPUDebugger::property(unsigned id, string &name, string &value) {
|
|||
if(id == n++) { name = "Transfer Mode"; value = dma_transfer_mode(i); return true; }
|
||||
|
||||
//$43x1
|
||||
if(id == n++) { name = "B-Bus Address"; value = sprint("0x", strhex<4>(dma_bbus_address(i))); return true; }
|
||||
if(id == n++) { name = "B-Bus Address"; value = string("0x", strhex<4>(dma_bbus_address(i))); return true; }
|
||||
|
||||
//$43x2-$43x3
|
||||
if(id == n++) { name = "A-Bus Address"; value = sprint("0x", strhex<4>(dma_abus_address(i))); return true; }
|
||||
if(id == n++) { name = "A-Bus Address"; value = string("0x", strhex<4>(dma_abus_address(i))); return true; }
|
||||
|
||||
//$43x4
|
||||
if(id == n++) { name = "A-Bus Bank"; value = sprint("0x", strhex<2>(dma_abus_bank(i))); return true; }
|
||||
if(id == n++) { name = "A-Bus Bank"; value = string("0x", strhex<2>(dma_abus_bank(i))); return true; }
|
||||
|
||||
//$43x5-$43x6
|
||||
if(id == n++) { name = "Transfer Size / Indirect Address"; value = sprint("0x", strhex<4>(dma_transfer_size(i))); return true; }
|
||||
if(id == n++) { name = "Transfer Size / Indirect Address"; value = string("0x", strhex<4>(dma_transfer_size(i))); return true; }
|
||||
|
||||
//$43x7
|
||||
if(id == n++) { name = "Indirect Bank"; value = sprint("0x", strhex<2>(dma_indirect_bank(i))); return true; }
|
||||
if(id == n++) { name = "Indirect Bank"; value = string("0x", strhex<2>(dma_indirect_bank(i))); return true; }
|
||||
|
||||
//$43x8-$43x9
|
||||
if(id == n++) { name = "Table Address"; value = sprint("0x", strhex<4>(dma_table_address(i))); return true; }
|
||||
if(id == n++) { name = "Table Address"; value = string("0x", strhex<4>(dma_table_address(i))); return true; }
|
||||
|
||||
//$43xa
|
||||
if(id == n++) { name = "Line Counter"; value = sprint("0x", strhex<2>(dma_line_counter(i))); return true; }
|
||||
if(id == n++) { name = "Line Counter"; value = string("0x", strhex<2>(dma_line_counter(i))); return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -7,39 +7,39 @@ bool DSPDebugger::property(unsigned id, string &name, string &value) {
|
|||
if(id == n++) { name = "Main Volume - Right"; value = main_volume_right(); return true; }
|
||||
if(id == n++) { name = "Echo Volume - Left"; value = echo_volume_left(); return true; }
|
||||
if(id == n++) { name = "Echo Volume - Right"; value = echo_volume_right(); return true; }
|
||||
if(id == n++) { name = "Key On"; value = sprint("0x", strhex<2>(key_on())); return true; }
|
||||
if(id == n++) { name = "Key Off"; value = sprint("0x", strhex<2>(key_off())); return true; }
|
||||
if(id == n++) { name = "Key On"; value = string("0x", strhex<2>(key_on())); return true; }
|
||||
if(id == n++) { name = "Key Off"; value = string("0x", strhex<2>(key_off())); return true; }
|
||||
if(id == n++) { name = "Flag - Reset"; value = flag_reset(); return true; }
|
||||
if(id == n++) { name = "Flag - Mute"; value = flag_mute(); return true; }
|
||||
if(id == n++) { name = "Flag - Echo Disable"; value = flag_echo_disable(); return true; }
|
||||
if(id == n++) { name = "Flag - Noise Clock"; value = flag_noise_clock(); return true; }
|
||||
if(id == n++) { name = "Source End Block"; value = source_end_block(); return true; }
|
||||
if(id == n++) { name = "Echo Feedback"; value = echo_feedback(); return true; }
|
||||
if(id == n++) { name = "Pitch Modulation Enable"; value = sprint("0x", strhex<2>(pitch_modulation_enable())); return true; }
|
||||
if(id == n++) { name = "Noise Enable"; value = sprint("0x", strhex<2>(noise_enable())); return true; }
|
||||
if(id == n++) { name = "Echo Enable"; value = sprint("0x", strhex<2>(echo_enable())); return true; }
|
||||
if(id == n++) { name = "Pitch Modulation Enable"; value = string("0x", strhex<2>(pitch_modulation_enable())); return true; }
|
||||
if(id == n++) { name = "Noise Enable"; value = string("0x", strhex<2>(noise_enable())); return true; }
|
||||
if(id == n++) { name = "Echo Enable"; value = string("0x", strhex<2>(echo_enable())); return true; }
|
||||
if(id == n++) { name = "Source Directory"; value = source_directory(); return true; }
|
||||
if(id == n++) { name = "Echo Start Address"; value = echo_start_address(); return true; }
|
||||
if(id == n++) { name = "Echo Directory"; value = echo_directory(); return true; }
|
||||
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
if(id == n++) {
|
||||
name = string() << "Coefficient " << i;
|
||||
value = sprint("0x", strhex<2>(echo_filter_coefficient(i)));
|
||||
name = string("Coefficient ", i);
|
||||
value = string("0x", strhex<2>(echo_filter_coefficient(i)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
if(id == n++) {
|
||||
name = string() << "Voice " << i;
|
||||
name = string("Voice ", i);
|
||||
value = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
if(id == n++) { name = "Volume - Left"; value = voice_volume_left(i); return true; }
|
||||
if(id == n++) { name = "Volume - Right"; value = voice_volume_right(i); return true; }
|
||||
if(id == n++) { name = "Pitch Height"; value = sprint("0x", strhex<4>(voice_pitch_height(i))); return true; }
|
||||
if(id == n++) { name = "Pitch Height"; value = string("0x", strhex<4>(voice_pitch_height(i))); return true; }
|
||||
if(id == n++) { name = "Source Number"; value = voice_source_number(i); return true; }
|
||||
if(id == n++) { name = "ADSR1"; value = voice_adsr1(i); return true; }
|
||||
if(id == n++) { name = "ADSR2"; value = voice_adsr2(i); return true; }
|
||||
|
|
|
@ -4,8 +4,8 @@ bool PPUDebugger::property(unsigned id, string &name, string &value) {
|
|||
unsigned n = 0;
|
||||
|
||||
//internal
|
||||
if(id == n++) { name = "S-PPU1 MDR"; value = sprint("0x", strhex<2>(ppu1_mdr())); return true; }
|
||||
if(id == n++) { name = "S-PPU2 MDR"; value = sprint("0x", strhex<2>(ppu2_mdr())); return true; }
|
||||
if(id == n++) { name = "S-PPU1 MDR"; value = string("0x", strhex<2>(ppu1_mdr())); return true; }
|
||||
if(id == n++) { name = "S-PPU2 MDR"; value = string("0x", strhex<2>(ppu2_mdr())); return true; }
|
||||
|
||||
//$2100
|
||||
if(id == n++) { name = "$2100"; value = ""; return true; }
|
||||
|
@ -16,11 +16,11 @@ bool PPUDebugger::property(unsigned id, string &name, string &value) {
|
|||
if(id == n++) { name = "$2101"; value = ""; return true; }
|
||||
if(id == n++) { name = "OAM Base Size"; value = oam_base_size(); return true; }
|
||||
if(id == n++) { name = "OAM Name Select"; value = oam_name_select(); return true; }
|
||||
if(id == n++) { name = "OAM Name Base Address"; value = sprint("0x", strhex<4>(oam_name_base_address())); return true; }
|
||||
if(id == n++) { name = "OAM Name Base Address"; value = string("0x", strhex<4>(oam_name_base_address())); return true; }
|
||||
|
||||
//$2102-$2103
|
||||
if(id == n++) { name = "$2102-$2103"; value = ""; return true; }
|
||||
if(id == n++) { name = "OAM Base Address"; value = sprint("0x", strhex<4>(oam_base_address())); return true; }
|
||||
if(id == n++) { name = "OAM Base Address"; value = string("0x", strhex<4>(oam_base_address())); return true; }
|
||||
if(id == n++) { name = "OAM Priority"; value = oam_priority(); return true; }
|
||||
|
||||
//$2105
|
||||
|
@ -44,33 +44,33 @@ bool PPUDebugger::property(unsigned id, string &name, string &value) {
|
|||
|
||||
//$2107
|
||||
if(id == n++) { name = "$2107"; value = ""; return true; }
|
||||
if(id == n++) { name = "BG1 Screen Address"; value = sprint("0x", strhex<4>(bg1_screen_address())); return true; }
|
||||
if(id == n++) { name = "BG1 Screen Address"; value = string("0x", strhex<4>(bg1_screen_address())); return true; }
|
||||
if(id == n++) { name = "BG1 Screen Size"; value = screen_size[bg1_screen_size()]; return true; }
|
||||
|
||||
//$2108
|
||||
if(id == n++) { name = "$2108"; value = ""; return true; }
|
||||
if(id == n++) { name = "BG2 Screen Address"; value = sprint("0x", strhex<4>(bg2_screen_address())); return true; }
|
||||
if(id == n++) { name = "BG2 Screen Address"; value = string("0x", strhex<4>(bg2_screen_address())); return true; }
|
||||
if(id == n++) { name = "BG2 Screen Size"; value = screen_size[bg2_screen_size()]; return true; }
|
||||
|
||||
//$2109
|
||||
if(id == n++) { name = "$2109"; value = ""; return true; }
|
||||
if(id == n++) { name = "BG3 Screen Address"; value = sprint("0x", strhex<4>(bg3_screen_address())); return true; }
|
||||
if(id == n++) { name = "BG3 Screen Address"; value = string("0x", strhex<4>(bg3_screen_address())); return true; }
|
||||
if(id == n++) { name = "BG3 Screen Size"; value = screen_size[bg3_screen_size()]; return true; }
|
||||
|
||||
//$210a
|
||||
if(id == n++) { name = "$210a"; value = ""; return true; }
|
||||
if(id == n++) { name = "BG4 Screen Address"; value = sprint("0x", strhex<4>(bg4_screen_address())); return true; }
|
||||
if(id == n++) { name = "BG4 Screen Address"; value = string("0x", strhex<4>(bg4_screen_address())); return true; }
|
||||
if(id == n++) { name = "BG4 Screen Size"; value = screen_size[bg4_screen_size()]; return true; }
|
||||
|
||||
//$210b
|
||||
if(id == n++) { name = "$210b"; value = ""; return true; }
|
||||
if(id == n++) { name = "BG1 Name Base Address"; value = sprint("0x", strhex<4>(bg1_name_base_address())); return true; }
|
||||
if(id == n++) { name = "BG2 Name Base Address"; value = sprint("0x", strhex<4>(bg2_name_base_address())); return true; }
|
||||
if(id == n++) { name = "BG1 Name Base Address"; value = string("0x", strhex<4>(bg1_name_base_address())); return true; }
|
||||
if(id == n++) { name = "BG2 Name Base Address"; value = string("0x", strhex<4>(bg2_name_base_address())); return true; }
|
||||
|
||||
//$210c
|
||||
if(id == n++) { name = "$210c"; value = ""; return true; }
|
||||
if(id == n++) { name = "BG3 Name Base Address"; value = sprint("0x", strhex<4>(bg3_name_base_address())); return true; }
|
||||
if(id == n++) { name = "BG4 Name Base Address"; value = sprint("0x", strhex<4>(bg4_name_base_address())); return true; }
|
||||
if(id == n++) { name = "BG3 Name Base Address"; value = string("0x", strhex<4>(bg3_name_base_address())); return true; }
|
||||
if(id == n++) { name = "BG4 Name Base Address"; value = string("0x", strhex<4>(bg4_name_base_address())); return true; }
|
||||
|
||||
//$210d
|
||||
if(id == n++) { name = "$210d"; value = ""; return true; }
|
||||
|
@ -114,7 +114,7 @@ bool PPUDebugger::property(unsigned id, string &name, string &value) {
|
|||
|
||||
//$2116-$2117
|
||||
if(id == n++) { name = "$2116-$2117"; value = ""; return true; }
|
||||
if(id == n++) { name = "VRAM Address"; value = sprint("0x", strhex<4>(vram_address())); return true; }
|
||||
if(id == n++) { name = "VRAM Address"; value = string("0x", strhex<4>(vram_address())); return true; }
|
||||
|
||||
//$211a
|
||||
if(id == n++) { name = "$211a"; value = ""; return true; }
|
||||
|
@ -148,7 +148,7 @@ bool PPUDebugger::property(unsigned id, string &name, string &value) {
|
|||
|
||||
//$2121
|
||||
if(id == n++) { name = "$2121"; value = ""; return true; }
|
||||
if(id == n++) { name = "CGRAM Address"; value = sprint("0x", strhex<4>(cgram_address())); return true; }
|
||||
if(id == n++) { name = "CGRAM Address"; value = string("0x", strhex<4>(cgram_address())); return true; }
|
||||
|
||||
//$2123
|
||||
if(id == n++) { name = "$2123"; value = ""; return true; }
|
||||
|
|
|
@ -17,7 +17,7 @@ bool SMPDebugger::property(unsigned id, string &name, string &value) {
|
|||
|
||||
//$00f2
|
||||
if(id == n++) { name = "$00f2"; value = ""; return true; }
|
||||
if(id == n++) { name = "DSP Address"; value = sprint("0x", strhex<2>(dsp_address())); return true; }
|
||||
if(id == n++) { name = "DSP Address"; value = string("0x", strhex<2>(dsp_address())); return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
static const char bsnesVersion[] = "065.02";
|
||||
static const char bsnesVersion[] = "065.03";
|
||||
static const char bsnesTitle[] = "bsnes";
|
||||
static const unsigned bsnesSerializerVersion = 10;
|
||||
|
||||
|
|
|
@ -102,8 +102,8 @@ void FileBrowser::onChangeCartridge(const string &path) {
|
|||
else filename = path;
|
||||
|
||||
string info;
|
||||
string image = sprint(nall::basename(filename), ".png");
|
||||
string patch = sprint(filepath(nall::basename(filename), config().path.patch), ".ups");
|
||||
string image(nall::basename(filename), ".png");
|
||||
string patch(filepath(nall::basename(filename), config().path.patch), ".ups");
|
||||
|
||||
if(file::exists(filename)) {
|
||||
if(striend(filename, ".sfc")) {
|
||||
|
|
|
@ -49,6 +49,7 @@ bool Cartridge::saveStatesSupported() {
|
|||
if(SNES::cartridge.has_dsp4()) return false;
|
||||
if(SNES::cartridge.has_st0011()) return false;
|
||||
if(SNES::cartridge.has_st0018()) return false;
|
||||
if(SNES::cartridge.has_serial()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -56,7 +57,7 @@ bool Cartridge::saveStatesSupported() {
|
|||
bool Cartridge::loadNormal(const char *base) {
|
||||
unload();
|
||||
if(loadCartridge(baseName = base, cartridge.baseXml, SNES::memory::cartrom) == false) return false;
|
||||
SNES::msu1.base(nall::basename(baseName));
|
||||
SNES::cartridge.basename = nall::basename(baseName);
|
||||
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::Normal,
|
||||
lstring() << cartridge.baseXml);
|
||||
|
@ -75,6 +76,8 @@ bool Cartridge::loadBsxSlotted(const char *base, const char *slot) {
|
|||
unload();
|
||||
if(loadCartridge(baseName = base, cartridge.baseXml, SNES::memory::cartrom) == false) return false;
|
||||
loadCartridge(slotAName = slot, cartridge.slotAXml, SNES::memory::bsxflash);
|
||||
SNES::cartridge.basename = nall::basename(baseName);
|
||||
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::BsxSlotted,
|
||||
lstring() << cartridge.baseXml << cartridge.slotAXml);
|
||||
|
||||
|
@ -93,6 +96,8 @@ bool Cartridge::loadBsx(const char *base, const char *slot) {
|
|||
unload();
|
||||
if(loadCartridge(baseName = base, cartridge.baseXml, SNES::memory::cartrom) == false) return false;
|
||||
loadCartridge(slotAName = slot, cartridge.slotAXml, SNES::memory::bsxflash);
|
||||
SNES::cartridge.basename = nall::basename(baseName);
|
||||
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::Bsx,
|
||||
lstring() << cartridge.baseXml << cartridge.slotAXml);
|
||||
|
||||
|
@ -113,6 +118,8 @@ bool Cartridge::loadSufamiTurbo(const char *base, const char *slotA, const char
|
|||
if(loadCartridge(baseName = base, cartridge.baseXml, SNES::memory::cartrom) == false) return false;
|
||||
loadCartridge(slotAName = slotA, cartridge.slotAXml, SNES::memory::stArom);
|
||||
loadCartridge(slotBName = slotB, cartridge.slotBXml, SNES::memory::stBrom);
|
||||
SNES::cartridge.basename = nall::basename(baseName);
|
||||
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::SufamiTurbo,
|
||||
lstring() << cartridge.baseXml << cartridge.slotAXml << cartridge.slotBXml);
|
||||
|
||||
|
@ -133,6 +140,8 @@ bool Cartridge::loadSuperGameBoy(const char *base, const char *slot) {
|
|||
unload();
|
||||
if(loadCartridge(baseName = base, cartridge.baseXml, SNES::memory::cartrom) == false) return false;
|
||||
loadCartridge(slotAName = slot, cartridge.slotAXml, SNES::memory::gbrom);
|
||||
SNES::cartridge.basename = nall::basename(baseName);
|
||||
|
||||
SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy,
|
||||
lstring() << cartridge.baseXml << cartridge.slotAXml);
|
||||
|
||||
|
@ -207,7 +216,7 @@ bool Cartridge::loadCartridge(string &filename, string &xml, SNES::MappedRAM &me
|
|||
if(reader.load(filename, data, size) == false) return false;
|
||||
|
||||
patchApplied = false;
|
||||
string name = sprint(filepath(nall::basename(filename), config().path.patch), ".ups");
|
||||
string name(filepath(nall::basename(filename), config().path.patch), ".ups");
|
||||
|
||||
file fp;
|
||||
if(config().file.applyPatches && fp.open(name, file::mode_read)) {
|
||||
|
@ -239,7 +248,7 @@ bool Cartridge::loadCartridge(string &filename, string &xml, SNES::MappedRAM &me
|
|||
}
|
||||
}
|
||||
|
||||
name = sprint(nall::basename(filename), ".xml");
|
||||
name = string(nall::basename(filename), ".xml");
|
||||
if(file::exists(name)) {
|
||||
//prefer manually created XML cartridge mapping
|
||||
xml.readfile(name);
|
||||
|
|
|
@ -2,7 +2,10 @@
|
|||
State state;
|
||||
|
||||
bool State::save(unsigned slot) {
|
||||
if(!allowed()) return false;
|
||||
if(!allowed()) {
|
||||
utility.showMessage("Cannot save state.");
|
||||
return false;
|
||||
}
|
||||
|
||||
SNES::system.runtosave();
|
||||
serializer state = SNES::system.serialize();
|
||||
|
@ -24,7 +27,10 @@ bool State::save(unsigned slot) {
|
|||
}
|
||||
|
||||
bool State::load(unsigned slot) {
|
||||
if(!allowed()) return false;
|
||||
if(!allowed()) {
|
||||
utility.showMessage("Cannot load state.");
|
||||
return false;
|
||||
}
|
||||
|
||||
file fp;
|
||||
bool result = false;
|
||||
|
|
Loading…
Reference in New Issue