mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-05-09 12:24:04 -05:00
HW/GBPlayer: Try to load CGB boot ROM for (C)GB games
If the Game Boy Player boots a Game Boy or Game Boy Color game we try to load a boot ROM now. The mGBA core configuration has also been updated to reflect that the Game Boy Player is based on a Game Boy Advance SoC and not a Game Boy Color. This means that (C)GB games can detect that they are running on a Game Boy Advance now.
This commit is contained in:
parent
914f5c5621
commit
296e81a8a3
|
|
@ -70,6 +70,7 @@ enum class StringSetting(
|
|||
),
|
||||
MAIN_WFS_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "WFSPath", ""),
|
||||
MAIN_GBA_BIOS_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GBA, "BIOS", ""),
|
||||
MAIN_GBA_CGB_BOOT_ROM_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GBA, "CGBBootROM", ""),
|
||||
MAIN_GB_PLAYER_ROM(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GBA, "GBPlayerRom", ""),
|
||||
MAIN_GBA_SAVES_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GBA, "SavesPath", ""),
|
||||
MAIN_TRIFORCE_IP_REDIRECTIONS(
|
||||
|
|
|
|||
|
|
@ -714,6 +714,16 @@ class SettingsFragmentPresenter(
|
|||
"/GBA/gba_bios.bin"
|
||||
)
|
||||
)
|
||||
sl.add(
|
||||
FilePicker(
|
||||
context,
|
||||
StringSetting.MAIN_GBA_CGB_BOOT_ROM_PATH,
|
||||
R.string.gba_cgb_boot_rom_path,
|
||||
0,
|
||||
fragmentView.activityResultLaunchers.requestBinFile,
|
||||
"/GBA/cgb_agb_boot.bin"
|
||||
)
|
||||
)
|
||||
sl.add(
|
||||
FilePicker(
|
||||
context,
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@
|
|||
<string name="serial_port_1_device">GameCube Serial Port 1 Device</string>
|
||||
<string name="gba_settings">GBA Settings</string>
|
||||
<string name="gba_bios_path">BIOS</string>
|
||||
<string name="gba_cgb_boot_rom_path">Game Boy Color Boot ROM</string>
|
||||
<string name="gb_player_rom">Game Boy Player ROM</string>
|
||||
<string name="gba_saves_path">Saves</string>
|
||||
<string name="wii_submenu">Wii</string>
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@
|
|||
#define GC_MEMCARD_NETPLAY "NetPlayTemp"
|
||||
|
||||
#define GBA_BIOS "gba_bios.bin"
|
||||
#define GBA_CGB_BOOT_ROM "cgb_agb_boot.bin"
|
||||
#define GBA_SAVE_NETPLAY "NetPlayTemp"
|
||||
|
||||
#define WII_STATE "state.dat"
|
||||
|
|
|
|||
|
|
@ -908,6 +908,7 @@ static void RebuildUserDirectories(unsigned int dir_index)
|
|||
s_user_paths[D_GBAUSER_IDX] = s_user_paths[D_USER_IDX] + GBA_USER_DIR DIR_SEP;
|
||||
s_user_paths[D_GBASAVES_IDX] = s_user_paths[D_GBAUSER_IDX] + GBASAVES_DIR DIR_SEP;
|
||||
s_user_paths[F_GBABIOS_IDX] = s_user_paths[D_GBAUSER_IDX] + GBA_BIOS;
|
||||
s_user_paths[F_GBACGBBOOTROM_IDX] = s_user_paths[D_GBAUSER_IDX] + GBA_CGB_BOOT_ROM;
|
||||
|
||||
s_user_paths[D_ASM_ROOT_IDX] = s_user_paths[D_USER_IDX] + ASSEMBLY_DIR DIR_SEP;
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ enum
|
|||
F_FREELOOKCONFIG_IDX,
|
||||
F_GBABIOS_IDX,
|
||||
F_RETROACHIEVEMENTSCONFIG_IDX,
|
||||
F_GBACGBBOOTROM_IDX,
|
||||
NUM_PATH_INDICES
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -398,6 +398,7 @@ void SetIsoPaths(std::span<const std::string> paths)
|
|||
|
||||
#ifdef HAS_LIBMGBA
|
||||
const Info<std::string> MAIN_GBA_BIOS_PATH{{System::Main, "GBA", "BIOS"}, ""};
|
||||
const Info<std::string> MAIN_GBA_CGB_BOOT_ROM_PATH{{System::Main, "GBA", "CGBBootROM"}, ""};
|
||||
const std::array<Info<std::string>, 5> MAIN_GBA_ROM_PATHS{
|
||||
Info<std::string>{{System::Main, "GBA", "Rom1"}, ""},
|
||||
Info<std::string>{{System::Main, "GBA", "Rom2"}, ""},
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ void SetIsoPaths(std::span<const std::string> paths);
|
|||
|
||||
#ifdef HAS_LIBMGBA
|
||||
extern const Info<std::string> MAIN_GBA_BIOS_PATH;
|
||||
extern const Info<std::string> MAIN_GBA_CGB_BOOT_ROM_PATH;
|
||||
extern const std::array<Info<std::string>, 5> MAIN_GBA_ROM_PATHS;
|
||||
extern const Info<std::string> MAIN_GBA_SAVES_PATH;
|
||||
extern const Info<bool> MAIN_GBA_SAVES_IN_ROM_PATH;
|
||||
|
|
|
|||
|
|
@ -218,12 +218,21 @@ bool Core::Start(u64 gc_ticks)
|
|||
mCoreConfigSetIntValue(&m_core->config, "useBios", 0);
|
||||
mCoreConfigSetIntValue(&m_core->config, "skipBios", 0);
|
||||
|
||||
// If we eventually load GBC BIOS, then these should potentially all be "CGB".
|
||||
// The official GBC/GBA bootstrap ROM will detect a non-"GBC compatible" ROM, load palettes as
|
||||
// desired, and switch into GB mode. If forced into GBC/GBA mode without a bootstrap ROM, mGBA
|
||||
// will not perform this step. Instead, we set gb.colors to inform it to load the palette and set
|
||||
// it directly to DMG mode in advance. However, if a GBC or GBA bootstrap ROM is loaded, we want
|
||||
// to stay in GBC/GBA mode as appropriate so the bootstrap ROM can take care of it itself and we
|
||||
// show the right boot splash.
|
||||
// Note that even when using a GBC bootstrap ROM and not the one from
|
||||
// an actual GBA, the system will appear as GBA to games because mGBA fixes the B register when it
|
||||
// unloads the bootstrap ROM, so features such as Oracle's "Advance Shop" will be available.
|
||||
// See `GBUnmapBIOS` in mGBA’s `src/gb/gb.c`.
|
||||
mCoreConfigSetValue(&m_core->config, "gb.model", "DMG");
|
||||
mCoreConfigSetValue(&m_core->config, "sgb.model", "DMG");
|
||||
mCoreConfigSetValue(&m_core->config, "cgb.model", "CGB");
|
||||
mCoreConfigSetValue(&m_core->config, "cgb.hybridModel", "CGB");
|
||||
mCoreConfigSetValue(&m_core->config, "cgb.sgbModel", "CGB");
|
||||
mCoreConfigSetValue(&m_core->config, "cgb.model", "AGB");
|
||||
mCoreConfigSetValue(&m_core->config, "cgb.hybridModel", "AGB");
|
||||
mCoreConfigSetValue(&m_core->config, "cgb.sgbModel", "AGB");
|
||||
|
||||
mCoreConfigSetIntValue(&m_core->config, "gb.colors", GB_COLORS_CGB);
|
||||
|
||||
|
|
@ -231,6 +240,10 @@ bool Core::Start(u64 gc_ticks)
|
|||
{
|
||||
LoadBIOS(File::GetUserPath(F_GBABIOS_IDX).c_str());
|
||||
}
|
||||
else if (m_core->platform(m_core) == mPLATFORM_GB)
|
||||
{
|
||||
LoadCGBBootROM(File::GetUserPath(F_GBACGBBOOTROM_IDX).c_str());
|
||||
}
|
||||
|
||||
if (rom)
|
||||
{
|
||||
|
|
@ -371,6 +384,45 @@ bool Core::LoadBIOS(const char* bios_path)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Core::LoadCGBBootROM(const char* boot_rom_path)
|
||||
{
|
||||
VFile* vf = OpenReadOnlyFile(boot_rom_path);
|
||||
if (!vf)
|
||||
{
|
||||
ERROR_LOG_FMT(CORE, "GBA{0} failed to open the Game Boy Color boot ROM in {1}",
|
||||
m_device_number + 1, boot_rom_path);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GBIsCompatibleBIOS(vf, GB_MODEL_AGB))
|
||||
{
|
||||
ERROR_LOG_FMT(CORE, "The provided Game Boy Color boot ROM in {1} is not compatible with GBA{0}",
|
||||
m_device_number + 1, boot_rom_path);
|
||||
vf->close(vf);
|
||||
return false;
|
||||
}
|
||||
|
||||
// When a compatible boot ROM is provided, nothing should break if mGBA is set to run as GBA
|
||||
// for non-CGB games
|
||||
mCoreConfigSetValue(&m_core->config, "gb.model", "AGB");
|
||||
mCoreConfigSetValue(&m_core->config, "sgb.model", "AGB");
|
||||
|
||||
if (!m_core->loadBIOS(m_core, vf, 0))
|
||||
{
|
||||
ERROR_LOG_FMT(CORE, "GBA{0} failed to load the GBC Boot ROM in {1}", m_device_number + 1,
|
||||
boot_rom_path);
|
||||
vf->close(vf);
|
||||
|
||||
// Reset the pre-CGB model config to be safe
|
||||
mCoreConfigSetValue(&m_core->config, "gb.model", "DMG");
|
||||
mCoreConfigSetValue(&m_core->config, "sgb.model", "DMG");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Core::LoadSave(const char* save_path)
|
||||
{
|
||||
VFile* vf = VFileOpen(save_path, O_CREAT | O_RDWR);
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ private:
|
|||
void HandleEvent(SyncEvent event);
|
||||
|
||||
bool LoadBIOS(const char* bios_path);
|
||||
bool LoadCGBBootROM(const char* boot_rom_path);
|
||||
bool LoadSave(const char* save_path);
|
||||
|
||||
void SetSIODriver();
|
||||
|
|
|
|||
|
|
@ -211,6 +211,15 @@ void GameCubePane::CreateWidgets()
|
|||
gba_layout->addWidget(m_gba_browse_bios, gba_row, 2);
|
||||
gba_row++;
|
||||
|
||||
m_gba_cgb_boot_rom_edit =
|
||||
new ConfigUserPath(F_GBACGBBOOTROM_IDX, Config::MAIN_GBA_CGB_BOOT_ROM_PATH);
|
||||
m_gba_browse_cgb_boot_rom = new NonDefaultQPushButton(QStringLiteral("..."));
|
||||
|
||||
gba_layout->addWidget(new QLabel(tr("Game Boy Color Boot ROM:")), gba_row, 0);
|
||||
gba_layout->addWidget(m_gba_cgb_boot_rom_edit, gba_row, 1);
|
||||
gba_layout->addWidget(m_gba_browse_cgb_boot_rom, gba_row, 2);
|
||||
gba_row++;
|
||||
|
||||
for (size_t i = 0; i < m_gba_rom_edits.size(); ++i)
|
||||
{
|
||||
m_gba_rom_edits[i] = new ConfigText(Config::MAIN_GBA_ROM_PATHS[i]);
|
||||
|
|
@ -279,6 +288,8 @@ void GameCubePane::ConnectWidgets()
|
|||
#ifdef HAS_LIBMGBA
|
||||
// GBA Settings
|
||||
connect(m_gba_browse_bios, &QPushButton::clicked, this, &GameCubePane::BrowseGBABios);
|
||||
connect(m_gba_browse_cgb_boot_rom, &QPushButton::clicked, this,
|
||||
&GameCubePane::BrowseGBACGBBootRom);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)
|
||||
connect(m_gba_save_rom_path, &QCheckBox::checkStateChanged, this,
|
||||
&GameCubePane::SaveRomPathChanged);
|
||||
|
|
@ -696,6 +707,16 @@ void GameCubePane::BrowseGBABios()
|
|||
m_gba_bios_edit->SetTextAndUpdate(file);
|
||||
}
|
||||
|
||||
void GameCubePane::BrowseGBACGBBootRom()
|
||||
{
|
||||
QString file = QDir::toNativeSeparators(DolphinFileDialog::getOpenFileName(
|
||||
this, tr("Select GBC boot ROM"),
|
||||
QString::fromStdString(Config::Get(Config::MAIN_GBA_CGB_BOOT_ROM_PATH)),
|
||||
tr("All Files (*)")));
|
||||
if (!file.isEmpty())
|
||||
m_gba_cgb_boot_rom_edit->SetTextAndUpdate(file);
|
||||
}
|
||||
|
||||
void GameCubePane::BrowseGBARom(size_t index)
|
||||
{
|
||||
QString file = QString::fromStdString(GetOpenGBARom({}));
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ private:
|
|||
|
||||
#ifdef HAS_LIBMGBA
|
||||
void BrowseGBABios();
|
||||
void BrowseGBACGBBootRom();
|
||||
void BrowseGBARom(size_t index);
|
||||
void SaveRomPathChanged();
|
||||
void BrowseGBASaves();
|
||||
|
|
@ -84,6 +85,8 @@ private:
|
|||
ConfigBool* m_gba_save_rom_path;
|
||||
QPushButton* m_gba_browse_bios;
|
||||
ConfigUserPath* m_gba_bios_edit;
|
||||
QPushButton* m_gba_browse_cgb_boot_rom;
|
||||
ConfigUserPath* m_gba_cgb_boot_rom_edit;
|
||||
std::array<QPushButton*, 5> m_gba_browse_roms;
|
||||
std::array<ConfigText*, 5> m_gba_rom_edits;
|
||||
QPushButton* m_gba_browse_saves;
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ static void InitCustomPaths()
|
|||
File::CreateFullPath(File::GetUserPath(D_WIISDCARDSYNCFOLDER_IDX));
|
||||
#ifdef HAS_LIBMGBA
|
||||
File::SetUserPath(F_GBABIOS_IDX, Config::Get(Config::MAIN_GBA_BIOS_PATH));
|
||||
File::SetUserPath(F_GBACGBBOOTROM_IDX, Config::Get(Config::MAIN_GBA_CGB_BOOT_ROM_PATH));
|
||||
File::SetUserPath(D_GBASAVES_IDX, Config::Get(Config::MAIN_GBA_SAVES_PATH));
|
||||
File::CreateFullPath(File::GetUserPath(D_GBASAVES_IDX));
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user