GB Video: SGB borders can now be toggled during games (fixes #868)
jump to
@@ -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);
@@ -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
@@ -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); }
@@ -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) {
@@ -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 }
@@ -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(); };
@@ -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);
@@ -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; }
@@ -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();
@@ -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);
@@ -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;
@@ -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);