From e27963bd29653427b99a97742c48a79e7d3a887a Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 31 Jul 2020 18:02:29 -0700 Subject: [PATCH] GB/GBA Video: Move dummy renderer to core --- include/mgba/internal/gb/video.h | 6 +++ include/mgba/internal/gba/video.h | 2 + src/gb/core.c | 4 ++ src/gb/video.c | 84 +++++++++++++++++++------------ src/gba/core.c | 66 ++++++++++++------------ src/gba/video.c | 48 +++++++++++------- 6 files changed, 125 insertions(+), 85 deletions(-) diff --git a/include/mgba/internal/gb/video.h b/include/mgba/internal/gb/video.h index b7dc54ecf..13473776a 100644 --- a/include/mgba/internal/gb/video.h +++ b/include/mgba/internal/gb/video.h @@ -10,9 +10,12 @@ CXX_GUARD_START +#include #include #include +mLOG_DECLARE_CATEGORY(GB_VIDEO); + enum { GB_VIDEO_HORIZONTAL_PIXELS = 160, GB_VIDEO_VERTICAL_PIXELS = 144, @@ -160,7 +163,10 @@ struct GBVideo { void GBVideoInit(struct GBVideo* video); void GBVideoReset(struct GBVideo* video); void GBVideoDeinit(struct GBVideo* video); + +void GBVideoDummyRendererCreate(struct GBVideoRenderer*); void GBVideoAssociateRenderer(struct GBVideo* video, struct GBVideoRenderer* renderer); + void GBVideoSkipBIOS(struct GBVideo* video); void GBVideoProcessDots(struct GBVideo* video, uint32_t cyclesLate); diff --git a/include/mgba/internal/gba/video.h b/include/mgba/internal/gba/video.h index 87e5c38cc..c9ae1974a 100644 --- a/include/mgba/internal/gba/video.h +++ b/include/mgba/internal/gba/video.h @@ -221,6 +221,8 @@ struct GBAVideo { void GBAVideoInit(struct GBAVideo* video); void GBAVideoReset(struct GBAVideo* video); void GBAVideoDeinit(struct GBAVideo* video); + +void GBAVideoDummyRendererCreate(struct GBAVideoRenderer*); void GBAVideoAssociateRenderer(struct GBAVideo* video, struct GBAVideoRenderer* renderer); void GBAVideoWriteDISPSTAT(struct GBAVideo* video, uint16_t value); diff --git a/src/gb/core.c b/src/gb/core.c index 0f17c4cc8..ebbacbfd2 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -64,6 +64,7 @@ struct mVideoLogContext; struct GBCore { struct mCore d; struct GBVideoSoftwareRenderer renderer; + struct GBVideoRenderer dummyRenderer; #ifndef MINIMAL_CORE struct GBVideoProxyRenderer proxyRenderer; struct mVideoLogContext* logContext; @@ -419,6 +420,9 @@ static void _GBCoreReset(struct mCore* core) { struct GB* gb = (struct GB*) core->board; if (gbcore->renderer.outputBuffer) { GBVideoAssociateRenderer(&gb->video, &gbcore->renderer.d); + } else { + GBVideoDummyRendererCreate(&gbcore->dummyRenderer); + GBVideoAssociateRenderer(&gb->video, &gbcore->dummyRenderer); } if (gb->memory.rom) { diff --git a/src/gb/video.c b/src/gb/video.c index 85522ddf8..09588fc14 100644 --- a/src/gb/video.c +++ b/src/gb/video.c @@ -16,6 +16,8 @@ #include +mLOG_DEFINE_CATEGORY(GB_VIDEO, "GB Video", "gb.video"); + static void GBVideoDummyRendererInit(struct GBVideoRenderer* renderer, enum GBModel model, bool borders); static void GBVideoDummyRendererDeinit(struct GBVideoRenderer* renderer); static uint8_t GBVideoDummyRendererWriteVideoRegister(struct GBVideoRenderer* renderer, uint16_t address, uint8_t value); @@ -38,26 +40,8 @@ static void _endMode2(struct mTiming* timing, void* context, uint32_t cyclesLate static void _endMode3(struct mTiming* timing, void* context, uint32_t cyclesLate); static void _updateFrameCount(struct mTiming* timing, void* context, uint32_t cyclesLate); -static struct GBVideoRenderer dummyRenderer = { - .init = GBVideoDummyRendererInit, - .deinit = GBVideoDummyRendererDeinit, - .writeVideoRegister = GBVideoDummyRendererWriteVideoRegister, - .writeSGBPacket = GBVideoDummyRendererWriteSGBPacket, - .writeVRAM = GBVideoDummyRendererWriteVRAM, - .writeOAM = GBVideoDummyRendererWriteOAM, - .writePalette = GBVideoDummyRendererWritePalette, - .drawRange = GBVideoDummyRendererDrawRange, - .finishScanline = GBVideoDummyRendererFinishScanline, - .finishFrame = GBVideoDummyRendererFinishFrame, - .enableSGBBorder = GBVideoDummyRendererEnableSGBBorder, - .getPixels = GBVideoDummyRendererGetPixels, - .putPixels = GBVideoDummyRendererPutPixels, -}; - void GBVideoInit(struct GBVideo* video) { - video->renderer = &dummyRenderer; - video->renderer->cache = NULL; - video->renderer->sgbRenderMode = 0; + video->renderer = NULL; video->vram = anonymousMemoryMap(GB_SIZE_VRAM); video->frameskip = 0; @@ -84,12 +68,6 @@ void GBVideoInit(struct GBVideo* video) { video->dmgPalette[11] = 0x0000; video->sgbBorders = true; - - video->renderer->sgbCharRam = NULL; - video->renderer->sgbMapRam = NULL; - video->renderer->sgbPalRam = NULL; - video->renderer->sgbAttributes = NULL; - video->renderer->sgbAttributeFiles = NULL; } void GBVideoReset(struct GBVideo* video) { @@ -116,6 +94,12 @@ void GBVideoReset(struct GBVideo* video) { memset(video->renderer->sgbAttributes, 0, 90 * 45); video->sgbCommandHeader = 0; video->sgbBufferIndex = 0; + } else { + video->renderer->sgbCharRam = NULL; + video->renderer->sgbMapRam = NULL; + video->renderer->sgbPalRam = NULL; + video->renderer->sgbAttributes = NULL; + video->renderer->sgbAttributeFiles = NULL; } video->palette[0] = video->dmgPalette[0]; @@ -131,6 +115,11 @@ void GBVideoReset(struct GBVideo* video) { video->palette[9 * 4 + 2] = video->dmgPalette[10]; video->palette[9 * 4 + 3] = video->dmgPalette[11]; + if (!video->renderer) { + mLOG(GB_VIDEO, FATAL, "No renderer associated"); + return; + } + video->renderer->deinit(video->renderer); video->renderer->init(video->renderer, video->p->model, video->sgbBorders); @@ -173,15 +162,44 @@ void GBVideoDeinit(struct GBVideo* video) { } } +void GBVideoDummyRendererCreate(struct GBVideoRenderer* renderer) { + static const struct GBVideoRenderer dummyRenderer = { + .init = GBVideoDummyRendererInit, + .deinit = GBVideoDummyRendererDeinit, + .writeVideoRegister = GBVideoDummyRendererWriteVideoRegister, + .writeSGBPacket = GBVideoDummyRendererWriteSGBPacket, + .writeVRAM = GBVideoDummyRendererWriteVRAM, + .writeOAM = GBVideoDummyRendererWriteOAM, + .writePalette = GBVideoDummyRendererWritePalette, + .drawRange = GBVideoDummyRendererDrawRange, + .finishScanline = GBVideoDummyRendererFinishScanline, + .finishFrame = GBVideoDummyRendererFinishFrame, + .enableSGBBorder = GBVideoDummyRendererEnableSGBBorder, + .getPixels = GBVideoDummyRendererGetPixels, + .putPixels = GBVideoDummyRendererPutPixels, + }; + memcpy(renderer, &dummyRenderer, sizeof(*renderer)); +} + void GBVideoAssociateRenderer(struct GBVideo* video, struct GBVideoRenderer* renderer) { - video->renderer->deinit(video->renderer); - renderer->cache = video->renderer->cache; - renderer->sgbRenderMode = video->renderer->sgbRenderMode; - renderer->sgbCharRam = video->renderer->sgbCharRam; - renderer->sgbMapRam = video->renderer->sgbMapRam; - renderer->sgbPalRam = video->renderer->sgbPalRam; - renderer->sgbAttributeFiles = video->renderer->sgbAttributeFiles; - renderer->sgbAttributes = video->renderer->sgbAttributes; + if (video->renderer) { + video->renderer->deinit(video->renderer); + renderer->cache = video->renderer->cache; + renderer->sgbRenderMode = video->renderer->sgbRenderMode; + renderer->sgbCharRam = video->renderer->sgbCharRam; + renderer->sgbMapRam = video->renderer->sgbMapRam; + renderer->sgbPalRam = video->renderer->sgbPalRam; + renderer->sgbAttributeFiles = video->renderer->sgbAttributeFiles; + renderer->sgbAttributes = video->renderer->sgbAttributes; + } else { + renderer->cache = NULL; + renderer->sgbRenderMode = 0; + renderer->sgbCharRam = NULL; + renderer->sgbMapRam = NULL; + renderer->sgbPalRam = NULL; + renderer->sgbAttributeFiles = NULL; + renderer->sgbAttributes = NULL; + } video->renderer = renderer; renderer->vram = video->vram; video->renderer->init(video->renderer, video->p->model, video->sgbBorders); diff --git a/src/gba/core.c b/src/gba/core.c index c8f9c7348..c1aa5b047 100644 --- a/src/gba/core.c +++ b/src/gba/core.c @@ -130,6 +130,7 @@ struct mVideoLogContext; struct GBACore { struct mCore d; struct GBAVideoSoftwareRenderer renderer; + struct GBAVideoRenderer dummyRenderer; #if defined(BUILD_GLES2) || defined(BUILD_GLES3) struct GBAVideoGLRenderer glRenderer; #endif @@ -382,9 +383,11 @@ static void _GBACoreReloadConfigOption(struct mCore* core, const char* option, c renderer = &gbacore->proxyRenderer.d; } #endif - if (renderer) { - GBAVideoAssociateRenderer(&gba->video, renderer); + if (!renderer) { + renderer = &gbacore->dummyRenderer; + GBAVideoDummyRendererCreate(renderer); } + GBAVideoAssociateRenderer(&gba->video, renderer); } } @@ -542,42 +545,39 @@ static void _GBACoreChecksum(const struct mCore* core, void* data, enum mCoreChe static void _GBACoreReset(struct mCore* core) { struct GBACore* gbacore = (struct GBACore*) core; struct GBA* gba = (struct GBA*) core->board; - if (gbacore->renderer.outputBuffer + struct GBAVideoRenderer* renderer = NULL; + if (gbacore->renderer.outputBuffer) { + renderer = &gbacore->renderer.d; + } + int fakeBool ATTRIBUTE_UNUSED; #if defined(BUILD_GLES2) || defined(BUILD_GLES3) - || gbacore->glRenderer.outputTex != (unsigned) -1 -#endif - ) { - struct GBAVideoRenderer* renderer = NULL; - if (gbacore->renderer.outputBuffer) { - renderer = &gbacore->renderer.d; - } - int fakeBool ATTRIBUTE_UNUSED; -#if defined(BUILD_GLES2) || defined(BUILD_GLES3) - if (gbacore->glRenderer.outputTex != (unsigned) -1 && mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { - mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale); - renderer = &gbacore->glRenderer.d; - } else { - gbacore->glRenderer.scale = 1; - } + if (gbacore->glRenderer.outputTex != (unsigned) -1 && mCoreConfigGetIntValue(&core->config, "hwaccelVideo", &fakeBool) && fakeBool) { + mCoreConfigGetIntValue(&core->config, "videoScale", &gbacore->glRenderer.scale); + renderer = &gbacore->glRenderer.d; + } else { + gbacore->glRenderer.scale = 1; + } #endif #ifndef DISABLE_THREADING - if (mCoreConfigGetIntValue(&core->config, "threadedVideo", &fakeBool) && fakeBool) { - if (!core->videoLogger) { - core->videoLogger = &gbacore->threadProxy.d; - } - } -#endif -#ifndef MINIMAL_CORE - if (renderer && core->videoLogger) { - gbacore->proxyRenderer.logger = core->videoLogger; - GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); - renderer = &gbacore->proxyRenderer.d; - } -#endif - if (renderer) { - GBAVideoAssociateRenderer(&gba->video, renderer); + if (mCoreConfigGetIntValue(&core->config, "threadedVideo", &fakeBool) && fakeBool) { + if (!core->videoLogger) { + core->videoLogger = &gbacore->threadProxy.d; } } +#endif +#ifndef MINIMAL_CORE + if (renderer && core->videoLogger) { + gbacore->proxyRenderer.logger = core->videoLogger; + GBAVideoProxyRendererCreate(&gbacore->proxyRenderer, renderer); + renderer = &gbacore->proxyRenderer.d; + } +#endif + if (!renderer) { + renderer = &gbacore->dummyRenderer; + GBAVideoDummyRendererCreate(renderer); + } + + GBAVideoAssociateRenderer(&gba->video, renderer); #ifndef MINIMAL_CORE int useAudioMixer; diff --git a/src/gba/video.c b/src/gba/video.c index 785cc80bd..2d2c7f453 100644 --- a/src/gba/video.c +++ b/src/gba/video.c @@ -53,23 +53,8 @@ MGBA_EXPORT const int GBAVideoObjSizes[16][2] = { { 0, 0 }, }; -static struct GBAVideoRenderer dummyRenderer = { - .init = GBAVideoDummyRendererInit, - .reset = GBAVideoDummyRendererReset, - .deinit = GBAVideoDummyRendererDeinit, - .writeVideoRegister = GBAVideoDummyRendererWriteVideoRegister, - .writeVRAM = GBAVideoDummyRendererWriteVRAM, - .writePalette = GBAVideoDummyRendererWritePalette, - .writeOAM = GBAVideoDummyRendererWriteOAM, - .drawScanline = GBAVideoDummyRendererDrawScanline, - .finishFrame = GBAVideoDummyRendererFinishFrame, - .getPixels = GBAVideoDummyRendererGetPixels, - .putPixels = GBAVideoDummyRendererPutPixels, -}; - void GBAVideoInit(struct GBAVideo* video) { - video->renderer = &dummyRenderer; - video->renderer->cache = NULL; + video->renderer = NULL; video->vram = anonymousMemoryMap(SIZE_VRAM); video->frameskip = 0; video->event.name = "GBA Video"; @@ -94,12 +79,16 @@ void GBAVideoReset(struct GBAVideo* video) { video->frameCounter = 0; video->frameskipCounter = 0; - video->renderer->vram = video->vram; video->shouldStall = 0; memset(video->palette, 0, sizeof(video->palette)); memset(video->oam.raw, 0, sizeof(video->oam.raw)); + if (!video->renderer) { + mLOG(GBA_VIDEO, FATAL, "No renderer associated"); + return; + } + video->renderer->vram = video->vram; video->renderer->reset(video->renderer); } @@ -108,9 +97,30 @@ void GBAVideoDeinit(struct GBAVideo* video) { mappedMemoryFree(video->vram, SIZE_VRAM); } +void GBAVideoDummyRendererCreate(struct GBAVideoRenderer* renderer) { + static const struct GBAVideoRenderer dummyRenderer = { + .init = GBAVideoDummyRendererInit, + .reset = GBAVideoDummyRendererReset, + .deinit = GBAVideoDummyRendererDeinit, + .writeVideoRegister = GBAVideoDummyRendererWriteVideoRegister, + .writeVRAM = GBAVideoDummyRendererWriteVRAM, + .writePalette = GBAVideoDummyRendererWritePalette, + .writeOAM = GBAVideoDummyRendererWriteOAM, + .drawScanline = GBAVideoDummyRendererDrawScanline, + .finishFrame = GBAVideoDummyRendererFinishFrame, + .getPixels = GBAVideoDummyRendererGetPixels, + .putPixels = GBAVideoDummyRendererPutPixels, + }; + memcpy(renderer, &dummyRenderer, sizeof(*renderer)); +} + void GBAVideoAssociateRenderer(struct GBAVideo* video, struct GBAVideoRenderer* renderer) { - video->renderer->deinit(video->renderer); - renderer->cache = video->renderer->cache; + if (video->renderer) { + video->renderer->deinit(video->renderer); + renderer->cache = video->renderer->cache; + } else { + renderer->cache = NULL; + } video->renderer = renderer; renderer->palette = video->palette; renderer->vram = video->vram;