Files
bsnes-mercury/changes-libretro.diff
2015-08-10 18:39:34 +02:00

540 lines
23 KiB
Diff

--- ../bsnes-libretro/target-libretro/libretro.cpp 2015-04-23 18:11:06.227925641 +0200
+++ target-libretro/libretro.cpp 2015-04-23 17:17:56.059865750 +0200
@@ -64,9 +64,21 @@
/*fffe*/ 0xc0, 0xff //reset vector location ($ffc0)
};
+static void retro_log_default(enum retro_log_level level, const char *fmt, ...)
+{
+ fprintf(stderr, "[bsnes]: ");
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+}
+static retro_log_printf_t output;
+
+static const char * read_opt(const char * name, const char * defval);
+
struct Callbacks : Emulator::Interface::Bind {
retro_video_refresh_t pvideo_refresh;
- retro_audio_sample_batch_t paudio_sample;
+ retro_audio_sample_batch_t paudio;
retro_input_poll_t pinput_poll;
retro_input_state_t pinput_state;
retro_environment_t penviron;
@@ -129,7 +141,7 @@
uint16_t video_buffer_16[512 * 480];
};
- void videoRefresh(const uint32_t *palette, const uint32_t *data, unsigned pitch, unsigned width, unsigned height) {
+ void videoRefresh(const uint32_t* palette, const uint32_t* data, unsigned pitch, unsigned width, unsigned height) override {
if (!overscan) {
data += 8 * 1024;
@@ -161,20 +173,26 @@
}
}
- void audioSample(int16_t left, int16_t right)
- {
- const int16_t samples[2] = { left, right };
- paudio_sample(samples, 1);
+ int16_t sampleBuf[128];
+ unsigned int sampleBufPos;
+
+ void audioSample(int16_t left, int16_t right) override {
+ sampleBuf[sampleBufPos++] = left;
+ sampleBuf[sampleBufPos++] = right;
+ if(sampleBufPos==128) {
+ paudio(sampleBuf, 64);
+ sampleBufPos = 0;
+ }
}
- int16_t inputPoll(unsigned port, unsigned device, unsigned id) {
+ int16_t inputPoll(unsigned port, unsigned device, unsigned id) override {
if(id > 11) return 0;
return pinput_state(port, snes_to_retro(device), 0, snes_to_retro(device, id));
}
- void saveRequest(unsigned id, string p) {
+ void saveRequest(unsigned id, string p) override {
if (manifest) {
- fprintf(stderr, "[bsnes]: [Save]: ID %u, Request \"%s\".\n", id, (const char*)p);
+ output(RETRO_LOG_INFO, "[Save]: ID %u, Request \"%s\".\n", id, (const char*)p);
string save_path = {path(0), p};
filestream stream(save_path, file::mode::write);
iface->save(id, stream);
@@ -196,11 +214,11 @@
mmapstream stream(load_path);
iface->load(id, stream);
} else {
- fprintf(stderr, "[bsnes]: Cannot find requested file in system directory: \"%s\".\n", (const char*)load_path);
+ output(RETRO_LOG_ERROR, "Cannot find requested file in system directory: \"%s\".\n", (const char*)load_path);
load_request_error = true;
}
} else {
- fprintf(stderr, "[bsnes]: Cannot find requested file: \"%s\" in ROM directory nor system directory.\n", (const char*)p);
+ output(RETRO_LOG_ERROR, "Cannot find requested file: \"%s\" in ROM directory nor system directory.\n", (const char*)p);
load_request_error = true;
}
}
@@ -231,7 +249,7 @@
}
void loadRequestManifest(unsigned id, const string& p) {
- fprintf(stderr, "[bsnes]: [Manifest]: ID %u, Request \"%s\".\n", id, (const char*)p);
+ output(RETRO_LOG_INFO, "[Manifest]: ID %u, Request \"%s\".\n", id, (const char*)p);
switch(id) {
case SuperFamicom::ID::IPLROM:
loadIPLROM(id);
@@ -248,7 +266,7 @@
}
void loadRequestMemory(unsigned id, const string& p) {
- fprintf(stderr, "[bsnes]: [Memory]: ID %u, Request \"%s\".\n", id, (const char*)p);
+ output(RETRO_LOG_INFO, "[Memory]: ID %u, Request \"%s\".\n", id, (const char*)p);
switch(id) {
case SuperFamicom::ID::Manifest:
loadManifest(id);
@@ -264,7 +282,7 @@
case SuperFamicom::ID::SDD1ROM:
case SuperFamicom::ID::HitachiDSPROM:
case SuperFamicom::ID::SPC7110PROM:
- fprintf(stderr, "[bsnes]: Load ROM.\n");
+ output(RETRO_LOG_INFO, "Load ROM.\n");
loadROM(id);
break;
@@ -319,37 +337,37 @@
break;
default:
- fprintf(stderr, "[bsnes]: Load BIOS.\n");
+ output(RETRO_LOG_INFO, "Load BIOS.\n");
loadFile(id, p);
break;
}
}
- void loadRequest(unsigned id, string p) {
+ void loadRequest(unsigned id, string p) override {
if (manifest)
loadRequestManifest(id, p);
else
loadRequestMemory(id, p);
- fprintf(stderr, "[bsnes]: Complete load request.\n");
+ output(RETRO_LOG_INFO, "Complete load request.\n");
}
- void loadRequest(unsigned id, string p, string manifest) {
+ void loadRequest(unsigned id, string p, string manifest) override {
switch (id) {
case SuperFamicom::ID::SuperGameBoy:
- fprintf(stderr, "[bsnes]: Loading GB ROM.\n");
+ output(RETRO_LOG_INFO, "Loading GB ROM.\n");
loadSGBROMManifest(id);
break;
default:
- fprintf(stderr, "[bsnes]: Didn't do anything with loadRequest (3 arg).\n");
+ output(RETRO_LOG_INFO, "Didn't do anything with loadRequest (3 arg).\n");
}
}
- string path(unsigned) {
+ string path(unsigned) override {
return string(basename);
}
- uint32_t videoColor(unsigned, uint16_t, uint16_t r, uint16_t g, uint16_t b) {
+ uint32_t videoColor(unsigned, uint16_t, uint16_t r, uint16_t g, uint16_t b) override {
r >>= 8;
g >>= 8;
b >>= 8;
@@ -357,10 +375,43 @@
if (video_fmt == video_fmt_16) return (r>>3 << 11) | (g>>2 << 5) | (b>>3 << 0);
if (video_fmt == video_fmt_15) return (r>>3 << 10) | (g>>3 << 5) | (b>>3 << 0);
}
+
+ void notify(string text) {
+ output(RETRO_LOG_ERROR, "%s\n", (const char*)text);
+ }
+
+ unsigned altImplementation(unsigned item) override {
+ if (item==SuperFamicom::Alt::ForDSP)
+ {
+ if (!strcmp(read_opt("bsnes_chip_hle", "LLE"), "HLE")) return SuperFamicom::Alt::DSP::HLE;
+ else return SuperFamicom::Alt::DSP::LLE;
+ }
+#ifdef EXPERIMENTAL_FEATURES
+ if (item==SuperFamicom::Alt::ForSuperGameBoy)
+ {
+ if (!strcmp(read_opt("bsnes_sgb_core", "Internal"), "Gambatte")) return SuperFamicom::Alt::SuperGameBoy::External;
+ else return SuperFamicom::Alt::SuperGameBoy::Internal;
+ }
+#endif
+ return 0;
+ }
};
static Callbacks core_bind;
+static const char * read_opt(const char * name, const char * defval)
+{
+ struct retro_variable allowvar = { "bsnes_violate_accuracy", "No" };
+ core_bind.penviron(RETRO_ENVIRONMENT_GET_VARIABLE, (void*)&allowvar);
+ if (!strcmp(allowvar.value, "Yes"))
+ {
+ struct retro_variable var = {name, defval};
+ core_bind.penviron(RETRO_ENVIRONMENT_GET_VARIABLE, (void*)&var);
+ return var.value;
+ }
+ else return defval;
+}
+
struct Interface : public SuperFamicom::Interface {
SuperFamicomCartridge::Mode mode;
@@ -426,10 +477,28 @@
return RETRO_API_VERSION;
}
+static unsigned superfx_freq_orig;
+
void retro_set_environment(retro_environment_t environ_cb)
{
core_bind.penviron = environ_cb;
+ static const struct retro_variable vars[] = {
+ { "bsnes_violate_accuracy", "Respect accuracy-impacting settings; No|Yes" },
+ { "bsnes_chip_hle", "Special chip accuracy; LLE|HLE" },
+ { "bsnes_superfx_overclock", "SuperFX speed; 100%|150%|200%|300%|400%|500%|1000%" },
+ //Any integer is usable here, but there is no such thing as "any integer" in core options.
+#ifdef EXPERIMENTAL_FEATURES
+ { "bsnes_sgb_core", "Super Game Boy core; Internal|Gambatte" },
+#endif
+ { NULL, NULL },
+ };
+ core_bind.penviron(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars);
+
+ static struct retro_log_callback log={retro_log_default};
+ core_bind.penviron(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, (void*)&log);
+ output=log.log;
+
static const retro_subsystem_memory_info sgb_memory[] = {
{ "srm", RETRO_MEMORY_SNES_GAME_BOY_RAM },
{ "rtc", RETRO_MEMORY_SNES_GAME_BOY_RTC },
@@ -498,11 +567,19 @@
environ_cb(RETRO_ENVIRONMENT_SET_CONTROLLER_INFO, (void*)ports);
}
-void retro_set_video_refresh(retro_video_refresh_t video_refresh) { core_bind.pvideo_refresh = video_refresh; }
-void retro_set_audio_sample(retro_audio_sample_t) { }
-void retro_set_audio_sample_batch(retro_audio_sample_batch_t audio_sample) { core_bind.paudio_sample = audio_sample; }
-void retro_set_input_poll(retro_input_poll_t input_poll) { core_bind.pinput_poll = input_poll; }
-void retro_set_input_state(retro_input_state_t input_state) { core_bind.pinput_state = input_state; }
+static void update_variables(void) {
+ if (SuperFamicom::cartridge.has_superfx()) {
+ const char * speed=read_opt("bsnes_superfx_overclock", "100%");
+ unsigned percent=strtoul(speed, NULL, 10);//we can assume that the input is one of our advertised options
+ SuperFamicom::superfx.frequency=(uint64)superfx_freq_orig*percent/100;
+ }
+}
+
+void retro_set_video_refresh(retro_video_refresh_t cb) { core_bind.pvideo_refresh = cb; }
+void retro_set_audio_sample(retro_audio_sample_t) { }
+void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb) { core_bind.paudio = cb; }
+void retro_set_input_poll(retro_input_poll_t cb) { core_bind.pinput_poll = cb; }
+void retro_set_input_state(retro_input_state_t cb) { core_bind.pinput_state = cb; }
void retro_set_controller_port_device(unsigned port, unsigned device) {
if (port < 2)
@@ -515,6 +592,8 @@
core_interface.init();
core_gb_interface.init();
+
+ core_bind.sampleBufPos = 0;
SuperFamicom::system.init();
SuperFamicom::input.connect(SuperFamicom::Controller::Port1, SuperFamicom::Input::Device::Joypad);
@@ -530,7 +609,14 @@
}
void retro_run(void) {
+ bool updated = false;
+ if (core_bind.penviron(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
+ update_variables();
SuperFamicom::system.run();
+ if(core_bind.sampleBufPos) {
+ core_bind.paudio(core_bind.sampleBuf, core_bind.sampleBufPos/2);
+ core_bind.sampleBufPos = 0;
+ }
}
size_t retro_serialize_size(void) {
@@ -550,6 +636,7 @@
return SuperFamicom::system.unserialize(s);
}
+#if 0
struct CheatList {
bool enable;
string code;
@@ -557,27 +644,33 @@
};
static vector<CheatList> cheatList;
+#endif
void retro_cheat_reset(void) {
+#if 0
cheatList.reset();
core_interface.setCheats();
+#endif
}
void retro_cheat_set(unsigned index, bool enable, const char *code) {
+#if 0
+ cheatList.reserve(index+1);
cheatList[index].enable = enable;
cheatList[index].code = code;
lstring list;
-
+
for(unsigned n = 0; n < cheatList.size(); n++) {
if(cheatList[n].enable) list.append(cheatList[n].code);
}
-
+
core_interface.setCheats(list);
+#endif
}
void retro_get_system_info(struct retro_system_info *info) {
static string version("v", Emulator::Version, " (", Emulator::Profile, ")");
- info->library_name = "bsnes";
+ info->library_name = "bsnes-mercury";
info->library_version = version;
info->valid_extensions = "sfc|smc|bml";
info->need_fullpath = false;
@@ -615,6 +708,19 @@
}
}
+static void output_multiline(enum retro_log_level level, char * data)
+{
+ while (true)
+ {
+ char* data_linebreak=strchr(data, '\n');
+ if (data_linebreak) *data_linebreak='\0';
+ if (*data) output(level, "%s\n", data);
+ if (!data_linebreak) break;
+ *data_linebreak='\n';
+ data=data_linebreak+1;
+ }
+}
+
static bool snes_load_cartridge_normal(
const char *rom_xml, const uint8_t *rom_data, unsigned rom_size
) {
@@ -623,7 +729,8 @@
core_bind.rom_data = rom_data;
core_bind.rom_size = rom_size;
core_bind.xmlrom = xmlrom;
- fprintf(stderr, "[bsnes]: XML map:\n%s\n", (const char*)xmlrom);
+ output(RETRO_LOG_INFO, "BML map:\n");
+ output_multiline(RETRO_LOG_INFO, xmlrom.data());
core_bind.iface->load(SuperFamicom::ID::SuperFamicom);
SuperFamicom::system.power();
return !core_bind.load_request_error;
@@ -689,8 +796,10 @@
) {
string xmlrom_sgb = (rom_xml && *rom_xml) ? string(rom_xml) : SuperFamicomCartridge(rom_data, rom_size).markup;
string xmlrom_gb = (dmg_xml && *dmg_xml) ? string(dmg_xml) : GameBoyCartridge((uint8_t*)dmg_data, dmg_size).markup;
- fprintf(stderr, "[bsnes]: Markup SGB: %s\n", (const char*)xmlrom_sgb);
- fprintf(stderr, "[bsnes]: Markup GB: %s\n", (const char*)xmlrom_gb);
+ output(RETRO_LOG_INFO, "Markup SGB:\n");
+ output_multiline(RETRO_LOG_INFO, xmlrom_sgb.data());
+ output(RETRO_LOG_INFO, "Markup GB:\n");
+ output_multiline(RETRO_LOG_INFO, xmlrom_gb.data());
core_bind.rom_data = rom_data;
core_bind.rom_size = rom_size;
@@ -708,70 +817,70 @@
static void init_descriptors(void)
{
struct retro_input_descriptor desc[] = {
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
- { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
-
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
- { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
-
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
- { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
-
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
- { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
-
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
- { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
+ { 0, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
+ { 1, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
+ { 2, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
+ { 3, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
+
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_LEFT, "D-Pad Left" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_UP, "D-Pad Up" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_DOWN, "D-Pad Down" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_RIGHT, "D-Pad Right" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_B, "B" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_A, "A" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_X, "X" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_Y, "Y" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_L, "L" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_R, "R" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_SELECT, "Select" },
+ { 4, RETRO_DEVICE_JOYPAD, 0, RETRO_DEVICE_ID_JOYPAD_START, "Start" },
{ 0 },
};
@@ -811,9 +920,19 @@
std::string manifest;
if (core_bind.manifest)
manifest = std::string((const char*)info->data, info->size); // Might not be 0 terminated.
- return snes_load_cartridge_normal(core_bind.manifest ? manifest.data() : info->meta, data, size);
+
+ bool ret=snes_load_cartridge_normal(core_bind.manifest ? manifest.data() : info->meta, data, size);
+ SuperFamicom::bus.libretro_mem_map.reverse();
+ retro_memory_map map={SuperFamicom::bus.libretro_mem_map.data(), SuperFamicom::bus.libretro_mem_map.size()};
+ core_bind.penviron(RETRO_ENVIRONMENT_SET_MEMORY_MAPS, (void*)&map);
+
+ if (SuperFamicom::cartridge.has_superfx())
+ superfx_freq_orig=SuperFamicom::superfx.frequency;
+
+ return ret;
}
+
bool retro_load_game_special(unsigned game_type,
const struct retro_game_info *info, size_t num_info) {
core_bind.manifest = false;
@@ -898,7 +1017,7 @@
}
unsigned retro_get_region(void) {
- return SuperFamicom::system.region() == SuperFamicom::System::Region::NTSC ? 0 : 1;
+ return SuperFamicom::system.region() == SuperFamicom::System::Region::NTSC ? RETRO_REGION_NTSC : RETRO_REGION_PAL;
}
void* retro_get_memory_data(unsigned id) {
@@ -942,7 +1061,7 @@
switch(id) {
case RETRO_MEMORY_SAVE_RAM:
size = core_bind.sram_size;
- fprintf(stderr, "[bsnes]: SRAM memory size: %u.\n", (unsigned)size);
+ output(RETRO_LOG_INFO, "SRAM memory size: %u.\n", (unsigned)size);
break;
case RETRO_MEMORY_RTC:
size = 0;