Core: Cores can now have multiple sets of callbacks

This commit is contained in:
Vicki Pfau 2017-02-08 11:34:05 -08:00
parent be3e884ba5
commit 3ac0b20ff8
13 changed files with 68 additions and 28 deletions

View File

@ -68,6 +68,7 @@ Misc:
- Util: Add 8-bit PNG write support - Util: Add 8-bit PNG write support
- Qt: Rename "Resample video" option to "Bilinear filtering" - Qt: Rename "Resample video" option to "Bilinear filtering"
- GBA Video: Optimize when BLD* registers are written frequently - GBA Video: Optimize when BLD* registers are written frequently
- Core: Cores can now have multiple sets of callbacks
0.5.2: (2016-12-31) 0.5.2: (2016-12-31)
Bugfixes: Bugfixes:

View File

@ -73,7 +73,8 @@ struct mCore {
void (*setAudioBufferSize)(struct mCore*, size_t samples); void (*setAudioBufferSize)(struct mCore*, size_t samples);
size_t (*getAudioBufferSize)(struct mCore*); size_t (*getAudioBufferSize)(struct mCore*);
void (*setCoreCallbacks)(struct mCore*, struct mCoreCallbacks*); void (*addCoreCallbacks)(struct mCore*, struct mCoreCallbacks*);
void (*clearCoreCallbacks)(struct mCore*);
void (*setAVStream)(struct mCore*, struct mAVStream*); void (*setAVStream)(struct mCore*, struct mAVStream*);
bool (*isROM)(struct VFile* vf); bool (*isROM)(struct VFile* vf);

View File

@ -10,6 +10,8 @@
CXX_GUARD_START CXX_GUARD_START
#include <mgba-util/vector.h>
struct mCore; struct mCore;
#ifdef COLOR_16_BIT #ifdef COLOR_16_BIT
@ -37,6 +39,8 @@ struct mCoreCallbacks {
void (*coreCrashed)(void* context); void (*coreCrashed)(void* context);
}; };
DECLARE_VECTOR(mCoreCallbacksList, struct mCoreCallbacks);
struct mAVStream { struct mAVStream {
void (*videoDimensionsChanged)(struct mAVStream*, unsigned width, unsigned height); void (*videoDimensionsChanged)(struct mAVStream*, unsigned width, unsigned height);
void (*postVideoFrame)(struct mAVStream*, const color_t* buffer, size_t stride); void (*postVideoFrame)(struct mAVStream*, const color_t* buffer, size_t stride);

View File

@ -11,6 +11,7 @@
CXX_GUARD_START CXX_GUARD_START
#include <mgba/core/cpu.h> #include <mgba/core/cpu.h>
#include <mgba/core/interface.h>
#include <mgba/core/log.h> #include <mgba/core/log.h>
#include <mgba/core/timing.h> #include <mgba/core/timing.h>
@ -46,7 +47,6 @@ enum GBIRQVector {
struct LR35902Core; struct LR35902Core;
struct mCoreSync; struct mCoreSync;
struct mAVStream; struct mAVStream;
struct mCoreCallbacks;
struct GB { struct GB {
struct mCPUComponent d; struct mCPUComponent d;
@ -76,7 +76,7 @@ struct GB {
int32_t sramDirtAge; int32_t sramDirtAge;
bool sramMaskWriteback; bool sramMaskWriteback;
struct mCoreCallbacks* coreCallbacks; struct mCoreCallbacksList coreCallbacks;
struct mAVStream* stream; struct mAVStream* stream;
bool cpuBlocked; bool cpuBlocked;

View File

@ -100,7 +100,7 @@ struct GBA {
struct mAVStream* stream; struct mAVStream* stream;
struct mKeyCallback* keyCallback; struct mKeyCallback* keyCallback;
struct mStopCallback* stopCallback; struct mStopCallback* stopCallback;
struct mCoreCallbacks* coreCallbacks; struct mCoreCallbacksList coreCallbacks;
enum GBAIdleLoopOptimization idleOptimization; enum GBAIdleLoopOptimization idleOptimization;
uint32_t idleLoop; uint32_t idleLoop;

View File

@ -7,6 +7,8 @@
#include <mgba/core/core.h> #include <mgba/core/core.h>
DEFINE_VECTOR(mCoreCallbacksList, struct mCoreCallbacks);
static time_t _rtcGenericCallback(struct mRTCSource* source) { static time_t _rtcGenericCallback(struct mRTCSource* source) {
struct mRTCGenericSource* rtc = (struct mRTCGenericSource*) source; struct mRTCGenericSource* rtc = (struct mRTCGenericSource*) source;
switch (rtc->override) { switch (rtc->override) {

View File

@ -143,7 +143,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
.coreCrashed = _crashed, .coreCrashed = _crashed,
.context = threadContext .context = threadContext
}; };
core->setCoreCallbacks(core, &callbacks); core->addCoreCallbacks(core, &callbacks);
core->setSync(core, &threadContext->sync); core->setSync(core, &threadContext->sync);
core->reset(core); core->reset(core);
@ -223,7 +223,7 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
if (threadContext->cleanCallback) { if (threadContext->cleanCallback) {
threadContext->cleanCallback(threadContext); threadContext->cleanCallback(threadContext);
} }
core->setCoreCallbacks(core, NULL); core->clearCoreCallbacks(core);
return 0; return 0;
} }

View File

@ -156,9 +156,14 @@ static size_t _GBCoreGetAudioBufferSize(struct mCore* core) {
return gb->audio.samples; return gb->audio.samples;
} }
static void _GBCoreSetCoreCallbacks(struct mCore* core, struct mCoreCallbacks* coreCallbacks) { static void _GBCoreAddCoreCallbacks(struct mCore* core, struct mCoreCallbacks* coreCallbacks) {
struct GB* gb = core->board; struct GB* gb = core->board;
gb->coreCallbacks = coreCallbacks; *mCoreCallbacksListAppend(&gb->coreCallbacks) = *coreCallbacks;
}
static void _GBCoreClearCoreCallbacks(struct mCore* core) {
struct GB* gb = core->board;
mCoreCallbacksListClear(&gb->coreCallbacks);
} }
static void _GBCoreSetAVStream(struct mCore* core, struct mAVStream* stream) { static void _GBCoreSetAVStream(struct mCore* core, struct mAVStream* stream) {
@ -576,7 +581,8 @@ struct mCore* GBCoreCreate(void) {
core->setAudioBufferSize = _GBCoreSetAudioBufferSize; core->setAudioBufferSize = _GBCoreSetAudioBufferSize;
core->getAudioBufferSize = _GBCoreGetAudioBufferSize; core->getAudioBufferSize = _GBCoreGetAudioBufferSize;
core->setAVStream = _GBCoreSetAVStream; core->setAVStream = _GBCoreSetAVStream;
core->setCoreCallbacks = _GBCoreSetCoreCallbacks; core->addCoreCallbacks = _GBCoreAddCoreCallbacks;
core->clearCoreCallbacks = _GBCoreClearCoreCallbacks;
core->isROM = GBIsROM; core->isROM = GBIsROM;
core->loadROM = _GBCoreLoadROM; core->loadROM = _GBCoreLoadROM;
core->loadBIOS = _GBCoreLoadBIOS; core->loadBIOS = _GBCoreLoadBIOS;

View File

@ -83,7 +83,7 @@ static void GBInit(void* cpu, struct mCPUComponent* component) {
gb->pristineRomSize = 0; gb->pristineRomSize = 0;
gb->yankedRomSize = 0; gb->yankedRomSize = 0;
gb->coreCallbacks = NULL; mCoreCallbacksListInit(&gb->coreCallbacks, 0);
gb->stream = NULL; gb->stream = NULL;
mTimingInit(&gb->timing, &gb->cpu->cycles, &gb->cpu->nextEvent); mTimingInit(&gb->timing, &gb->cpu->cycles, &gb->cpu->nextEvent);
@ -349,6 +349,7 @@ void GBDestroy(struct GB* gb) {
GBAudioDeinit(&gb->audio); GBAudioDeinit(&gb->audio);
GBVideoDeinit(&gb->video); GBVideoDeinit(&gb->video);
GBSIODeinit(&gb->sio); GBSIODeinit(&gb->sio);
mCoreCallbacksListDeinit(&gb->coreCallbacks);
} }
void GBInterruptHandlerInit(struct LR35902InterruptHandler* irqh) { void GBInterruptHandlerInit(struct LR35902InterruptHandler* irqh) {

View File

@ -129,9 +129,12 @@ void _endMode0(struct mTiming* timing, void* context, uint32_t cyclesLate) {
} }
video->p->memory.io[REG_IF] |= (1 << GB_IRQ_VBLANK); video->p->memory.io[REG_IF] |= (1 << GB_IRQ_VBLANK);
struct mCoreCallbacks* callbacks = video->p->coreCallbacks; size_t c;
if (callbacks && callbacks->videoFrameEnded) { for (c = 0; c < mCoreCallbacksListSize(&video->p->coreCallbacks); ++c) {
callbacks->videoFrameEnded(callbacks->context); struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&video->p->coreCallbacks, c);
if (callbacks->videoFrameEnded) {
callbacks->videoFrameEnded(callbacks->context);
}
} }
} }
if (!GBRegisterSTATIsHblankIRQ(video->stat) && GBRegisterSTATIsLYCIRQ(video->stat) && lyc == video->ly) { if (!GBRegisterSTATIsHblankIRQ(video->stat) && GBRegisterSTATIsLYCIRQ(video->stat) && lyc == video->ly) {
@ -244,9 +247,12 @@ void _updateFrameCount(struct mTiming* timing, void* context, uint32_t cyclesLat
video->p->stream->postVideoFrame(video->p->stream, pixels, stride); video->p->stream->postVideoFrame(video->p->stream, pixels, stride);
} }
struct mCoreCallbacks* callbacks = video->p->coreCallbacks; size_t c;
if (callbacks && callbacks->videoFrameStarted) { for (c = 0; c < mCoreCallbacksListSize(&video->p->coreCallbacks); ++c) {
callbacks->videoFrameStarted(callbacks->context); struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&video->p->coreCallbacks, c);
if (callbacks->videoFrameEnded) {
callbacks->videoFrameStarted(callbacks->context);
}
} }
if (!GBRegisterLCDCIsEnable(video->p->memory.io[REG_LCDC])) { if (!GBRegisterLCDCIsEnable(video->p->memory.io[REG_LCDC])) {

View File

@ -186,9 +186,14 @@ static size_t _GBACoreGetAudioBufferSize(struct mCore* core) {
return gba->audio.samples; return gba->audio.samples;
} }
static void _GBACoreSetCoreCallbacks(struct mCore* core, struct mCoreCallbacks* coreCallbacks) { static void _GBACoreAddCoreCallbacks(struct mCore* core, struct mCoreCallbacks* coreCallbacks) {
struct GBA* gba = core->board; struct GBA* gba = core->board;
gba->coreCallbacks = coreCallbacks; *mCoreCallbacksListAppend(&gba->coreCallbacks) = *coreCallbacks;
}
static void _GBACoreClearCoreCallbacks(struct mCore* core) {
struct GBA* gba = core->board;
mCoreCallbacksListClear(&gba->coreCallbacks);
} }
static void _GBACoreSetAVStream(struct mCore* core, struct mAVStream* stream) { static void _GBACoreSetAVStream(struct mCore* core, struct mAVStream* stream) {
@ -589,7 +594,8 @@ struct mCore* GBACoreCreate(void) {
core->getAudioChannel = _GBACoreGetAudioChannel; core->getAudioChannel = _GBACoreGetAudioChannel;
core->setAudioBufferSize = _GBACoreSetAudioBufferSize; core->setAudioBufferSize = _GBACoreSetAudioBufferSize;
core->getAudioBufferSize = _GBACoreGetAudioBufferSize; core->getAudioBufferSize = _GBACoreGetAudioBufferSize;
core->setCoreCallbacks = _GBACoreSetCoreCallbacks; core->addCoreCallbacks = _GBACoreAddCoreCallbacks;
core->clearCoreCallbacks = _GBACoreClearCoreCallbacks;
core->setAVStream = _GBACoreSetAVStream; core->setAVStream = _GBACoreSetAVStream;
core->isROM = GBAIsROM; core->isROM = GBAIsROM;
core->loadROM = _GBACoreLoadROM; core->loadROM = _GBACoreLoadROM;

View File

@ -91,7 +91,7 @@ static void GBAInit(void* cpu, struct mCPUComponent* component) {
gba->keyCallback = NULL; gba->keyCallback = NULL;
gba->stopCallback = NULL; gba->stopCallback = NULL;
gba->stopCallback = NULL; gba->stopCallback = NULL;
gba->coreCallbacks = NULL; mCoreCallbacksListInit(&gba->coreCallbacks, 0);
gba->biosChecksum = GBAChecksum(gba->memory.bios, SIZE_BIOS); gba->biosChecksum = GBAChecksum(gba->memory.bios, SIZE_BIOS);
@ -152,6 +152,7 @@ void GBADestroy(struct GBA* gba) {
GBASIODeinit(&gba->sio); GBASIODeinit(&gba->sio);
gba->rr = 0; gba->rr = 0;
mTimingDeinit(&gba->timing); mTimingDeinit(&gba->timing);
mCoreCallbacksListDeinit(&gba->coreCallbacks);
} }
void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh) { void GBAInterruptHandlerInit(struct ARMInterruptHandler* irqh) {
@ -632,9 +633,12 @@ void GBABreakpoint(struct ARMCore* cpu, int immediate) {
void GBAFrameStarted(struct GBA* gba) { void GBAFrameStarted(struct GBA* gba) {
UNUSED(gba); UNUSED(gba);
struct mCoreCallbacks* callbacks = gba->coreCallbacks; size_t c;
if (callbacks && callbacks->videoFrameStarted) { for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) {
callbacks->videoFrameStarted(callbacks->context); struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c);
if (callbacks->videoFrameEnded) {
callbacks->videoFrameStarted(callbacks->context);
}
} }
} }
@ -665,9 +669,12 @@ void GBAFrameEnded(struct GBA* gba) {
GBAHardwarePlayerUpdate(gba); GBAHardwarePlayerUpdate(gba);
} }
struct mCoreCallbacks* callbacks = gba->coreCallbacks; size_t c;
if (callbacks && callbacks->videoFrameEnded) { for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) {
callbacks->videoFrameEnded(callbacks->context); struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c);
if (callbacks->videoFrameEnded) {
callbacks->videoFrameEnded(callbacks->context);
}
} }
} }

View File

@ -303,9 +303,15 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
cpu->memory.activeMask = 0; cpu->memory.activeMask = 0;
if (gba->yankedRomSize || !gba->hardCrash) { if (gba->yankedRomSize || !gba->hardCrash) {
mLOG(GBA_MEM, GAME_ERROR, "Jumped to invalid address: %08X", address); mLOG(GBA_MEM, GAME_ERROR, "Jumped to invalid address: %08X", address);
} else if (gba->coreCallbacks && gba->coreCallbacks->coreCrashed) { } else if (mCoreCallbacksListSize(&gba->coreCallbacks)) {
mLOG(GBA_MEM, GAME_ERROR, "Jumped to invalid address: %08X", address); mLOG(GBA_MEM, GAME_ERROR, "Jumped to invalid address: %08X", address);
gba->coreCallbacks->coreCrashed(gba->coreCallbacks->context); size_t c;
for (c = 0; c < mCoreCallbacksListSize(&gba->coreCallbacks); ++c) {
struct mCoreCallbacks* callbacks = mCoreCallbacksListGetPointer(&gba->coreCallbacks, c);
if (callbacks->coreCrashed) {
callbacks->coreCrashed(callbacks->context);
}
}
} else { } else {
mLOG(GBA_MEM, FATAL, "Jumped to invalid address: %08X", address); mLOG(GBA_MEM, FATAL, "Jumped to invalid address: %08X", address);
} }