mirror of https://github.com/mgba-emu/mgba.git
Core: Begin modernizing game override API (fixes #2963)
This commit is contained in:
parent
4d94ab7a38
commit
200e846b81
1
CHANGES
1
CHANGES
|
@ -16,6 +16,7 @@ Emulation fixes:
|
||||||
- GBA BIOS: Fix clobbering registers with word-sized CpuSet
|
- GBA BIOS: Fix clobbering registers with word-sized CpuSet
|
||||||
- GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722)
|
- GBA Video: Disable BG target 1 blending when OBJ blending (fixes mgba.io/i/2722)
|
||||||
Other fixes:
|
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
|
- 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)
|
- 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)
|
- Qt: Fix savestate preview sizes with different scales (fixes mgba.io/i/2560)
|
||||||
|
|
|
@ -65,6 +65,7 @@ struct mCore {
|
||||||
void (*setSync)(struct mCore*, struct mCoreSync*);
|
void (*setSync)(struct mCore*, struct mCoreSync*);
|
||||||
void (*loadConfig)(struct mCore*, const struct mCoreConfig*);
|
void (*loadConfig)(struct mCore*, const struct mCoreConfig*);
|
||||||
void (*reloadConfigOption)(struct mCore*, const char* option, 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 (*baseVideoSize)(const struct mCore*, unsigned* width, unsigned* height);
|
||||||
void (*currentVideoSize)(const struct mCore*, unsigned* width, unsigned* height);
|
void (*currentVideoSize)(const struct mCore*, unsigned* width, unsigned* height);
|
||||||
|
|
|
@ -99,6 +99,8 @@ struct GBCore {
|
||||||
uint8_t keys;
|
uint8_t keys;
|
||||||
struct mCPUComponent* components[CPU_COMPONENT_MAX];
|
struct mCPUComponent* components[CPU_COMPONENT_MAX];
|
||||||
const struct Configuration* overrides;
|
const struct Configuration* overrides;
|
||||||
|
struct GBCartridgeOverride override;
|
||||||
|
bool hasOverride;
|
||||||
struct mDebuggerPlatform* debuggerPlatform;
|
struct mDebuggerPlatform* debuggerPlatform;
|
||||||
struct mCheatDevice* cheatDevice;
|
struct mCheatDevice* cheatDevice;
|
||||||
struct mCoreMemoryBlock memoryBlocks[8];
|
struct mCoreMemoryBlock memoryBlocks[8];
|
||||||
|
@ -124,6 +126,8 @@ static bool _GBCoreInit(struct mCore* core) {
|
||||||
gbcore->logContext = NULL;
|
gbcore->logContext = NULL;
|
||||||
#endif
|
#endif
|
||||||
memcpy(gbcore->memoryBlocks, _GBMemoryBlocks, sizeof(_GBMemoryBlocks));
|
memcpy(gbcore->memoryBlocks, _GBMemoryBlocks, sizeof(_GBMemoryBlocks));
|
||||||
|
memset(&gbcore->override, 0, sizeof(gbcore->override));
|
||||||
|
gbcore->hasOverride = false;
|
||||||
|
|
||||||
GBCreate(gb);
|
GBCreate(gb);
|
||||||
memset(gbcore->components, 0, sizeof(gbcore->components));
|
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) {
|
static void _GBCoreBaseVideoSize(const struct mCore* core, unsigned* width, unsigned* height) {
|
||||||
UNUSED(core);
|
UNUSED(core);
|
||||||
*width = SGB_VIDEO_HORIZONTAL_PIXELS;
|
*width = SGB_VIDEO_HORIZONTAL_PIXELS;
|
||||||
|
@ -541,14 +551,15 @@ static void _GBCoreReset(struct mCore* core) {
|
||||||
mCoreConfigGetIntValue(&core->config, "useCgbColors", &doColorOverride);
|
mCoreConfigGetIntValue(&core->config, "useCgbColors", &doColorOverride);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GBCartridgeOverride override;
|
|
||||||
const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100];
|
const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100];
|
||||||
override.headerCrc32 = doCrc32(cart, sizeof(*cart));
|
if (!gbcore->hasOverride) {
|
||||||
bool modelOverride = GBOverrideFind(gbcore->overrides, &override) || (doColorOverride && GBOverrideColorFind(&override, doColorOverride));
|
gbcore->override.headerCrc32 = doCrc32(cart, sizeof(*cart));
|
||||||
if (modelOverride) {
|
gbcore->hasOverride = GBOverrideFind(gbcore->overrides, &gbcore->override) || (doColorOverride && GBOverrideColorFind(&gbcore->override, doColorOverride));
|
||||||
GBOverrideApply(gb, &override);
|
|
||||||
}
|
}
|
||||||
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* modelGB = mCoreConfigGetValue(&core->config, "gb.model");
|
||||||
const char* modelSGB = mCoreConfigGetValue(&core->config, "sgb.model");
|
const char* modelSGB = mCoreConfigGetValue(&core->config, "sgb.model");
|
||||||
const char* modelCGB = mCoreConfigGetValue(&core->config, "cgb.model");
|
const char* modelCGB = mCoreConfigGetValue(&core->config, "cgb.model");
|
||||||
|
@ -1280,6 +1291,7 @@ struct mCore* GBCoreCreate(void) {
|
||||||
core->setSync = _GBCoreSetSync;
|
core->setSync = _GBCoreSetSync;
|
||||||
core->loadConfig = _GBCoreLoadConfig;
|
core->loadConfig = _GBCoreLoadConfig;
|
||||||
core->reloadConfigOption = _GBCoreReloadConfigOption;
|
core->reloadConfigOption = _GBCoreReloadConfigOption;
|
||||||
|
core->setOverride = _GBCoreSetOverride;
|
||||||
core->baseVideoSize = _GBCoreBaseVideoSize;
|
core->baseVideoSize = _GBCoreBaseVideoSize;
|
||||||
core->currentVideoSize = _GBCoreCurrentVideoSize;
|
core->currentVideoSize = _GBCoreCurrentVideoSize;
|
||||||
core->videoScale = _GBCoreVideoScale;
|
core->videoScale = _GBCoreVideoScale;
|
||||||
|
|
|
@ -182,6 +182,8 @@ struct GBACore {
|
||||||
#endif
|
#endif
|
||||||
struct mCPUComponent* components[CPU_COMPONENT_MAX];
|
struct mCPUComponent* components[CPU_COMPONENT_MAX];
|
||||||
const struct Configuration* overrides;
|
const struct Configuration* overrides;
|
||||||
|
struct GBACartridgeOverride override;
|
||||||
|
bool hasOverride;
|
||||||
struct mDebuggerPlatform* debuggerPlatform;
|
struct mDebuggerPlatform* debuggerPlatform;
|
||||||
struct mCheatDevice* cheatDevice;
|
struct mCheatDevice* cheatDevice;
|
||||||
struct GBAAudioMixer* audioMixer;
|
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) {
|
static void _GBACoreBaseVideoSize(const struct mCore* core, unsigned* width, unsigned* height) {
|
||||||
UNUSED(core);
|
UNUSED(core);
|
||||||
*width = GBA_VIDEO_HORIZONTAL_PIXELS;
|
*width = GBA_VIDEO_HORIZONTAL_PIXELS;
|
||||||
|
@ -678,7 +686,11 @@ static void _GBACoreReset(struct mCore* core) {
|
||||||
if (!forceGbp) {
|
if (!forceGbp) {
|
||||||
gba->memory.hw.devices &= ~HW_GB_PLAYER_DETECTION;
|
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) {
|
if (forceGbp) {
|
||||||
gba->memory.hw.devices |= HW_GB_PLAYER_DETECTION;
|
gba->memory.hw.devices |= HW_GB_PLAYER_DETECTION;
|
||||||
}
|
}
|
||||||
|
@ -1405,6 +1417,7 @@ struct mCore* GBACoreCreate(void) {
|
||||||
core->setSync = _GBACoreSetSync;
|
core->setSync = _GBACoreSetSync;
|
||||||
core->loadConfig = _GBACoreLoadConfig;
|
core->loadConfig = _GBACoreLoadConfig;
|
||||||
core->reloadConfigOption = _GBACoreReloadConfigOption;
|
core->reloadConfigOption = _GBACoreReloadConfigOption;
|
||||||
|
core->setOverride = _GBACoreSetOverride;
|
||||||
core->baseVideoSize = _GBACoreBaseVideoSize;
|
core->baseVideoSize = _GBACoreBaseVideoSize;
|
||||||
core->currentVideoSize = _GBACoreCurrentVideoSize;
|
core->currentVideoSize = _GBACoreCurrentVideoSize;
|
||||||
core->videoScale = _GBACoreVideoScale;
|
core->videoScale = _GBACoreVideoScale;
|
||||||
|
|
|
@ -79,6 +79,11 @@ CoreController::CoreController(mCore* core, QObject* parent)
|
||||||
controller->updatePlayerSave();
|
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");
|
QMetaObject::invokeMethod(controller, "started");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,11 +93,6 @@ CoreController::CoreController(mCore* core, QObject* parent)
|
||||||
action();
|
action();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller->m_override) {
|
|
||||||
controller->m_override->identify(context->core);
|
|
||||||
controller->m_override->apply(context->core);
|
|
||||||
}
|
|
||||||
|
|
||||||
controller->m_resetActions.clear();
|
controller->m_resetActions.clear();
|
||||||
controller->m_frameCounter = -1;
|
controller->m_frameCounter = -1;
|
||||||
|
|
||||||
|
|
|
@ -10,17 +10,6 @@
|
||||||
|
|
||||||
using namespace QGBA;
|
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) {
|
void GBAOverride::identify(const struct mCore* core) {
|
||||||
if (core->platform(core) != mPLATFORM_GBA) {
|
if (core->platform(core) != mPLATFORM_GBA) {
|
||||||
return;
|
return;
|
||||||
|
@ -33,3 +22,7 @@ void GBAOverride::identify(const struct mCore* core) {
|
||||||
void GBAOverride::save(struct Configuration* config) const {
|
void GBAOverride::save(struct Configuration* config) const {
|
||||||
GBAOverrideSave(config, &override);
|
GBAOverrideSave(config, &override);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const void* GBAOverride::raw() const {
|
||||||
|
return &override;
|
||||||
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ namespace QGBA {
|
||||||
|
|
||||||
class GBAOverride : public Override {
|
class GBAOverride : public Override {
|
||||||
public:
|
public:
|
||||||
void apply(struct mCore*) override;
|
|
||||||
void identify(const struct mCore*) override;
|
void identify(const struct mCore*) override;
|
||||||
void save(struct Configuration*) const override;
|
void save(struct Configuration*) const override;
|
||||||
|
const void* raw() const override;
|
||||||
|
|
||||||
struct GBACartridgeOverride override;
|
struct GBACartridgeOverride override;
|
||||||
bool vbaBugCompatSet;
|
bool vbaBugCompatSet;
|
||||||
|
|
|
@ -11,13 +11,6 @@
|
||||||
|
|
||||||
using namespace QGBA;
|
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) {
|
void GBOverride::identify(const struct mCore* core) {
|
||||||
if (core->platform(core) != mPLATFORM_GB) {
|
if (core->platform(core) != mPLATFORM_GB) {
|
||||||
return;
|
return;
|
||||||
|
@ -32,3 +25,7 @@ void GBOverride::identify(const struct mCore* core) {
|
||||||
void GBOverride::save(struct Configuration* config) const {
|
void GBOverride::save(struct Configuration* config) const {
|
||||||
GBOverrideSave(config, &override);
|
GBOverrideSave(config, &override);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const void* GBOverride::raw() const {
|
||||||
|
return &override;
|
||||||
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ namespace QGBA {
|
||||||
|
|
||||||
class GBOverride : public Override {
|
class GBOverride : public Override {
|
||||||
public:
|
public:
|
||||||
void apply(struct mCore*) override;
|
|
||||||
void identify(const struct mCore*) override;
|
void identify(const struct mCore*) override;
|
||||||
void save(struct Configuration*) const override;
|
void save(struct Configuration*) const override;
|
||||||
|
const void* raw() const override;
|
||||||
|
|
||||||
struct GBCartridgeOverride override;
|
struct GBCartridgeOverride override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,9 +14,9 @@ class Override {
|
||||||
public:
|
public:
|
||||||
virtual ~Override() {}
|
virtual ~Override() {}
|
||||||
|
|
||||||
virtual void apply(struct mCore*) = 0;
|
|
||||||
virtual void identify(const struct mCore*) = 0;
|
virtual void identify(const struct mCore*) = 0;
|
||||||
virtual void save(struct Configuration*) const = 0;
|
virtual void save(struct Configuration*) const = 0;
|
||||||
|
virtual const void* raw() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue