mirror of https://github.com/mgba-emu/mgba.git
GB Video: SGB borders can now be toggled during games (fixes #868)
This commit is contained in:
parent
d9d89fad2b
commit
7cc09c713b
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue