GB: Add separate overrides for GBC games that can also run on SGB or regular GB
Vicki Pfau vi@endrift.com
Fri, 28 Aug 2020 18:19:13 -0700
6 files changed,
158 insertions(+),
84 deletions(-)
M
CHANGES
→
CHANGES
@@ -1,9 +1,10 @@
0.9.0: (Future) Features: - e-Reader card scanning - - Add WebP and APNG recording - - Add mute option in homebrew ports - - Add status indicators for fast-forward and mute in homebrew ports + - WebP and APNG recording + - Separate overrides for GBC games that can also run on SGB or regular GB + - Mute option in homebrew ports + - Status indicators for fast-forward and mute in homebrew ports - Support for unlicensed Pokemon Jade/Diamond Game Boy mapper - Support for unlicensed BBD Game Boy mapper - Support for unlicensed Hitek Game Boy mapper
M
include/mgba/gb/interface.h
→
include/mgba/gb/interface.h
@@ -59,6 +59,8 @@
enum GBModel GBNameToModel(const char*); const char* GBModelToName(enum GBModel); +int GBValidModels(const uint8_t* bank0); + CXX_GUARD_END #endif
M
src/gb/core.c
→
src/gb/core.c
@@ -221,6 +221,8 @@ 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, "cgb.hybridModel"); + mCoreConfigCopyValue(&core->config, config, "cgb.sgbModel"); mCoreConfigCopyValue(&core->config, config, "useCgbColors"); mCoreConfigCopyValue(&core->config, config, "allowOpposingDirections");@@ -437,19 +439,42 @@ override.headerCrc32 = doCrc32(cart, sizeof(*cart));
if (GBOverrideFind(gbcore->overrides, &override) || (doColorOverride && GBOverrideColorFind(&override))) { GBOverrideApply(gb, &override); } - } - const char* modelGB = mCoreConfigGetValue(&core->config, "gb.model"); - const char* modelCGB = mCoreConfigGetValue(&core->config, "cgb.model"); - const char* modelSGB = mCoreConfigGetValue(&core->config, "sgb.model"); - if (modelGB || modelCGB || modelSGB) { - GBDetectModel(gb); - if (gb->model == GB_MODEL_DMG && modelGB) { - gb->model = GBNameToModel(modelGB); - } else if ((gb->model & GB_MODEL_CGB) && modelCGB) { - gb->model = GBNameToModel(modelCGB); - } else if ((gb->model & GB_MODEL_SGB) && modelSGB) { - gb->model = GBNameToModel(modelSGB); + const char* modelGB = mCoreConfigGetValue(&core->config, "gb.model"); + const char* modelSGB = mCoreConfigGetValue(&core->config, "sgb.model"); + const char* modelCGB = mCoreConfigGetValue(&core->config, "cgb.model"); + const char* modelCGBHybrid = mCoreConfigGetValue(&core->config, "cgb.hybridModel"); + const char* modelCGBSGB = mCoreConfigGetValue(&core->config, "cgb.sgbModel"); + if (modelGB || modelCGB || modelSGB || modelCGBHybrid || modelCGBSGB) { + int models = GBValidModels(gb->memory.rom); + switch (models) { + case GB_MODEL_SGB | GB_MODEL_MGB: + if (modelSGB) { + gb->model = GBNameToModel(modelSGB); + } + break; + case GB_MODEL_MGB: + if (modelGB) { + gb->model = GBNameToModel(modelGB); + } + break; + case GB_MODEL_MGB | GB_MODEL_CGB: + if (modelCGBHybrid) { + gb->model = GBNameToModel(modelCGBHybrid); + } + break; + case GB_MODEL_SGB | GB_MODEL_CGB: // TODO: Do these even exist? + case GB_MODEL_MGB | GB_MODEL_SGB | GB_MODEL_CGB: + if (modelCGBSGB) { + gb->model = GBNameToModel(modelCGBSGB); + } + break; + case GB_MODEL_CGB: + if (modelCGB) { + gb->model = GBNameToModel(modelCGB); + } + break; + } } }
M
src/gb/gb.c
→
src/gb/gb.c
@@ -656,6 +656,22 @@ break;
} } +int GBValidModels(const uint8_t* bank0) { + const struct GBCartridge* cart = (const struct GBCartridge*) &bank0[0x100]; + int models; + if (cart->cgb == 0x80) { + models = GB_MODEL_CGB | GB_MODEL_MGB; + } else if (cart->cgb == 0xC0) { + models = GB_MODEL_CGB; + } else { + models = GB_MODEL_MGB; + } + if (cart->sgb == 0x03 && cart->oldLicensee == 0x33) { + models |= GB_MODEL_SGB; + } + return models; +} + void GBUpdateIRQs(struct GB* gb) { int irqs = gb->memory.ie & gb->memory.io[REG_IF] & 0x1F; if (!irqs) {
M
src/platform/qt/SettingsView.cpp
→
src/platform/qt/SettingsView.cpp
@@ -33,15 +33,19 @@ {
m_ui.setupUi(this); #ifdef M_CORE_GB - m_ui.gbModel->setItemData(0, GB_MODEL_AUTODETECT); - m_ui.sgbModel->setItemData(0, GB_MODEL_AUTODETECT); - m_ui.cgbModel->setItemData(0, GB_MODEL_AUTODETECT); - for (auto model : GameBoy::modelList()) { m_ui.gbModel->addItem(GameBoy::modelName(model), model); m_ui.sgbModel->addItem(GameBoy::modelName(model), model); m_ui.cgbModel->addItem(GameBoy::modelName(model), model); + m_ui.cgbHybridModel->addItem(GameBoy::modelName(model), model); + m_ui.cgbSgbModel->addItem(GameBoy::modelName(model), model); } + + m_ui.gbModel->setCurrentIndex(m_ui.gbModel->findData(GB_MODEL_DMG)); + m_ui.sgbModel->setCurrentIndex(m_ui.gbModel->findData(GB_MODEL_SGB)); + m_ui.cgbModel->setCurrentIndex(m_ui.gbModel->findData(GB_MODEL_CGB)); + m_ui.cgbHybridModel->setCurrentIndex(m_ui.gbModel->findData(GB_MODEL_CGB)); + m_ui.cgbSgbModel->setCurrentIndex(m_ui.gbModel->findData(GB_MODEL_CGB)); #endif reloadConfig();@@ -527,6 +531,16 @@ if (modelCGB.isValid()) {
m_controller->setOption("cgb.model", GBModelToName(static_cast<GBModel>(modelCGB.toInt()))); } + QVariant modelCGBHybrid = m_ui.cgbHybridModel->currentData(); + if (modelCGBHybrid.isValid()) { + m_controller->setOption("cgb.hybridModel", GBModelToName(static_cast<GBModel>(modelCGBHybrid.toInt()))); + } + + QVariant modelCGBSGB = m_ui.cgbSgbModel->currentData(); + if (modelCGBSGB.isValid()) { + m_controller->setOption("cgb.sgbModel", GBModelToName(static_cast<GBModel>(modelCGBSGB.toInt()))); + } + for (int colorId = 0; colorId < 12; ++colorId) { if (!(m_gbColors[colorId] & 0xFF000000)) { continue;@@ -664,6 +678,20 @@ if (!modelCGB.isNull()) {
GBModel model = GBNameToModel(modelCGB.toUtf8().constData()); int index = m_ui.cgbModel->findData(model); m_ui.cgbModel->setCurrentIndex(index >= 0 ? index : 0); + } + + QString modelCGBHybrid = m_controller->getOption("cgb.hybridModel"); + if (!modelCGBHybrid.isNull()) { + GBModel model = GBNameToModel(modelCGBHybrid.toUtf8().constData()); + int index = m_ui.cgbHybridModel->findData(model); + m_ui.cgbHybridModel->setCurrentIndex(index >= 0 ? index : 0); + } + + QString modelCGBSGB = m_controller->getOption("cgb.sgbModel"); + if (!modelCGBSGB.isNull()) { + GBModel model = GBNameToModel(modelCGBSGB.toUtf8().constData()); + int index = m_ui.cgbSgbModel->findData(model); + m_ui.cgbSgbModel->setCurrentIndex(index >= 0 ? index : 0); } #endif
M
src/platform/qt/SettingsView.ui
→
src/platform/qt/SettingsView.ui
@@ -1465,18 +1465,12 @@ <layout class="QFormLayout" name="formLayout_1">
<item row="0" column="0"> <widget class="QLabel" name="label_29"> <property name="text"> - <string>Game Boy model:</string> + <string>Game Boy-only model:</string> </property> </widget> </item> <item row="0" column="1"> - <widget class="QComboBox" name="gbModel"> - <item> - <property name="text"> - <string>Autodetect</string> - </property> - </item> - </widget> + <widget class="QComboBox" name="gbModel"/> </item> <item row="1" column="0"> <widget class="QLabel" name="label_32">@@ -1486,45 +1480,40 @@ </property>
</widget> </item> <item row="1" column="1"> - <widget class="QComboBox" name="sgbModel"> - <item> - <property name="text"> - <string>Autodetect</string> - </property> - </item> - </widget> + <widget class="QComboBox" name="sgbModel"/> </item> <item row="2" column="0"> <widget class="QLabel" name="label_33"> <property name="text"> - <string>Game Boy Color model:</string> + <string>Game Boy Color-only model:</string> </property> </widget> </item> <item row="2" column="1"> - <widget class="QComboBox" name="cgbModel"> - <item> - <property name="text"> - <string>Autodetect</string> - </property> - </item> + <widget class="QComboBox" name="cgbModel"/> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_38"> + <property name="text"> + <string>Game Boy/Game Boy Color model:</string> + </property> </widget> </item> - <item row="3" column="0" colspan="2"> + <item row="5" column="0" colspan="2"> <widget class="Line" name="line_12"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> - <item row="4" column="0"> + <item row="6" column="0"> <widget class="QLabel" name="label_28"> <property name="text"> <string>Default BG colors:</string> </property> </widget> </item> - <item row="4" column="1"> + <item row="6" column="1"> <layout class="QHBoxLayout" name="horizontalLayout_9"> <item> <widget class="QFrame" name="color0">@@ -1604,7 +1593,14 @@ </widget>
</item> </layout> </item> - <item row="5" column="1"> + <item row="7" column="0"> + <widget class="QLabel" name="label_69"> + <property name="text"> + <string>Default sprite colors 1:</string> + </property> + </widget> + </item> + <item row="7" column="1"> <layout class="QHBoxLayout" name="horizontalLayout_15"> <item> <widget class="QFrame" name="color4">@@ -1684,38 +1680,14 @@ </widget>
</item> </layout> </item> - <item row="8" column="1"> - <widget class="QCheckBox" name="sgbBorders"> - <property name="text"> - <string>Super Game Boy borders</string> - </property> - </widget> - </item> - <item row="9" column="0" colspan="2"> - <widget class="Line" name="line_11"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item row="10" column="0"> - <widget class="QLabel" name="label_27"> + <item row="8" column="0"> + <widget class="QLabel" name="label_70"> <property name="text"> - <string>Camera driver:</string> - </property> - </widget> - </item> - <item row="10" column="1"> - <widget class="QComboBox" name="cameraDriver"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <string>Default sprite colors 2:</string> </property> </widget> </item> - <item row="6" column="1"> + <item row="8" column="1"> <layout class="QHBoxLayout" name="horizontalLayout_37"> <item> <widget class="QFrame" name="color8">@@ -1795,35 +1767,52 @@ </widget>
</item> </layout> </item> - <item row="5" column="0"> - <widget class="QLabel" name="label_69"> + <item row="9" column="1"> + <widget class="QCheckBox" name="useCgbColors"> <property name="text"> - <string>Default sprite colors 1:</string> + <string>Use GBC colors in GB games</string> </property> </widget> </item> - <item row="6" column="0"> - <widget class="QLabel" name="label_70"> + <item row="10" column="1"> + <widget class="QCheckBox" name="sgbBorders"> <property name="text"> - <string>Default sprite colors 2:</string> + <string>Super Game Boy borders</string> </property> </widget> </item> - <item row="7" column="1"> - <widget class="QCheckBox" name="useCgbColors"> + <item row="11" column="0" colspan="2"> + <widget class="Line" name="line_11"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="12" column="0"> + <widget class="QLabel" name="label_27"> <property name="text"> - <string>Use GBC colors in GB games</string> + <string>Camera driver:</string> </property> </widget> </item> - <item row="11" column="0"> + <item row="12" column="1"> + <widget class="QComboBox" name="cameraDriver"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item row="13" column="0"> <widget class="QLabel" name="label_35"> <property name="text"> <string>Camera:</string> </property> </widget> </item> - <item row="11" column="1"> + <item row="13" column="1"> <widget class="QComboBox" name="camera"> <property name="enabled"> <bool>false</bool>@@ -1835,6 +1824,19 @@ <verstretch>0</verstretch>
</sizepolicy> </property> </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="cgbHybridModel"/> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_39"> + <property name="text"> + <string>Super Game Boy/Game Boy Color model:</string> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QComboBox" name="cgbSgbModel"/> </item> </layout> </widget>