Skip to content
Draft
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
3 changes: 1 addition & 2 deletions Source/Core/Core/HW/GBACore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,8 +758,7 @@ bool Core::GetRomInfo(const char* rom_path, std::array<u8, 20>& hash, std::strin

std::string Core::GetSavePath(std::string_view rom_path, int device_number)
{
std::string save_path =
fmt::format("{}-{}.sav", rom_path.substr(0, rom_path.find_last_of('.')), device_number + 1);
std::string save_path = fmt::format("{}.srm", rom_path.substr(0, rom_path.find_last_of('.')));

if (!Config::Get(Config::MAIN_GBA_SAVES_IN_ROM_PATH))
{
Expand Down
116 changes: 112 additions & 4 deletions Source/Core/DolphinLibretro/Boot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "Common/CommonPaths.h"
#include "Core/CommonTitles.h"
#include "Common/FileUtil.h"
#include "Common/StringUtil.h"
#include "Common/Version.h"
#include "Core/Boot/Boot.h"
#include "Core/BootManager.h"
Expand All @@ -19,6 +20,7 @@
#include "Core/GeckoCodeConfig.h"
#include "Core/HW/DVD/DVDInterface.h"
#include "Core/HW/EXI/EXI_Device.h"
#include "Core/HW/HSP/HSP_Device.h"
#include "Core/HW/VideoInterface.h"
#include "Core/HW/WiimoteReal/WiimoteReal.h"
#include "Core/PowerPC/PowerPC.h"
Expand Down Expand Up @@ -53,6 +55,10 @@ static unsigned disk_index = 0;
static bool eject_state;
static std::vector<std::string> disk_paths;

// GBPlayer
static std::string GBPlayer_rom_path;
static bool GBPlayer_active;

// silence forward declaration warnings
void reload_cheats_from_ini();
void generate_cht_from_ini(std::string fileName);
Expand Down Expand Up @@ -168,12 +174,64 @@ void generate_cht_from_ini(std::string fileName)
bool retro_load_game(const struct retro_game_info* game)
{
const char* save_dir = NULL;
const char* gba_save_dir = NULL;
const char* system_dir = NULL;
const char* core_assets_dir = NULL;
std::string rebuild_save_dir;
std::string user_dir;
std::string sys_dir;

Libretro::environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &save_dir);
/*
* If the GBPlayer is active, we try to reconstruct the GC save dir location
* with regards to content sorting and core sorting. If we do not do this,
* there will be a User directory with GC saves in the GB/GBC/GBA rom save path
* when a user has content/core sorting enabled. Since the user is trying to avoid
* said behavior actively if those sorting options are enabled,
* we should seperate them accordingly.
*/
if (Libretro::GBPlayer_active)
{
std::filesystem::path gba_content_dir = std::filesystem::path("");
if (!Libretro::GBPlayer_rom_path.empty())
gba_content_dir = std::filesystem::path(Libretro::GBPlayer_rom_path).parent_path().filename().string();

Libretro::environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &gba_save_dir);
std::filesystem::path base = std::filesystem::path(gba_save_dir);

bool core_sort = false;
retro_system_info sys_info{};
retro_get_system_info(&sys_info);
const std::string library_name = sys_info.library_name;

if (!base.empty() && !library_name.empty())
core_sort = Common::CaseInsensitiveEquals(base.filename().string(), library_name);
if (core_sort)
base = base.parent_path();

bool content_sort = false;
std::string gc_content_dir;
if (!gba_content_dir.empty() && !base.empty())
content_sort = Common::CaseInsensitiveEquals(base.filename().string(), gba_content_dir.string());
if (content_sort)
{
gc_content_dir = std::filesystem::path(game->path).parent_path().filename().string();
base = base.parent_path();
}

rebuild_save_dir = base.string();
if (content_sort)
rebuild_save_dir = rebuild_save_dir + DIR_SEP + gc_content_dir;
if (core_sort)
rebuild_save_dir = rebuild_save_dir + DIR_SEP + library_name;

save_dir = rebuild_save_dir.c_str();
INFO_LOG_FMT(BOOT, "GBPlayer: GC save dir reconstructed to: '{}'", save_dir);
}
else
{
Libretro::environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &save_dir);
}

Libretro::environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &system_dir);
Libretro::environ_cb(RETRO_ENVIRONMENT_GET_CORE_ASSETS_DIRECTORY, &core_assets_dir);
Libretro::InitDiskControlInterface();
Expand Down Expand Up @@ -212,6 +270,22 @@ bool retro_load_game(const struct retro_game_info* game)
UICommon::CreateDirectories();
UICommon::Init();
Libretro::Log::Init();

if (Libretro::GBPlayer_active)
{
Config::SetBase(Config::MAIN_GBA_ROM_PATHS[Config::GBPLAYER_GBA_INDEX], Libretro::GBPlayer_rom_path);
INFO_LOG_FMT(BOOT, "GBPlayer: GBA ROM path applied from subsystem: '{}'", Libretro::GBPlayer_rom_path);
Config::SetBase(Config::MAIN_GBA_SAVES_PATH, std::string(gba_save_dir));
INFO_LOG_FMT(BOOT, "GBPlayer: ROM save set to: '{}'", gba_save_dir);
// In order to prevent confusion for the settings of the save location between RA and the
// emulator we just turn this off
Config::SetBase(Config::MAIN_GBA_SAVES_IN_ROM_PATH, false);
}
else
{
Config::SetBase(Config::MAIN_GBA_ROM_PATHS[Config::GBPLAYER_GBA_INDEX], std::string{});
}

Discord::SetDiscordPresenceEnabled(false);
Common::SetEnableAlert(false);
Common::SetAbortOnPanicAlert(false);
Expand Down Expand Up @@ -621,10 +695,44 @@ bool retro_load_game(const struct retro_game_info* game)
return true;
}

bool retro_load_game_special(unsigned game_type, const struct retro_game_info* info,
size_t num_info)
bool retro_load_game_special(unsigned game_type, const struct retro_game_info* info, size_t num_info)
{
return false;
if (game_type != Libretro::g_gbplayer_subsystem_id)
{
ERROR_LOG_FMT(BOOT, "retro_load_game_special: unknown game_type {}", game_type);
return false;
}
if (num_info < 1 || !info)
{
ERROR_LOG_FMT(BOOT, "retro_load_game_special: no content info");
return false;
}

const retro_game_info* gba_slot = (num_info >= 2 && info[0].path && *info[0].path) ? &info[0] : nullptr;

const retro_game_info* gc_slot = (info[1].path && *info[1].path) ? &info[1] : nullptr;

if (!gc_slot)
{
ERROR_LOG_FMT(BOOT, "GBPlayer: no GC disc path provided in slot 0");
return false;
}

INFO_LOG_FMT(BOOT, "GBPlayer: GC disc = '{}'", gc_slot->path);
if (gba_slot)
{
Libretro::GBPlayer_rom_path = gba_slot->path;
INFO_LOG_FMT(BOOT, "GBPlayer: ROM = '{}'", gba_slot->path);
}
else
{
Libretro::GBPlayer_rom_path.clear();
INFO_LOG_FMT(BOOT, "GBPlayer: no ROM");
}

Libretro::GBPlayer_active = true;

return retro_load_game(gc_slot);
}

void retro_unload_game(void)
Expand Down
1 change: 1 addition & 0 deletions Source/Core/DolphinLibretro/Common/Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ extern retro_environment_t environ_cb;
extern bool g_emuthread_launched;
extern std::vector<Gecko::GeckoCode> g_gecko_codes;
extern std::vector<ActionReplay::ARCode> g_ar_codes;
inline constexpr unsigned g_gbplayer_subsystem_id = 0x101;

namespace Input
{
Expand Down
24 changes: 24 additions & 0 deletions Source/Core/DolphinLibretro/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,30 @@ void retro_set_environment(retro_environment_t cb)
#ifdef PERF_TEST
environ_cb(RETRO_ENVIRONMENT_GET_PERF_INTERFACE, &perf_cb);
#endif
static const struct retro_subsystem_memory_info gbp_gba_memory[] = {
{"srm", RETRO_MEMORY_SAVE_RAM},
};
static const struct retro_subsystem_rom_info gbp_roms[] = {
{"GBA ROM", "gba|gbc|gb|zip|7z",
true,
true,
false,
gbp_gba_memory, 1},
{"GameCube Disc", "rvz|gcm|iso|ciso|wbfs|gcz|tgc|m3u",
true,
false,
true,
nullptr, 0},
};
static const struct retro_subsystem_info subsystems[] = {
{
"Game Boy Player",
"GBP",
gbp_roms, 2,
Libretro::g_gbplayer_subsystem_id
},
{nullptr, nullptr, nullptr, 0, 0}};
cb(RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO, (void*)subsystems);
}

void retro_init(void)
Expand Down
Loading