Merge branch 'main' into nac-spice22x
Merge official spice2x 'main', up tob53447bNotes:dc82c98is where the nixac fork starts. - Upstream's OBJECT-library + forbidden-static-DLL-import build refactor merged with nixAC's blob/dsdmo resources - SPICE_XP / runtime large-address-aware detection builds have been integrated from upstream - README.md grabs from upstream; .gitignore keeps nixAC's fork-specific entries
This commit is contained in:
+34
-32
@@ -366,6 +366,7 @@ static void __cdecl device_update() {
|
||||
|
||||
// update touch
|
||||
games::jb::touch_update();
|
||||
auto touched = games::jb::touch_state();
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::jb::get_buttons();
|
||||
@@ -382,52 +383,52 @@ static void __cdecl device_update() {
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::CoinMech))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 29;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[3] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button1))) {
|
||||
if (touched[3] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button1))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 13;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[7] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button2))) {
|
||||
if (touched[7] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button2))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 9;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[11] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button3))) {
|
||||
if (touched[11] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button3))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 21;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[15] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button4))) {
|
||||
if (touched[15] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button4))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 17;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[2] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button5))) {
|
||||
if (touched[2] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button5))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 14;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[6] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button6))) {
|
||||
if (touched[6] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button6))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 10;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[10] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button7))) {
|
||||
if (touched[10] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button7))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 22;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[14] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button8))) {
|
||||
if (touched[14] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button8))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 18;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[1] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button9))) {
|
||||
if (touched[1] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button9))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 15;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[5] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button10))) {
|
||||
if (touched[5] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button10))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 11;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[9] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button11))) {
|
||||
if (touched[9] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button11))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 23;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[13] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button12))) {
|
||||
if (touched[13] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button12))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 19;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[0] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button13))) {
|
||||
if (touched[0] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button13))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 24;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[4] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button14))) {
|
||||
if (touched[4] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button14))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 12;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[8] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button15))) {
|
||||
if (touched[8] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button15))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 26;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[12] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button16))) {
|
||||
if (touched[12] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button16))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 20;
|
||||
}
|
||||
|
||||
@@ -439,6 +440,7 @@ static void __cdecl device_update() {
|
||||
|
||||
// update touch
|
||||
games::jb::touch_update();
|
||||
auto touched = games::jb::touch_state();
|
||||
|
||||
// get buttons
|
||||
auto &buttons = games::jb::get_buttons();
|
||||
@@ -455,52 +457,52 @@ static void __cdecl device_update() {
|
||||
if (Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::CoinMech))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 24;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[0] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button1))) {
|
||||
if (touched[0] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button1))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 5;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[1] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button2))) {
|
||||
if (touched[1] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button2))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 1;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[2] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button3))) {
|
||||
if (touched[2] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button3))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 13;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[3] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button4))) {
|
||||
if (touched[3] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button4))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 9;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[4] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button5))) {
|
||||
if (touched[4] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button5))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 6;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[5] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button6))) {
|
||||
if (touched[5] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button6))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 2;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[6] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button7))) {
|
||||
if (touched[6] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button7))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 14;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[7] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button8))) {
|
||||
if (touched[7] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button8))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 10;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[8] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button9))) {
|
||||
if (touched[8] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button9))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 7;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[9] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button10))) {
|
||||
if (touched[9] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button10))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 3;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[10] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button11))) {
|
||||
if (touched[10] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button11))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 15;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[11] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button12))) {
|
||||
if (touched[11] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button12))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 11;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[12] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button13))) {
|
||||
if (touched[12] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button13))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 16;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[13] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button14))) {
|
||||
if (touched[13] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button14))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 4;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[14] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button15))) {
|
||||
if (touched[14] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button15))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 20;
|
||||
}
|
||||
if (games::jb::TOUCH_STATE[15] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button16))) {
|
||||
if (touched[15] || Buttons::getState(RI_MGR, buttons.at(games::jb::Buttons::Button16))) {
|
||||
DEVICE_INPUT_STATE |= 1 << 12;
|
||||
}
|
||||
}
|
||||
|
||||
+99
-18
@@ -1,5 +1,7 @@
|
||||
#include "eamuse.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
|
||||
@@ -12,14 +14,16 @@
|
||||
#include "util/time.h"
|
||||
#include "util/utils.h"
|
||||
#include "overlay/overlay.h"
|
||||
#include "overlay/notifications.h"
|
||||
|
||||
#include "bt5api.h"
|
||||
|
||||
// state
|
||||
static constexpr double NOTIFICATION_THROTTLE_SECONDS = 3.0;
|
||||
static bool CARD_INSERT[2] = {false, false};
|
||||
static double CARD_INSERT_TIME[2] = {0, 0};
|
||||
static double CARD_INSERT_TIMEOUT = 2.0;
|
||||
static char CARD_INSERT_UID[2][8];
|
||||
static char CARD_INSERT_UID[2][8] = {{0}, {0}};
|
||||
static char CARD_INSERT_UID_ENABLE[2] = {false, false};
|
||||
static int COIN_STOCK = 0;
|
||||
static bool COIN_BLOCK = false;
|
||||
@@ -43,6 +47,9 @@ static uint8_t AUTO_INSERT_CARD_CACHED_DATA[2][8];
|
||||
// pin macro
|
||||
bool PIN_MACRO_ENABLED = false;
|
||||
std::string PIN_MACRO_VALUES[2] = {"", ""};
|
||||
std::string AUTO_PIN_MACRO_TRIGGER[2];
|
||||
static std::atomic_bool AUTO_PIN_MACRO_REQUEST[2] {false, false};
|
||||
static bool AUTO_PIN_MACRO_PLAYER_ACTIVE[2] = {false, false};
|
||||
static std::thread *PIN_MACRO_THREAD = nullptr;
|
||||
static bool PIN_MACRO_THREAD_ACTIVE = false;
|
||||
static uint16_t PIN_MACRO_TRIGGER_KEYS[2] = {
|
||||
@@ -50,6 +57,18 @@ static uint16_t PIN_MACRO_TRIGGER_KEYS[2] = {
|
||||
games::OverlayButtons::TriggerPinMacroP2
|
||||
};
|
||||
|
||||
static bool pin_macro_log_hook(void *, const std::string &data, logger::Style, std::string &) {
|
||||
for (int unit = 0; unit < 2; unit++) {
|
||||
if (!AUTO_PIN_MACRO_PLAYER_ACTIVE[unit]) {
|
||||
continue;
|
||||
}
|
||||
if (data.find(AUTO_PIN_MACRO_TRIGGER[unit]) != std::string::npos) {
|
||||
AUTO_PIN_MACRO_REQUEST[unit].store(true);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool eamuse_get_card(int active_count, int unit_id, uint8_t *card) {
|
||||
|
||||
// get unit index
|
||||
@@ -87,7 +106,7 @@ bool eamuse_get_card(const std::filesystem::path &path, uint8_t *card, int index
|
||||
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_override.empty()) {
|
||||
|
||||
@@ -102,6 +121,12 @@ bool eamuse_get_card(const std::filesystem::path &path, uint8_t *card, int index
|
||||
"{} card override contains an invalid character sequence at byte {} (16 characters, 0-9/A-F only)",
|
||||
card_override, n);
|
||||
|
||||
overlay::notifications::add_throttled(
|
||||
overlay::notifications::Severity::Error,
|
||||
fmt::format("eamuse.card_override_error.p{}", index + 1),
|
||||
NOTIFICATION_THROTTLE_SECONDS,
|
||||
fmt::format("[P{}] invalid card override", index + 1));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -131,7 +156,12 @@ bool eamuse_get_card_from_file(const std::filesystem::path &path, uint8_t *card,
|
||||
// open file
|
||||
std::ifstream f(path);
|
||||
if (!f) {
|
||||
log_warning("eamuse", "{} can not be opened!", path.string());
|
||||
log_warning("eamuse", "{} can not be opened!", path);
|
||||
overlay::notifications::add_throttled(
|
||||
overlay::notifications::Severity::Error,
|
||||
fmt::format("eamuse.card_file_error.p{}", index + 1),
|
||||
NOTIFICATION_THROTTLE_SECONDS,
|
||||
fmt::format("[P{}] can't open card file", index + 1));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -142,7 +172,13 @@ bool eamuse_get_card_from_file(const std::filesystem::path &path, uint8_t *card,
|
||||
|
||||
// check size
|
||||
if (length < 16) {
|
||||
log_warning("eamuse", "{} is too small (must be at least 16 characters)", path.string());
|
||||
log_warning("eamuse", "{} is too small (must be at least 16 characters)", path);
|
||||
overlay::notifications::add_throttled(
|
||||
overlay::notifications::Severity::Error,
|
||||
fmt::format("eamuse.card_file_error.p{}", index + 1),
|
||||
NOTIFICATION_THROTTLE_SECONDS,
|
||||
fmt::format("[P{}] card file error", index + 1));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -160,14 +196,19 @@ bool eamuse_get_card_from_file(const std::filesystem::path &path, uint8_t *card,
|
||||
if (!digit && !character_big && !character_small) {
|
||||
log_warning("eamuse",
|
||||
"{} contains an invalid character sequence at byte {} (16 characters, 0-9/A-F only)",
|
||||
path.string(), n);
|
||||
path, n);
|
||||
|
||||
overlay::notifications::add_throttled(
|
||||
overlay::notifications::Severity::Error,
|
||||
fmt::format("eamuse.card_file_error.p{}", index + 1),
|
||||
NOTIFICATION_THROTTLE_SECONDS,
|
||||
fmt::format("[P{}] card file error", index + 1));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// info
|
||||
log_info("eamuse", "[P{}] Inserted {}: {}", index+1, path.string(), buffer);
|
||||
log_info("eamuse", "[P{}] Inserted {}: {}", index+1, path, buffer);
|
||||
|
||||
// convert hex to bytes
|
||||
hex2bin(buffer, card);
|
||||
@@ -234,8 +275,16 @@ bool eamuse_card_insert_consume(int active_count, int unit_id) {
|
||||
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", "[P{}] Card insert on reader (total active count: {})", unit_id+1, active_count);
|
||||
CARD_INSERT[index] = false;
|
||||
|
||||
overlay::notifications::add_throttled(
|
||||
overlay::notifications::Severity::Info,
|
||||
fmt::format("eamuse.card_inserted.p{}", unit_id + 1),
|
||||
NOTIFICATION_THROTTLE_SECONDS,
|
||||
fmt::format("[P{}] card inserted", unit_id + 1));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -305,7 +354,7 @@ void eamuse_coin_start_thread() {
|
||||
}
|
||||
|
||||
// once every two frames
|
||||
Sleep(1000 / 30);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000 / 30));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -322,6 +371,25 @@ void eamuse_pin_macro_start_thread() {
|
||||
// set active
|
||||
PIN_MACRO_THREAD_ACTIVE = true;
|
||||
|
||||
// a unit is eligible for auto-trigger only if all the static prerequisites are
|
||||
// satisfied at startup; precomputing this lets the log hook skip per-line checks
|
||||
// on values that never change at runtime
|
||||
for (int unit = 0; unit < 2; unit++) {
|
||||
AUTO_PIN_MACRO_PLAYER_ACTIVE[unit] =
|
||||
!AUTO_PIN_MACRO_TRIGGER[unit].empty() &&
|
||||
!PIN_MACRO_VALUES[unit].empty();
|
||||
if(!AUTO_PIN_MACRO_TRIGGER[unit].empty() && PIN_MACRO_VALUES[unit].empty()) {
|
||||
log_warning("eamuse", "Configuration error; Pin Macro empty for P{}.", unit+1);
|
||||
}
|
||||
}
|
||||
|
||||
// register scene log hook so the macro fires on the per-game trigger string,
|
||||
// but only if at least one player is eligible
|
||||
if (AUTO_PIN_MACRO_PLAYER_ACTIVE[0] || AUTO_PIN_MACRO_PLAYER_ACTIVE[1]) {
|
||||
logger::hook_add(pin_macro_log_hook, nullptr);
|
||||
log_info("eamuse", "AUTO_PIN_MACRO enabled");
|
||||
}
|
||||
|
||||
// create thread
|
||||
PIN_MACRO_THREAD = new std::thread([]() {
|
||||
uint16_t keypad_overrides[] = {
|
||||
@@ -342,15 +410,24 @@ void eamuse_pin_macro_start_thread() {
|
||||
std::optional<uint8_t> active_unit = std::nullopt;
|
||||
|
||||
while (PIN_MACRO_THREAD_ACTIVE) {
|
||||
// wait for key press
|
||||
// wait for key press or auto-trigger
|
||||
if (!active_unit.has_value()) {
|
||||
for (int unit = 0; unit < 2; unit++) {
|
||||
if (PIN_MACRO_VALUES[unit].empty()) {
|
||||
continue;
|
||||
}
|
||||
if (overlay_buttons &&
|
||||
bool key_press = overlay_buttons &&
|
||||
(!overlay::OVERLAY || overlay::OVERLAY->hotkeys_triggered()) &&
|
||||
GameAPI::Buttons::getState(RI_MGR, overlay_buttons->at(PIN_MACRO_TRIGGER_KEYS[unit]))) {
|
||||
GameAPI::Buttons::getState(RI_MGR, overlay_buttons->at(PIN_MACRO_TRIGGER_KEYS[unit]));
|
||||
bool auto_request = AUTO_PIN_MACRO_REQUEST[unit].exchange(false);
|
||||
if (auto_request) {
|
||||
log_info("eamuse", "AUTO_PIN_MACRO_REQUEST detected for P{}", unit+1);
|
||||
}
|
||||
if (key_press || auto_request) {
|
||||
overlay::notifications::add(
|
||||
overlay::notifications::Severity::Info,
|
||||
fmt::format("[P{}] PIN macro fired ({})",
|
||||
unit + 1, auto_request ? "auto" : "manual"));
|
||||
active_unit = unit;
|
||||
// Reset key index
|
||||
pin_index[unit] = 0;
|
||||
@@ -359,7 +436,7 @@ void eamuse_pin_macro_start_thread() {
|
||||
}
|
||||
|
||||
if (!active_unit.has_value()) {
|
||||
Sleep(20);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -375,22 +452,22 @@ void eamuse_pin_macro_start_thread() {
|
||||
eamuse_set_keypad_overrides(unit, keypad_overrides[char_index]);
|
||||
}
|
||||
pin_index[unit]++;
|
||||
Sleep(100);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
// clear
|
||||
eamuse_set_keypad_overrides(unit, 0);
|
||||
Sleep(50);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||
|
||||
// end of PIN
|
||||
if (pin_index[unit] == PIN_MACRO_VALUES[unit].length()) {
|
||||
active_unit = std::nullopt;
|
||||
Sleep(120);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(120));
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
Sleep(200);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -402,6 +479,9 @@ void eamuse_pin_macro_stop_thread() {
|
||||
delete PIN_MACRO_THREAD;
|
||||
PIN_MACRO_THREAD = nullptr;
|
||||
}
|
||||
if (AUTO_PIN_MACRO_PLAYER_ACTIVE[0] || AUTO_PIN_MACRO_PLAYER_ACTIVE[1]) {
|
||||
logger::hook_remove(pin_macro_log_hook, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void eamuse_set_keypad_overrides(size_t unit, uint16_t keypad_state) {
|
||||
@@ -454,7 +534,7 @@ uint16_t eamuse_get_keypad_state(size_t unit) {
|
||||
if (unit >= std::size(KEYPAD_STATE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// reset
|
||||
KEYPAD_STATE[unit] = KEYPAD_STATE_OVERRIDES[unit];
|
||||
KEYPAD_STATE[unit] |= KEYPAD_STATE_OVERRIDES_BT5[unit];
|
||||
@@ -549,7 +629,7 @@ void eamuse_update_keypad_bindings() {
|
||||
KEYPAD_BINDINGS = Config::getInstance().getKeypadBindings(EAMUSE_GAME_NAME);
|
||||
}
|
||||
|
||||
std::string eamuse_get_game() {
|
||||
const std::string &eamuse_get_game() {
|
||||
return EAMUSE_GAME_NAME;
|
||||
}
|
||||
|
||||
@@ -593,7 +673,8 @@ void eamuse_autodetect_game() {
|
||||
eamuse_set_game("Beatmania IIDX");
|
||||
else if (avs::game::is_model("J44") ||
|
||||
avs::game::is_model("K44") ||
|
||||
avs::game::is_model("L44"))
|
||||
avs::game::is_model("L44") ||
|
||||
avs::game::is_model("T44"))
|
||||
eamuse_set_game("Jubeat");
|
||||
else if (avs::game::is_model("KDM"))
|
||||
eamuse_set_game("Dance Evolution");
|
||||
|
||||
@@ -38,6 +38,7 @@ extern float AUTO_INSERT_CARD_COOLDOWN;
|
||||
|
||||
extern bool PIN_MACRO_ENABLED;
|
||||
extern std::string PIN_MACRO_VALUES[2];
|
||||
extern std::string AUTO_PIN_MACRO_TRIGGER[2];
|
||||
|
||||
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 unit_id);
|
||||
@@ -77,7 +78,7 @@ bool eamuse_keypad_state_naive();
|
||||
|
||||
void eamuse_set_game(std::string game);
|
||||
|
||||
std::string eamuse_get_game();
|
||||
const std::string &eamuse_get_game();
|
||||
int eamuse_get_game_keypads();
|
||||
int eamuse_get_game_keypads_name();
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ static cardunit_card_cardnumber_t cardunit_card_cardnumber = nullptr;
|
||||
static HINSTANCE SCIUNIT_INSTANCE;
|
||||
static std::string SCIUNIT_INSTANCE_NAME = "sciunit.dll";
|
||||
static bool SCIUNIT_INITIALIZED = false;
|
||||
static int SCIUNIT_STATUS = 0;
|
||||
static bool CARD_IN = false;
|
||||
static bool CARD_PRESSED = false;
|
||||
static uint8_t CARD_UID[8];
|
||||
@@ -150,11 +151,11 @@ static int __cdecl sciunit_finalize() {
|
||||
}
|
||||
|
||||
static int __cdecl sciunit_get_errorunit() {
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int __cdecl sciunit_get_stat() {
|
||||
return 0;
|
||||
return SCIUNIT_STATUS;
|
||||
}
|
||||
|
||||
static int __cdecl sciunit_get_version(int a1, int a2) {
|
||||
@@ -163,6 +164,7 @@ static int __cdecl sciunit_get_version(int a1, int a2) {
|
||||
|
||||
static int __cdecl sciunit_initialize() {
|
||||
SCIUNIT_INITIALIZED = true;
|
||||
SCIUNIT_STATUS = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -223,8 +225,12 @@ static int __cdecl sciunit_reset() {
|
||||
}
|
||||
|
||||
static int __cdecl sciunit_update() {
|
||||
if (SCIUNIT_INITIALIZED)
|
||||
if (SCIUNIT_INITIALIZED) {
|
||||
if (SCIUNIT_STATUS == 1) {
|
||||
SCIUNIT_STATUS = 2;
|
||||
}
|
||||
update_card();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "cfg/screen_resize.h"
|
||||
#include "games/gitadora/gitadora.h"
|
||||
#include "games/iidx/iidx.h"
|
||||
#include "games/popn/popn.h"
|
||||
#include "hooks/graphics/graphics.h"
|
||||
#include "overlay/overlay.h"
|
||||
#include "overlay/windows/generic_sub.h"
|
||||
@@ -20,6 +21,7 @@
|
||||
#include "util/logging.h"
|
||||
#include "util/time.h"
|
||||
#include "util/utils.h"
|
||||
#include "rawinput/touch.h"
|
||||
|
||||
#include "avs/game.h"
|
||||
|
||||
@@ -36,6 +38,9 @@ namespace wintouchemu {
|
||||
bool INJECT_MOUSE_AS_WM_TOUCH = false;
|
||||
bool LOG_FPS = false;
|
||||
bool ADD_TOUCH_FLAG_PRIMARY = false;
|
||||
|
||||
// state
|
||||
double last_touch_event = 0.0;
|
||||
|
||||
static inline bool is_emu_enabled() {
|
||||
return FORCE || !is_touch_available("wintouchemu::is_emu_enabled") || GRAPHICS_SHOW_CURSOR;
|
||||
@@ -126,6 +131,11 @@ namespace wintouchemu {
|
||||
WINDOW_TITLE_END = window_title_end;
|
||||
}
|
||||
|
||||
static void flip_touch_points(PTOUCHINPUT point) {
|
||||
point->x = rawinput::touch::DISPLAY_SIZE_X * 100 - point->x;
|
||||
point->y = rawinput::touch::DISPLAY_SIZE_Y * 100 - point->y;
|
||||
}
|
||||
|
||||
static BOOL WINAPI GetTouchInputInfoHook(HANDLE hTouchInput, UINT cInputs, PTOUCHINPUT pInputs, int cbSize) {
|
||||
|
||||
// check if original should be called
|
||||
@@ -220,6 +230,12 @@ namespace wintouchemu {
|
||||
touch_input->cxContact = 0;
|
||||
touch_input->cyContact = 0;
|
||||
|
||||
if (avs::game::is_model("KFC") &&
|
||||
rawinput::touch::DISPLAY_INITIALIZED &&
|
||||
rawinput::touch::DISPLAY_ORIENTATION == DMDO_270) {
|
||||
flip_touch_points(touch_input);
|
||||
}
|
||||
|
||||
} else if (USE_MOUSE && !mouse_used) {
|
||||
|
||||
// disable further mouse inputs this call
|
||||
@@ -235,7 +251,10 @@ namespace wintouchemu {
|
||||
touch_input->y -= SPICETOUCH_TOUCH_Y;
|
||||
}
|
||||
|
||||
// log_misc("wintouchemu", "mouse state ({}, {})", to_string(touch_input->x), to_string(touch_input->y));
|
||||
// log_misc(
|
||||
// "wintouchemu",
|
||||
// "mouse state ({}, {}) event={}",
|
||||
// to_string(touch_input->x), to_string(touch_input->y), mouse_state.touch_event);
|
||||
|
||||
auto valid = true;
|
||||
if (overlay::OVERLAY) {
|
||||
@@ -393,7 +412,11 @@ namespace wintouchemu {
|
||||
// use mouse position as ImGui overlay will block the touch window
|
||||
log_info("wintouchemu", "use mouse cursor API for ldj overlay subscreen");
|
||||
USE_MOUSE = true;
|
||||
} else if (games::gitadora::is_arena_model() && games::gitadora::ARENA_SINGLE_WINDOW) {
|
||||
} else if (games::popn::is_pikapika_model()) {
|
||||
// same as iidx case above
|
||||
log_info("wintouchemu", "use mouse cursor API for popn overlay subscreen");
|
||||
USE_MOUSE = true;
|
||||
} else if (games::gitadora::is_arena_model() && GRAPHICS_PREVENT_SECONDARY_WINDOWS) {
|
||||
log_info("wintouchemu", "use mouse cursor API for gitadora overlay subscreen");
|
||||
USE_MOUSE = true;
|
||||
} else {
|
||||
@@ -422,6 +445,8 @@ namespace wintouchemu {
|
||||
}
|
||||
}
|
||||
|
||||
const auto now = get_performance_milliseconds();
|
||||
|
||||
// update touch events
|
||||
if (hWnd != nullptr) {
|
||||
|
||||
@@ -441,6 +466,7 @@ namespace wintouchemu {
|
||||
|
||||
// check if new events are available
|
||||
if (event_count > 0) {
|
||||
last_touch_event = now;
|
||||
|
||||
// send fake event to make the game update it's touch inputs
|
||||
auto wndProc = (WNDPROC) GetWindowLongPtr(hWnd, GWLP_WNDPROC);
|
||||
@@ -467,7 +493,20 @@ namespace wintouchemu {
|
||||
// value from GetTouchInputInfo or fail to read dwFlags for valid events, so it's not OK to
|
||||
// send empty events when the mouse button is not clicked/released
|
||||
if (hWnd != nullptr && USE_MOUSE) {
|
||||
bool button_pressed = ((GetKeyState(VK_LBUTTON) & 0x100) != 0);
|
||||
bool button_pressed = get_async_primary_mouse();
|
||||
|
||||
// while the subscreen overlay cannot accept the mouse, treat the button as
|
||||
// released; this ends any active touch and prevents new mouse touch contacts
|
||||
if (overlay::OVERLAY &&
|
||||
overlay::OVERLAY->has_subscreen_touch_transform() &&
|
||||
!overlay::OVERLAY->accepts_subscreen_mouse_input()) {
|
||||
button_pressed = false;
|
||||
}
|
||||
|
||||
// if there was a touch event in the last 500 ms, don't insert new button presses
|
||||
if (button_pressed && (now - last_touch_event) < 500) {
|
||||
button_pressed = false;
|
||||
}
|
||||
|
||||
// figure out what kind of touch event to simulate
|
||||
if (button_pressed && !mouse_state.last_button_pressed) {
|
||||
|
||||
Reference in New Issue
Block a user