GBA e-Reader: Batch scanning

This commit is contained in:
Vicki Pfau 2020-02-23 16:52:18 -08:00
parent 44175d9381
commit 7091494583
8 changed files with 74 additions and 4 deletions

View File

@ -88,6 +88,8 @@ struct GBASIOBattlechipGate {
void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*);
void GBAEReaderQueueCard(struct GBA* gba, const void* data, size_t size);
CXX_GUARD_END
#endif

View File

@ -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 @@ enum EReaderCommand {
EREADER_COMMAND_READ_DATA = 0x23,
};
struct EReaderCard {
void* data;
size_t size;
};
struct GBACartridgeHardware {
struct GBA* p;
uint32_t devices;
@ -177,6 +183,7 @@ struct GBACartridgeHardware {
int eReaderX;
int eReaderY;
uint8_t* eReaderDots;
struct EReaderCard eReaderCards[EREADER_CARDS_MAX];
};
void GBAHardwareInit(struct GBACartridgeHardware* gpio, uint16_t* gpioBase);

View File

@ -514,6 +514,19 @@ void _eReaderWriteControl0(struct GBACartridgeHardware* hw, uint8_t value) {
}
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 _eReaderWriteControl1(struct GBACartridgeHardware* hw, uint8_t value) {
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 @@ void _eReaderReadData(struct GBACartridgeHardware* hw) {
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;
}
}

View File

@ -51,6 +51,7 @@ static const int RTC_BYTES[8] = {
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;
@ -77,6 +78,15 @@ void GBAHardwareClear(struct GBACartridgeHardware* hw) {
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) {
GBASIOSetDriver(&hw->p->sio, 0, SIO_NORMAL_32);

View File

@ -688,7 +688,7 @@ void CoreController::scanCard(const QString& path) {
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
}

View File

@ -163,6 +163,17 @@ QString GBAApp::getOpenFileName(QWidget* owner, const QString& title, const QStr
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);

View File

@ -59,6 +59,7 @@ public:
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);

View File

@ -424,8 +424,8 @@ void Window::selectPatch() {
}
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 @@ void Window::setupMenu(QMenuBar* menubar) {
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