GBA e-Reader: Batch scanning
Vicki Pfau vi@endrift.com
Sun, 23 Feb 2020 16:52:18 -0800
8 files changed,
74 insertions(+),
4 deletions(-)
M
include/mgba/gba/interface.h
→
include/mgba/gba/interface.h
@@ -88,6 +88,8 @@ };
void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*); +void GBAEReaderQueueCard(struct GBA* gba, const void* data, size_t size); + CXX_GUARD_END #endif
M
include/mgba/internal/gba/hardware.h
→
include/mgba/internal/gba/hardware.h
@@ -18,6 +18,7 @@ mLOG_DECLARE_CATEGORY(GBA_HW);
#define EREADER_DOTCODE_STRIDE 1200 #define EREADER_DOTCODE_SIZE (EREADER_DOTCODE_STRIDE * 40 + 200) +#define EREADER_CARDS_MAX 16 #define IS_GPIO_REGISTER(reg) ((reg) == GPIO_REG_DATA || (reg) == GPIO_REG_DIRECTION || (reg) == GPIO_REG_CONTROL)@@ -133,6 +134,11 @@ EREADER_COMMAND_SET_INDEX = 0x22,
EREADER_COMMAND_READ_DATA = 0x23, }; +struct EReaderCard { + void* data; + size_t size; +}; + struct GBACartridgeHardware { struct GBA* p; uint32_t devices;@@ -177,6 +183,7 @@ uint8_t eReaderByte;
int eReaderX; int eReaderY; uint8_t* eReaderDots; + struct EReaderCard eReaderCards[EREADER_CARDS_MAX]; }; void GBAHardwareInit(struct GBACartridgeHardware* gpio, uint16_t* gpioBase);
M
src/gba/ereader.c
→
src/gba/ereader.c
@@ -514,6 +514,19 @@ control = EReaderControl0ClearData(control);
} hw->eReaderRegisterControl0 = control; if (!EReaderControl0IsScan(oldControl) && EReaderControl0IsScan(control)) { + if (hw->eReaderX > 1000) { + int i; + for (i = 0; i < EREADER_CARDS_MAX; ++i) { + if (!hw->eReaderCards[i].data) { + continue; + } + GBAHardwareEReaderScan(hw, hw->eReaderCards[i].data, hw->eReaderCards[i].size); + free(hw->eReaderCards[i].data); + hw->eReaderCards[i].data = NULL; + hw->eReaderCards[i].size = 0; + break; + } + } hw->eReaderX = 0; hw->eReaderY = 0; } else if (EReaderControl0IsLedEnable(control) && EReaderControl0IsScan(control) && !EReaderControl1IsScanline(hw->eReaderRegisterControl1)) {@@ -540,6 +553,19 @@ }
void _eReaderReadData(struct GBACartridgeHardware* hw) { memset(hw->eReaderData, 0, EREADER_BLOCK_SIZE); + if (!hw->eReaderDots) { + int i; + for (i = 0; i < EREADER_CARDS_MAX; ++i) { + if (!hw->eReaderCards[i].data) { + continue; + } + GBAHardwareEReaderScan(hw, hw->eReaderCards[i].data, hw->eReaderCards[i].size); + free(hw->eReaderCards[i].data); + hw->eReaderCards[i].data = NULL; + hw->eReaderCards[i].size = 0; + break; + } + } if (hw->eReaderDots) { int y = hw->eReaderY - 10; if (y < 0 || y >= 120) {@@ -579,3 +605,16 @@ }
GBARaiseIRQ(hw->p, IRQ_GAMEPAK, -led); } } + +void GBAEReaderQueueCard(struct GBA* gba, const void* data, size_t size) { + int i; + for (i = 0; i < EREADER_CARDS_MAX; ++i) { + if (gba->memory.hw.eReaderCards[i].data) { + continue; + } + gba->memory.hw.eReaderCards[i].data = malloc(size); + memcpy(gba->memory.hw.eReaderCards[i].data, data, size); + gba->memory.hw.eReaderCards[i].size = size; + return; + } +}
M
src/gba/hardware.c
→
src/gba/hardware.c
@@ -51,6 +51,7 @@
void GBAHardwareInit(struct GBACartridgeHardware* hw, uint16_t* base) { hw->gpioBase = base; hw->eReaderDots = NULL; + memset(hw->eReaderCards, 0, sizeof(hw->eReaderCards)); GBAHardwareClear(hw); hw->gbpCallback.d.readKeys = _gbpRead;@@ -76,6 +77,15 @@
if (hw->eReaderDots) { mappedMemoryFree(hw->eReaderDots, EREADER_DOTCODE_SIZE); hw->eReaderDots = NULL; + } + int i; + for (i = 0; i < EREADER_CARDS_MAX; ++i) { + if (!hw->eReaderCards[i].data) { + continue; + } + free(hw->eReaderCards[i].data); + hw->eReaderCards[i].data = NULL; + hw->eReaderCards[i].size = 0; } if (hw->p->sio.drivers.normal == &hw->gbpDriver.d) {
M
src/platform/qt/CoreController.cpp
→
src/platform/qt/CoreController.cpp
@@ -688,7 +688,7 @@ m_eReaderData = file.read(2912);
mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* thread) { CoreController* controller = static_cast<CoreController*>(thread->userData); - GBAHardwareEReaderScan(&static_cast<GBA*>(thread->core->board)->memory.hw, controller->m_eReaderData.constData(), controller->m_eReaderData.size()); + GBAEReaderQueueCard(static_cast<GBA*>(thread->core->board), controller->m_eReaderData.constData(), controller->m_eReaderData.size()); }); #endif }
M
src/platform/qt/GBAApp.cpp
→
src/platform/qt/GBAApp.cpp
@@ -163,6 +163,17 @@ }
return filename; } +QStringList GBAApp::getOpenFileNames(QWidget* owner, const QString& title, const QString& filter) { + QList<Window*> paused; + pauseAll(&paused); + QStringList filenames = QFileDialog::getOpenFileNames(owner, title, m_configController->getOption("lastDirectory"), filter); + continueAll(paused); + if (!filenames.isEmpty()) { + m_configController->setOption("lastDirectory", QFileInfo(filenames.at(0)).dir().canonicalPath()); + } + return filenames; +} + QString GBAApp::getSaveFileName(QWidget* owner, const QString& title, const QString& filter) { QList<Window*> paused; pauseAll(&paused);
M
src/platform/qt/GBAApp.h
→
src/platform/qt/GBAApp.h
@@ -59,6 +59,7 @@
Window* newWindow(); QString getOpenFileName(QWidget* owner, const QString& title, const QString& filter = QString()); + QStringList getOpenFileNames(QWidget* owner, const QString& title, const QString& filter = QString()); QString getSaveFileName(QWidget* owner, const QString& title, const QString& filter = QString()); QString getOpenDirectoryName(QWidget* owner, const QString& title);
M
src/platform/qt/Window.cpp
→
src/platform/qt/Window.cpp
@@ -424,8 +424,8 @@ }
} void Window::scanCard() { - QString filename = GBAApp::app()->getOpenFileName(this, tr("Select e-Reader dotcode"), tr("e-Reader card (*.raw *.bin)")); - if (!filename.isEmpty()) { + QStringList filenames = GBAApp::app()->getOpenFileNames(this, tr("Select e-Reader dotcode"), tr("e-Reader card (*.raw *.bin)")); + for (QString& filename : filenames) { m_controller->scanCard(filename); } }@@ -1126,7 +1126,7 @@ #endif
addGameAction(tr("Replace ROM..."), "replaceROM", this, &Window::replaceROM, "file"); #ifdef M_CORE_GBA - Action* scanCard = addGameAction(tr("Scan e-Reader dotcode..."), "scanCard", this, &Window::scanCard, "file"); + Action* scanCard = addGameAction(tr("Scan e-Reader dotcodes..."), "scanCard", this, &Window::scanCard, "file"); m_platformActions.insert(PLATFORM_GBA, scanCard); #endif