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)
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

View File

@ -59,6 +59,8 @@ bool GBIsBIOS(struct VFile* vf);
enum GBModel GBNameToModel(const char*);
const char* GBModelToName(enum GBModel);
int GBValidModels(const uint8_t* bank0);
CXX_GUARD_END
#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, "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,20 +439,43 @@ static void _GBCoreReset(struct mCore* core) {
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) {
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;
}
}
}
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2

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) {
int irqs = gb->memory.ie & gb->memory.io[REG_IF] & 0x1F;
if (!irqs) {

View File

@ -33,15 +33,19 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC
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 @@ void SettingsView::updateConfig() {
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;
@ -665,6 +679,20 @@ void SettingsView::reloadConfig() {
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
int hwaccelVideo = m_controller->getOption("hwaccelVideo", 0).toInt();

View File

@ -1465,18 +1465,12 @@
<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 @@
</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>
<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 @@
</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 @@
</item>
</layout>
</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">
<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">
<item>
<widget class="QFrame" name="color8">
@ -1795,35 +1767,52 @@
</item>
</layout>
</item>
<item row="5" column="0">
<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">
<item row="9" column="1">
<widget class="QCheckBox" name="useCgbColors">
<property name="text">
<string>Use GBC colors in GB games</string>
</property>
</widget>
</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">
<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>
@ -1836,6 +1825,19 @@
</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>
</widget>