Core: Begin modernizing game override API (fixes #2963)

This commit is contained in:
Vicki Pfau 2023-06-26 04:43:23 -07:00
parent 4d94ab7a38
commit 200e846b81
10 changed files with 50 additions and 33 deletions

View File

@ -16,6 +16,7 @@ Emulation fixes:
- GBA BIOS: Fix clobbering registers with word-sized CpuSet
- GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722)
Other fixes:
- Core: Fix inconsistencies with setting game-specific overrides (fixes mgba.io/i/2963)
- Debugger: Fix writing to specific segment in command-line debugger
- mGUI: Fix cases where an older save state screenshot would be shown. (fixes mgba.io/i/2183)
- Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560)

View File

@ -65,6 +65,7 @@ struct mCore {
void (*setSync)(struct mCore*, struct mCoreSync*);
void (*loadConfig)(struct mCore*, const struct mCoreConfig*);
void (*reloadConfigOption)(struct mCore*, const char* option, const struct mCoreConfig*);
void (*setOverride)(struct mCore*, const void* override);
void (*baseVideoSize)(const struct mCore*, unsigned* width, unsigned* height);
void (*currentVideoSize)(const struct mCore*, unsigned* width, unsigned* height);

View File

@ -99,6 +99,8 @@ struct GBCore {
uint8_t keys;
struct mCPUComponent* components[CPU_COMPONENT_MAX];
const struct Configuration* overrides;
struct GBCartridgeOverride override;
bool hasOverride;
struct mDebuggerPlatform* debuggerPlatform;
struct mCheatDevice* cheatDevice;
struct mCoreMemoryBlock memoryBlocks[8];
@ -124,6 +126,8 @@ static bool _GBCoreInit(struct mCore* core) {
gbcore->logContext = NULL;
#endif
memcpy(gbcore->memoryBlocks, _GBMemoryBlocks, sizeof(_GBMemoryBlocks));
memset(&gbcore->override, 0, sizeof(gbcore->override));
gbcore->hasOverride = false;
GBCreate(gb);
memset(gbcore->components, 0, sizeof(gbcore->components));
@ -364,6 +368,12 @@ static void _GBCoreReloadConfigOption(struct mCore* core, const char* option, co
}
}
static void _GBCoreSetOverride(struct mCore* core, const void* override) {
struct GBCore* gbcore = (struct GBCore*) core;
memcpy(&gbcore->override, override, sizeof(gbcore->override));
gbcore->hasOverride = true;
}
static void _GBCoreBaseVideoSize(const struct mCore* core, unsigned* width, unsigned* height) {
UNUSED(core);
*width = SGB_VIDEO_HORIZONTAL_PIXELS;
@ -541,14 +551,15 @@ static void _GBCoreReset(struct mCore* core) {
mCoreConfigGetIntValue(&core->config, "useCgbColors", &doColorOverride);
}
struct GBCartridgeOverride override;
const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100];
override.headerCrc32 = doCrc32(cart, sizeof(*cart));
bool modelOverride = GBOverrideFind(gbcore->overrides, &override) || (doColorOverride && GBOverrideColorFind(&override, doColorOverride));
if (modelOverride) {
GBOverrideApply(gb, &override);
if (!gbcore->hasOverride) {
gbcore->override.headerCrc32 = doCrc32(cart, sizeof(*cart));
gbcore->hasOverride = GBOverrideFind(gbcore->overrides, &gbcore->override) || (doColorOverride && GBOverrideColorFind(&gbcore->override, doColorOverride));
}
if (!modelOverride || override.model == GB_MODEL_AUTODETECT) {
if (gbcore->hasOverride) {
GBOverrideApply(gb, &gbcore->override);
}
if (!gbcore->hasOverride || gbcore->override.model == GB_MODEL_AUTODETECT) {
const char* modelGB = mCoreConfigGetValue(&core->config, "gb.model");
const char* modelSGB = mCoreConfigGetValue(&core->config, "sgb.model");
const char* modelCGB = mCoreConfigGetValue(&core->config, "cgb.model");
@ -1280,6 +1291,7 @@ struct mCore* GBCoreCreate(void) {
core->setSync = _GBCoreSetSync;
core->loadConfig = _GBCoreLoadConfig;
core->reloadConfigOption = _GBCoreReloadConfigOption;
core->setOverride = _GBCoreSetOverride;
core->baseVideoSize = _GBCoreBaseVideoSize;
core->currentVideoSize = _GBCoreCurrentVideoSize;
core->videoScale = _GBCoreVideoScale;

View File

@ -182,6 +182,8 @@ struct GBACore {
#endif
struct mCPUComponent* components[CPU_COMPONENT_MAX];
const struct Configuration* overrides;
struct GBACartridgeOverride override;
bool hasOverride;
struct mDebuggerPlatform* debuggerPlatform;
struct mCheatDevice* cheatDevice;
struct GBAAudioMixer* audioMixer;
@ -426,6 +428,12 @@ static void _GBACoreReloadConfigOption(struct mCore* core, const char* option, c
}
}
static void _GBACoreSetOverride(struct mCore* core, const void* override) {
struct GBACore* gbacore = (struct GBACore*) core;
memcpy(&gbacore->override, override, sizeof(gbacore->override));
gbacore->hasOverride = true;
}
static void _GBACoreBaseVideoSize(const struct mCore* core, unsigned* width, unsigned* height) {
UNUSED(core);
*width = GBA_VIDEO_HORIZONTAL_PIXELS;
@ -678,7 +686,11 @@ static void _GBACoreReset(struct mCore* core) {
if (!forceGbp) {
gba->memory.hw.devices &= ~HW_GB_PLAYER_DETECTION;
}
GBAOverrideApplyDefaults(gba, gbacore->overrides);
if (gbacore->hasOverride) {
GBAOverrideApply(gba, &gbacore->override);
} else {
GBAOverrideApplyDefaults(gba, gbacore->overrides);
}
if (forceGbp) {
gba->memory.hw.devices |= HW_GB_PLAYER_DETECTION;
}
@ -1405,6 +1417,7 @@ struct mCore* GBACoreCreate(void) {
core->setSync = _GBACoreSetSync;
core->loadConfig = _GBACoreLoadConfig;
core->reloadConfigOption = _GBACoreReloadConfigOption;
core->setOverride = _GBACoreSetOverride;
core->baseVideoSize = _GBACoreBaseVideoSize;
core->currentVideoSize = _GBACoreCurrentVideoSize;
core->videoScale = _GBACoreVideoScale;

View File

@ -79,6 +79,11 @@ CoreController::CoreController(mCore* core, QObject* parent)
controller->updatePlayerSave();
}
if (controller->m_override) {
controller->m_override->identify(context->core);
context->core->setOverride(context->core, controller->m_override->raw());
}
QMetaObject::invokeMethod(controller, "started");
};
@ -88,11 +93,6 @@ CoreController::CoreController(mCore* core, QObject* parent)
action();
}
if (controller->m_override) {
controller->m_override->identify(context->core);
controller->m_override->apply(context->core);
}
controller->m_resetActions.clear();
controller->m_frameCounter = -1;

View File

@ -10,17 +10,6 @@
using namespace QGBA;
void GBAOverride::apply(struct mCore* core) {
if (core->platform(core) != mPLATFORM_GBA) {
return;
}
GBA* gba = static_cast<GBA*>(core->board);
if (!vbaBugCompatSet) {
override.vbaBugCompat = gba->vbaBugCompat;
}
GBAOverrideApply(gba, &override);
}
void GBAOverride::identify(const struct mCore* core) {
if (core->platform(core) != mPLATFORM_GBA) {
return;
@ -33,3 +22,7 @@ void GBAOverride::identify(const struct mCore* core) {
void GBAOverride::save(struct Configuration* config) const {
GBAOverrideSave(config, &override);
}
const void* GBAOverride::raw() const {
return &override;
}

View File

@ -13,9 +13,9 @@ namespace QGBA {
class GBAOverride : public Override {
public:
void apply(struct mCore*) override;
void identify(const struct mCore*) override;
void save(struct Configuration*) const override;
const void* raw() const override;
struct GBACartridgeOverride override;
bool vbaBugCompatSet;

View File

@ -11,13 +11,6 @@
using namespace QGBA;
void GBOverride::apply(struct mCore* core) {
if (core->platform(core) != mPLATFORM_GB) {
return;
}
GBOverrideApply(static_cast<GB*>(core->board), &override);
}
void GBOverride::identify(const struct mCore* core) {
if (core->platform(core) != mPLATFORM_GB) {
return;
@ -32,3 +25,7 @@ void GBOverride::identify(const struct mCore* core) {
void GBOverride::save(struct Configuration* config) const {
GBOverrideSave(config, &override);
}
const void* GBOverride::raw() const {
return &override;
}

View File

@ -13,9 +13,9 @@ namespace QGBA {
class GBOverride : public Override {
public:
void apply(struct mCore*) override;
void identify(const struct mCore*) override;
void save(struct Configuration*) const override;
const void* raw() const override;
struct GBCartridgeOverride override;
};

View File

@ -14,9 +14,9 @@ class Override {
public:
virtual ~Override() {}
virtual void apply(struct mCore*) = 0;
virtual void identify(const struct mCore*) = 0;
virtual void save(struct Configuration*) const = 0;
virtual const void* raw() const = 0;
};
}