mirror of https://github.com/mgba-emu/mgba.git
Library: store platform models in database, render GBC/SGB icons
This commit is contained in:
parent
65fbf52d0a
commit
f5c90ee34b
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue