GB: Add separate overrides for GBC games that can also run on SGB or regular GB

This commit is contained in:
Vicki Pfau 2020-08-28 18:19:13 -07:00
parent 3e91c50f2d
commit 9dc6dc7e65
6 changed files with 167 additions and 93 deletions

View File

@ -1,9 +1,10 @@
0.9.0: (Future) 0.9.0: (Future)
Features: Features:
- e-Reader card scanning - e-Reader card scanning
- Add WebP and APNG recording - WebP and APNG recording
- Add mute option in homebrew ports - Separate overrides for GBC games that can also run on SGB or regular GB
- Add status indicators for fast-forward and mute in homebrew ports - 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 Pokemon Jade/Diamond Game Boy mapper
- Support for unlicensed BBD Game Boy mapper - Support for unlicensed BBD Game Boy mapper
- Support for unlicensed Hitek Game Boy mapper - Support for unlicensed Hitek Game Boy mapper

View File

@ -59,6 +59,8 @@ bool GBIsBIOS(struct VFile* vf);
enum GBModel GBNameToModel(const char*); enum GBModel GBNameToModel(const char*);
const char* GBModelToName(enum GBModel); const char* GBModelToName(enum GBModel);
int GBValidModels(const uint8_t* bank0);
CXX_GUARD_END CXX_GUARD_END
#endif #endif

View File

@ -221,6 +221,8 @@ static void _GBCoreLoadConfig(struct mCore* core, const struct mCoreConfig* conf
mCoreConfigCopyValue(&core->config, config, "gb.model"); mCoreConfigCopyValue(&core->config, config, "gb.model");
mCoreConfigCopyValue(&core->config, config, "sgb.model"); mCoreConfigCopyValue(&core->config, config, "sgb.model");
mCoreConfigCopyValue(&core->config, config, "cgb.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, "useCgbColors");
mCoreConfigCopyValue(&core->config, config, "allowOpposingDirections"); mCoreConfigCopyValue(&core->config, config, "allowOpposingDirections");
@ -437,19 +439,42 @@ static void _GBCoreReset(struct mCore* core) {
if (GBOverrideFind(gbcore->overrides, &override) || (doColorOverride && GBOverrideColorFind(&override))) { if (GBOverrideFind(gbcore->overrides, &override) || (doColorOverride && GBOverrideColorFind(&override))) {
GBOverrideApply(gb, &override); GBOverrideApply(gb, &override);
} }
}
const char* modelGB = mCoreConfigGetValue(&core->config, "gb.model"); const char* modelGB = mCoreConfigGetValue(&core->config, "gb.model");
const char* modelCGB = mCoreConfigGetValue(&core->config, "cgb.model"); const char* modelSGB = mCoreConfigGetValue(&core->config, "sgb.model");
const char* modelSGB = mCoreConfigGetValue(&core->config, "sgb.model"); const char* modelCGB = mCoreConfigGetValue(&core->config, "cgb.model");
if (modelGB || modelCGB || modelSGB) { const char* modelCGBHybrid = mCoreConfigGetValue(&core->config, "cgb.hybridModel");
GBDetectModel(gb); const char* modelCGBSGB = mCoreConfigGetValue(&core->config, "cgb.sgbModel");
if (gb->model == GB_MODEL_DMG && modelGB) { if (modelGB || modelCGB || modelSGB || modelCGBHybrid || modelCGBSGB) {
gb->model = GBNameToModel(modelGB); int models = GBValidModels(gb->memory.rom);
} else if ((gb->model & GB_MODEL_CGB) && modelCGB) { switch (models) {
gb->model = GBNameToModel(modelCGB); case GB_MODEL_SGB | GB_MODEL_MGB:
} else if ((gb->model & GB_MODEL_SGB) && modelSGB) { if (modelSGB) {
gb->model = GBNameToModel(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;
}
} }
} }

View File

@ -656,6 +656,22 @@ void GBDetectModel(struct GB* gb) {
} }
} }
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) { void GBUpdateIRQs(struct GB* gb) {
int irqs = gb->memory.ie & gb->memory.io[REG_IF] & 0x1F; int irqs = gb->memory.ie & gb->memory.io[REG_IF] & 0x1F;
if (!irqs) { if (!irqs) {

View File

@ -33,15 +33,19 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC
m_ui.setupUi(this); m_ui.setupUi(this);
#ifdef M_CORE_GB #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()) { for (auto model : GameBoy::modelList()) {
m_ui.gbModel->addItem(GameBoy::modelName(model), model); m_ui.gbModel->addItem(GameBoy::modelName(model), model);
m_ui.sgbModel->addItem(GameBoy::modelName(model), model); m_ui.sgbModel->addItem(GameBoy::modelName(model), model);
m_ui.cgbModel->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 #endif
reloadConfig(); reloadConfig();
@ -527,6 +531,16 @@ void SettingsView::updateConfig() {
m_controller->setOption("cgb.model", GBModelToName(static_cast<GBModel>(modelCGB.toInt()))); 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) { for (int colorId = 0; colorId < 12; ++colorId) {
if (!(m_gbColors[colorId] & 0xFF000000)) { if (!(m_gbColors[colorId] & 0xFF000000)) {
continue; continue;
@ -665,6 +679,20 @@ void SettingsView::reloadConfig() {
int index = m_ui.cgbModel->findData(model); int index = m_ui.cgbModel->findData(model);
m_ui.cgbModel->setCurrentIndex(index >= 0 ? index : 0); 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 #endif
int hwaccelVideo = m_controller->getOption("hwaccelVideo", 0).toInt(); int hwaccelVideo = m_controller->getOption("hwaccelVideo", 0).toInt();

View File

@ -1465,18 +1465,12 @@
<item row="0" column="0"> <item row="0" column="0">
<widget class="QLabel" name="label_29"> <widget class="QLabel" name="label_29">
<property name="text"> <property name="text">
<string>Game Boy model:</string> <string>Game Boy-only model:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">
<widget class="QComboBox" name="gbModel"> <widget class="QComboBox" name="gbModel"/>
<item>
<property name="text">
<string>Autodetect</string>
</property>
</item>
</widget>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QLabel" name="label_32"> <widget class="QLabel" name="label_32">
@ -1486,45 +1480,40 @@
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
<widget class="QComboBox" name="sgbModel"> <widget class="QComboBox" name="sgbModel"/>
<item>
<property name="text">
<string>Autodetect</string>
</property>
</item>
</widget>
</item> </item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QLabel" name="label_33"> <widget class="QLabel" name="label_33">
<property name="text"> <property name="text">
<string>Game Boy Color model:</string> <string>Game Boy Color-only model:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="2" column="1">
<widget class="QComboBox" name="cgbModel"> <widget class="QComboBox" name="cgbModel"/>
<item> </item>
<property name="text"> <item row="3" column="0">
<string>Autodetect</string> <widget class="QLabel" name="label_38">
</property> <property name="text">
</item> <string>Game Boy/Game Boy Color model:</string>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="2"> <item row="5" column="0" colspan="2">
<widget class="Line" name="line_12"> <widget class="Line" name="line_12">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0"> <item row="6" column="0">
<widget class="QLabel" name="label_28"> <widget class="QLabel" name="label_28">
<property name="text"> <property name="text">
<string>Default BG colors:</string> <string>Default BG colors:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="1"> <item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_9"> <layout class="QHBoxLayout" name="horizontalLayout_9">
<item> <item>
<widget class="QFrame" name="color0"> <widget class="QFrame" name="color0">
@ -1604,7 +1593,14 @@
</item> </item>
</layout> </layout>
</item> </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"> <layout class="QHBoxLayout" name="horizontalLayout_15">
<item> <item>
<widget class="QFrame" name="color4"> <widget class="QFrame" name="color4">
@ -1684,38 +1680,14 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="8" column="0">
<widget class="QLabel" name="label_70">
<property name="text">
<string>Default sprite colors 2:</string>
</property>
</widget>
</item>
<item row="8" column="1"> <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">
<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>
</property>
</widget>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_37"> <layout class="QHBoxLayout" name="horizontalLayout_37">
<item> <item>
<widget class="QFrame" name="color8"> <widget class="QFrame" name="color8">
@ -1795,35 +1767,52 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="5" column="0"> <item row="9" column="1">
<widget class="QLabel" name="label_69">
<property name="text">
<string>Default sprite colors 1:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_70">
<property name="text">
<string>Default sprite colors 2:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="useCgbColors"> <widget class="QCheckBox" name="useCgbColors">
<property name="text"> <property name="text">
<string>Use GBC colors in GB games</string> <string>Use GBC colors in GB games</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="0"> <item row="10" column="1">
<widget class="QCheckBox" name="sgbBorders">
<property name="text">
<string>Super Game Boy borders</string>
</property>
</widget>
</item>
<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>Camera driver:</string>
</property>
</widget>
</item>
<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"> <widget class="QLabel" name="label_35">
<property name="text"> <property name="text">
<string>Camera:</string> <string>Camera:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="11" column="1"> <item row="13" column="1">
<widget class="QComboBox" name="camera"> <widget class="QComboBox" name="camera">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
@ -1836,6 +1825,19 @@
</property> </property>
</widget> </widget>
</item> </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> </layout>
</widget> </widget>
</widget> </widget>