Library: store platform models in database, render GBC/SGB icons

This commit is contained in:
Adam Higerd 2022-07-02 14:10:48 -05:00
parent 65fbf52d0a
commit f5c90ee34b
8 changed files with 94 additions and 5 deletions

View File

@ -15,6 +15,8 @@ CXX_GUARD_START
#include <mgba/core/core.h>
#include <mgba-util/vector.h>
#define M_LIBRARY_MODEL_UNKNOWN -1
struct mLibraryEntry {
const char* base;
const char* filename;
@ -24,6 +26,7 @@ struct mLibraryEntry {
enum mPlatform platform;
size_t filesize;
uint32_t crc32;
int platformModels;
};
#ifdef USE_SQLITE3

View File

@ -9,6 +9,11 @@
#include <mgba-util/string.h>
#include <mgba-util/vfs.h>
#ifdef M_CORE_GB
#include <mgba/gb/interface.h>
#include <mgba/internal/gb/gb.h>
#endif
#ifdef USE_SQLITE3
#include <sqlite3.h>
@ -92,12 +97,38 @@ static void _bindConstraints(sqlite3_stmt* statement, const struct mLibraryEntry
sqlite3_bind_int(statement, useIndex, 1);
sqlite3_bind_int(statement, index, constraints->platform);
}
if (constraints->platformModels != M_LIBRARY_MODEL_UNKNOWN) {
index = sqlite3_bind_parameter_index(statement, ":models");
sqlite3_bind_int(statement, index, constraints->platformModels);
}
}
struct mLibrary* mLibraryCreateEmpty(void) {
return mLibraryLoad(":memory:");
}
static int _mLibraryTableVersion(struct mLibrary* library, const char* tableName) {
int version = -1;
static const char getVersion[] = "SELECT version FROM version WHERE tname=?";
sqlite3_stmt* getVersionStmt;
if (sqlite3_prepare_v2(library->db, getVersion, -1, &getVersionStmt, NULL)) {
goto error;
}
sqlite3_clear_bindings(getVersionStmt);
sqlite3_reset(getVersionStmt);
sqlite3_bind_text(getVersionStmt, 1, tableName, -1, SQLITE_TRANSIENT);
if (sqlite3_step(getVersionStmt) != SQLITE_DONE) {
version = sqlite3_column_int(getVersionStmt, 0);
}
error:
sqlite3_finalize(getVersionStmt);
return version;
}
struct mLibrary* mLibraryLoad(const char* path) {
struct mLibrary* library = malloc(sizeof(*library));
memset(library, 0, sizeof(*library));
@ -124,6 +155,7 @@ struct mLibrary* mLibraryLoad(const char* path) {
"\n internalTitle TEXT,"
"\n internalCode TEXT,"
"\n platform INTEGER NOT NULL DEFAULT -1,"
"\n models INTEGER NULL,"
"\n size INTEGER,"
"\n crc32 INTEGER,"
"\n md5 BLOB,"
@ -141,18 +173,35 @@ struct mLibrary* mLibraryLoad(const char* path) {
"\n CREATE INDEX IF NOT EXISTS crc32 ON roms (crc32);"
"\n INSERT OR IGNORE INTO version (tname, version) VALUES ('version', 1);"
"\n INSERT OR IGNORE INTO version (tname, version) VALUES ('roots', 1);"
"\n INSERT OR IGNORE INTO version (tname, version) VALUES ('roms', 1);"
"\n INSERT OR IGNORE INTO version (tname, version) VALUES ('roms', 2);"
"\n INSERT OR IGNORE INTO version (tname, version) VALUES ('paths', 1);";
if (sqlite3_exec(library->db, createTables, NULL, NULL, NULL)) {
goto error;
}
int romsTableVersion = _mLibraryTableVersion(library, "roms");
if (romsTableVersion < 0) {
goto error;
} else if (romsTableVersion < 2) {
static const char upgradeRomsTable[] =
" ALTER TABLE roms"
"\nADD COLUMN models INTEGER NULL";
if (sqlite3_exec(library->db, upgradeRomsTable, NULL, NULL, NULL)) {
goto error;
}
static const char updateRomsTableVersion[] = "UPDATE version SET version=2 WHERE tname='roms'";
if (sqlite3_exec(library->db, updateRomsTableVersion, NULL, NULL, NULL)) {
goto error;
}
}
static const char insertPath[] = "INSERT INTO paths (romid, path, customTitle, rootid) VALUES (?, ?, ?, ?);";
if (sqlite3_prepare_v2(library->db, insertPath, -1, &library->insertPath, NULL)) {
goto error;
}
static const char insertRom[] = "INSERT INTO roms (crc32, size, internalCode, platform) VALUES (:crc32, :size, :internalCode, :platform);";
static const char insertRom[] = "INSERT INTO roms (crc32, size, internalCode, platform, models) VALUES (:crc32, :size, :internalCode, :platform, :models);";
if (sqlite3_prepare_v2(library->db, insertRom, -1, &library->insertRom, NULL)) {
goto error;
}
@ -298,6 +347,15 @@ bool _mLibraryAddEntry(struct mLibrary* library, const char* filename, const cha
strlcpy(entry.internalTitle, info.title, sizeof(entry.internalTitle));
core->checksum(core, &entry.crc32, mCHECKSUM_CRC32);
entry.platform = core->platform(core);
entry.platformModels = M_LIBRARY_MODEL_UNKNOWN;
#ifdef M_CORE_GB
if (entry.platform == mPLATFORM_GB) {
struct GB* gb = (struct GB*) core->board;
if (gb->memory.rom) {
entry.platformModels = GBValidModels(gb->memory.rom);
}
}
#endif
entry.title = NULL;
entry.base = base;
entry.filename = filename;
@ -410,6 +468,8 @@ size_t mLibraryGetEntries(struct mLibrary* library, struct mLibraryListing* out,
}
} else if (strcmp(colName, "platform") == 0) {
entry->platform = sqlite3_column_int(library->select, i);
} else if (strcmp(colName, "models") == 0) {
entry->platformModels = sqlite3_column_int(library->select, i);
} else if (strcmp(colName, "size") == 0) {
entry->filesize = sqlite3_column_int64(library->select, i);
} else if (strcmp(colName, "internalCode") == 0 && sqlite3_column_type(library->select, i) == SQLITE_TEXT) {

View File

@ -6,6 +6,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "LibraryEntry.h"
#include "utils.h"
#include <mgba/core/library.h>
using namespace QGBA;
@ -22,6 +24,7 @@ LibraryEntry::LibraryEntry(const mLibraryEntry* entry)
, internalTitle(entry->internalTitle)
, internalCode(entry->internalCode)
, platform(entry->platform)
, platformModels(entry->platformModels)
, filesize(entry->filesize)
, crc32(entry->crc32)
{
@ -38,6 +41,10 @@ QString LibraryEntry::displayTitle(bool showFilename) const {
return title;
}
QString LibraryEntry::displayPlatform() const {
return nicePlatformFormat(platform, platformModels);
}
bool LibraryEntry::operator==(const LibraryEntry& other) const {
return other.fullpath == fullpath;
}

View File

@ -25,6 +25,7 @@ struct LibraryEntry {
bool isNull() const;
QString displayTitle(bool showFilename = false) const;
QString displayPlatform() const;
QString base;
QString filename;
@ -33,6 +34,7 @@ struct LibraryEntry {
QByteArray internalTitle;
QByteArray internalCode;
mPlatform platform;
int platformModels;
size_t filesize;
uint32_t crc32;

View File

@ -21,6 +21,7 @@ static const QStringList iconSets{
"GBA",
"GBC",
"GB",
"SGB",
// "DS",
};
@ -348,7 +349,7 @@ QVariant LibraryModel::data(const QModelIndex& index, int role) const {
switch (index.column()) {
case COL_NAME:
if (role == Qt::DecorationRole) {
return m_icons.value(nicePlatformFormat(entry->platform), qApp->style()->standardIcon(QStyle::SP_FileIcon));
return m_icons.value(entry->displayPlatform(), qApp->style()->standardIcon(QStyle::SP_FileIcon));
}
return entry->displayTitle(m_showFilename);
case COL_LOCATION:

View File

@ -19,6 +19,12 @@
<file>../../../res/gbc-icon-24.png</file>
<file>../../../res/gbc-icon-16.png</file>
<file>../../../res/gbc-icon.svg</file>
<file>../../../res/sgb-icon-256.png</file>
<file>../../../res/sgb-icon-128.png</file>
<file>../../../res/sgb-icon-32.png</file>
<file>../../../res/sgb-icon-24.png</file>
<file>../../../res/sgb-icon-16.png</file>
<file>../../../res/sgb-icon.svg</file>
<file>../../../res/gba-icon-256.png</file>
<file>../../../res/gba-icon-128.png</file>
<file>../../../res/gba-icon-32.png</file>

View File

@ -5,6 +5,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "utils.h"
#include <mgba/core/library.h>
#include <mgba/gb/interface.h>
#include <QCoreApplication>
#include <QHostAddress>
#include <QKeySequence>
@ -30,7 +33,7 @@ QString niceSizeFormat(size_t filesize) {
return unit.arg(size, 0, 'f', int(size * 10) % 10 ? 1 : 0);
}
QString nicePlatformFormat(mPlatform platform) {
QString nicePlatformFormat(mPlatform platform, int validModels) {
switch (platform) {
#ifdef M_CORE_GBA
case mPLATFORM_GBA:
@ -38,6 +41,13 @@ QString nicePlatformFormat(mPlatform platform) {
#endif
#ifdef M_CORE_GB
case mPLATFORM_GB:
if (validModels != M_LIBRARY_MODEL_UNKNOWN) {
if (validModels & GB_MODEL_CGB) {
return QObject::tr("GBC");
} else if (validModels & GB_MODEL_SGB) {
return QObject::tr("SGB");
}
}
return QObject::tr("GB");
#endif
default:

View File

@ -31,7 +31,7 @@ enum class Endian {
};
QString niceSizeFormat(size_t filesize);
QString nicePlatformFormat(mPlatform platform);
QString nicePlatformFormat(mPlatform platform, int validModels = 0);
bool convertAddress(const QHostAddress* input, Address* output);