Update to spice2x-25-04-25 (pre-apply)
> broken commit
This commit is contained in:
+182
-20
@@ -11,6 +11,7 @@
|
||||
#include "util/logging.h"
|
||||
#include "util/time.h"
|
||||
#include "util/utils.h"
|
||||
#include "overlay/overlay.h"
|
||||
|
||||
#include "bt5api.h"
|
||||
|
||||
@@ -32,16 +33,40 @@ static uint16_t KEYPAD_STATE_OVERRIDES_OVERLAY[] = {0, 0};
|
||||
static std::string EAMUSE_GAME_NAME;
|
||||
static ConfigKeypadBindings KEYPAD_BINDINGS {};
|
||||
|
||||
// auto card
|
||||
bool AUTO_INSERT_CARD[2] = {false, false};
|
||||
float AUTO_INSERT_CARD_COOLDOWN = 8.f; // seconds
|
||||
static std::optional<double> AUTO_INSERT_CARD_FIRST_CONSUME_TIME;
|
||||
static bool AUTO_INSERT_CARD_CACHED[2];
|
||||
static uint8_t AUTO_INSERT_CARD_CACHED_DATA[2][8];
|
||||
|
||||
// pin macro
|
||||
bool PIN_MACRO_ENABLED = false;
|
||||
std::string PIN_MACRO_VALUES[2] = {"", ""};
|
||||
static std::thread *PIN_MACRO_THREAD = nullptr;
|
||||
static bool PIN_MACRO_THREAD_ACTIVE = false;
|
||||
static uint16_t PIN_MACRO_TRIGGER_KEYS[2] = {
|
||||
games::OverlayButtons::TriggerPinMacroP1,
|
||||
games::OverlayButtons::TriggerPinMacroP2
|
||||
};
|
||||
|
||||
bool eamuse_get_card(int active_count, int unit_id, uint8_t *card) {
|
||||
|
||||
// get unit index
|
||||
int index = unit_id > 0 && active_count > 1 ? 1 : 0;
|
||||
|
||||
// check cards cached for auto-insert
|
||||
// explicitly not logging anything in this path to avoid log spam
|
||||
if (AUTO_INSERT_CARD[index] && AUTO_INSERT_CARD_CACHED[index]) {
|
||||
memcpy(card, AUTO_INSERT_CARD_CACHED_DATA[index], 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
// reader card input
|
||||
if (CARD_INSERT_UID_ENABLE[index]) {
|
||||
CARD_INSERT_UID_ENABLE[index] = false;
|
||||
memcpy(card, CARD_INSERT_UID[index], 8);
|
||||
log_info("eamuse", "Inserted card from reader {}: {}", index, bin2hex(card, 8));
|
||||
log_info("eamuse", "[P{}] Inserted card from reader: {}", index+1, bin2hex(card, 8));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -58,38 +83,50 @@ bool eamuse_get_card(int active_count, int unit_id, uint8_t *card) {
|
||||
}
|
||||
|
||||
bool eamuse_get_card(const std::filesystem::path &path, uint8_t *card, int index) {
|
||||
|
||||
// do a quick copy under lock
|
||||
std::unique_lock<std::mutex> lock(CARD_OVERRIDES_LOCK);
|
||||
const auto card_override = CARD_OVERRIDES[index];
|
||||
lock.unlock();
|
||||
|
||||
// Check if card overrides are present
|
||||
if (!CARD_OVERRIDES[index].empty()) {
|
||||
if (!card_override.empty()) {
|
||||
|
||||
// Override is present
|
||||
for (int n = 0; n < 16; n++) {
|
||||
char c = CARD_OVERRIDES[index].c_str()[n];
|
||||
char c = card_override.c_str()[n];
|
||||
bool digit = c >= '0' && c <= '9';
|
||||
bool character_big = c >= 'A' && c <= 'F';
|
||||
bool character_small = c >= 'a' && c <= 'f';
|
||||
if (!digit && !character_big && !character_small) {
|
||||
log_warning("eamuse",
|
||||
"{} card override contains an invalid character sequence at byte {} (16 characters, 0-9/A-F only)",
|
||||
CARD_OVERRIDES[index], n);
|
||||
card_override, n);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Log info
|
||||
log_info("eamuse", "Inserted card override: {}", CARD_OVERRIDES[index]);
|
||||
log_info("eamuse", "[P{}] Inserted card override: {}", index+1, card_override);
|
||||
|
||||
// Card is valid, convert and set it.
|
||||
hex2bin(CARD_OVERRIDES[index].c_str(), card);
|
||||
hex2bin(card_override.c_str(), card);
|
||||
|
||||
// cache it for auto-insert
|
||||
// always overwrite from overrides since override may have changed by user in card manager
|
||||
if (AUTO_INSERT_CARD[index]) {
|
||||
memcpy(AUTO_INSERT_CARD_CACHED_DATA[index], card, 8);
|
||||
AUTO_INSERT_CARD_CACHED[index] = true;
|
||||
log_info("eamuse", "[P{}] Auto card insert - caching this card override in memory: {}", index+1, card_override);
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
// Overrides are not present. Use the standard file reading method.
|
||||
return eamuse_get_card(path, card);
|
||||
return eamuse_get_card_from_file(path, card, index);
|
||||
}
|
||||
|
||||
bool eamuse_get_card(const std::filesystem::path &path, uint8_t *card) {
|
||||
bool eamuse_get_card_from_file(const std::filesystem::path &path, uint8_t *card, int index) {
|
||||
|
||||
// open file
|
||||
std::ifstream f(path);
|
||||
@@ -130,11 +167,18 @@ bool eamuse_get_card(const std::filesystem::path &path, uint8_t *card) {
|
||||
}
|
||||
|
||||
// info
|
||||
log_info("eamuse", "Inserted {}: {}", path.string(), buffer);
|
||||
log_info("eamuse", "[P{}] Inserted {}: {}", index+1, path.string(), buffer);
|
||||
|
||||
// convert hex to bytes
|
||||
hex2bin(buffer, card);
|
||||
|
||||
// cache it for auto-insert
|
||||
if (AUTO_INSERT_CARD[index] && !AUTO_INSERT_CARD_CACHED[index]) {
|
||||
memcpy(AUTO_INSERT_CARD_CACHED_DATA[index], card, 8);
|
||||
AUTO_INSERT_CARD_CACHED[index] = true;
|
||||
log_info("eamuse", "[P{}] Auto card insert - caching this card from file in memory: {}", index+1, buffer);
|
||||
}
|
||||
|
||||
// success
|
||||
return true;
|
||||
}
|
||||
@@ -161,12 +205,29 @@ bool eamuse_card_insert_consume(int active_count, int unit_id) {
|
||||
bt5api_poll_reader_card((uint8_t) index);
|
||||
}
|
||||
|
||||
// auto insert card
|
||||
if (AUTO_INSERT_CARD[index]) {
|
||||
// reset timer if enough time has passed since last insert
|
||||
if (CARD_INSERT[index] &&
|
||||
AUTO_INSERT_CARD_COOLDOWN < (get_performance_seconds() - CARD_INSERT_TIME[index])) {
|
||||
CARD_INSERT[index] = false;
|
||||
}
|
||||
|
||||
if (!CARD_INSERT[index]) {
|
||||
eamuse_card_insert(index);
|
||||
// not logging anything here to prevent spam
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check for card insert
|
||||
auto keypad_buttons = games::get_buttons_keypads(eamuse_get_game());
|
||||
auto offset = unit_id * games::KeypadButtons::Size;
|
||||
if ((CARD_INSERT[index] && fabs(get_performance_seconds() - CARD_INSERT_TIME[index]) < CARD_INSERT_TIMEOUT)
|
||||
|| GameAPI::Buttons::getState(RI_MGR, keypad_buttons->at(games::KeypadButtons::InsertCard + offset))) {
|
||||
log_info("eamuse", "Card insert on {}/{}", unit_id + 1, active_count);
|
||||
|| GameAPI::Buttons::getState(RI_MGR, keypad_buttons->at(games::KeypadButtons::InsertCard + offset))) {
|
||||
log_info("eamuse", "[P{}] Card insert on reader (total active count: {})", unit_id+1, active_count);
|
||||
CARD_INSERT[index] = false;
|
||||
return true;
|
||||
}
|
||||
@@ -249,6 +310,93 @@ void eamuse_coin_stop_thread() {
|
||||
COIN_INPUT_THREAD = nullptr;
|
||||
}
|
||||
|
||||
void eamuse_pin_macro_start_thread() {
|
||||
|
||||
// set active
|
||||
PIN_MACRO_THREAD_ACTIVE = true;
|
||||
|
||||
// create thread
|
||||
PIN_MACRO_THREAD = new std::thread([]() {
|
||||
uint16_t keypad_overrides[] = {
|
||||
1 << EAM_IO_KEYPAD_0,
|
||||
1 << EAM_IO_KEYPAD_1,
|
||||
1 << EAM_IO_KEYPAD_2,
|
||||
1 << EAM_IO_KEYPAD_3,
|
||||
1 << EAM_IO_KEYPAD_4,
|
||||
1 << EAM_IO_KEYPAD_5,
|
||||
1 << EAM_IO_KEYPAD_6,
|
||||
1 << EAM_IO_KEYPAD_7,
|
||||
1 << EAM_IO_KEYPAD_8,
|
||||
1 << EAM_IO_KEYPAD_9,
|
||||
};
|
||||
auto overlay_buttons = games::get_buttons_overlay(eamuse_get_game());
|
||||
size_t pin_index[2] = {PIN_MACRO_VALUES[0].length(), PIN_MACRO_VALUES[1].length()};
|
||||
|
||||
std::optional<uint8_t> active_unit = std::nullopt;
|
||||
|
||||
while (PIN_MACRO_THREAD_ACTIVE) {
|
||||
// wait for key press
|
||||
if (!active_unit.has_value()) {
|
||||
for (int unit = 0; unit < 2; unit++) {
|
||||
if (PIN_MACRO_VALUES[unit].empty()) {
|
||||
continue;
|
||||
}
|
||||
if (overlay_buttons &&
|
||||
(!overlay::OVERLAY || overlay::OVERLAY->hotkeys_triggered()) &&
|
||||
GameAPI::Buttons::getState(RI_MGR, overlay_buttons->at(PIN_MACRO_TRIGGER_KEYS[unit]))) {
|
||||
active_unit = unit;
|
||||
// Reset key index
|
||||
pin_index[unit] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!active_unit.has_value()) {
|
||||
Sleep(20);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const auto unit = active_unit.value();
|
||||
// get character from config
|
||||
if (pin_index[unit] < PIN_MACRO_VALUES[unit].length()) {
|
||||
|
||||
// insert character
|
||||
char pin_char = PIN_MACRO_VALUES[unit].at(pin_index[unit]);
|
||||
if (pin_char >= '0' && pin_char <= '9') {
|
||||
int char_index = pin_char - '0';
|
||||
eamuse_set_keypad_overrides(unit, keypad_overrides[char_index]);
|
||||
}
|
||||
pin_index[unit]++;
|
||||
Sleep(100);
|
||||
|
||||
// clear
|
||||
eamuse_set_keypad_overrides(unit, 0);
|
||||
Sleep(50);
|
||||
|
||||
// end of PIN
|
||||
if (pin_index[unit] == PIN_MACRO_VALUES[unit].length()) {
|
||||
active_unit = std::nullopt;
|
||||
Sleep(120);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Sleep(200);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void eamuse_pin_macro_stop_thread() {
|
||||
PIN_MACRO_THREAD_ACTIVE = false;
|
||||
if (PIN_MACRO_THREAD != nullptr) {
|
||||
PIN_MACRO_THREAD->join();
|
||||
delete PIN_MACRO_THREAD;
|
||||
PIN_MACRO_THREAD = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void eamuse_set_keypad_overrides(size_t unit, uint16_t keypad_state) {
|
||||
|
||||
// check unit
|
||||
@@ -300,13 +448,6 @@ uint16_t eamuse_get_keypad_state(size_t unit) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// keypad disabled for KFC in BI2X mode, since the game won't handle it correctly
|
||||
// this check for IO is necessary (as opposed to just doing a check for Valkyrie cab mode)
|
||||
// because there are hex edits that allow you to use legacy (KFC/BIO2) IO while in Valk mode.
|
||||
if (avs::game::is_model("KFC") && games::sdvx::BI2X_INITIALIZED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// reset
|
||||
KEYPAD_STATE[unit] = KEYPAD_STATE_OVERRIDES[unit];
|
||||
KEYPAD_STATE[unit] |= KEYPAD_STATE_OVERRIDES_BT5[unit];
|
||||
@@ -512,6 +653,12 @@ void eamuse_autodetect_game() {
|
||||
eamuse_set_game("Ongaku Paradise");
|
||||
else if (avs::game::is_model("TBS"))
|
||||
eamuse_set_game("Busou Shinki: Armored Princess Battle Conductor");
|
||||
else if (avs::game::is_model("UJK"))
|
||||
eamuse_set_game("Chase Chase Jokers");
|
||||
else if (avs::game::is_model("UKS"))
|
||||
eamuse_set_game("QuizKnock STADIUM");
|
||||
else if (avs::game::is_model("VFG"))
|
||||
eamuse_set_game("Mahjong Fight Girl");
|
||||
else {
|
||||
log_warning("eamuse", "unknown game model: {}", avs::game::MODEL);
|
||||
eamuse_set_game("unknown");
|
||||
@@ -519,7 +666,22 @@ void eamuse_autodetect_game() {
|
||||
}
|
||||
|
||||
void eamuse_scard_callback(uint8_t slot_no, card_info_t *cardinfo) {
|
||||
log_misc("scard", "eamuse_scard_callback: slot_no={}, card_type={}", slot_no, cardinfo->card_type);
|
||||
if (cardinfo->card_type > 0) {
|
||||
eamuse_card_insert(slot_no, cardinfo->uid);
|
||||
eamuse_card_insert(slot_no & 1, cardinfo->uid);
|
||||
}
|
||||
}
|
||||
|
||||
bool eamuse_scanned_card_peek_noninvasive(size_t unit, char card_uid[8]) {
|
||||
const int unit_index = unit > 0 ? 1 : 0;
|
||||
if (!CARD_INSERT_UID_ENABLE[unit_index]) {
|
||||
return false;
|
||||
}
|
||||
memcpy(card_uid, CARD_INSERT_UID[unit_index], 8);
|
||||
return true;
|
||||
}
|
||||
|
||||
void eamuse_scanned_card_clear(size_t unit) {
|
||||
const int unit_index = unit > 0 ? 1 : 0;
|
||||
CARD_INSERT_UID_ENABLE[unit_index] = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user