GB Core: Ability to set default Game Boy model
@@ -6,6 +6,7 @@ - Qt: Set default Game Boy colors
- Game Boy Printer support - Super Game Boy support - Customizable autofire speed + - Ability to set default Game Boy model Bugfixes: - GB Audio: Make audio unsigned with bias (fixes mgba.io/i/749) - Python: Fix importing .gb or .gba before .core
@@ -47,6 +47,9 @@ void (*writeSB)(struct GBSIODriver* driver, uint8_t value);
uint8_t (*writeSC)(struct GBSIODriver* driver, uint8_t value); }; +enum GBModel GBNameToModel(const char*); +const char* GBModelToName(enum GBModel); + CXX_GUARD_END #endif
@@ -183,6 +183,9 @@
mCoreConfigCopyValue(&core->config, config, "gb.bios"); mCoreConfigCopyValue(&core->config, config, "sgb.bios"); mCoreConfigCopyValue(&core->config, config, "gbc.bios"); + mCoreConfigCopyValue(&core->config, config, "gb.model"); + mCoreConfigCopyValue(&core->config, config, "sgb.model"); + mCoreConfigCopyValue(&core->config, config, "cgb.model"); #if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2 struct GBCore* gbcore = (struct GBCore*) core;@@ -324,6 +327,20 @@ const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100];
override.headerCrc32 = doCrc32(cart, sizeof(*cart)); if (GBOverrideFind(gbcore->overrides, &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); } }
@@ -737,3 +737,40 @@ }
GBTestKeypadIRQ(gb); } + +enum GBModel GBNameToModel(const char* model) { + if (strcasecmp(model, "DMG") == 0) { + return GB_MODEL_DMG; + } else if (strcasecmp(model, "CGB") == 0) { + return GB_MODEL_CGB; + } else if (strcasecmp(model, "AGB") == 0) { + return GB_MODEL_AGB; + } else if (strcasecmp(model, "SGB") == 0) { + return GB_MODEL_SGB; + } else if (strcasecmp(model, "MGB") == 0) { + return GB_MODEL_MGB; + } else if (strcasecmp(model, "SGB2") == 0) { + return GB_MODEL_SGB2; + } + return GB_MODEL_AUTODETECT; +} + +const char* GBModelToName(enum GBModel model) { + switch (model) { + case GB_MODEL_DMG: + return "DMG"; + case GB_MODEL_SGB: + return "SGB"; + case GB_MODEL_MGB: + return "MGB"; + case GB_MODEL_SGB2: + return "SGB2"; + case GB_MODEL_CGB: + return "CGB"; + case GB_MODEL_AGB: + return "AGB"; + default: + case GB_MODEL_AUTODETECT: + return NULL; + } +}
@@ -43,25 +43,8 @@ ConfigurationGetValue(config, sectionName, "pal[3]")
}; if (model) { - if (strcasecmp(model, "DMG") == 0) { - found = true; - override->model = GB_MODEL_DMG; - } else if (strcasecmp(model, "CGB") == 0) { - found = true; - override->model = GB_MODEL_CGB; - } else if (strcasecmp(model, "AGB") == 0) { - found = true; - override->model = GB_MODEL_AGB; - } else if (strcasecmp(model, "SGB") == 0) { - found = true; - override->model = GB_MODEL_SGB; - } else if (strcasecmp(model, "MGB") == 0) { - found = true; - override->model = GB_MODEL_MGB; - } else if (strcasecmp(model, "SGB2") == 0) { - found = true; - override->model = GB_MODEL_SGB2; - } + override->model = GBNameToModel(model); + found = override->model != GB_MODEL_AUTODETECT; } if (mbc) {@@ -94,29 +77,7 @@
void GBOverrideSave(struct Configuration* config, const struct GBCartridgeOverride* override) { char sectionName[24] = ""; snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32); - const char* model = 0; - switch (override->model) { - case GB_MODEL_DMG: - model = "DMG"; - break; - case GB_MODEL_SGB: - model = "SGB"; - break; - case GB_MODEL_MGB: - model = "MGB"; - break; - case GB_MODEL_SGB2: - model = "SGB2"; - break; - case GB_MODEL_CGB: - model = "CGB"; - break; - case GB_MODEL_AGB: - model = "AGB"; - break; - case GB_MODEL_AUTODETECT: - break; - } + const char* model = GBModelToName(override->model); ConfigurationSetValue(config, sectionName, "model", model); if (override->gbColors[0] | override->gbColors[1] | override->gbColors[2] | override->gbColors[3]) {
@@ -20,11 +20,26 @@ #include <mgba/internal/gba/gba.h>
using namespace QGBA; +#ifdef M_CORE_GB +QList<enum GBModel> SettingsView::s_gbModelList; +#endif + SettingsView::SettingsView(ConfigController* controller, InputController* inputController, ShortcutController* shortcutController, QWidget* parent) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint) , m_controller(controller) { m_ui.setupUi(this); + +#ifdef M_CORE_GB + if (s_gbModelList.isEmpty()) { + // NB: Keep in sync with SettingsView.ui + s_gbModelList.append(GB_MODEL_AUTODETECT); + s_gbModelList.append(GB_MODEL_DMG); + s_gbModelList.append(GB_MODEL_SGB); + s_gbModelList.append(GB_MODEL_CGB); + s_gbModelList.append(GB_MODEL_AGB); + } +#endif reloadConfig();@@ -365,12 +380,23 @@ m_controller->setQtOption("language", language.bcp47Name());
emit languageChanged(); } +#ifdef M_CORE_GB + GBModel modelGB = s_gbModelList[m_ui.gbModel->currentIndex()]; + m_controller->setOption("gb.model", GBModelToName(modelGB)); + + GBModel modelSGB = s_gbModelList[m_ui.sgbModel->currentIndex()]; + m_controller->setOption("sgb.model", GBModelToName(modelSGB)); + + GBModel modelCGB = s_gbModelList[m_ui.cgbModel->currentIndex()]; + m_controller->setOption("cgb.model", GBModelToName(modelCGB)); + if (m_gbColors[0] | m_gbColors[1] | m_gbColors[2] | m_gbColors[3]) { m_controller->setOption("gb.pal[0]", m_gbColors[0]); m_controller->setOption("gb.pal[1]", m_gbColors[1]); m_controller->setOption("gb.pal[2]", m_gbColors[2]); m_controller->setOption("gb.pal[3]", m_gbColors[3]); } +#endif m_controller->write();@@ -448,6 +474,29 @@ }
m_ui.saveStateScreenshot->setChecked(saveState & SAVESTATE_SCREENSHOT); m_ui.saveStateSave->setChecked(saveState & SAVESTATE_SAVEDATA); m_ui.saveStateCheats->setChecked(saveState & SAVESTATE_CHEATS); + +#ifdef M_CORE_GB + QString modelGB = m_controller->getOption("gb.model"); + if (!modelGB.isNull()) { + GBModel model = GBNameToModel(modelGB.toUtf8().constData()); + int index = s_gbModelList.indexOf(model); + m_ui.gbModel->setCurrentIndex(index >= 0 ? index : 0); + } + + QString modelSGB = m_controller->getOption("sgb.model"); + if (!modelSGB.isNull()) { + GBModel model = GBNameToModel(modelSGB.toUtf8().constData()); + int index = s_gbModelList.indexOf(model); + m_ui.sgbModel->setCurrentIndex(index >= 0 ? index : 0); + } + + QString modelCGB = m_controller->getOption("cgb.model"); + if (!modelCGB.isNull()) { + GBModel model = GBNameToModel(modelCGB.toUtf8().constData()); + int index = s_gbModelList.indexOf(model); + m_ui.cgbModel->setCurrentIndex(index >= 0 ? index : 0); + } +#endif } void SettingsView::saveSetting(const char* key, const QAbstractButton* field) {
@@ -12,6 +12,10 @@ #include "ColorPicker.h"
#include <mgba/core/core.h> +#ifdef M_CORE_GB +#include <mgba/gb/interface.h> +#endif + #include "ui_SettingsView.h" namespace QGBA {@@ -50,8 +54,12 @@
ConfigController* m_controller; InputController* m_input; ShaderSelector* m_shader = nullptr; + +#ifdef M_CORE_GB uint32_t m_gbColors[4]{}; ColorPicker m_colorPickers[4]; + static QList<enum GBModel> s_gbModelList; +#endif void saveSetting(const char* key, const QAbstractButton*); void saveSetting(const char* key, const QComboBox*);
@@ -6,7 +6,7 @@ <property name="geometry">
<rect> <x>0</x> <y>0</y> - <width>650</width> + <width>588</width> <height>488</height> </rect> </property>@@ -1061,22 +1061,16 @@ </item>
</layout> </widget> <widget class="QWidget" name="gb"> - <layout class="QFormLayout" name="formLayout"> + <layout class="QFormLayout" name="formLayout_1"> <item row="0" column="0"> <widget class="QLabel" name="label_29"> - <property name="enabled"> - <bool>false</bool> - </property> <property name="text"> - <string>Default model</string> + <string>Game Boy model</string> </property> </widget> </item> <item row="0" column="1"> <widget class="QComboBox" name="gbModel"> - <property name="enabled"> - <bool>false</bool> - </property> <item> <property name="text"> <string>Autodetect</string>@@ -1089,6 +1083,11 @@ </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>@@ -1099,14 +1098,14 @@ </property>
</item> </widget> </item> - <item row="1" column="0"> + <item row="3" column="0"> <widget class="QLabel" name="label_28"> <property name="text"> - <string>Default colors</string> + <string>Default colors:</string> </property> </widget> </item> - <item row="1" column="1"> + <item row="3" column="1"> <layout class="QHBoxLayout" name="horizontalLayout_9"> <item> <widget class="QFrame" name="color0">@@ -1186,21 +1185,21 @@ </widget>
</item> </layout> </item> - <item row="2" column="0" colspan="2"> + <item row="4" column="0" colspan="2"> <widget class="Line" name="line_11"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> - <item row="3" column="0"> + <item row="5" column="0"> <widget class="QLabel" name="label_27"> <property name="text"> - <string>Camera driver</string> + <string>Camera driver:</string> </property> </widget> </item> - <item row="3" column="1"> + <item row="5" column="1"> <widget class="QComboBox" name="cameraDriver"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Fixed">@@ -1208,6 +1207,78 @@ <horstretch>0</horstretch>
<verstretch>0</verstretch> </sizepolicy> </property> + </widget> + </item> + <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="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>