mirror of https://github.com/mgba-emu/mgba.git
GBA e-Reader: Batch scanning
This commit is contained in:
parent
44175d9381
commit
7091494583
|
@ -88,6 +88,8 @@ struct GBASIOBattlechipGate {
|
||||||
|
|
||||||
void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*);
|
void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*);
|
||||||
|
|
||||||
|
void GBAEReaderQueueCard(struct GBA* gba, const void* data, size_t size);
|
||||||
|
|
||||||
CXX_GUARD_END
|
CXX_GUARD_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,6 +18,7 @@ mLOG_DECLARE_CATEGORY(GBA_HW);
|
||||||
|
|
||||||
#define EREADER_DOTCODE_STRIDE 1200
|
#define EREADER_DOTCODE_STRIDE 1200
|
||||||
#define EREADER_DOTCODE_SIZE (EREADER_DOTCODE_STRIDE * 40 + 200)
|
#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)
|
#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,
|
EREADER_COMMAND_READ_DATA = 0x23,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EReaderCard {
|
||||||
|
void* data;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
struct GBACartridgeHardware {
|
struct GBACartridgeHardware {
|
||||||
struct GBA* p;
|
struct GBA* p;
|
||||||
uint32_t devices;
|
uint32_t devices;
|
||||||
|
@ -177,6 +183,7 @@ struct GBACartridgeHardware {
|
||||||
int eReaderX;
|
int eReaderX;
|
||||||
int eReaderY;
|
int eReaderY;
|
||||||
uint8_t* eReaderDots;
|
uint8_t* eReaderDots;
|
||||||
|
struct EReaderCard eReaderCards[EREADER_CARDS_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
void GBAHardwareInit(struct GBACartridgeHardware* gpio, uint16_t* gpioBase);
|
void GBAHardwareInit(struct GBACartridgeHardware* gpio, uint16_t* gpioBase);
|
||||||
|
|
|
@ -514,6 +514,19 @@ void _eReaderWriteControl0(struct GBACartridgeHardware* hw, uint8_t value) {
|
||||||
}
|
}
|
||||||
hw->eReaderRegisterControl0 = control;
|
hw->eReaderRegisterControl0 = control;
|
||||||
if (!EReaderControl0IsScan(oldControl) && EReaderControl0IsScan(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->eReaderX = 0;
|
||||||
hw->eReaderY = 0;
|
hw->eReaderY = 0;
|
||||||
} else if (EReaderControl0IsLedEnable(control) && EReaderControl0IsScan(control) && !EReaderControl1IsScanline(hw->eReaderRegisterControl1)) {
|
} 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) {
|
void _eReaderReadData(struct GBACartridgeHardware* hw) {
|
||||||
memset(hw->eReaderData, 0, EREADER_BLOCK_SIZE);
|
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) {
|
if (hw->eReaderDots) {
|
||||||
int y = hw->eReaderY - 10;
|
int y = hw->eReaderY - 10;
|
||||||
if (y < 0 || y >= 120) {
|
if (y < 0 || y >= 120) {
|
||||||
|
@ -579,3 +605,16 @@ void _eReaderReadData(struct GBACartridgeHardware* hw) {
|
||||||
GBARaiseIRQ(hw->p, IRQ_GAMEPAK, -led);
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,6 +51,7 @@ static const int RTC_BYTES[8] = {
|
||||||
void GBAHardwareInit(struct GBACartridgeHardware* hw, uint16_t* base) {
|
void GBAHardwareInit(struct GBACartridgeHardware* hw, uint16_t* base) {
|
||||||
hw->gpioBase = base;
|
hw->gpioBase = base;
|
||||||
hw->eReaderDots = NULL;
|
hw->eReaderDots = NULL;
|
||||||
|
memset(hw->eReaderCards, 0, sizeof(hw->eReaderCards));
|
||||||
GBAHardwareClear(hw);
|
GBAHardwareClear(hw);
|
||||||
|
|
||||||
hw->gbpCallback.d.readKeys = _gbpRead;
|
hw->gbpCallback.d.readKeys = _gbpRead;
|
||||||
|
@ -77,6 +78,15 @@ void GBAHardwareClear(struct GBACartridgeHardware* hw) {
|
||||||
mappedMemoryFree(hw->eReaderDots, EREADER_DOTCODE_SIZE);
|
mappedMemoryFree(hw->eReaderDots, EREADER_DOTCODE_SIZE);
|
||||||
hw->eReaderDots = NULL;
|
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) {
|
if (hw->p->sio.drivers.normal == &hw->gbpDriver.d) {
|
||||||
GBASIOSetDriver(&hw->p->sio, 0, SIO_NORMAL_32);
|
GBASIOSetDriver(&hw->p->sio, 0, SIO_NORMAL_32);
|
||||||
|
|
|
@ -688,7 +688,7 @@ void CoreController::scanCard(const QString& path) {
|
||||||
|
|
||||||
mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* thread) {
|
mCoreThreadRunFunction(&m_threadContext, [](mCoreThread* thread) {
|
||||||
CoreController* controller = static_cast<CoreController*>(thread->userData);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,17 @@ QString GBAApp::getOpenFileName(QWidget* owner, const QString& title, const QStr
|
||||||
return filename;
|
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) {
|
QString GBAApp::getSaveFileName(QWidget* owner, const QString& title, const QString& filter) {
|
||||||
QList<Window*> paused;
|
QList<Window*> paused;
|
||||||
pauseAll(&paused);
|
pauseAll(&paused);
|
||||||
|
|
|
@ -59,6 +59,7 @@ public:
|
||||||
Window* newWindow();
|
Window* newWindow();
|
||||||
|
|
||||||
QString getOpenFileName(QWidget* owner, const QString& title, const QString& filter = QString());
|
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 getSaveFileName(QWidget* owner, const QString& title, const QString& filter = QString());
|
||||||
QString getOpenDirectoryName(QWidget* owner, const QString& title);
|
QString getOpenDirectoryName(QWidget* owner, const QString& title);
|
||||||
|
|
||||||
|
|
|
@ -424,8 +424,8 @@ void Window::selectPatch() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::scanCard() {
|
void Window::scanCard() {
|
||||||
QString filename = GBAApp::app()->getOpenFileName(this, tr("Select e-Reader dotcode"), tr("e-Reader card (*.raw *.bin)"));
|
QStringList filenames = GBAApp::app()->getOpenFileNames(this, tr("Select e-Reader dotcode"), tr("e-Reader card (*.raw *.bin)"));
|
||||||
if (!filename.isEmpty()) {
|
for (QString& filename : filenames) {
|
||||||
m_controller->scanCard(filename);
|
m_controller->scanCard(filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1126,7 +1126,7 @@ void Window::setupMenu(QMenuBar* menubar) {
|
||||||
|
|
||||||
addGameAction(tr("Replace ROM..."), "replaceROM", this, &Window::replaceROM, "file");
|
addGameAction(tr("Replace ROM..."), "replaceROM", this, &Window::replaceROM, "file");
|
||||||
#ifdef M_CORE_GBA
|
#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);
|
m_platformActions.insert(PLATFORM_GBA, scanCard);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue