mirror of https://github.com/mgba-emu/mgba.git
GB: Add per-game color overrides
This commit is contained in:
parent
b61b8a0d2b
commit
a2c1ef2fcc
|
@ -16,6 +16,8 @@ struct GBCartridgeOverride {
|
||||||
int headerCrc32;
|
int headerCrc32;
|
||||||
enum GBModel model;
|
enum GBModel model;
|
||||||
enum GBMemoryBankControllerType mbc;
|
enum GBMemoryBankControllerType mbc;
|
||||||
|
|
||||||
|
uint32_t gbColors[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Configuration;
|
struct Configuration;
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
static const struct GBCartridgeOverride _overrides[] = {
|
static const struct GBCartridgeOverride _overrides[] = {
|
||||||
// None yet
|
// None yet
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0, { 0 } }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GBOverrideFind(const struct Configuration* config, struct GBCartridgeOverride* override) {
|
bool GBOverrideFind(const struct Configuration* config, struct GBCartridgeOverride* override) {
|
||||||
|
@ -35,6 +35,12 @@ bool GBOverrideFind(const struct Configuration* config, struct GBCartridgeOverri
|
||||||
snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
|
snprintf(sectionName, sizeof(sectionName), "gb.override.%08X", override->headerCrc32);
|
||||||
const char* model = ConfigurationGetValue(config, sectionName, "model");
|
const char* model = ConfigurationGetValue(config, sectionName, "model");
|
||||||
const char* mbc = ConfigurationGetValue(config, sectionName, "mbc");
|
const char* mbc = ConfigurationGetValue(config, sectionName, "mbc");
|
||||||
|
const char* pal[4] = {
|
||||||
|
ConfigurationGetValue(config, sectionName, "pal[0]"),
|
||||||
|
ConfigurationGetValue(config, sectionName, "pal[1]"),
|
||||||
|
ConfigurationGetValue(config, sectionName, "pal[2]"),
|
||||||
|
ConfigurationGetValue(config, sectionName, "pal[3]")
|
||||||
|
};
|
||||||
|
|
||||||
if (model) {
|
if (model) {
|
||||||
if (strcasecmp(model, "DMG") == 0) {
|
if (strcasecmp(model, "DMG") == 0) {
|
||||||
|
@ -63,6 +69,21 @@ bool GBOverrideFind(const struct Configuration* config, struct GBCartridgeOverri
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pal[0] && pal[1] && pal[2] && pal[3]) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < 4; ++i) {
|
||||||
|
char* end;
|
||||||
|
unsigned long value = strtoul(pal[i], &end, 10);
|
||||||
|
if (end == &pal[i][1] && *end == 'x') {
|
||||||
|
value = strtoul(pal[i], &end, 16);
|
||||||
|
}
|
||||||
|
if (*end) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
override->gbColors[i] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
@ -89,6 +110,12 @@ void GBOverrideSave(struct Configuration* config, const struct GBCartridgeOverri
|
||||||
}
|
}
|
||||||
ConfigurationSetValue(config, sectionName, "model", model);
|
ConfigurationSetValue(config, sectionName, "model", model);
|
||||||
|
|
||||||
|
if (override->gbColors[0] | override->gbColors[1] | override->gbColors[2] | override->gbColors[3]) {
|
||||||
|
ConfigurationSetIntValue(config, sectionName, "pal[0]", override->gbColors[0]);
|
||||||
|
ConfigurationSetIntValue(config, sectionName, "pal[1]", override->gbColors[1]);
|
||||||
|
ConfigurationSetIntValue(config, sectionName, "pal[2]", override->gbColors[2]);
|
||||||
|
ConfigurationSetIntValue(config, sectionName, "pal[3]", override->gbColors[3]);
|
||||||
|
}
|
||||||
if (override->mbc != GB_MBC_AUTODETECT) {
|
if (override->mbc != GB_MBC_AUTODETECT) {
|
||||||
ConfigurationSetIntValue(config, sectionName, "mbc", override->mbc);
|
ConfigurationSetIntValue(config, sectionName, "mbc", override->mbc);
|
||||||
} else {
|
} else {
|
||||||
|
@ -105,6 +132,13 @@ void GBOverrideApply(struct GB* gb, const struct GBCartridgeOverride* override)
|
||||||
gb->memory.mbcType = override->mbc;
|
gb->memory.mbcType = override->mbc;
|
||||||
GBMBCInit(gb);
|
GBMBCInit(gb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (override->gbColors[0] | override->gbColors[1] | override->gbColors[2] | override->gbColors[3]) {
|
||||||
|
GBVideoSetPalette(&gb->video, 0, override->gbColors[0]);
|
||||||
|
GBVideoSetPalette(&gb->video, 1, override->gbColors[1]);
|
||||||
|
GBVideoSetPalette(&gb->video, 2, override->gbColors[2]);
|
||||||
|
GBVideoSetPalette(&gb->video, 3, override->gbColors[3]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBOverrideApplyDefaults(struct GB* gb) {
|
void GBOverrideApplyDefaults(struct GB* gb) {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
#include "OverrideView.h"
|
#include "OverrideView.h"
|
||||||
|
|
||||||
|
#include <QColorDialog>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
#include "ConfigController.h"
|
#include "ConfigController.h"
|
||||||
|
@ -79,6 +80,21 @@ OverrideView::OverrideView(GameController* controller, ConfigController* config,
|
||||||
connect(m_ui.gbModel, &QComboBox::currentTextChanged, this, &OverrideView::updateOverrides);
|
connect(m_ui.gbModel, &QComboBox::currentTextChanged, this, &OverrideView::updateOverrides);
|
||||||
connect(m_ui.mbc, &QComboBox::currentTextChanged, this, &OverrideView::updateOverrides);
|
connect(m_ui.mbc, &QComboBox::currentTextChanged, this, &OverrideView::updateOverrides);
|
||||||
|
|
||||||
|
QPalette palette = m_ui.color0->palette();
|
||||||
|
palette.setColor(backgroundRole(), QColor(0xF8, 0xF8, 0xF8));
|
||||||
|
m_ui.color0->setPalette(palette);
|
||||||
|
palette.setColor(backgroundRole(), QColor(0xA8, 0xA8, 0xA8));
|
||||||
|
m_ui.color1->setPalette(palette);
|
||||||
|
palette.setColor(backgroundRole(), QColor(0x50, 0x50, 0x50));
|
||||||
|
m_ui.color2->setPalette(palette);
|
||||||
|
palette.setColor(backgroundRole(), QColor(0x00, 0x00, 0x00));
|
||||||
|
m_ui.color3->setPalette(palette);
|
||||||
|
|
||||||
|
m_ui.color0->installEventFilter(this);
|
||||||
|
m_ui.color1->installEventFilter(this);
|
||||||
|
m_ui.color2->installEventFilter(this);
|
||||||
|
m_ui.color3->installEventFilter(this);
|
||||||
|
|
||||||
connect(m_ui.tabWidget, &QTabWidget::currentChanged, this, &OverrideView::updateOverrides);
|
connect(m_ui.tabWidget, &QTabWidget::currentChanged, this, &OverrideView::updateOverrides);
|
||||||
#ifndef M_CORE_GBA
|
#ifndef M_CORE_GBA
|
||||||
m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.tabGBA));
|
m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.tabGBA));
|
||||||
|
@ -96,6 +112,42 @@ OverrideView::OverrideView(GameController* controller, ConfigController* config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OverrideView::eventFilter(QObject* obj, QEvent* event) {
|
||||||
|
#ifdef M_CORE_GB
|
||||||
|
if (event->type() != QEvent::MouseButtonRelease) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int colorId;
|
||||||
|
if (obj == m_ui.color0) {
|
||||||
|
colorId = 0;
|
||||||
|
} else if (obj == m_ui.color1) {
|
||||||
|
colorId = 1;
|
||||||
|
} else if (obj == m_ui.color2) {
|
||||||
|
colorId = 2;
|
||||||
|
} else if (obj == m_ui.color3) {
|
||||||
|
colorId = 3;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget* swatch = static_cast<QWidget*>(obj);
|
||||||
|
|
||||||
|
QColorDialog* colorPicker = new QColorDialog;
|
||||||
|
colorPicker->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
colorPicker->open();
|
||||||
|
connect(colorPicker, &QColorDialog::colorSelected, [this, swatch, colorId](const QColor& color) {
|
||||||
|
QPalette palette = swatch->palette();
|
||||||
|
palette.setColor(backgroundRole(), color);
|
||||||
|
swatch->setPalette(palette);
|
||||||
|
m_gbColors[colorId] = color.rgb();
|
||||||
|
updateOverrides();
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void OverrideView::saveOverride() {
|
void OverrideView::saveOverride() {
|
||||||
if (!m_config) {
|
if (!m_config) {
|
||||||
return;
|
return;
|
||||||
|
@ -155,7 +207,13 @@ void OverrideView::updateOverrides() {
|
||||||
GBOverride* gb = new GBOverride;
|
GBOverride* gb = new GBOverride;
|
||||||
gb->override.mbc = s_mbcList[m_ui.mbc->currentIndex()];
|
gb->override.mbc = s_mbcList[m_ui.mbc->currentIndex()];
|
||||||
gb->override.model = s_gbModelList[m_ui.gbModel->currentIndex()];
|
gb->override.model = s_gbModelList[m_ui.gbModel->currentIndex()];
|
||||||
if (gb->override.mbc != GB_MBC_AUTODETECT || gb->override.model != GB_MODEL_AUTODETECT) {
|
gb->override.gbColors[0] = m_gbColors[0];
|
||||||
|
gb->override.gbColors[1] = m_gbColors[1];
|
||||||
|
gb->override.gbColors[2] = m_gbColors[2];
|
||||||
|
gb->override.gbColors[3] = m_gbColors[3];
|
||||||
|
bool hasOverride = gb->override.mbc != GB_MBC_AUTODETECT || gb->override.model != GB_MODEL_AUTODETECT;
|
||||||
|
hasOverride = hasOverride || (m_gbColors[0] | m_gbColors[1] | m_gbColors[2] | m_gbColors[3]);
|
||||||
|
if (hasOverride) {
|
||||||
m_controller->setOverride(gb);
|
m_controller->setOverride(gb);
|
||||||
} else {
|
} else {
|
||||||
m_controller->clearOverride();
|
m_controller->clearOverride();
|
||||||
|
|
|
@ -36,6 +36,9 @@ private slots:
|
||||||
void gameStarted(mCoreThread*);
|
void gameStarted(mCoreThread*);
|
||||||
void gameStopped();
|
void gameStopped();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject* obj, QEvent* event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::OverrideView m_ui;
|
Ui::OverrideView m_ui;
|
||||||
|
|
||||||
|
@ -43,6 +46,8 @@ private:
|
||||||
ConfigController* m_config;
|
ConfigController* m_config;
|
||||||
|
|
||||||
#ifdef M_CORE_GB
|
#ifdef M_CORE_GB
|
||||||
|
uint32_t m_gbColors[4]{};
|
||||||
|
|
||||||
static QList<enum GBModel> s_gbModelList;
|
static QList<enum GBModel> s_gbModelList;
|
||||||
static QList<enum GBMemoryBankControllerType> s_mbcList;
|
static QList<enum GBMemoryBankControllerType> s_mbcList;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>443</width>
|
<width>444</width>
|
||||||
<height>282</height>
|
<height>284</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
|
@ -326,6 +326,93 @@
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Colors</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="color0">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>30</width>
|
||||||
|
<height>30</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="color1">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>30</width>
|
||||||
|
<height>30</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="color2">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>30</width>
|
||||||
|
<height>30</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="color3">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>30</width>
|
||||||
|
<height>30</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoFillBackground">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
Loading…
Reference in New Issue