GB Video: Ability to disable SGB borders

This commit is contained in:
Vicki Pfau 2017-08-05 08:52:09 -07:00
parent f0686a3b78
commit 558055277f
9 changed files with 127 additions and 97 deletions

View File

@ -42,6 +42,7 @@ struct GBVideoSoftwareRenderer {
int sgbPacketId;
int sgbDataSets;
uint8_t sgbPartialDataSet[15];
bool sgbBorders;
};
void GBVideoSoftwareRendererCreate(struct GBVideoSoftwareRenderer*);

View File

@ -67,7 +67,7 @@ union GBOAM {
struct mTileCache;
struct GBVideoRenderer {
void (*init)(struct GBVideoRenderer* renderer, enum GBModel model);
void (*init)(struct GBVideoRenderer* renderer, enum GBModel model, bool borders);
void (*deinit)(struct GBVideoRenderer* renderer);
uint8_t (*writeVideoRegister)(struct GBVideoRenderer* renderer, uint16_t address, uint8_t value);
@ -148,6 +148,8 @@ struct GBVideo {
uint16_t dmgPalette[4];
uint16_t palette[64];
bool sgbBorders;
int32_t frameCounter;
int frameskip;
int frameskipCounter;

View File

@ -187,6 +187,11 @@ static void _GBCoreLoadConfig(struct mCore* core, const struct mCoreConfig* conf
mCoreConfigCopyValue(&core->config, config, "sgb.model");
mCoreConfigCopyValue(&core->config, config, "cgb.model");
int fakeBool;
if (mCoreConfigGetIntValue(config, "sgb.borders", &fakeBool)) {
gb->video.sgbBorders = fakeBool;
}
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
struct GBCore* gbcore = (struct GBCore*) core;
gbcore->overrides = mCoreConfigGetOverridesConst(config);
@ -195,7 +200,7 @@ static void _GBCoreLoadConfig(struct mCore* core, const struct mCoreConfig* conf
static void _GBCoreDesiredVideoDimensions(struct mCore* core, unsigned* width, unsigned* height) {
struct GB* gb = core->board;
if (!gb || gb->model != GB_MODEL_SGB) {
if (!gb || gb->model != GB_MODEL_SGB || !gb->video.sgbBorders) {
*width = GB_VIDEO_HORIZONTAL_PIXELS;
*height = GB_VIDEO_VERTICAL_PIXELS;
} else {

View File

@ -12,7 +12,7 @@
#define BUFFER_OAM 1
#define BUFFER_SGB 2
static void GBVideoProxyRendererInit(struct GBVideoRenderer* renderer, enum GBModel model);
static void GBVideoProxyRendererInit(struct GBVideoRenderer* renderer, enum GBModel model, bool borders);
static void GBVideoProxyRendererDeinit(struct GBVideoRenderer* renderer);
static uint8_t GBVideoProxyRendererWriteVideoRegister(struct GBVideoRenderer* renderer, uint16_t address, uint8_t value);
static void GBVideoProxyRendererWriteSGBPacket(struct GBVideoRenderer* renderer, uint8_t* data);
@ -96,12 +96,12 @@ void GBVideoProxyRendererUnshim(struct GBVideo* video, struct GBVideoProxyRender
mVideoLoggerRendererDeinit(renderer->logger);
}
void GBVideoProxyRendererInit(struct GBVideoRenderer* renderer, enum GBModel model) {
void GBVideoProxyRendererInit(struct GBVideoRenderer* renderer, enum GBModel model, bool borders) {
struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer;
_init(proxyRenderer);
proxyRenderer->backend->init(proxyRenderer->backend, model);
proxyRenderer->backend->init(proxyRenderer->backend, model, borders);
}
void GBVideoProxyRendererDeinit(struct GBVideoRenderer* renderer) {

View File

@ -10,7 +10,7 @@
#include <mgba-util/math.h>
#include <mgba-util/memory.h>
static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer, enum GBModel model);
static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer, enum GBModel model, bool borders);
static void GBVideoSoftwareRendererDeinit(struct GBVideoRenderer* renderer);
static uint8_t GBVideoSoftwareRendererWriteVideoRegister(struct GBVideoRenderer* renderer, uint16_t address, uint8_t value);
static void GBVideoSoftwareRendererWriteSGBPacket(struct GBVideoRenderer* renderer, uint8_t* data);
@ -28,7 +28,7 @@ static void GBVideoSoftwareRendererDrawObj(struct GBVideoSoftwareRenderer* rende
static void _clearScreen(struct GBVideoSoftwareRenderer* renderer) {
size_t sgbOffset = 0;
if (renderer->model == GB_MODEL_SGB) {
if (renderer->model == GB_MODEL_SGB && renderer->sgbBorders) {
sgbOffset = renderer->outputBufferStride * 40 + 48;
}
int y;
@ -166,7 +166,7 @@ void GBVideoSoftwareRendererCreate(struct GBVideoSoftwareRenderer* renderer) {
renderer->temporaryBuffer = 0;
}
static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer, enum GBModel model) {
static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer, enum GBModel model, bool sgbBorders) {
struct GBVideoSoftwareRenderer* softwareRenderer = (struct GBVideoSoftwareRenderer*) renderer;
softwareRenderer->lcdc = 0;
softwareRenderer->scy = 0;
@ -177,6 +177,7 @@ static void GBVideoSoftwareRendererInit(struct GBVideoRenderer* renderer, enum G
softwareRenderer->model = model;
softwareRenderer->sgbTransfer = 0;
softwareRenderer->sgbCommandHeader = 0;
softwareRenderer->sgbBorders = sgbBorders;
int i;
for (i = 0; i < 64; ++i) {
softwareRenderer->lookup[i] = i;
@ -271,7 +272,9 @@ static void GBVideoSoftwareRendererWriteSGBPacket(struct GBVideoRenderer* render
}
break;
case SGB_ATRC_EN:
_regenerateSGBBorder(softwareRenderer);
if (softwareRenderer->sgbBorders) {
_regenerateSGBBorder(softwareRenderer);
}
break;
}
}
@ -334,11 +337,11 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i
}
size_t sgbOffset = 0;
if (softwareRenderer->model == GB_MODEL_SGB) {
if (softwareRenderer->model == GB_MODEL_SGB && softwareRenderer->sgbBorders) {
sgbOffset = softwareRenderer->outputBufferStride * 40 + 48;
}
color_t* row = &softwareRenderer->outputBuffer[softwareRenderer->outputBufferStride * y + sgbOffset];
int x;
int x = startX;
int p = 0;
switch (softwareRenderer->d.sgbRenderMode) {
case 0:
@ -348,7 +351,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i
p &= 3;
p <<= 2;
}
for (x = startX; x < ((startX + 7) & ~7) && x < endX; ++x) {
for (; x < ((startX + 7) & ~7) && x < endX; ++x) {
row[x] = softwareRenderer->palette[p | softwareRenderer->lookup[softwareRenderer->row[x] & 0x7F]];
}
for (; x + 7 < (endX & ~7); x += 8) {
@ -380,7 +383,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i
case 1:
break;
case 2:
for (x = startX; x < ((startX + 7) & ~7) && x < endX; ++x) {
for (; x < ((startX + 7) & ~7) && x < endX; ++x) {
row[x] = 0;
}
for (; x + 7 < (endX & ~7); x += 8) {
@ -398,7 +401,7 @@ static void GBVideoSoftwareRendererDrawRange(struct GBVideoRenderer* renderer, i
}
break;
case 3:
for (x = startX; x < ((startX + 7) & ~7) && x < endX; ++x) {
for (; x < ((startX + 7) & ~7) && x < endX; ++x) {
row[x] = softwareRenderer->palette[0];
}
for (; x + 7 < (endX & ~7); x += 8) {
@ -498,7 +501,7 @@ static void GBVideoSoftwareRendererFinishFrame(struct GBVideoRenderer* renderer)
case SGB_PAL_TRN:
case SGB_CHR_TRN:
case SGB_PCT_TRN:
if (softwareRenderer->sgbTransfer > 0) {
if (softwareRenderer->sgbTransfer > 0 && softwareRenderer->sgbBorders) {
// Make sure every buffer sees this if we're multibuffering
_regenerateSGBBorder(softwareRenderer);
}

View File

@ -15,7 +15,7 @@
#include <mgba-util/memory.h>
static void GBVideoDummyRendererInit(struct GBVideoRenderer* renderer, enum GBModel model);
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);
static void GBVideoDummyRendererWriteSGBPacket(struct GBVideoRenderer* renderer, uint8_t* data);
@ -72,6 +72,8 @@ void GBVideoInit(struct GBVideo* video) {
video->dmgPalette[2] = 0x294A;
video->dmgPalette[3] = 0x0000;
video->sgbBorders = true;
video->renderer->sgbCharRam = NULL;
video->renderer->sgbMapRam = NULL;
video->renderer->sgbPalRam = NULL;
@ -122,7 +124,7 @@ void GBVideoReset(struct GBVideo* video) {
video->palette[9 * 4 + 3] = video->dmgPalette[3];
video->renderer->deinit(video->renderer);
video->renderer->init(video->renderer, video->p->model);
video->renderer->init(video->renderer, video->p->model, video->sgbBorders);
video->renderer->writePalette(video->renderer, 0, video->palette[0]);
video->renderer->writePalette(video->renderer, 1, video->palette[1]);
@ -174,7 +176,7 @@ void GBVideoAssociateRenderer(struct GBVideo* video, struct GBVideoRenderer* ren
renderer->sgbAttributes = video->renderer->sgbAttributes;
video->renderer = renderer;
renderer->vram = video->vram;
video->renderer->init(video->renderer, video->p->model);
video->renderer->init(video->renderer, video->p->model, video->sgbBorders);
}
static bool _statIRQAsserted(struct GBVideo* video, GBRegisterSTAT stat) {
@ -676,9 +678,10 @@ void GBVideoWriteSGBPacket(struct GBVideo* video, uint8_t* data) {
video->renderer->writeSGBPacket(video->renderer, data);
}
static void GBVideoDummyRendererInit(struct GBVideoRenderer* renderer, enum GBModel model) {
static void GBVideoDummyRendererInit(struct GBVideoRenderer* renderer, enum GBModel model, bool borders) {
UNUSED(renderer);
UNUSED(model);
UNUSED(borders);
// Nothing to do
}
@ -833,5 +836,5 @@ void GBVideoDeserialize(struct GBVideo* video, const struct GBSerializedState* s
GBVideoSwitchBank(video, video->vramCurrentBank);
video->renderer->deinit(video->renderer);
video->renderer->init(video->renderer, video->p->model);
video->renderer->init(video->renderer, video->p->model, video->sgbBorders);
}

View File

@ -295,6 +295,7 @@ void SettingsView::updateConfig() {
saveSetting("gb.bios", m_ui.gbBios);
saveSetting("gbc.bios", m_ui.gbcBios);
saveSetting("sgb.bios", m_ui.sgbBios);
saveSetting("sgb.borders", m_ui.sgbBorders);
saveSetting("useBios", m_ui.useBios);
saveSetting("skipBios", m_ui.skipBios);
saveSetting("audioBuffers", m_ui.audioBufferSize);
@ -410,6 +411,7 @@ void SettingsView::reloadConfig() {
loadSetting("gb.bios", m_ui.gbBios);
loadSetting("gbc.bios", m_ui.gbcBios);
loadSetting("sgb.bios", m_ui.sgbBios);
loadSetting("sgb.borders", m_ui.sgbBorders, true);
loadSetting("useBios", m_ui.useBios);
loadSetting("skipBios", m_ui.skipBios);
loadSetting("audioBuffers", m_ui.audioBufferSize);
@ -529,9 +531,9 @@ void SettingsView::saveSetting(const char* key, const QVariant& field) {
m_controller->updateOption(key);
}
void SettingsView::loadSetting(const char* key, QAbstractButton* field) {
void SettingsView::loadSetting(const char* key, QAbstractButton* field, bool defaultVal) {
QString option = loadSetting(key);
field->setChecked(!option.isNull() && option != "0");
field->setChecked((!option.isNull() && option != "0") || defaultVal);
}
void SettingsView::loadSetting(const char* key, QComboBox* field) {

View File

@ -69,7 +69,7 @@ private:
void saveSetting(const char* key, const QSpinBox*);
void saveSetting(const char* key, const QVariant&);
void loadSetting(const char* key, QAbstractButton*);
void loadSetting(const char* key, QAbstractButton*, bool defaultVal = false);
void loadSetting(const char* key, QComboBox*);
void loadSetting(const char* key, QDoubleSpinBox*);
void loadSetting(const char* key, QLineEdit*);

View File

@ -1098,14 +1098,86 @@
</item>
</widget>
</item>
<item row="3" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label_32">
<property name="text">
<string>Super Game Boy model</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="sgbModel">
<item>
<property name="text">
<string>Autodetect</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy (DMG)</string>
</property>
</item>
<item>
<property name="text">
<string>Super Game Boy (SGB)</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy Color (CGB)</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy Advance (AGB)</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_33">
<property name="text">
<string>Game Boy Color model</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="cgbModel">
<item>
<property name="text">
<string>Autodetect</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy (DMG)</string>
</property>
</item>
<item>
<property name="text">
<string>Super Game Boy (SGB)</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy Color (CGB)</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy Advance (AGB)</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_28">
<property name="text">
<string>Default colors:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
<widget class="QFrame" name="color0">
@ -1185,21 +1257,28 @@
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<item row="5" column="1">
<widget class="QCheckBox" name="sgbBorders">
<property name="text">
<string>Super Game Boy borders</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="Line" name="line_11">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="5" column="0">
<item row="7" column="0">
<widget class="QLabel" name="label_27">
<property name="text">
<string>Camera driver:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="7" column="1">
<widget class="QComboBox" name="cameraDriver">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
@ -1209,78 +1288,13 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_32">
<property name="text">
<string>Super Game Boy model</string>
<item row="3" column="0" colspan="2">
<widget class="Line" name="line_12">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_33">
<property name="text">
<string>Game Boy Color model</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="sgbModel">
<item>
<property name="text">
<string>Autodetect</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy (DMG)</string>
</property>
</item>
<item>
<property name="text">
<string>Super Game Boy (SGB)</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy Color (CGB)</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy Advance (AGB)</string>
</property>
</item>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="cgbModel">
<item>
<property name="text">
<string>Autodetect</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy (DMG)</string>
</property>
</item>
<item>
<property name="text">
<string>Super Game Boy (SGB)</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy Color (CGB)</string>
</property>
</item>
<item>
<property name="text">
<string>Game Boy Advance (AGB)</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</widget>