Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Libretro: Add SGB MSU-1 and Satellaview support #69

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bsnes/heuristics/bs-memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ auto BSMemory::manifest() const -> string {
output.append(" label: ", Location::prefix(location), "\n");
output.append(" name: ", Location::prefix(location), "\n");
output.append(" board\n");
output.append(Memory{}.type("Flash").size(data.size()).content("Program").text());
output.append(Memory{}.type("Flash").size(0x100000).content("Program").text());
return output;
}

Expand Down
71 changes: 64 additions & 7 deletions bsnes/target-libretro/libretro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@ static vector<string> cheatList;
#define RETRO_DEVICE_LIGHTGUN_JUSTIFIERS RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_LIGHTGUN, 2)

#define RETRO_GAME_TYPE_SGB 0x101 | 0x1000
#define RETRO_GAME_TYPE_BSX 0x110 | 0x1000
#define RETRO_MEMORY_SGB_SRAM ((1 << 8) | RETRO_MEMORY_SAVE_RAM)
#define RETRO_MEMORY_GB_SRAM ((2 << 8) | RETRO_MEMORY_SAVE_RAM)
#define RETRO_MEMORY_BSX_SRAM ((3 << 8) | RETRO_MEMORY_SAVE_RAM)

static bool flush_variables() // returns whether video dimensions have changed (overscan, aspectcorrection scale or widescreen AR)
{
Expand Down Expand Up @@ -598,14 +600,24 @@ static void set_environment_info(retro_environment_t cb)
static const struct retro_subsystem_memory_info gb_memory[] = {
{ "srm", RETRO_MEMORY_GB_SRAM },
};

static const struct retro_subsystem_memory_info bsx_memory[] = {
{ "srm", RETRO_MEMORY_BSX_SRAM },
};

static const struct retro_subsystem_rom_info sgb_roms[] = {
{ "Game Boy ROM", "gb|gbc", true, false, true, gb_memory, 1 },
{ "Super Game Boy ROM", "smc|sfc|swc|fig|bs", true, false, true, sgb_memory, 1 },
{ "Super Game Boy ROM", "smc|sfc|swc|fig", true, false, true, sgb_memory, 1 },
};

static const struct retro_subsystem_rom_info bsx_roms[] = {
{ "BS-X ROM", "bs", true, false, true, bsx_memory, 1 },
{ "BS-X BIOS ROM", "smc|sfc|swc|fig", true, false, true, bsx_memory, 1 },
};

static const struct retro_subsystem_info subsystems[] = {
{ "Super Game Boy", "sgb", sgb_roms, 2, RETRO_GAME_TYPE_SGB },
{ "BS-X Satellaview", "bsx", bsx_roms, 2, RETRO_GAME_TYPE_BSX },
{}
};

Expand Down Expand Up @@ -808,7 +820,7 @@ RETRO_API void retro_get_system_info(retro_system_info *info)
info->library_name = Emulator::Name;
info->library_version = Emulator::Version;
info->need_fullpath = true;
info->valid_extensions = "smc|sfc";
info->valid_extensions = "smc|sfc|gb|gbc|bs";
info->block_extract = false;
}

Expand Down Expand Up @@ -933,17 +945,54 @@ RETRO_API bool retro_load_game(const retro_game_info *game)

flush_variables();

if (string(game->path).endsWith(".gb") || string(game->path).endsWith(".gbc"))
if (string(game->path).endsWith(".gb"))
{
const char *system_dir;
environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir);
string sgb_full_path = string(system_dir, "/", sgb_bios).transform("\\", "/");
if (!file::exists(sgb_full_path)) {
string sgb_full_path = string(game->path).transform("\\", "/");
string sgb_full_path2 = string(sgb_full_path).replace(".gb", ".sfc");
if (!file::exists(sgb_full_path2)) {
string sgb_full_path = string(system_dir, "/", sgb_bios).transform("\\", "/");
program->superFamicom.location = sgb_full_path;
}
else {
program->superFamicom.location = sgb_full_path2;
}
program->gameBoy.location = string(game->path);
if (!file::exists(program->superFamicom.location)) {
return false;
}

program->superFamicom.location = sgb_full_path;
}
else if (string(game->path).endsWith(".gbc"))
{
const char *system_dir;
environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir);
string sgb_full_path = string(game->path).transform("\\", "/");
string sgb_full_path2 = string(sgb_full_path).replace(".gbc", ".sfc");
if (!file::exists(sgb_full_path2)) {
string sgb_full_path = string(system_dir, "/", sgb_bios).transform("\\", "/");
program->superFamicom.location = sgb_full_path;
}
else {
program->superFamicom.location = sgb_full_path2;
}
program->gameBoy.location = string(game->path);
if (!file::exists(program->superFamicom.location)) {
return false;
}

}
else if (string(game->path).endsWith(".bs"))
{
const char *system_dir;
environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir);
string bs_full_path = string(system_dir, "/", "BS-X.bin").transform("\\", "/");
if (!file::exists(bs_full_path)) {
return false;
}

program->superFamicom.location = bs_full_path;
program->bsMemory.location = string(game->path);
}
else
{
Expand Down Expand Up @@ -979,6 +1028,14 @@ RETRO_API bool retro_load_game_special(unsigned game_type,
program->superFamicom.location = info[1].path;
}
break;
case RETRO_GAME_TYPE_BSX:
{
libretro_print(RETRO_LOG_INFO, "BS-X ROM: %s\n", info[0].path);
libretro_print(RETRO_LOG_INFO, "BS-X BIOS ROM: %s\n", info[1].path);
program->bsMemory.location = info[0].path;
program->superFamicom.location = info[1].path;
}
break;
default:
return false;
}
Expand Down
59 changes: 59 additions & 0 deletions bsnes/target-libretro/program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ using namespace nall;
#include <heuristics/heuristics.cpp>
#include <heuristics/super-famicom.cpp>
#include <heuristics/game-boy.cpp>
#include <heuristics/bs-memory.cpp>

#include "resources.hpp"

Expand All @@ -36,11 +37,13 @@ struct Program : Emulator::Platform
auto loadFile(string location) -> vector<uint8_t>;
auto loadSuperFamicom(string location) -> bool;
auto loadGameBoy(string location) -> bool;
auto loadBSMemory(string location) -> bool;

auto save() -> void;

auto openRomSuperFamicom(string name, vfs::file::mode mode) -> shared_pointer<vfs::file>;
auto openRomGameBoy(string name, vfs::file::mode mode) -> shared_pointer<vfs::file>;
auto openRomBSMemory(string name, vfs::file::mode mode) -> shared_pointer<vfs::file>;

auto hackPatchMemory(vector<uint8_t>& data) -> void;

Expand Down Expand Up @@ -76,6 +79,10 @@ struct Program : Emulator::Platform
struct GameBoy : Game {
vector<uint8_t> program;
} gameBoy;

struct BSMemory : Game {
vector<uint8_t> program;
} bsMemory;
};

static Program *program = nullptr;
Expand Down Expand Up @@ -136,6 +143,21 @@ auto Program::open(uint id, string name, vfs::file::mode mode, bool required) ->
result = openRomGameBoy(name, mode);
}
}
else if (id == 3) { //BS Memory
if (name == "manifest.bml" && mode == vfs::file::mode::read) {
result = vfs::memory::file::open(bsMemory.manifest.data<uint8_t>(), bsMemory.manifest.size());
}
else if (name == "program.rom" && mode == vfs::file::mode::read) {
result = vfs::memory::file::open(bsMemory.program.data(), bsMemory.program.size());
}
else if(name == "program.flash") {
//writes are not flushed to disk in bsnes
result = vfs::memory::file::open(bsMemory.program.data(), bsMemory.program.size());
}
else {
result = openRomBSMemory(name, mode);
}
}
return result;
}

Expand Down Expand Up @@ -221,6 +243,11 @@ auto Program::load(uint id, string name, string type, vector<string> options) ->
return { id, NULL };
}
}
else if (id == 3) {
if (loadBSMemory(bsMemory.location)) {
return { id, NULL };
}
}
return { id, options(0) };
}

Expand Down Expand Up @@ -421,6 +448,21 @@ auto Program::openRomGameBoy(string name, vfs::file::mode mode) -> shared_pointe
return {};
}

auto Program::openRomBSMemory(string name, vfs::file::mode mode) -> shared_pointer<vfs::file> {
if (name == "program.rom" && mode == vfs::file::mode::read)
{
return vfs::memory::file::open(bsMemory.program.data(), bsMemory.program.size());
}

if (name == "program.flash")
{
//writes are not flushed to disk
return vfs::memory::file::open(bsMemory.program.data(), bsMemory.program.size());
}

return {};
}

auto Program::loadFile(string location) -> vector<uint8_t>
{
if(Location::suffix(location).downcase() == ".zip") {
Expand Down Expand Up @@ -510,6 +552,23 @@ auto Program::loadGameBoy(string location) -> bool {
return true;
}

auto Program::loadBSMemory(string location) -> bool {
vector<uint8_t> rom;
rom = loadFile(location);

if (rom.size() < 0x8000) return false;

auto heuristics = Heuristics::BSMemory(rom, location);
auto sha256 = Hash::SHA256(rom).digest();

bsMemory.manifest = heuristics.manifest();
bsMemory.document = BML::unserialize(bsMemory.manifest);
bsMemory.location = location;

bsMemory.program = rom;
return true;
}

auto Program::hackPatchMemory(vector<uint8_t>& data) -> void
{
auto title = superFamicom.title;
Expand Down