all repos — mgba @ 7cc09c713b3219023c0fdc8fa709739cdaacdbff

mGBA Game Boy Advance Emulator

GB Video: SGB borders can now be toggled during games (fixes #868)
Vicki Pfau vi@endrift.com
Tue, 28 Aug 2018 13:12:33 -0700
commit

7cc09c713b3219023c0fdc8fa709739cdaacdbff

parent

d9d89fad2b10df544fd882d3c9999c8905f9d533

M include/mgba/internal/gb/video.hinclude/mgba/internal/gb/video.h

@@ -77,6 +77,7 @@ void (*writeOAM)(struct GBVideoRenderer* renderer, uint16_t oam);

void (*drawRange)(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* objOnLine, size_t nObj); void (*finishScanline)(struct GBVideoRenderer* renderer, int y); void (*finishFrame)(struct GBVideoRenderer* renderer); + void (*enableSGBBorder)(struct GBVideoRenderer* renderer, bool enable); void (*getPixels)(struct GBVideoRenderer* renderer, size_t* stride, const void** pixels); void (*putPixels)(struct GBVideoRenderer* renderer, size_t stride, const void* pixels);
M src/gb/core.csrc/gb/core.c

@@ -210,7 +210,12 @@ mCoreConfigCopyValue(&core->config, config, "gbc.bios");

mCoreConfigCopyValue(&core->config, config, "gb.model"); mCoreConfigCopyValue(&core->config, config, "sgb.model"); mCoreConfigCopyValue(&core->config, config, "cgb.model"); - mCoreConfigCopyValue(&core->config, config, "sgb.borders"); + + int fakeBool; + if (mCoreConfigGetIntValue(config, "sgb.borders", &fakeBool)) { + gb->video.sgbBorders = fakeBool; + gb->video.renderer->enableSGBBorder(gb->video.renderer, fakeBool); + } #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 struct GBCore* gbcore = (struct GBCore*) core;

@@ -369,11 +374,6 @@ gb->model = GBNameToModel(modelCGB);

} else if (gb->model == GB_MODEL_SGB && modelSGB) { gb->model = GBNameToModel(modelSGB); } - } - - int fakeBool; - if (mCoreConfigGetIntValue(&core->config, "sgb.borders", &fakeBool)) { - gb->video.sgbBorders = fakeBool; } #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
M src/gb/extra/proxy.csrc/gb/extra/proxy.c

@@ -22,6 +22,7 @@ static void GBVideoProxyRendererWritePalette(struct GBVideoRenderer* renderer, int address, uint16_t value);

static void GBVideoProxyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax); static void GBVideoProxyRendererFinishScanline(struct GBVideoRenderer* renderer, int y); static void GBVideoProxyRendererFinishFrame(struct GBVideoRenderer* renderer); +static void GBVideoProxyRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable); static void GBVideoProxyRendererGetPixels(struct GBVideoRenderer* renderer, size_t* stride, const void** pixels); static void GBVideoProxyRendererPutPixels(struct GBVideoRenderer* renderer, size_t stride, const void* pixels);

@@ -39,6 +40,7 @@ renderer->d.writePalette = GBVideoProxyRendererWritePalette;

renderer->d.drawRange = GBVideoProxyRendererDrawRange; renderer->d.finishScanline = GBVideoProxyRendererFinishScanline; renderer->d.finishFrame = GBVideoProxyRendererFinishFrame; + renderer->d.enableSGBBorder = GBVideoProxyRendererEnableSGBBorder; renderer->d.getPixels = GBVideoProxyRendererGetPixels; renderer->d.putPixels = GBVideoProxyRendererPutPixels;

@@ -255,6 +257,20 @@ }

proxyRenderer->backend->finishFrame(proxyRenderer->backend); mVideoLoggerRendererFinishFrame(proxyRenderer->logger); mVideoLoggerRendererFlush(proxyRenderer->logger); + if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { + proxyRenderer->logger->unlock(proxyRenderer->logger); + } +} + +static void GBVideoProxyRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable) { + struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer; + if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { + proxyRenderer->logger->lock(proxyRenderer->logger); + // Insert an extra item into the queue to make sure it gets flushed + mVideoLoggerRendererFlush(proxyRenderer->logger); + proxyRenderer->logger->wait(proxyRenderer->logger); + } + proxyRenderer->backend->enableSGBBorder(proxyRenderer->backend, enable); if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { proxyRenderer->logger->unlock(proxyRenderer->logger); }
M src/gb/renderers/software.csrc/gb/renderers/software.c

@@ -21,6 +21,7 @@ static void GBVideoSoftwareRendererWriteOAM(struct GBVideoRenderer* renderer, uint16_t oam);

static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax); static void GBVideoSoftwareRendererFinishScanline(struct GBVideoRenderer* renderer, int y); static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer); +static void GBVideoSoftwareRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable); static void GBVideoSoftwareRendererGetPixels(struct GBVideoRenderer* renderer, size_t* stride, const void** pixels); static void GBVideoSoftwareRendererPutPixels(struct GBVideoRenderer* renderer, size_t stride, const void* pixels);

@@ -174,6 +175,7 @@ renderer->d.writeOAM = GBVideoSoftwareRendererWriteOAM;

renderer->d.drawRange = GBVideoSoftwareRendererDrawRange; renderer->d.finishScanline = GBVideoSoftwareRendererFinishScanline; renderer->d.finishFrame = GBVideoSoftwareRendererFinishFrame; + renderer->d.enableSGBBorder = GBVideoSoftwareRendererEnableSGBBorder; renderer->d.getPixels = GBVideoSoftwareRendererGetPixels; renderer->d.putPixels = GBVideoSoftwareRendererPutPixels;

@@ -705,6 +707,16 @@ }

softwareRenderer->lastY = GB_VIDEO_VERTICAL_PIXELS; softwareRenderer->currentWy = 0; softwareRenderer->hasWindow = false; +} + +static void GBVideoSoftwareRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable) { + struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer; + if (softwareRenderer->model == GB_MODEL_SGB) { + softwareRenderer->sgbBorders = enable; + if (softwareRenderer->sgbBorders && !renderer->sgbRenderMode) { + _regenerateSGBBorder(softwareRenderer); + } + } } static void GBVideoSoftwareRendererDrawBackground(struct GBVideoSoftwareRenderer* renderer, uint8_t* maps, int startX, int endX, int sx, int sy) {
M src/gb/video.csrc/gb/video.c

@@ -26,6 +26,7 @@ static void GBVideoDummyRendererWriteOAM(struct GBVideoRenderer* renderer, uint16_t oam);

static void GBVideoDummyRendererDrawRange(struct GBVideoRenderer* renderer, int startX, int endX, int y, struct GBObj* obj, size_t oamMax); static void GBVideoDummyRendererFinishScanline(struct GBVideoRenderer* renderer, int y); static void GBVideoDummyRendererFinishFrame(struct GBVideoRenderer* renderer); +static void GBVideoDummyRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable); static void GBVideoDummyRendererGetPixels(struct GBVideoRenderer* renderer, size_t* stride, const void** pixels); static void GBVideoDummyRendererPutPixels(struct GBVideoRenderer* renderer, size_t stride, const void* pixels);

@@ -48,6 +49,7 @@ .writePalette = GBVideoDummyRendererWritePalette,

.drawRange = GBVideoDummyRendererDrawRange, .finishScanline = GBVideoDummyRendererFinishScanline, .finishFrame = GBVideoDummyRendererFinishFrame, + .enableSGBBorder = GBVideoDummyRendererEnableSGBBorder, .getPixels = GBVideoDummyRendererGetPixels, .putPixels = GBVideoDummyRendererPutPixels, };

@@ -781,6 +783,12 @@ }

static void GBVideoDummyRendererFinishFrame(struct GBVideoRenderer* renderer) { UNUSED(renderer); + // Nothing to do +} + +static void GBVideoDummyRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable) { + UNUSED(renderer); + UNUSED(enable); // Nothing to do }
M src/platform/qt/CoreController.cppsrc/platform/qt/CoreController.cpp

@@ -90,14 +90,8 @@ }

controller->m_resetActions.clear(); - QSize size = controller->screenDimensions(); - controller->m_buffers[0].resize(size.width() * size.height() * sizeof(color_t)); - controller->m_buffers[1].resize(size.width() * size.height() * sizeof(color_t)); - controller->m_buffers[0].fill(0xFF); - controller->m_buffers[1].fill(0xFF); controller->m_activeBuffer = &controller->m_buffers[0]; - - context->core->setVideoBuffer(context->core, reinterpret_cast<color_t*>(controller->m_activeBuffer->data()), size.width()); + context->core->setVideoBuffer(context->core, reinterpret_cast<color_t*>(controller->m_activeBuffer->data()), 256); controller->finishFrame(); };
M src/platform/qt/Display.hsrc/platform/qt/Display.h

@@ -63,6 +63,7 @@ virtual void filter(bool filter);

virtual void framePosted() = 0; virtual void setShaders(struct VDir*) = 0; virtual void clearShaders() = 0; + virtual void resizeContext() = 0; void showMessage(const QString& message);
M src/platform/qt/DisplayGL.cppsrc/platform/qt/DisplayGL.cpp

@@ -159,6 +159,15 @@ void DisplayGL::clearShaders() {

QMetaObject::invokeMethod(m_painter, "clearShaders"); } + +void DisplayGL::resizeContext() { + if (m_drawThread) { + m_isDrawing = false; + CoreController::Interrupter interrupter(m_context); + QMetaObject::invokeMethod(m_painter, "resizeContext", Qt::BlockingQueuedConnection); + } +} + void DisplayGL::resizeEvent(QResizeEvent* event) { Display::resizeEvent(event); resizePainter();

@@ -250,8 +259,11 @@ }

void PainterGL::setContext(std::shared_ptr<CoreController> context) { m_context = context; + resizeContext(); +} - if (!context) { +void PainterGL::resizeContext() { + if (!m_context) { return; }
M src/platform/qt/DisplayGL.hsrc/platform/qt/DisplayGL.h

@@ -61,6 +61,7 @@ void filter(bool filter) override;

void framePosted() override; void setShaders(struct VDir*) override; void clearShaders() override; + void resizeContext() override; protected: virtual void paintEvent(QPaintEvent*) override {}

@@ -100,6 +101,7 @@ void resize(const QSize& size);

void lockAspectRatio(bool lock); void lockIntegerScaling(bool lock); void filter(bool filter); + void resizeContext(); void setShaders(struct VDir*); void clearShaders();
M src/platform/qt/DisplayQt.cppsrc/platform/qt/DisplayQt.cpp

@@ -67,6 +67,18 @@ m_backing = m_backing.convertToFormat(QImage::Format_RGB32);

#endif } +void DisplayQt::resizeContext() { + if (!m_context) { + return; + } + QSize size = m_context->screenDimensions(); + if (m_width != size.width() || m_height != size.height()) { + m_width = size.width(); + m_height = size.height(); + m_backing = std::move(QImage()); + } +} + void DisplayQt::paintEvent(QPaintEvent*) { QPainter painter(this); painter.fillRect(QRect(QPoint(), size()), Qt::black);
M src/platform/qt/DisplayQt.hsrc/platform/qt/DisplayQt.h

@@ -34,6 +34,7 @@ void filter(bool filter) override;

void framePosted() override; void setShaders(struct VDir*) override {} void clearShaders() override {} + void resizeContext() override; protected: virtual void paintEvent(QPaintEvent*) override;
M src/platform/qt/Window.cppsrc/platform/qt/Window.cpp

@@ -238,6 +238,7 @@ if (m_audioProcessor) {

m_audioProcessor->setBufferSamples(opts->audioBuffers); m_audioProcessor->requestSampleRate(opts->sampleRate); } + m_display->resizeContext(); } m_display->lockAspectRatio(opts->lockAspectRatio); m_display->filter(opts->resampleVideo);

@@ -1808,7 +1809,7 @@

void Window::updateFrame() { QSize size = m_controller->screenDimensions(); QImage currentImage(reinterpret_cast<const uchar*>(m_controller->drawContext()), size.width(), size.height(), - size.width() * BYTES_PER_PIXEL, QImage::Format_RGBX8888); + 256 * BYTES_PER_PIXEL, QImage::Format_RGBX8888); QPixmap pixmap; pixmap.convertFromImage(currentImage); m_screenWidget->setPixmap(pixmap);