mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 06:40:42 -07:00
bt5api fix (#552)
## Description of change use case: user with two ICCA readers in a daisy chain configuration (as is wired in og IIDX/DDR) wanted to play DDR using their existing equipment. Existing `reader/` implementation is only designed for a single reader per com port vs two readers on one daisy chained com port. This can be implemented and improved at a future date. Due to time constraints `eamio-icca.dll` from btools did support both wavepass and slotted in a daisy chain configuration, and spice does support bt5api calls. However, the implementation was not sufficient to allow use of both modules correctly, often stalling, not did it allow the ability to eject the card. I have cleaned up the implementation such that it matches the btools `eamiotest` implementation and allows the user to use decimal to eject the card as desired. As well as properly staging the requests for state of the two individual readers, like `eamio-icca` expects. ## Testing Tested with both wavepass and slotted (ICCA and ICCB) modules and in combination with released `eamio-icca.dll` binaries from btools 5.49 as released by their github using `MDX` as a test subject. Works as expected and allows end users to use real readers (if they have them) as virtual readers in spice's emulation layer.
This commit is contained in:
+52
-20
@@ -119,6 +119,7 @@ static std::string EAMIO_DLL_NAME = "eamio.dll";
|
||||
static robin_hood::unordered_map<int, std::thread *> BT5API_THREADS;
|
||||
static robin_hood::unordered_map<int, int> BT5API_THREAD_RESULTS;
|
||||
static uint8_t BT5API_CARD_STATES[] = {0, 0};
|
||||
static uint16_t BT5API_KEYPAD_STATES[] = {0, 0};
|
||||
|
||||
static void bt5api_log(const char *bt5_module, const char *fmt, ...) {
|
||||
|
||||
@@ -240,46 +241,77 @@ void bt5api_hook(HINSTANCE module) {
|
||||
|
||||
void bt5api_poll_reader_card(uint8_t unit_no) {
|
||||
|
||||
// check if initialized
|
||||
if (!EAMIO_DLL) {
|
||||
// check if initialized or out of bounds
|
||||
if (!EAMIO_DLL || unit_no >= eamuse_get_game_keypads()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// poll
|
||||
if (!eam_io_poll(unit_no)) {
|
||||
log_warning("bt5api", "polling bt5api reader {} returned failure",
|
||||
log_warning("bt5api", "polling bt5api reader card {} returned failure",
|
||||
static_cast<int>(unit_no));
|
||||
return;
|
||||
}
|
||||
|
||||
// get sensor state
|
||||
uint8_t sensor_state = eam_io_get_sensor_state(unit_no);
|
||||
|
||||
// if we have a change in state.
|
||||
if(sensor_state != BT5API_CARD_STATES[unit_no]) {
|
||||
|
||||
// check for card in
|
||||
if (sensor_state > BT5API_CARD_STATES[unit_no]) {
|
||||
uint8_t card_id[8];
|
||||
eam_io_read_card(unit_no, card_id, 8);
|
||||
eamuse_card_insert(unit_no, card_id);
|
||||
// card inserted into the back.
|
||||
if(sensor_state & (1 << EAM_IO_SENSOR_BACK)) {
|
||||
uint8_t card_id[8];
|
||||
|
||||
log_info("bt5api", "card unit {} inserted", static_cast<int>(unit_no));
|
||||
|
||||
// do the bt5 dance
|
||||
eam_io_card_slot_cmd(unit_no, EAM_IO_CARD_SLOT_CMD_CLOSE);
|
||||
eam_io_poll(unit_no);
|
||||
eam_io_card_slot_cmd(unit_no, EAM_IO_CARD_SLOT_CMD_READ);
|
||||
eam_io_poll(unit_no);
|
||||
|
||||
// ask the api for the card, then insert it into our engine.
|
||||
eam_io_read_card(unit_no, card_id, 8);
|
||||
eamuse_card_insert(unit_no, card_id);
|
||||
}
|
||||
|
||||
// if card removed entirely, do another bt5 dance!
|
||||
if(sensor_state == 0) {
|
||||
eam_io_card_slot_cmd(unit_no, EAM_IO_CARD_SLOT_CMD_CLOSE);
|
||||
eam_io_poll(unit_no);
|
||||
eam_io_card_slot_cmd(unit_no, EAM_IO_CARD_SLOT_CMD_OPEN);
|
||||
|
||||
log_info("bt5api", "card unit {} removed", static_cast<int>(unit_no));
|
||||
}
|
||||
}
|
||||
|
||||
// save state
|
||||
|
||||
// save prev state
|
||||
BT5API_CARD_STATES[unit_no] = sensor_state;
|
||||
}
|
||||
|
||||
|
||||
void bt5api_poll_reader_keypad(uint8_t unit_no) {
|
||||
|
||||
// check if initialized
|
||||
if (!EAMIO_DLL) {
|
||||
// check if initialized or out of bounds
|
||||
if (!EAMIO_DLL || unit_no >= eamuse_get_game_keypads()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// poll
|
||||
if (!eam_io_poll(unit_no)) {
|
||||
log_warning("bt5api", "polling bt5api reader {} returned failure",
|
||||
static_cast<int>(unit_no));
|
||||
|
||||
uint16_t keypad_current = eam_io_get_keypad_state(unit_no);
|
||||
uint16_t keypad_changes = ~BT5API_KEYPAD_STATES[unit_no] & keypad_current;
|
||||
|
||||
// if user has pressed decimal for the first time, eject the slotted reader.
|
||||
if(keypad_changes & (1 << EAM_IO_KEYPAD_DECIMAL)) {
|
||||
log_info("bt5api", "card unit {} ejecting", static_cast<int>(unit_no));
|
||||
|
||||
eam_io_card_slot_cmd(unit_no, EAM_IO_CARD_SLOT_CMD_EJECT);
|
||||
}
|
||||
|
||||
// save the last pressed.
|
||||
BT5API_KEYPAD_STATES[unit_no] = keypad_current;
|
||||
|
||||
// get keypad
|
||||
eamuse_set_keypad_overrides_bt5(unit_no, eam_io_get_keypad_state(unit_no));
|
||||
// send off the state to the main engine.
|
||||
eamuse_set_keypad_overrides_bt5(unit_no, keypad_current);
|
||||
}
|
||||
|
||||
void bt5api_dispose() {
|
||||
|
||||
@@ -202,7 +202,14 @@ bool eamuse_card_insert_consume(int active_count, int unit_id) {
|
||||
|
||||
// bt5api
|
||||
if (BT5API_ENABLED) {
|
||||
bt5api_poll_reader_card((uint8_t) index);
|
||||
// some bt5api want to be polled in order.
|
||||
if (eamuse_get_game_keypads() > 1) {
|
||||
bt5api_poll_reader_card(1);
|
||||
bt5api_poll_reader_card(0);
|
||||
}
|
||||
else {
|
||||
bt5api_poll_reader_card((uint8_t) index);
|
||||
}
|
||||
}
|
||||
|
||||
// auto insert card
|
||||
|
||||
Reference in New Issue
Block a user