Skip to content

Commit

Permalink
Library: store platform models in database, render GBC icons
Browse files Browse the repository at this point in the history
  • Loading branch information
ahigerd committed Feb 16, 2023
1 parent 8430779 commit 964b303
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 7 deletions.
3 changes: 3 additions & 0 deletions include/mgba/core/library.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,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;
Expand All @@ -22,6 +24,7 @@ struct mLibraryEntry {
enum mPlatform platform;
size_t filesize;
uint32_t crc32;
int platformModels;
};

#ifdef USE_SQLITE3
Expand Down
64 changes: 62 additions & 2 deletions src/core/library.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
#include <mgba/core/core.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>
Expand Down Expand Up @@ -91,12 +96,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));
Expand All @@ -123,6 +154,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,"
Expand All @@ -140,18 +172,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;
}
Expand Down Expand Up @@ -295,6 +344,15 @@ bool _mLibraryAddEntry(struct mLibrary* library, const char* filename, const cha
core->getGameCode(core, entry.internalCode);
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;
Expand Down Expand Up @@ -407,6 +465,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) {
Expand Down
4 changes: 2 additions & 2 deletions src/platform/qt/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi
if (value.toBool()) {
attachWidget(m_libraryView);
} else {
attachWidget(m_screenWidget);
attachWidget(m_screenWidget);
}
}
}, this);
Expand All @@ -131,7 +131,7 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi
ConfigOption* showFilenameInLibrary = m_config->addOption("showFilenameInLibrary");
showFilenameInLibrary->connect([this](const QVariant& value) {
m_libraryView->setShowFilename(value.toBool());
}, this);
}, this);
m_config->updateOption("showFilenameInLibrary");
ConfigOption* libraryStyle = m_config->addOption("libraryStyle");
libraryStyle->connect([this](const QVariant& value) {
Expand Down
7 changes: 7 additions & 0 deletions src/platform/qt/library/LibraryEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
{
Expand All @@ -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;
}
Expand Down
2 changes: 2 additions & 0 deletions src/platform/qt/library/LibraryEntry.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct LibraryEntry {
bool isNull() const;

QString displayTitle(bool showFilename = false) const;
QString displayPlatform() const;

QString base;
QString filename;
Expand All @@ -33,6 +34,7 @@ struct LibraryEntry {
QByteArray internalTitle;
QByteArray internalCode;
mPlatform platform;
int platformModels;
size_t filesize;
uint32_t crc32;

Expand Down
3 changes: 2 additions & 1 deletion src/platform/qt/library/LibraryModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ static const QStringList iconSets{
"GBA",
"GBC",
"GB",
"SGB",
// "DS",
};

Expand Down Expand Up @@ -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:
Expand Down
12 changes: 11 additions & 1 deletion src/platform/qt/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -30,14 +33,21 @@ 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:
return QObject::tr("GBA");
#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:
Expand Down
2 changes: 1 addition & 1 deletion src/platform/qt/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down

0 comments on commit 964b303

Please sign in to comment.