all repos — mgba @ ca6b2e7b09c66ad14db5977a68c428f7ee4e7f7d

mGBA Game Boy Advance Emulator

Qt: Display hex values within cheats
Jeffrey Pfau jeffrey@endrift.com
Sat, 14 Feb 2015 22:45:40 -0800
commit

ca6b2e7b09c66ad14db5977a68c428f7ee4e7f7d

parent

8741a374a54185418a47500122440c357a13f9e4

M src/gba/cheats.csrc/gba/cheats.c

@@ -15,6 +15,7 @@ const uint32_t GBA_CHEAT_DEVICE_ID = 0xABADC0DE;

DEFINE_VECTOR(GBACheatList, struct GBACheat); DEFINE_VECTOR(GBACheatSets, struct GBACheatSet*); +DEFINE_VECTOR(StringList, char*); static const uint32_t _gsa1S[4] = { 0x09F4FBBD, 0x9681884A, 0x352027E9, 0xF3DEE5A7 }; static const uint32_t _par3S[4] = { 0x7AA9648F, 0x7FAE6994, 0xC0EFAAD5, 0x42712C57 };

@@ -186,6 +187,10 @@ value |= nybble;

} *out = value; return line; +} + +static void _registerLine(struct GBACheatSet* cheats, const char* line) { + *StringListAppend(&cheats->lines) = strdup(line); } // http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm

@@ -405,6 +410,7 @@ }

void GBACheatSetInit(struct GBACheatSet* set, const char* name) { GBACheatListInit(&set->list, 4); + StringListInit(&set->lines, 4); set->incompleteCheat = 0; set->gsaVersion = 0; set->remainingAddresses = 0;

@@ -422,6 +428,10 @@ }

void GBACheatSetDeinit(struct GBACheatSet* set) { GBACheatListDeinit(&set->list); + size_t i; + for (i = 0; i < StringListSize(&set->lines); ++i) { + free(*StringListGetPointer(&set->lines, i)); + } if (set->name) { free(set->name); }

@@ -463,6 +473,10 @@ _removeBreakpoint(device, cheats);

} bool GBACheatAddCodeBreaker(struct GBACheatSet* cheats, uint32_t op1, uint16_t op2) { + char line[14] = "XXXXXXXX XXXX"; + snprintf(line, sizeof(line), "%08X %04X", op1, op2); + _registerLine(cheats, line); + enum GBACodeBreakerType type = op1 >> 28; struct GBACheat* cheat = 0;

@@ -592,6 +606,10 @@

bool GBACheatAddGameShark(struct GBACheatSet* set, uint32_t op1, uint32_t op2) { uint32_t o1 = op1; uint32_t o2 = op2; + char line[18] = "XXXXXXXX XXXXXXXX"; + snprintf(line, sizeof(line), "%08X %08X", op1, op2); + _registerLine(set, line); + switch (set->gsaVersion) { case 0: _setGameSharkVersion(set, 1);

@@ -623,6 +641,10 @@

bool GBACheatAddAutodetect(struct GBACheatSet* set, uint32_t op1, uint32_t op2) { uint32_t o1 = op1; uint32_t o2 = op2; + char line[18] = "XXXXXXXX XXXXXXXX"; + snprintf(line, sizeof(line), "%08X %08X", op1, op2); + _registerLine(set, line); + switch (set->gsaVersion) { case 0: // Try to detect GameShark version
M src/gba/cheats.hsrc/gba/cheats.h

@@ -142,6 +142,7 @@ size_t reentries;

}; DECLARE_VECTOR(GBACheatList, struct GBACheat); +DECLARE_VECTOR(StringList, char*); struct GBACheatSet { struct GBACheatHook* hook;

@@ -162,6 +163,7 @@ uint32_t gsaSeeds[4];

int remainingAddresses; char* name; + struct StringList lines; }; DECLARE_VECTOR(GBACheatSets, struct GBACheatSet*);
M src/platform/qt/CheatsModel.cppsrc/platform/qt/CheatsModel.cpp

@@ -5,6 +5,8 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this

* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "CheatsModel.h" +#include <QFont> + extern "C" { #include "gba/cheats.h" #include "util/vfs.h"

@@ -23,8 +25,22 @@ if (!index.isValid()) {

return QVariant(); } + if (index.parent().isValid()) { + int row = index.row(); + GBACheatSet* cheats = static_cast<GBACheatSet*>(index.internalPointer()); + const char* line = *StringListGetPointer(&cheats->lines, row); + switch (role) { + case Qt::DisplayRole: + return line; + case Qt::FontRole: + return QFont("Courier New", 13); + default: + return QVariant(); + } + } + int row = index.row(); - const GBACheatSet* cheats = static_cast<const GBACheatSet*>(index.internalPointer()); + const GBACheatSet* cheats = *GBACheatSetsGetPointer(&m_device->cheats, index.row()); switch (role) { case Qt::DisplayRole: case Qt::EditRole:

@@ -37,12 +53,12 @@ }

} bool CheatsModel::setData(const QModelIndex& index, const QVariant& value, int role) { - if (!index.isValid()) { + if (!index.isValid() || index.parent().isValid()) { return false; } int row = index.row(); - GBACheatSet* cheats = static_cast<GBACheatSet*>(index.internalPointer()); + GBACheatSet* cheats = *GBACheatSetsGetPointer(&m_device->cheats, index.row()); switch (role) { case Qt::DisplayRole: case Qt::EditRole:

@@ -60,10 +76,26 @@ }

} QModelIndex CheatsModel::index(int row, int column, const QModelIndex& parent) const { - return createIndex(row, column, *GBACheatSetsGetPointer(&m_device->cheats, row)); + if (parent.isValid()) { + return createIndex(row, column, *GBACheatSetsGetPointer(&m_device->cheats, parent.row())); + } else { + return createIndex(row, column, nullptr); + } } QModelIndex CheatsModel::parent(const QModelIndex& index) const { + if (!index.isValid()) { + return QModelIndex(); + } + const GBACheatSet* cheats = static_cast<const GBACheatSet*>(index.internalPointer()); + if (!cheats) { + return QModelIndex(); + } + for (size_t i = 0; i < GBACheatSetsSize(&m_device->cheats); ++i) { + if (cheats == *GBACheatSetsGetPointer(&m_device->cheats, i)) { + return createIndex(i, 0, nullptr); + } + } return QModelIndex(); }

@@ -72,6 +104,10 @@ if (!index.isValid()) {

return 0; } + if (index.parent().isValid()) { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } + return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; }

@@ -81,7 +117,11 @@ }

int CheatsModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { - return 0; + if (parent.internalPointer()) { + return 0; + } + const GBACheatSet* set = *GBACheatSetsGetPointer(&m_device->cheats, parent.row()); + return StringListSize(&set->lines); } return GBACheatSetsSize(&m_device->cheats); }

@@ -90,15 +130,18 @@ GBACheatSet* CheatsModel::itemAt(const QModelIndex& index) {

if (!index.isValid()) { return nullptr; } - return static_cast<GBACheatSet*>(index.internalPointer()); + if (index.parent().isValid()) { + return static_cast<GBACheatSet*>(index.internalPointer()); + } + return *GBACheatSetsGetPointer(&m_device->cheats, index.row()); } void CheatsModel::removeAt(const QModelIndex& index) { - if (!index.isValid()) { + if (!index.isValid() || index.parent().isValid()) { return; } int row = index.row(); - GBACheatSet* set = static_cast<GBACheatSet*>(index.internalPointer()); + GBACheatSet* set = *GBACheatSetsGetPointer(&m_device->cheats, index.row()); beginRemoveRows(QModelIndex(), row, row); GBACheatRemoveSet(m_device, set); GBACheatSetDeinit(set);

@@ -107,6 +150,18 @@ endInsertRows();

} +void CheatsModel::beginAppendRow(const QModelIndex& index) { + if (index.parent().isValid()) { + beginInsertRows(index.parent(), rowCount(index.parent()), rowCount(index.parent())); + return; + } + beginInsertRows(index, rowCount(index), rowCount(index)); +} + +void CheatsModel::endAppendRow() { + endInsertRows(); +} + void CheatsModel::loadFile(const QString& path) { VFile* vf = VFileOpen(path.toLocal8Bit().constData(), O_RDONLY); if (!vf) {

@@ -119,7 +174,7 @@ vf->close(vf);

} void CheatsModel::addSet(GBACheatSet* set) { - beginInsertRows(QModelIndex(), GBACheatSetsSize(&m_device->cheats), GBACheatSetsSize(&m_device->cheats) + 1); + beginInsertRows(QModelIndex(), GBACheatSetsSize(&m_device->cheats), GBACheatSetsSize(&m_device->cheats)); GBACheatAddSet(m_device, set); endInsertRows(); }
M src/platform/qt/CheatsModel.hsrc/platform/qt/CheatsModel.h

@@ -32,6 +32,9 @@

GBACheatSet* itemAt(const QModelIndex& index); void removeAt(const QModelIndex& index); + void beginAppendRow(const QModelIndex& index); + void endAppendRow(); + void loadFile(const QString& path); void addSet(GBACheatSet* set);
M src/platform/qt/CheatsView.cppsrc/platform/qt/CheatsView.cpp

@@ -60,11 +60,13 @@

void CheatsView::removeSet() { GBACheatSet* set; QModelIndexList selection = m_ui.cheatList->selectionModel()->selectedIndexes(); - if (selection.count() != 1) { + if (selection.count() < 1) { return; } m_controller->threadInterrupt(); - m_model.removeAt(selection[0]); + for (const QModelIndex& index : selection) { + m_model.removeAt(selection[0]); + } m_controller->threadContinue(); }

@@ -81,7 +83,9 @@ }

m_controller->threadInterrupt(); QStringList cheats = m_ui.codeEntry->toPlainText().split('\n', QString::SkipEmptyParts); for (const QString& string : cheats) { + m_model.beginAppendRow(selection[0]); callback(set, string.toLocal8Bit().constData()); + m_model.endAppendRow(); } m_controller->threadContinue(); m_ui.codeEntry->clear();
M src/platform/qt/CheatsView.uisrc/platform/qt/CheatsView.ui

@@ -94,6 +94,9 @@ </property>

<property name="defaultDropAction"> <enum>Qt::MoveAction</enum> </property> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> <property name="headerHidden"> <bool>true</bool> </property>
M src/util/vector.hsrc/util/vector.h

@@ -23,7 +23,7 @@ void NAME ## Resize(struct NAME* vector, ssize_t change); \

void NAME ## Shift(struct NAME* vector, size_t location, size_t difference); \ void NAME ## Unshift(struct NAME* vector, size_t location, size_t difference); \ void NAME ## EnsureCapacity(struct NAME* vector, size_t capacity); \ - size_t NAME ## Size(struct NAME* vector); \ + size_t NAME ## Size(const struct NAME* vector); \ #define DEFINE_VECTOR(NAME, TYPE) \ void NAME ## Init(struct NAME* vector, size_t capacity) { \

@@ -72,7 +72,7 @@ void NAME ## Unshift(struct NAME* vector, size_t location, size_t difference) { \

NAME ## Resize(vector, difference); \ memmove(&vector->vector[location + difference], &vector->vector[location], (vector->size - location - difference) * sizeof(TYPE)); \ } \ - size_t NAME ## Size(struct NAME* vector) { \ + size_t NAME ## Size(const struct NAME* vector) { \ return vector->size; \ } \