GB Video: SGB borders can now be toggled during games (fixes #868)

This commit is contained in:
Vicki Pfau 2018-08-28 13:12:33 -07:00
parent d9d89fad2b
commit 7cc09c713b
12 changed files with 75 additions and 15 deletions

View File

@ -77,6 +77,7 @@ struct GBVideoRenderer {
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);

View File

@ -210,7 +210,12 @@ static void _GBCoreLoadConfig(struct mCore* core, const struct mCoreConfig* conf
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;
@ -371,11 +376,6 @@ static void _GBCoreReset(struct mCore* core) {
}
}
int fakeBool;
if (mCoreConfigGetIntValue(&core->config, "sgb.borders", &fakeBool)) {
gb->video.sgbBorders = fakeBool;
}
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
if (!gb->biosVf && core->opts.useBios) {
struct VFile* bios = NULL;

View File

@ -22,6 +22,7 @@ static void GBVideoProxyRendererWritePalette(struct GBVideoRenderer* renderer, i
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 @@ void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GB
renderer->d.drawRange = GBVideoProxyRendererDrawRange;
renderer->d.finishScanline = GBVideoProxyRendererFinishScanline;
renderer->d.finishFrame = GBVideoProxyRendererFinishFrame;
renderer->d.enableSGBBorder = GBVideoProxyRendererEnableSGBBorder;
renderer->d.getPixels = GBVideoProxyRendererGetPixels;
renderer->d.putPixels = GBVideoProxyRendererPutPixels;
@ -260,6 +262,20 @@ void GBVideoProxyRendererFinishFrame(struct GBVideoRenderer* renderer) {
}
}
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);
}
}
static void GBVideoProxyRendererGetPixels(struct GBVideoRenderer* renderer, size_t* stride, const void** pixels) {
struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer;
if (proxyRenderer->logger->block && proxyRenderer->logger->wait) {

View File

@ -21,6 +21,7 @@ static void GBVideoSoftwareRendererWriteOAM(struct GBVideoRenderer* renderer, ui
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 @@ void GBVideoSoftwareRendererCreate(struct GBVideoSoftwareRenderer* renderer) {
renderer->d.drawRange = GBVideoSoftwareRendererDrawRange;
renderer->d.finishScanline = GBVideoSoftwareRendererFinishScanline;
renderer->d.finishFrame = GBVideoSoftwareRendererFinishFrame;
renderer->d.enableSGBBorder = GBVideoSoftwareRendererEnableSGBBorder;
renderer->d.getPixels = GBVideoSoftwareRendererGetPixels;
renderer->d.putPixels = GBVideoSoftwareRendererPutPixels;
@ -707,6 +709,16 @@ static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer)
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) {
uint8_t* data = renderer->d.vram;
uint8_t* attr = &maps[GB_SIZE_VRAM_BANK0];

View File

@ -26,6 +26,7 @@ static void GBVideoDummyRendererWriteOAM(struct GBVideoRenderer* renderer, uint1
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 @@ static struct GBVideoRenderer dummyRenderer = {
.drawRange = GBVideoDummyRendererDrawRange,
.finishScanline = GBVideoDummyRendererFinishScanline,
.finishFrame = GBVideoDummyRendererFinishFrame,
.enableSGBBorder = GBVideoDummyRendererEnableSGBBorder,
.getPixels = GBVideoDummyRendererGetPixels,
.putPixels = GBVideoDummyRendererPutPixels,
};
@ -784,6 +786,12 @@ static void GBVideoDummyRendererFinishFrame(struct GBVideoRenderer* renderer) {
// Nothing to do
}
static void GBVideoDummyRendererEnableSGBBorder(struct GBVideoRenderer* renderer, bool enable) {
UNUSED(renderer);
UNUSED(enable);
// Nothing to do
}
static void GBVideoDummyRendererGetPixels(struct GBVideoRenderer* renderer, size_t* stride, const void** pixels) {
UNUSED(renderer);
UNUSED(stride);

View File

@ -90,14 +90,8 @@ CoreController::CoreController(mCore* core, QObject* parent)
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();
};

View File

@ -63,6 +63,7 @@ public slots:
virtual void framePosted() = 0;
virtual void setShaders(struct VDir*) = 0;
virtual void clearShaders() = 0;
virtual void resizeContext() = 0;
void showMessage(const QString& message);

View File

@ -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 @@ PainterGL::~PainterGL() {
void PainterGL::setContext(std::shared_ptr<CoreController> context) {
m_context = context;
resizeContext();
}
if (!context) {
void PainterGL::resizeContext() {
if (!m_context) {
return;
}

View File

@ -61,6 +61,7 @@ public slots:
void framePosted() override;
void setShaders(struct VDir*) override;
void clearShaders() override;
void resizeContext() override;
protected:
virtual void paintEvent(QPaintEvent*) override {}
@ -100,6 +101,7 @@ public slots:
void lockAspectRatio(bool lock);
void lockIntegerScaling(bool lock);
void filter(bool filter);
void resizeContext();
void setShaders(struct VDir*);
void clearShaders();

View File

@ -67,6 +67,18 @@ void DisplayQt::framePosted() {
#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);

View File

@ -34,6 +34,7 @@ public slots:
void framePosted() override;
void setShaders(struct VDir*) override {}
void clearShaders() override {}
void resizeContext() override;
protected:
virtual void paintEvent(QPaintEvent*) override;

View File

@ -238,6 +238,7 @@ void Window::reloadConfig() {
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::focusCheck() {
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);