[GB] Add support for per-game overrides (#1370)
* [GB] Add support for per-game overrides Alleyway is a buggy game that does not work properly when a Game Boy Printer is connected. In order to work around this issue, this adds upport for built-in per-software Game Boy overrides. In addition, this renames various variables to make their meaning clearer. * This only supports built-in overrides. External INI files are not supported. * Only the Game Boy Printer option is supported, this only takes effect on game startup and the general configuration option is restored when the game is unloaded. * As a result, it is possible to override the per-game override by manually setting the option while the game is running, this is working as intended. * Future refactors of the option handling will manage overrides better. * Switch `gbPrinterEnabled` default to off. Fixes #1368
This commit is contained in:
parent
611f3a3409
commit
a8ec85d536
|
@ -70,7 +70,7 @@ extern struct CoreOptions {
|
|||
int skipSaveGameBattery = 1;
|
||||
int skipSaveGameCheats = 0;
|
||||
int useBios = 0;
|
||||
int winGbPrinterEnabled = 1;
|
||||
int gbPrinterEnabled = 0;
|
||||
uint32_t speedup_throttle = 100;
|
||||
uint32_t speedup_frame_skip = 9;
|
||||
uint32_t throttle = 100;
|
||||
|
|
|
@ -1416,7 +1416,7 @@ void gbWriteMemory(uint16_t address, uint8_t value)
|
|||
EmuReseted = false;
|
||||
gbMemory[0xff02] = value;
|
||||
if (gbSerialOn && (GetLinkMode() == LINK_GAMEBOY_IPC || GetLinkMode() == LINK_GAMEBOY_SOCKET
|
||||
|| GetLinkMode() == LINK_DISCONNECTED || coreOptions.winGbPrinterEnabled)) {
|
||||
|| GetLinkMode() == LINK_DISCONNECTED || coreOptions.gbPrinterEnabled)) {
|
||||
|
||||
gbSerialTicks = GBSERIAL_CLOCK_TICKS;
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
# Game Boy Overrrides
|
||||
|
||||
[ALLEY WAY]
|
||||
gbPrinter = 0
|
|
@ -590,7 +590,7 @@ void retro_init(void)
|
|||
coreOptions.parseDebug = true;
|
||||
coreOptions.cheatsEnabled = 0;
|
||||
coreOptions.skipSaveGameBattery = 0;
|
||||
coreOptions.winGbPrinterEnabled = 0;
|
||||
coreOptions.gbPrinterEnabled = 0;
|
||||
|
||||
struct retro_log_callback log;
|
||||
struct retro_rumble_interface rumble;
|
||||
|
|
|
@ -189,7 +189,7 @@ struct option argOptions[] = {
|
|||
{ "gb-emulator-type", required_argument, 0, OPT_GB_EMULATOR_TYPE },
|
||||
{ "gb-frame-skip", required_argument, 0, OPT_GB_FRAME_SKIP },
|
||||
{ "gb-palette-option", required_argument, 0, OPT_GB_PALETTE_OPTION },
|
||||
{ "gb-printer", no_argument, &coreOptions.winGbPrinterEnabled, 1 },
|
||||
{ "gb-printer", no_argument, &coreOptions.gbPrinterEnabled, 1 },
|
||||
{ "gdb", required_argument, 0, 'G' },
|
||||
{ "help", no_argument, &optPrintUsage, 1 },
|
||||
{ "ifb-filter", required_argument, 0, 'I' },
|
||||
|
@ -236,7 +236,7 @@ struct option argOptions[] = {
|
|||
{ "no-speedup-mute", no_argument, 0, OPT_NO_SPEEDUP_MUTE },
|
||||
{ "use-bios", no_argument, &coreOptions.useBios, 1 },
|
||||
{ "verbose", required_argument, 0, 'v' },
|
||||
{ "win-gb-printer-enabled", no_argument, &coreOptions.winGbPrinterEnabled, 1 },
|
||||
{ "win-gb-printer-enabled", no_argument, &coreOptions.gbPrinterEnabled, 1 },
|
||||
|
||||
|
||||
{ NULL, no_argument, NULL, 0 }
|
||||
|
@ -351,7 +351,7 @@ void LoadConfig()
|
|||
coreOptions.speedup_throttle_frame_skip = ReadPref("speedupThrottleFrameSkip", 0);
|
||||
coreOptions.speedup_mute = ReadPref("speedupMute", 1);
|
||||
coreOptions.useBios = ReadPrefHex("useBiosGBA");
|
||||
coreOptions.winGbPrinterEnabled = ReadPref("gbPrinter", 0);
|
||||
coreOptions.gbPrinterEnabled = ReadPref("gbPrinter", 0);
|
||||
|
||||
int soundQuality = (ReadPrefHex("soundQuality", 1));
|
||||
switch (soundQuality) {
|
||||
|
|
|
@ -59,6 +59,7 @@ set(VBAM_WX_COMMON
|
|||
${VBAM_GENERATED_DIR}/wx/builtin-over.h
|
||||
${VBAM_GENERATED_DIR}/wx/cmdhandlers.h
|
||||
${VBAM_GENERATED_DIR}/wx/cmd-evtable.h
|
||||
${VBAM_GENERATED_DIR}/wx/gb-builtin-over.h
|
||||
)
|
||||
|
||||
if(NOT ZIP_PROGRAM)
|
||||
|
@ -642,6 +643,12 @@ add_custom_command(
|
|||
DEPENDS ${CMAKE_SOURCE_DIR}/src/vba-over.ini ${BIN2C}
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${VBAM_GENERATED_DIR}/wx/gb-builtin-over.h
|
||||
COMMAND ${BIN2C} ${CMAKE_SOURCE_DIR}/src/gb-over.ini ${VBAM_GENERATED_DIR}/wx/gb-builtin-over.h gb_builtin_over
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/src/gb-over.ini ${BIN2C}
|
||||
)
|
||||
|
||||
set(VBAM_LOCALIZABLE_FILES ${VBAM_WX_COMMON} ${VBAM_LOCALIZABLE_WX_CONFIG_FILES})
|
||||
list(APPEND VBAM_LOCALIZABLE_FILES
|
||||
audio/internal/dsound.cpp
|
||||
|
|
|
@ -1990,7 +1990,7 @@ EVT_HANDLER(GameBoyAdvanceConfigure, "Game Boy Advance options...")
|
|||
XRCCTRL(*dlg, "GameCode", wxControl)
|
||||
->SetLabel(s);
|
||||
cmt = wxString((const char*)&g_rom[0xa0], wxConvLibc, 12);
|
||||
wxFileConfig* cfg = wxGetApp().overrides;
|
||||
wxFileConfig* cfg = wxGetApp().overrides_.get();
|
||||
|
||||
if (cfg->HasGroup(s)) {
|
||||
cfg->SetPath(s);
|
||||
|
@ -2024,7 +2024,7 @@ EVT_HANDLER(GameBoyAdvanceConfigure, "Game Boy Advance options...")
|
|||
if (panel->game_type() == IMAGE_GBA) {
|
||||
agbPrintEnable(OPTION(kPrefAgbPrint));
|
||||
wxString s = wxString((const char*)&g_rom[0xac], wxConvLibc, 4);
|
||||
wxFileConfig* cfg = wxGetApp().overrides;
|
||||
wxFileConfig* cfg = wxGetApp().overrides_.get();
|
||||
bool chg;
|
||||
|
||||
if (cfg->HasGroup(s)) {
|
||||
|
@ -2297,7 +2297,7 @@ EVT_HANDLER(RetainAspect, "Retain aspect ratio when resizing")
|
|||
|
||||
EVT_HANDLER(Printer, "Enable printer emulation")
|
||||
{
|
||||
GetMenuOptionInt("Printer", &coreOptions.winGbPrinterEnabled, 1);
|
||||
GetMenuOptionInt("Printer", &coreOptions.gbPrinterEnabled, 1);
|
||||
#if (defined __WIN32__ || defined _WIN32)
|
||||
#ifndef NO_LINK
|
||||
gbSerialFunction = gbStartLink;
|
||||
|
@ -2305,7 +2305,7 @@ EVT_HANDLER(Printer, "Enable printer emulation")
|
|||
gbSerialFunction = NULL;
|
||||
#endif
|
||||
#endif
|
||||
if (coreOptions.winGbPrinterEnabled)
|
||||
if (coreOptions.gbPrinterEnabled)
|
||||
gbSerialFunction = gbPrinterSend;
|
||||
|
||||
update_opts();
|
||||
|
|
|
@ -312,7 +312,7 @@ std::array<Option, kNbOptions>& Option::All() {
|
|||
Option(OptionID::kPrefFlashSize, &g_owned_opts.flash_size, 0, 1),
|
||||
Option(OptionID::kPrefFrameSkip, &g_owned_opts.frame_skip, -1, 9),
|
||||
Option(OptionID::kPrefGBPaletteOption, &gbPaletteOption, 0, 2),
|
||||
Option(OptionID::kPrefGBPrinter, &coreOptions.winGbPrinterEnabled, 0, 1),
|
||||
Option(OptionID::kPrefGBPrinter, &coreOptions.gbPrinterEnabled, 0, 1),
|
||||
Option(OptionID::kPrefGDBBreakOnLoad, &g_owned_opts.gdb_break_on_load),
|
||||
Option(OptionID::kPrefGDBPort, &gopts.gdb_port, 0, 65535),
|
||||
#ifndef NO_LINK
|
||||
|
|
|
@ -287,6 +287,15 @@ void GameArea::LoadGame(const wxString& name)
|
|||
gbApplyPatch(UTF8(pfn.GetFullPath()));
|
||||
}
|
||||
|
||||
// Apply overrides.
|
||||
wxFileConfig* cfg = wxGetApp().gb_overrides_.get();
|
||||
const std::string& title = g_gbCartData.title();
|
||||
if (cfg->HasGroup(title)) {
|
||||
cfg->SetPath(title);
|
||||
coreOptions.gbPrinterEnabled = cfg->Read("gbPrinter", coreOptions.gbPrinterEnabled);
|
||||
cfg->SetPath("/");
|
||||
}
|
||||
|
||||
// start sound; this must happen before CPU stuff
|
||||
gb_effects_config.enabled = OPTION(kSoundGBEnableEffects);
|
||||
gb_effects_config.surround = OPTION(kSoundGBSurround);
|
||||
|
@ -359,7 +368,7 @@ void GameArea::LoadGame(const wxString& name)
|
|||
gbaUpdateRomSize(size);
|
||||
}
|
||||
|
||||
wxFileConfig* cfg = wxGetApp().overrides;
|
||||
wxFileConfig* cfg = wxGetApp().overrides_.get();
|
||||
wxString id = wxString((const char*)&g_rom[0xac], wxConvLibc, 4);
|
||||
|
||||
if (cfg->HasGroup(id)) {
|
||||
|
@ -456,7 +465,7 @@ void GameArea::LoadGame(const wxString& name)
|
|||
SuspendScreenSaver();
|
||||
|
||||
// probably only need to do this for GB carts
|
||||
if (coreOptions.winGbPrinterEnabled)
|
||||
if (coreOptions.gbPrinterEnabled)
|
||||
gbSerialFunction = gbPrinterSend;
|
||||
|
||||
// probably only need to do this for GBA carts
|
||||
|
@ -666,6 +675,9 @@ void GameArea::UnloadGame(bool destruct)
|
|||
if (loaded == IMAGE_GB) {
|
||||
gbCleanUp();
|
||||
gbCheatRemoveAll();
|
||||
|
||||
// Reset overrides.
|
||||
coreOptions.gbPrinterEnabled = OPTION(kPrefGBPrinter);
|
||||
} else if (loaded == IMAGE_GBA) {
|
||||
CPUCleanUp();
|
||||
cheatsDeleteAll(false);
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "components/user_config/user_config.h"
|
||||
#include "core/gba/gbaSound.h"
|
||||
#include "wx/gb-builtin-over.h"
|
||||
#include "wx/builtin-over.h"
|
||||
#include "wx/builtin-xrc.h"
|
||||
#include "wx/config/cmdtab.h"
|
||||
|
@ -470,13 +471,17 @@ bool wxvbamApp::OnInit() {
|
|||
}
|
||||
}
|
||||
|
||||
// load gb-over.ini
|
||||
wxMemoryInputStream stream(gb_builtin_over, sizeof(gb_builtin_over));
|
||||
gb_overrides_ = std::make_unique<wxFileConfig>(stream);
|
||||
|
||||
// load vba-over.ini
|
||||
// rather than dealing with wxConfig's broken search path, just use
|
||||
// the same one that the xrc overrides use
|
||||
// this also allows us to override a group at a time, add commments, and
|
||||
// add the file from which the group came
|
||||
wxMemoryInputStream mis(builtin_over, sizeof(builtin_over));
|
||||
overrides = new wxFileConfig(mis);
|
||||
overrides_ = std::make_unique<wxFileConfig>(mis);
|
||||
wxRegEx cmtre;
|
||||
// not the most efficient thing to do: read entire file into a string
|
||||
// just to parse the comments out
|
||||
|
@ -486,8 +491,8 @@ bool wxvbamApp::OnInit() {
|
|||
long grp_idx;
|
||||
#define CMT_RE_START wxT("(^|[\n\r])# ?([^\n\r]*)(\r?\n|\r)\\[")
|
||||
|
||||
for (cont = overrides->GetFirstGroup(s, grp_idx); cont;
|
||||
cont = overrides->GetNextGroup(s, grp_idx)) {
|
||||
for (cont = overrides_->GetFirstGroup(s, grp_idx); cont;
|
||||
cont = overrides_->GetNextGroup(s, grp_idx)) {
|
||||
// apparently even MacOSX sometimes uses the old \r by itself
|
||||
wxString cmt(CMT_RE_START);
|
||||
cmt += s + wxT("\\]");
|
||||
|
@ -497,7 +502,7 @@ bool wxvbamApp::OnInit() {
|
|||
else
|
||||
cmt = wxEmptyString;
|
||||
|
||||
overrides->Write(s + wxT("/comment"), cmt);
|
||||
overrides_->Write(s + wxT("/comment"), cmt);
|
||||
}
|
||||
|
||||
if (vba_over.FileExists()) {
|
||||
|
@ -513,10 +518,10 @@ bool wxvbamApp::OnInit() {
|
|||
|
||||
for (cont = ov.GetFirstGroup(s, grp_idx); cont;
|
||||
cont = ov.GetNextGroup(s, grp_idx)) {
|
||||
overrides->DeleteGroup(s);
|
||||
overrides->SetPath(s);
|
||||
overrides_->DeleteGroup(s);
|
||||
overrides_->SetPath(s);
|
||||
ov.SetPath(s);
|
||||
overrides->Write(wxT("path"), GetConfigurationPath());
|
||||
overrides_->Write(wxT("path"), GetConfigurationPath());
|
||||
// apparently even MacOSX sometimes uses \r by itself
|
||||
wxString cmt(CMT_RE_START);
|
||||
cmt += s + wxT("\\]");
|
||||
|
@ -526,15 +531,15 @@ bool wxvbamApp::OnInit() {
|
|||
else
|
||||
cmt = wxEmptyString;
|
||||
|
||||
overrides->Write(wxT("comment"), cmt);
|
||||
overrides_->Write(wxT("comment"), cmt);
|
||||
long ent_idx;
|
||||
|
||||
for (cont = ov.GetFirstEntry(s, ent_idx); cont;
|
||||
cont = ov.GetNextEntry(s, ent_idx))
|
||||
overrides->Write(s, ov.Read(s, wxEmptyString));
|
||||
overrides_->Write(s, ov.Read(s, wxEmptyString));
|
||||
|
||||
ov.SetPath(wxT("/"));
|
||||
overrides->SetPath(wxT("/"));
|
||||
overrides_->SetPath(wxT("/"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -822,7 +827,6 @@ wxvbamApp::~wxvbamApp() {
|
|||
free(home);
|
||||
home = NULL;
|
||||
}
|
||||
delete overrides;
|
||||
|
||||
#ifndef NO_ONLINEUPDATES
|
||||
shutdownAutoupdater();
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
#ifndef VBAM_WX_WXVBAM_H_
|
||||
#define VBAM_WX_WXVBAM_H_
|
||||
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <wx/log.h>
|
||||
#include <wx/propdlg.h>
|
||||
#include <wx/datetime.h>
|
||||
|
@ -106,7 +108,8 @@ public:
|
|||
widgets::SdlPoller* sdl_poller() { return &sdl_poller_; }
|
||||
|
||||
// vba-over.ini
|
||||
wxFileConfig* overrides = nullptr;
|
||||
std::unique_ptr<wxFileConfig> overrides_;
|
||||
std::unique_ptr<wxFileConfig> gb_overrides_;
|
||||
|
||||
wxFileName rom_database;
|
||||
wxFileName rom_database_scene;
|
||||
|
|
Loading…
Reference in New Issue