GBA Peripherals: Start implementing Progress Gate

This commit is contained in:
Vicki Pfau 2019-02-15 21:41:04 -08:00
parent c82f9f0efc
commit 85a85672e4
9 changed files with 501 additions and 18 deletions

View File

@ -60,12 +60,19 @@ struct GBASIODriver {
void GBASIOJOYCreate(struct GBASIODriver* sio); void GBASIOJOYCreate(struct GBASIODriver* sio);
int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data); int GBASIOJOYSendCommand(struct GBASIODriver* sio, enum GBASIOJOYCommand command, uint8_t* data);
enum GBASIOBattleChipGateFlavor {
GBA_FLAVOR_BATTLECHIP_GATE = 4,
GBA_FLAVOR_PROGRESS_GATE = 5,
GBA_FLAVOR_BEAST_LINK_GATE = 6,
};
struct GBASIOBattlechipGate { struct GBASIOBattlechipGate {
struct GBASIODriver d; struct GBASIODriver d;
struct mTimingEvent event; struct mTimingEvent event;
uint16_t chipId; uint16_t chipId;
uint16_t data[2]; uint16_t data[2];
int state; int state;
int flavor;
}; };
void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*); void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*);

379
res/chip-names-5.txt Normal file
View File

@ -0,0 +1,379 @@
Cannon
Hi Cannon
Mega Cannon
Air Shot
Air Hockey
Fanfare
ProtoMan Navi
NumberMan Navi

View File

@ -26,6 +26,8 @@ enum {
enum { enum {
BATTLECHIP_OK = 0xFFC6, BATTLECHIP_OK = 0xFFC6,
PROGRESS_GATE_OK = 0xFFC7,
BEAST_LINK_GATE_OK = 0xFFC8,
BATTLECHIP_CONTINUE = 0xFFFF, BATTLECHIP_CONTINUE = 0xFFFF,
}; };
@ -46,11 +48,13 @@ void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate* gate) {
gate->event.context = gate; gate->event.context = gate;
gate->event.callback = _battlechipTransferEvent; gate->event.callback = _battlechipTransferEvent;
gate->event.priority = 0x80; gate->event.priority = 0x80;
gate->chipId = 0;
gate->flavor = GBA_FLAVOR_BATTLECHIP_GATE;
} }
bool GBASIOBattlechipGateInit(struct GBASIODriver* driver) { bool GBASIOBattlechipGateInit(struct GBASIODriver* driver) {
struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver; struct GBASIOBattlechipGate* gate = (struct GBASIOBattlechipGate*) driver;
gate->chipId = 0;
return true; return true;
} }
@ -100,6 +104,20 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle
mLOG(GBA_BATTLECHIP, DEBUG, "> %04X", cmd); mLOG(GBA_BATTLECHIP, DEBUG, "> %04X", cmd);
uint16_t ok;
switch (gate->flavor) {
case GBA_FLAVOR_BATTLECHIP_GATE:
default:
ok = BATTLECHIP_OK;
break;
case GBA_FLAVOR_PROGRESS_GATE:
ok = PROGRESS_GATE_OK;
break;
case GBA_FLAVOR_BEAST_LINK_GATE:
ok = BEAST_LINK_GATE_OK;
break;
}
switch (gate->state) { switch (gate->state) {
case BATTLECHIP_STATE_COMMAND: case BATTLECHIP_STATE_COMMAND:
mLOG(GBA_BATTLECHIP, DEBUG, "C %04X", cmd); mLOG(GBA_BATTLECHIP, DEBUG, "C %04X", cmd);
@ -112,6 +130,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle
case 0xA3B0: case 0xA3B0:
case 0xA3C0: case 0xA3C0:
case 0xA3D0: case 0xA3D0:
case 0xA6C0:
gate->state = -1; gate->state = -1;
// Fall through // Fall through
case 0x5379: case 0x5379:
@ -120,14 +139,22 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle
case 0x537C: case 0x537C:
case 0x537D: case 0x537D:
case 0x537E: case 0x537E:
case 0xC4D8:
case 0xD979: case 0xD979:
case 0xD97A: case 0xD97A:
case 0xD97B: case 0xD97B:
case 0xD97C: case 0xD97C:
case 0xD97D: case 0xD97D:
case 0xD97E: case 0xD97E:
reply = BATTLECHIP_OK; reply = ok;
break; break;
case 0x424A:
case 0x424B:
case 0x424C:
case 0x424D:
case 0x424E:
case 0x424F:
case 0x4250:
case 0x5745: case 0x5745:
case 0x5746: case 0x5746:
case 0x5747: case 0x5747:
@ -150,12 +177,12 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle
case BATTLECHIP_STATE_DATA_0: case BATTLECHIP_STATE_DATA_0:
reply = gate->data[0]; reply = gate->data[0];
gate->data[0] += 3; gate->data[0] += 3;
gate->data[0] &= 0xF0FF; gate->data[0] &= 0x00FF;
break; break;
case BATTLECHIP_STATE_DATA_1: case BATTLECHIP_STATE_DATA_1:
reply = gate->data[1]; reply = gate->data[1];
gate->data[1] -= 3; gate->data[1] -= 3;
gate->data[1] |= 0xFE00; gate->data[1] |= 0xFC00;
break; break;
case BATTLECHIP_STATE_ID: case BATTLECHIP_STATE_ID:
reply = gate->chipId; reply = gate->chipId;
@ -165,7 +192,7 @@ void _battlechipTransferEvent(struct mTiming* timing, void* user, uint32_t cycle
reply = 0; reply = 0;
break; break;
case BATTLECHIP_STATE_END: case BATTLECHIP_STATE_END:
reply = BATTLECHIP_OK; reply = ok;
gate->state = -1; gate->state = -1;
break; break;
} }

View File

@ -27,6 +27,24 @@ BattleChipView::BattleChipView(std::shared_ptr<CoreController> controller, QWidg
connect(m_ui.inserted, &QAbstractButton::toggled, this, &BattleChipView::insertChip); connect(m_ui.inserted, &QAbstractButton::toggled, this, &BattleChipView::insertChip);
connect(controller.get(), &CoreController::stopping, this, &QWidget::close); connect(controller.get(), &CoreController::stopping, this, &QWidget::close);
connect(m_ui.gateBattleChip, &QAbstractButton::toggled, this, [this](bool on) {
if (on) {
setFlavor(4);
}
});
connect(m_ui.gateProgress, &QAbstractButton::toggled, this, [this](bool on) {
if (on) {
setFlavor(5);
}
});
connect(m_ui.gateBeastLink, &QAbstractButton::toggled, this, [this](bool on) {
if (on) {
setFlavor(6);
}
});
m_controller->attachBattleChipGate();
setFlavor(4); setFlavor(4);
} }
@ -35,6 +53,7 @@ BattleChipView::~BattleChipView() {
} }
void BattleChipView::setFlavor(int flavor) { void BattleChipView::setFlavor(int flavor) {
m_controller->setBattleChipFlavor(flavor);
loadChipNames(flavor); loadChipNames(flavor);
} }

View File

@ -7,46 +7,92 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>426</width> <width>426</width>
<height>152</height> <height>278</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
<string>BattleChip Gate</string> <string>BattleChip Gate</string>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
<item row="2" column="1"> <item row="5" column="1">
<widget class="QCheckBox" name="inserted"> <widget class="QCheckBox" name="inserted">
<property name="text"> <property name="text">
<string>Inserted</string> <string>Inserted</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Chip ID</string> <string>Chip ID</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>Chip Name</string> <string>Chip name</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1"> <item row="4" column="1">
<widget class="QSpinBox" name="chipId"> <widget class="QSpinBox" name="chipId">
<property name="maximum"> <property name="maximum">
<number>65535</number> <number>65535</number>
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="1"> <item row="3" column="1">
<widget class="QComboBox" name="chipName"/> <widget class="QComboBox" name="chipName"/>
</item> </item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Gate type</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QRadioButton" name="gateProgress">
<property name="text">
<string>Progress &amp;Gate</string>
</property>
<attribute name="buttonGroup">
<string notr="true">gate</string>
</attribute>
</widget>
</item>
<item row="0" column="1">
<widget class="QRadioButton" name="gateBattleChip">
<property name="text">
<string>Ba&amp;ttleChip Gate</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">gate</string>
</attribute>
</widget>
</item>
<item row="2" column="1">
<widget class="QRadioButton" name="gateBeastLink">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Beast &amp;Link Gate</string>
</property>
<attribute name="buttonGroup">
<string notr="true">gate</string>
</attribute>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<resources/> <resources/>
<connections/> <connections/>
<buttongroups>
<buttongroup name="gate"/>
</buttongroups>
</ui> </ui>

View File

@ -750,6 +750,14 @@ void CoreController::setBattleChipId(uint16_t id) {
Interrupter interrupter(this); Interrupter interrupter(this);
m_battlechip.chipId = id; m_battlechip.chipId = id;
} }
void CoreController::setBattleChipFlavor(int flavor) {
if (platform() != PLATFORM_GBA) {
return;
}
Interrupter interrupter(this);
m_battlechip.flavor = flavor;
}
#endif #endif
void CoreController::setAVStream(mAVStream* stream) { void CoreController::setAVStream(mAVStream* stream) {

View File

@ -143,6 +143,7 @@ public slots:
void attachBattleChipGate(); void attachBattleChipGate();
void detachBattleChipGate(); void detachBattleChipGate();
void setBattleChipId(uint16_t id); void setBattleChipId(uint16_t id);
void setBattleChipFlavor(int flavor);
#endif #endif
void setAVStream(mAVStream*); void setAVStream(mAVStream*);

View File

@ -1365,12 +1365,7 @@ void Window::setupMenu(QMenuBar* menubar) {
#ifdef M_CORE_GBA #ifdef M_CORE_GBA
QAction* bcGate = new QAction(tr("BattleChip Gate..."), emulationMenu); QAction* bcGate = new QAction(tr("BattleChip Gate..."), emulationMenu);
connect(bcGate, &QAction::triggered, [this]() { connect(bcGate, &QAction::triggered, openControllerTView<BattleChipView>());
BattleChipView* view = new BattleChipView(m_controller);
openView(view);
m_controller->attachBattleChipGate();
});
addControlledAction(emulationMenu, bcGate, "bcGate"); addControlledAction(emulationMenu, bcGate, "bcGate");
m_gbaActions.append(bcGate); m_gbaActions.append(bcGate);
m_gameActions.append(bcGate); m_gameActions.append(bcGate);

View File

@ -5,5 +5,6 @@
<file>../../../res/patrons.txt</file> <file>../../../res/patrons.txt</file>
<file>../../../res/no-cam.png</file> <file>../../../res/no-cam.png</file>
<file>../../../res/chip-names-4.txt</file> <file>../../../res/chip-names-4.txt</file>
<file>../../../res/chip-names-5.txt</file>
</qresource> </qresource>
</RCC> </RCC>