mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 06:40:42 -07:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 06374ef78a | |||
| bdde1ec6b8 | |||
| d2176fe4f0 | |||
| fb9eef904a | |||
| 48903998a5 | |||
| f2dca0265f | |||
| 1147ed9858 | |||
| 19d93f4ffd |
@@ -217,8 +217,10 @@ namespace avs {
|
|||||||
ea3_config_name = "prop/eamuse-config.xml";
|
ea3_config_name = "prop/eamuse-config.xml";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avs::core::file_exists(ea3_config_name)) {
|
if (fileutils::file_exists(ea3_config_name)) {
|
||||||
log_info("avs-ea3", "booting (using {})", ea3_config_name);
|
log_info("avs-ea3", "found {} on disk", ea3_config_name);
|
||||||
|
} else if (CFG_PATH.size()) {
|
||||||
|
log_fatal("avs-ea3", "user-specified ea3 config file is missing: {}", ea3_config_name);
|
||||||
} else {
|
} else {
|
||||||
log_warning("avs-ea3", "looked for the following files in order:");
|
log_warning("avs-ea3", "looked for the following files in order:");
|
||||||
log_warning("avs-ea3", " * prop/ea3-config.xml");
|
log_warning("avs-ea3", " * prop/ea3-config.xml");
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ time (
|
|||||||
if ((BUILD_XP > 0))
|
if ((BUILD_XP > 0))
|
||||||
then
|
then
|
||||||
# 32 bit Windows XP
|
# 32 bit Windows XP
|
||||||
|
echo ""
|
||||||
echo "Building 32bit targets (WinXP toolchain)..."
|
echo "Building 32bit targets (WinXP toolchain)..."
|
||||||
echo "========================="
|
echo "========================="
|
||||||
if ((CLEAN_BUILD > 0))
|
if ((CLEAN_BUILD > 0))
|
||||||
@@ -187,6 +188,7 @@ time (
|
|||||||
CXXFLAGS="$CXXFLAGS -DSPICE_XP=1" cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_WINXP_64} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} "$OLDPWD" && ninja ${TARGETS_XP64}
|
CXXFLAGS="$CXXFLAGS -DSPICE_XP=1" cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_WINXP_64} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} "$OLDPWD" && ninja ${TARGETS_XP64}
|
||||||
popd > /dev/null
|
popd > /dev/null
|
||||||
else
|
else
|
||||||
|
echo ""
|
||||||
echo "Skipping WinXP builds, toolchain not specified"
|
echo "Skipping WinXP builds, toolchain not specified"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
+12
-2
@@ -199,9 +199,19 @@ GameAPI::Buttons::State GameAPI::Buttons::getState(rawinput::RawInputManager *ma
|
|||||||
if (vKey < value_states->size()) {
|
if (vKey < value_states->size()) {
|
||||||
auto value = value_states->at(vKey);
|
auto value = value_states->at(vKey);
|
||||||
if (current_button->getAnalogType() == BAT_POSITIVE) {
|
if (current_button->getAnalogType() == BAT_POSITIVE) {
|
||||||
state = value > 0.6f ? BUTTON_PRESSED : BUTTON_NOT_PRESSED;
|
float threshold = 0.6f;
|
||||||
|
if (current_button->getBatThreshold() > 0) {
|
||||||
|
threshold = std::clamp(current_button->getBatThreshold() / 100.f, 0.01f, 0.99f);
|
||||||
|
}
|
||||||
|
state = value > threshold ? BUTTON_PRESSED : BUTTON_NOT_PRESSED;
|
||||||
|
|
||||||
} else if (current_button->getAnalogType() == BAT_NEGATIVE) {
|
} else if (current_button->getAnalogType() == BAT_NEGATIVE) {
|
||||||
state = value < 0.4f ? BUTTON_PRESSED : BUTTON_NOT_PRESSED;
|
float threshold = 0.4f;
|
||||||
|
if (current_button->getBatThreshold() > 0) {
|
||||||
|
threshold = std::clamp((100 - current_button->getBatThreshold()) / 100.f, 0.01f, 0.99f);
|
||||||
|
}
|
||||||
|
state = value < threshold ? BUTTON_PRESSED : BUTTON_NOT_PRESSED;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
state = value > 0.01f ? BUTTON_PRESSED : BUTTON_NOT_PRESSED;
|
state = value > 0.01f ? BUTTON_PRESSED : BUTTON_NOT_PRESSED;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ private:
|
|||||||
ButtonAnalogType analog_type = BAT_NONE;
|
ButtonAnalogType analog_type = BAT_NONE;
|
||||||
double debounce_up = 0.0;
|
double debounce_up = 0.0;
|
||||||
double debounce_down = 0.0;
|
double debounce_down = 0.0;
|
||||||
|
int bat_threshold = 0; // for positive/negative only, value in percentage, zero is default
|
||||||
bool invert = false;
|
bool invert = false;
|
||||||
bool is_temporary = false;
|
bool is_temporary = false;
|
||||||
|
|
||||||
@@ -109,6 +110,7 @@ public:
|
|||||||
alternatives.clear();
|
alternatives.clear();
|
||||||
device_identifier = "";
|
device_identifier = "";
|
||||||
analog_type = BAT_NONE;
|
analog_type = BAT_NONE;
|
||||||
|
bat_threshold = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getDisplayString(rawinput::RawInputManager* manager);
|
std::string getDisplayString(rawinput::RawInputManager* manager);
|
||||||
@@ -169,6 +171,14 @@ public:
|
|||||||
this->debounce_down = debounce_time_down;
|
this->debounce_down = debounce_time_down;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void setBatThreshold(int bat_threshold) {
|
||||||
|
this->bat_threshold = bat_threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int getBatThreshold() const {
|
||||||
|
return this->bat_threshold;
|
||||||
|
}
|
||||||
|
|
||||||
inline bool getInvert() const {
|
inline bool getInvert() const {
|
||||||
return this->invert;
|
return this->invert;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ bool Config::addGame(Game &game) {
|
|||||||
auto analogType = (int) BAT_NONE;
|
auto analogType = (int) BAT_NONE;
|
||||||
double debounce_up = 0.0;
|
double debounce_up = 0.0;
|
||||||
double debounce_down = 0.0;
|
double debounce_down = 0.0;
|
||||||
|
int bat_threshold = 0;
|
||||||
int velocity_threshold = 0;
|
int velocity_threshold = 0;
|
||||||
bool invert = false;
|
bool invert = false;
|
||||||
tinyxml2::XMLError attrError = gameButtonNode->QueryIntAttribute("vkey", &vKey);
|
tinyxml2::XMLError attrError = gameButtonNode->QueryIntAttribute("vkey", &vKey);
|
||||||
@@ -169,6 +170,7 @@ bool Config::addGame(Game &game) {
|
|||||||
gameButtonNode->QueryIntAttribute("analogtype", &analogType);
|
gameButtonNode->QueryIntAttribute("analogtype", &analogType);
|
||||||
gameButtonNode->QueryDoubleAttribute("debounce_up", &debounce_up);
|
gameButtonNode->QueryDoubleAttribute("debounce_up", &debounce_up);
|
||||||
gameButtonNode->QueryDoubleAttribute("debounce_down", &debounce_down);
|
gameButtonNode->QueryDoubleAttribute("debounce_down", &debounce_down);
|
||||||
|
gameButtonNode->QueryIntAttribute("bat_threshold", &bat_threshold);
|
||||||
gameButtonNode->QueryIntAttribute("velocity_threshold", &velocity_threshold);
|
gameButtonNode->QueryIntAttribute("velocity_threshold", &velocity_threshold);
|
||||||
gameButtonNode->QueryBoolAttribute("invert", &invert);
|
gameButtonNode->QueryBoolAttribute("invert", &invert);
|
||||||
if (attrError != tinyxml2::XMLError::XML_SUCCESS) {
|
if (attrError != tinyxml2::XMLError::XML_SUCCESS) {
|
||||||
@@ -180,6 +182,7 @@ bool Config::addGame(Game &game) {
|
|||||||
gameButtonNode->SetAttribute("devid", button->getDeviceIdentifier().c_str());
|
gameButtonNode->SetAttribute("devid", button->getDeviceIdentifier().c_str());
|
||||||
gameButtonNode->SetAttribute("debounce_up", debounce_up);
|
gameButtonNode->SetAttribute("debounce_up", debounce_up);
|
||||||
gameButtonNode->SetAttribute("debounce_down", debounce_down);
|
gameButtonNode->SetAttribute("debounce_down", debounce_down);
|
||||||
|
gameButtonNode->SetAttribute("bat_threshold", bat_threshold);
|
||||||
gameButtonNode->SetAttribute("velocity_threshold", velocity_threshold);
|
gameButtonNode->SetAttribute("velocity_threshold", velocity_threshold);
|
||||||
gameButtonNode->SetAttribute("invert", invert);
|
gameButtonNode->SetAttribute("invert", invert);
|
||||||
gameButtonsNode->InsertEndChild(gameButtonNode);
|
gameButtonsNode->InsertEndChild(gameButtonNode);
|
||||||
@@ -188,6 +191,7 @@ bool Config::addGame(Game &game) {
|
|||||||
button->setAnalogType((ButtonAnalogType) analogType);
|
button->setAnalogType((ButtonAnalogType) analogType);
|
||||||
button->setDebounceUp(debounce_up);
|
button->setDebounceUp(debounce_up);
|
||||||
button->setDebounceDown(debounce_down);
|
button->setDebounceDown(debounce_down);
|
||||||
|
button->setBatThreshold(bat_threshold);
|
||||||
button->setVelocityThreshold(velocity_threshold);
|
button->setVelocityThreshold(velocity_threshold);
|
||||||
button->setInvert(invert);
|
button->setInvert(invert);
|
||||||
if (devid) {
|
if (devid) {
|
||||||
@@ -207,6 +211,7 @@ bool Config::addGame(Game &game) {
|
|||||||
gameButtonNode->SetAttribute("analogtype", (int) it.getAnalogType());
|
gameButtonNode->SetAttribute("analogtype", (int) it.getAnalogType());
|
||||||
gameButtonNode->SetAttribute("debounce_up", it.getDebounceUp());
|
gameButtonNode->SetAttribute("debounce_up", it.getDebounceUp());
|
||||||
gameButtonNode->SetAttribute("debounce_down", it.getDebounceDown());
|
gameButtonNode->SetAttribute("debounce_down", it.getDebounceDown());
|
||||||
|
gameButtonNode->SetAttribute("bat_threshold", it.getBatThreshold());
|
||||||
gameButtonNode->SetAttribute("velocity_threshold", it.getVelocityThreshold());
|
gameButtonNode->SetAttribute("velocity_threshold", it.getVelocityThreshold());
|
||||||
gameButtonNode->SetAttribute("invert", it.getInvert());
|
gameButtonNode->SetAttribute("invert", it.getInvert());
|
||||||
gameButtonNode->SetAttribute("devid", it.getDeviceIdentifier().c_str());
|
gameButtonNode->SetAttribute("devid", it.getDeviceIdentifier().c_str());
|
||||||
@@ -432,6 +437,7 @@ bool Config::addGame(Game &game) {
|
|||||||
gameButtonNode->SetAttribute("analogtype", it.getAnalogType());
|
gameButtonNode->SetAttribute("analogtype", it.getAnalogType());
|
||||||
gameButtonNode->SetAttribute("debounce_up", it.getDebounceUp());
|
gameButtonNode->SetAttribute("debounce_up", it.getDebounceUp());
|
||||||
gameButtonNode->SetAttribute("debounce_down", it.getDebounceDown());
|
gameButtonNode->SetAttribute("debounce_down", it.getDebounceDown());
|
||||||
|
gameButtonNode->SetAttribute("bat_threshold", it.getBatThreshold());
|
||||||
gameButtonNode->SetAttribute("velocity_threshold", it.getVelocityThreshold());
|
gameButtonNode->SetAttribute("velocity_threshold", it.getVelocityThreshold());
|
||||||
gameButtonNode->SetAttribute("invert", it.getInvert());
|
gameButtonNode->SetAttribute("invert", it.getInvert());
|
||||||
gameButtonNode->SetAttribute("devid", it.getDeviceIdentifier().c_str());
|
gameButtonNode->SetAttribute("devid", it.getDeviceIdentifier().c_str());
|
||||||
@@ -535,6 +541,7 @@ bool Config::updateBinding(const Game &game, const Button &button, int alternati
|
|||||||
gameButtonNode->SetAttribute("analogtype", (int) button.getAnalogType());
|
gameButtonNode->SetAttribute("analogtype", (int) button.getAnalogType());
|
||||||
gameButtonNode->SetAttribute("debounce_up", button.getDebounceUp());
|
gameButtonNode->SetAttribute("debounce_up", button.getDebounceUp());
|
||||||
gameButtonNode->SetAttribute("debounce_down", button.getDebounceDown());
|
gameButtonNode->SetAttribute("debounce_down", button.getDebounceDown());
|
||||||
|
gameButtonNode->SetAttribute("bat_threshold", button.getBatThreshold());
|
||||||
gameButtonNode->SetAttribute("velocity_threshold", button.getVelocityThreshold());
|
gameButtonNode->SetAttribute("velocity_threshold", button.getVelocityThreshold());
|
||||||
gameButtonNode->SetAttribute("invert", button.getInvert());
|
gameButtonNode->SetAttribute("invert", button.getInvert());
|
||||||
gameButtonNode->SetAttribute("devid", button.getDeviceIdentifier().c_str());
|
gameButtonNode->SetAttribute("devid", button.getDeviceIdentifier().c_str());
|
||||||
@@ -551,6 +558,7 @@ bool Config::updateBinding(const Game &game, const Button &button, int alternati
|
|||||||
gameButtonNode->SetAttribute("analogtype", 0);
|
gameButtonNode->SetAttribute("analogtype", 0);
|
||||||
gameButtonNode->SetAttribute("debounce_up", 0.0);
|
gameButtonNode->SetAttribute("debounce_up", 0.0);
|
||||||
gameButtonNode->SetAttribute("debounce_down", 0.0);
|
gameButtonNode->SetAttribute("debounce_down", 0.0);
|
||||||
|
gameButtonNode->SetAttribute("bat_threshold", 0);
|
||||||
gameButtonNode->SetAttribute("velocity_threshold", 0);
|
gameButtonNode->SetAttribute("velocity_threshold", 0);
|
||||||
gameButtonNode->SetAttribute("invert", false);
|
gameButtonNode->SetAttribute("invert", false);
|
||||||
gameButtonNode->SetAttribute("devid", "");
|
gameButtonNode->SetAttribute("devid", "");
|
||||||
@@ -946,12 +954,14 @@ std::vector<Button> Config::getButtons(const std::string &gameName) {
|
|||||||
auto analogType = (int) BAT_NONE;
|
auto analogType = (int) BAT_NONE;
|
||||||
double debounce_up = 0.0;
|
double debounce_up = 0.0;
|
||||||
double debounce_down = 0.0;
|
double debounce_down = 0.0;
|
||||||
|
int bat_threshold = 0;
|
||||||
int velocity_threshold = 0;
|
int velocity_threshold = 0;
|
||||||
bool invert = false;
|
bool invert = false;
|
||||||
gameButtonNode->QueryIntAttribute("vkey", &vKey);
|
gameButtonNode->QueryIntAttribute("vkey", &vKey);
|
||||||
gameButtonNode->QueryIntAttribute("analogtype", &analogType);
|
gameButtonNode->QueryIntAttribute("analogtype", &analogType);
|
||||||
gameButtonNode->QueryDoubleAttribute("debounce_up", &debounce_up);
|
gameButtonNode->QueryDoubleAttribute("debounce_up", &debounce_up);
|
||||||
gameButtonNode->QueryDoubleAttribute("debounce_down", &debounce_down);
|
gameButtonNode->QueryDoubleAttribute("debounce_down", &debounce_down);
|
||||||
|
gameButtonNode->QueryIntAttribute("bat_threshold", &bat_threshold);
|
||||||
gameButtonNode->QueryIntAttribute("velocity_threshold", &velocity_threshold);
|
gameButtonNode->QueryIntAttribute("velocity_threshold", &velocity_threshold);
|
||||||
gameButtonNode->QueryBoolAttribute("invert", &invert);
|
gameButtonNode->QueryBoolAttribute("invert", &invert);
|
||||||
const char *devid = gameButtonNode->Attribute("devid");
|
const char *devid = gameButtonNode->Attribute("devid");
|
||||||
@@ -966,6 +976,7 @@ std::vector<Button> Config::getButtons(const std::string &gameName) {
|
|||||||
alt.setAnalogType((ButtonAnalogType) analogType);
|
alt.setAnalogType((ButtonAnalogType) analogType);
|
||||||
alt.setDebounceUp(debounce_up);
|
alt.setDebounceUp(debounce_up);
|
||||||
alt.setDebounceDown(debounce_down);
|
alt.setDebounceDown(debounce_down);
|
||||||
|
alt.setBatThreshold(bat_threshold);
|
||||||
alt.setVelocityThreshold(velocity_threshold);
|
alt.setVelocityThreshold(velocity_threshold);
|
||||||
alt.setInvert(invert);
|
alt.setInvert(invert);
|
||||||
if (devid) {
|
if (devid) {
|
||||||
@@ -984,6 +995,7 @@ std::vector<Button> Config::getButtons(const std::string &gameName) {
|
|||||||
button.setAnalogType((ButtonAnalogType) analogType);
|
button.setAnalogType((ButtonAnalogType) analogType);
|
||||||
button.setDebounceUp(debounce_up);
|
button.setDebounceUp(debounce_up);
|
||||||
button.setDebounceDown(debounce_down);
|
button.setDebounceDown(debounce_down);
|
||||||
|
button.setBatThreshold(bat_threshold);
|
||||||
button.setVelocityThreshold(velocity_threshold);
|
button.setVelocityThreshold(velocity_threshold);
|
||||||
button.setInvert(invert);
|
button.setInvert(invert);
|
||||||
if (devid) {
|
if (devid) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace overlay::windows {
|
|||||||
el->SetAttribute("invert", entry.invert);
|
el->SetAttribute("invert", entry.invert);
|
||||||
el->SetAttribute("debounce_up", entry.debounce_up);
|
el->SetAttribute("debounce_up", entry.debounce_up);
|
||||||
el->SetAttribute("debounce_down", entry.debounce_down);
|
el->SetAttribute("debounce_down", entry.debounce_down);
|
||||||
|
el->SetAttribute("bat_threshold", entry.bat_threshold);
|
||||||
el->SetAttribute("velocity_threshold", entry.velocity_threshold);
|
el->SetAttribute("velocity_threshold", entry.velocity_threshold);
|
||||||
parent->InsertEndChild(el);
|
parent->InsertEndChild(el);
|
||||||
}
|
}
|
||||||
@@ -49,6 +50,10 @@ namespace overlay::windows {
|
|||||||
el->QueryIntAttribute("velocity_threshold", &vel);
|
el->QueryIntAttribute("velocity_threshold", &vel);
|
||||||
entry.velocity_threshold = (unsigned short)vel;
|
entry.velocity_threshold = (unsigned short)vel;
|
||||||
|
|
||||||
|
int bat = 0;
|
||||||
|
el->QueryIntAttribute("bat_threshold", &bat);
|
||||||
|
entry.bat_threshold = bat;
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,14 +66,16 @@ static HRESULT STDAPICALLTYPE CoCreateInstance_hook(
|
|||||||
if (FAILED(ret)) {
|
if (FAILED(ret)) {
|
||||||
if (IsEqualCLSID(rclsid, CLSID_MMDeviceEnumerator)) {
|
if (IsEqualCLSID(rclsid, CLSID_MMDeviceEnumerator)) {
|
||||||
log_warning("audio", "CoCreateInstance failed for CLSID_MMDeviceEnumerator, hr={}", FMT_HRESULT(ret));
|
log_warning("audio", "CoCreateInstance failed for CLSID_MMDeviceEnumerator, hr={}", FMT_HRESULT(ret));
|
||||||
}
|
} else if (IsEqualCLSID(rclsid, CLSID_DirectSoundI3DL2ReverbDMO)) {
|
||||||
|
// deal with reverb DMO missing from dsdmo.dll
|
||||||
// Windows 11 KB5052093 issue - reverb DMO went missing from dsdmo.dll (fails with 0x80040154)
|
// it usually fails with 0x80040154 (REGDB_E_CLASSNOTREG), but we have also seen 0x8007007e (ERROR_MOD_NOT_FOUND)
|
||||||
if (IsEqualCLSID(rclsid, CLSID_DirectSoundI3DL2ReverbDMO) && ret == (HRESULT)0x80040154) {
|
static std::once_flag printed;
|
||||||
log_warning(
|
std::call_once(printed, [ret]() {
|
||||||
"audio",
|
log_warning(
|
||||||
"CoCreateInstance for CLSID_DirectSoundI3DL2ReverbDMO failed with 0x80040154, swap with CLSID_DirectSoundWavesReverbDMO "
|
"audio",
|
||||||
"(workaround for Windows 11 KB5052093 issue); REVERB EX replaced with REVERB");
|
"CoCreateInstance for CLSID_DirectSoundI3DL2ReverbDMO failed with {}, swap with CLSID_DirectSoundWavesReverbDMO...",
|
||||||
|
FMT_HRESULT(ret));
|
||||||
|
});
|
||||||
ret = CoCreateInstance_orig(CLSID_DirectSoundWavesReverbDMO, pUnkOuter, dwClsContext, riid, ppv);
|
ret = CoCreateInstance_orig(CLSID_DirectSoundWavesReverbDMO, pUnkOuter, dwClsContext, riid, ppv);
|
||||||
if (FAILED(ret)) {
|
if (FAILED(ret)) {
|
||||||
log_warning("audio", "CoCreateInstance(CLSID_DirectSoundWavesReverbDMO...) failed, hr={}", FMT_HRESULT(ret));
|
log_warning("audio", "CoCreateInstance(CLSID_DirectSoundWavesReverbDMO...) failed, hr={}", FMT_HRESULT(ret));
|
||||||
|
|||||||
@@ -2364,9 +2364,9 @@ int main_implementation(int argc, char *argv[]) {
|
|||||||
// layeredfs
|
// layeredfs
|
||||||
if (fileutils::dir_exists("data_mods") &&
|
if (fileutils::dir_exists("data_mods") &&
|
||||||
GetModuleHandleA("ifs_hook.dll") == nullptr) {
|
GetModuleHandleA("ifs_hook.dll") == nullptr) {
|
||||||
log_warning("launcher", "data_mods directory found, but ifs_hook.dll is not present; mods will not load");
|
log_warning("launcher", "data_mods directory found, but ifs_hook.dll is not loaded; mods will not load");
|
||||||
deferredlogs::defer_error_messages({
|
deferredlogs::defer_error_messages({
|
||||||
"data_mods directory was found, but ifs_hook.dll is not present",
|
"data_mods directory was found, but ifs_hook.dll is not loaded",
|
||||||
" your mods will not load",
|
" your mods will not load",
|
||||||
" to fix this, download ifs_layeredfs and add it as a DLL hook (-k)",
|
" to fix this, download ifs_layeredfs and add it as a DLL hook (-k)",
|
||||||
" https://github.com/mon/ifs_layeredfs"
|
" https://github.com/mon/ifs_layeredfs"
|
||||||
|
|||||||
@@ -1063,6 +1063,7 @@ namespace overlay::windows {
|
|||||||
button->setAnalogType(BAT_NONE);
|
button->setAnalogType(BAT_NONE);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
button->setInvert(false);
|
button->setInvert(false);
|
||||||
button->setLastState(GameAPI::Buttons::BUTTON_NOT_PRESSED);
|
button->setLastState(GameAPI::Buttons::BUTTON_NOT_PRESSED);
|
||||||
@@ -1265,6 +1266,7 @@ namespace overlay::windows {
|
|||||||
button->setAnalogType(bat);
|
button->setAnalogType(bat);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
::Config::getInstance().updateBinding(
|
::Config::getInstance().updateBinding(
|
||||||
games_list[games_selected], *button,
|
games_list[games_selected], *button,
|
||||||
@@ -1313,6 +1315,7 @@ namespace overlay::windows {
|
|||||||
button->setAnalogType(buffer[0]);
|
button->setAnalogType(buffer[0]);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
::Config::getInstance().updateBinding(
|
::Config::getInstance().updateBinding(
|
||||||
games_list[games_selected], *button,
|
games_list[games_selected], *button,
|
||||||
@@ -1360,6 +1363,7 @@ namespace overlay::windows {
|
|||||||
button->setAnalogType(BAT_NONE);
|
button->setAnalogType(BAT_NONE);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
// same idea as setMidiVKey - keep velocity threshold consistent
|
// same idea as setMidiVKey - keep velocity threshold consistent
|
||||||
button->setVelocityThreshold(
|
button->setVelocityThreshold(
|
||||||
device->midiInfo->v2_velocity_threshold[button->getVKey()]);
|
device->midiInfo->v2_velocity_threshold[button->getVKey()]);
|
||||||
@@ -1385,6 +1389,7 @@ namespace overlay::windows {
|
|||||||
button->setAnalogType(BAT_MIDI_CTRL_PRECISION);
|
button->setAnalogType(BAT_MIDI_CTRL_PRECISION);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
::Config::getInstance().updateBinding(
|
::Config::getInstance().updateBinding(
|
||||||
games_list[games_selected], *button,
|
games_list[games_selected], *button,
|
||||||
@@ -1411,6 +1416,7 @@ namespace overlay::windows {
|
|||||||
button->setAnalogType(BAT_MIDI_CTRL_SINGLE);
|
button->setAnalogType(BAT_MIDI_CTRL_SINGLE);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
::Config::getInstance().updateBinding(
|
::Config::getInstance().updateBinding(
|
||||||
games_list[games_selected], *button,
|
games_list[games_selected], *button,
|
||||||
@@ -1437,6 +1443,7 @@ namespace overlay::windows {
|
|||||||
button->setAnalogType(BAT_MIDI_CTRL_ONOFF);
|
button->setAnalogType(BAT_MIDI_CTRL_ONOFF);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
::Config::getInstance().updateBinding(
|
::Config::getInstance().updateBinding(
|
||||||
games_list[games_selected], *button,
|
games_list[games_selected], *button,
|
||||||
@@ -1462,6 +1469,7 @@ namespace overlay::windows {
|
|||||||
button->setAnalogType(BAT_MIDI_PITCH_DOWN);
|
button->setAnalogType(BAT_MIDI_PITCH_DOWN);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
::Config::getInstance().updateBinding(
|
::Config::getInstance().updateBinding(
|
||||||
games_list[games_selected], *button,
|
games_list[games_selected], *button,
|
||||||
@@ -1482,6 +1490,7 @@ namespace overlay::windows {
|
|||||||
button->setAnalogType(BAT_MIDI_PITCH_UP);
|
button->setAnalogType(BAT_MIDI_PITCH_UP);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
::Config::getInstance().updateBinding(
|
::Config::getInstance().updateBinding(
|
||||||
games_list[games_selected], *button,
|
games_list[games_selected], *button,
|
||||||
@@ -1511,6 +1520,7 @@ namespace overlay::windows {
|
|||||||
button->setAnalogType(BAT_NONE);
|
button->setAnalogType(BAT_NONE);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
::Config::getInstance().updateBinding(
|
::Config::getInstance().updateBinding(
|
||||||
games_list[games_selected], *button,
|
games_list[games_selected], *button,
|
||||||
@@ -1635,6 +1645,7 @@ namespace overlay::windows {
|
|||||||
button->setVKey(vKey);
|
button->setVKey(vKey);
|
||||||
button->setDebounceUp(0.0);
|
button->setDebounceUp(0.0);
|
||||||
button->setDebounceDown(0.0);
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
::Config::getInstance().updateBinding(
|
::Config::getInstance().updateBinding(
|
||||||
games_list[games_selected], *button,
|
games_list[games_selected], *button,
|
||||||
@@ -1686,6 +1697,9 @@ namespace overlay::windows {
|
|||||||
button->setDeviceIdentifier(device.name);
|
button->setDeviceIdentifier(device.name);
|
||||||
// reset controls when switching devices
|
// reset controls when switching devices
|
||||||
button->setAnalogType(ButtonAnalogType::BAT_NONE);
|
button->setAnalogType(ButtonAnalogType::BAT_NONE);
|
||||||
|
button->setDebounceUp(0.0);
|
||||||
|
button->setDebounceDown(0.0);
|
||||||
|
button->setBatThreshold(0);
|
||||||
button->setVelocityThreshold(0);
|
button->setVelocityThreshold(0);
|
||||||
button->setVKey(0);
|
button->setVKey(0);
|
||||||
button->setInvert(false);
|
button->setInvert(false);
|
||||||
@@ -2050,11 +2064,48 @@ namespace overlay::windows {
|
|||||||
|
|
||||||
// invert
|
// invert
|
||||||
bool invert = button->getInvert();
|
bool invert = button->getInvert();
|
||||||
if (ImGui::Checkbox("Invert", &invert)) {
|
if (ImGui::Checkbox("Invert Resulting Value", &invert)) {
|
||||||
button->setInvert(invert);
|
button->setInvert(invert);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bat threshold
|
||||||
|
if (device->type == rawinput::HID &&
|
||||||
|
(button->getAnalogType() == BAT_POSITIVE || button->getAnalogType() == BAT_NEGATIVE)) {
|
||||||
|
int bat_threshold = button->getBatThreshold();
|
||||||
|
|
||||||
|
bool is_active = (bat_threshold > 0);
|
||||||
|
if (ImGui::Checkbox("Custom Analog Threshold", &is_active)) {
|
||||||
|
if (!is_active) {
|
||||||
|
button->setBatThreshold(0);
|
||||||
|
} else if (bat_threshold == 0) {
|
||||||
|
button->setBatThreshold(60);
|
||||||
|
}
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::HelpMarker(
|
||||||
|
"Assuming that 50% is the center, value exceeding 60% triggers the button by default. "
|
||||||
|
"With this option, you can customize the trigger threshold.\n\n"
|
||||||
|
"Setting this to 51% means tiny movements will trigger the button (small deadzone), "
|
||||||
|
"while setting this to 99% means the button will only trigger at maximum value (large deadzone).\n\n"
|
||||||
|
"Setting this to below 50% adjusts the neutral / center position.");
|
||||||
|
|
||||||
|
if (is_active) {
|
||||||
|
if (ImGui::SliderInt(
|
||||||
|
"Analog Threshold",
|
||||||
|
&bat_threshold,
|
||||||
|
1, 99,
|
||||||
|
"%d%%",
|
||||||
|
ImGuiSliderFlags_AlwaysClamp)) {
|
||||||
|
button->setBatThreshold(bat_threshold);
|
||||||
|
}
|
||||||
|
if (ImGui::IsItemDeactivatedAfterEdit()) {
|
||||||
|
dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// state display
|
// state display
|
||||||
ImGui::TextUnformatted("");
|
ImGui::TextUnformatted("");
|
||||||
if (device != nullptr && device->type == rawinput::MIDI) {
|
if (device != nullptr && device->type == rawinput::MIDI) {
|
||||||
@@ -5283,6 +5334,7 @@ namespace overlay::windows {
|
|||||||
btn.setInvert(entry->invert);
|
btn.setInvert(entry->invert);
|
||||||
btn.setDebounceUp(entry->debounce_up);
|
btn.setDebounceUp(entry->debounce_up);
|
||||||
btn.setDebounceDown(entry->debounce_down);
|
btn.setDebounceDown(entry->debounce_down);
|
||||||
|
btn.setBatThreshold(entry->bat_threshold);
|
||||||
btn.setVelocityThreshold(entry->velocity_threshold);
|
btn.setVelocityThreshold(entry->velocity_threshold);
|
||||||
::Config::getInstance().updateBinding(game, btn, -1);
|
::Config::getInstance().updateBinding(game, btn, -1);
|
||||||
} else {
|
} else {
|
||||||
@@ -5293,6 +5345,7 @@ namespace overlay::windows {
|
|||||||
alt_btn.setInvert(entry->invert);
|
alt_btn.setInvert(entry->invert);
|
||||||
alt_btn.setDebounceUp(entry->debounce_up);
|
alt_btn.setDebounceUp(entry->debounce_up);
|
||||||
alt_btn.setDebounceDown(entry->debounce_down);
|
alt_btn.setDebounceDown(entry->debounce_down);
|
||||||
|
alt_btn.setBatThreshold(entry->bat_threshold);
|
||||||
alt_btn.setVelocityThreshold(entry->velocity_threshold);
|
alt_btn.setVelocityThreshold(entry->velocity_threshold);
|
||||||
alt_btn.setTemporary(true);
|
alt_btn.setTemporary(true);
|
||||||
btn.getAlternatives().push_back(alt_btn);
|
btn.getAlternatives().push_back(alt_btn);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace overlay::windows {
|
|||||||
bool invert = false;
|
bool invert = false;
|
||||||
double debounce_up = 0.0;
|
double debounce_up = 0.0;
|
||||||
double debounce_down = 0.0;
|
double debounce_down = 0.0;
|
||||||
|
int bat_threshold = 0;
|
||||||
unsigned short velocity_threshold = 0;
|
unsigned short velocity_threshold = 0;
|
||||||
|
|
||||||
bool is_naive() const { return device_identifier.empty() && vKey != INVALID_VKEY; }
|
bool is_naive() const { return device_identifier.empty() && vKey != INVALID_VKEY; }
|
||||||
@@ -31,6 +32,7 @@ namespace overlay::windows {
|
|||||||
e.invert = btn.getInvert();
|
e.invert = btn.getInvert();
|
||||||
e.debounce_up = btn.getDebounceUp();
|
e.debounce_up = btn.getDebounceUp();
|
||||||
e.debounce_down = btn.getDebounceDown();
|
e.debounce_down = btn.getDebounceDown();
|
||||||
|
e.bat_threshold = btn.getBatThreshold();
|
||||||
e.velocity_threshold = btn.getVelocityThreshold();
|
e.velocity_threshold = btn.getVelocityThreshold();
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "avs/game.h"
|
#include "avs/game.h"
|
||||||
#include "games/iidx/iidx.h"
|
#include "games/iidx/iidx.h"
|
||||||
|
#include "games/popn/popn.h"
|
||||||
#include "misc/eamuse.h"
|
#include "misc/eamuse.h"
|
||||||
#include "util/logging.h"
|
#include "util/logging.h"
|
||||||
#include "overlay/imgui/extensions.h"
|
#include "overlay/imgui/extensions.h"
|
||||||
@@ -42,6 +43,8 @@ namespace overlay::windows {
|
|||||||
void Keypad::build_content() {
|
void Keypad::build_content() {
|
||||||
if (avs::game::is_model("LDJ") && games::iidx::TDJ_MODE) {
|
if (avs::game::is_model("LDJ") && games::iidx::TDJ_MODE) {
|
||||||
build_tdj_keypad();
|
build_tdj_keypad();
|
||||||
|
} else if (games::popn::is_pikapika_model()) {
|
||||||
|
build_popn_pika_keypad();
|
||||||
} else {
|
} else {
|
||||||
build_keypad();
|
build_keypad();
|
||||||
}
|
}
|
||||||
@@ -132,4 +135,26 @@ namespace overlay::windows {
|
|||||||
eamuse_set_keypad_overrides_overlay(this->unit, 0);
|
eamuse_set_keypad_overrides_overlay(this->unit, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Keypad::build_popn_pika_keypad() {
|
||||||
|
ImGui::AlignTextToFramePadding();
|
||||||
|
ImGui::TextDisabled("Keypad disabled in Pop'n Pikapika model!\nUse subscreen overlay.");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::WarnMarker(
|
||||||
|
nullptr,
|
||||||
|
"Pop'n Music Pikapika cabinets do not have any keypads; they use the subscreen.\n\n"
|
||||||
|
"Fullscreen mode: bind a key in Overlay tab, and press it in game to show the subscreen, "
|
||||||
|
"then use your mouse to click. Page Up button is the default binding.\n\n"
|
||||||
|
"Windowed mode: look for the second window in the taskbar (or ALT+TAB).\n\n"
|
||||||
|
"Windowed mode with -popnnosub: bring up the subscreen overlay (default Page Up).\n\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
|
||||||
|
if (ImGui::Button("Insert Card")) {
|
||||||
|
eamuse_set_keypad_overrides_overlay(this->unit, 1 << EAM_IO_INSERT);
|
||||||
|
} else {
|
||||||
|
eamuse_set_keypad_overrides_overlay(this->unit, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace overlay::windows {
|
|||||||
size_t unit = 0;
|
size_t unit = 0;
|
||||||
void build_keypad();
|
void build_keypad();
|
||||||
void build_tdj_keypad();
|
void build_tdj_keypad();
|
||||||
|
void build_popn_pika_keypad();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -605,16 +605,6 @@ void rawinput::RawInputManager::devices_scan_rawinput(RAWINPUTDEVICELIST *device
|
|||||||
value_caps.LogicalMax = 255;
|
value_caps.LogicalMax = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fix min and max values
|
|
||||||
if (value_caps.BitSize > 0 && value_caps.BitSize <= sizeof(value_caps.LogicalMin) * 8) {
|
|
||||||
auto shift_size = sizeof(value_caps.LogicalMin) * 8 - value_caps.BitSize + 1;
|
|
||||||
auto mask = ((uint64_t) 1 << value_caps.BitSize) - 1;
|
|
||||||
value_caps.LogicalMin &= mask;
|
|
||||||
value_caps.LogicalMin <<= shift_size;
|
|
||||||
value_caps.LogicalMin >>= shift_size;
|
|
||||||
value_caps.LogicalMax &= mask;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix up hat switch to initially report as neutral position
|
// fix up hat switch to initially report as neutral position
|
||||||
if (value_caps.UsagePage == 0x1 && value_caps.Range.UsageMin == 0x39) {
|
if (value_caps.UsagePage == 0x1 && value_caps.Range.UsageMin == 0x39) {
|
||||||
value_states[value_cap_num] = -1.f;
|
value_states[value_cap_num] = -1.f;
|
||||||
@@ -1914,15 +1904,6 @@ LRESULT CALLBACK rawinput::RawInputManager::input_wnd_proc(
|
|||||||
LONG value_min = value_caps.LogicalMin;
|
LONG value_min = value_caps.LogicalMin;
|
||||||
LONG value_max = value_caps.LogicalMax;
|
LONG value_max = value_caps.LogicalMax;
|
||||||
|
|
||||||
// fix sign bits for signed values
|
|
||||||
if (value_caps.LogicalMin < 0 &&
|
|
||||||
value_caps.BitSize > 0 &&
|
|
||||||
value_caps.BitSize <= sizeof(value_caps.LogicalMin) * 8) {
|
|
||||||
auto shift_size = sizeof(value_caps.LogicalMin) * 8 - value_caps.BitSize + 1;
|
|
||||||
value_raw <<= shift_size;
|
|
||||||
value_raw >>= shift_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
float value;
|
float value;
|
||||||
// 0x1 == generic desktop, 0x39 == hat switch
|
// 0x1 == generic desktop, 0x39 == hat switch
|
||||||
if (value_caps.UsagePage == 0x1 && value_caps.Range.UsageMin == 0x39) {
|
if (value_caps.UsagePage == 0x1 && value_caps.Range.UsageMin == 0x39) {
|
||||||
@@ -1935,6 +1916,16 @@ LRESULT CALLBACK rawinput::RawInputManager::input_wnd_proc(
|
|||||||
value = -1.f;
|
value = -1.f;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// fix sign bits for signed values
|
||||||
|
if (value_caps.LogicalMin < 0 &&
|
||||||
|
0 < value_caps.BitSize && value_caps.BitSize < 32) {
|
||||||
|
|
||||||
|
ULONG raw = static_cast<ULONG>(value_raw) & ((1u << value_caps.BitSize) - 1u);
|
||||||
|
const ULONG sign_bit = 1u << (value_caps.BitSize - 1);
|
||||||
|
value_raw = static_cast<LONG>((raw ^ sign_bit) - sign_bit);
|
||||||
|
}
|
||||||
|
|
||||||
// automatic calibration
|
// automatic calibration
|
||||||
if (value_raw < value_min) {
|
if (value_raw < value_min) {
|
||||||
value_caps.LogicalMin = value_raw;
|
value_caps.LogicalMin = value_raw;
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ namespace rawinput::touch {
|
|||||||
|
|
||||||
// check type
|
// check type
|
||||||
if (device->type != HID) {
|
if (device->type != HID) {
|
||||||
log_fatal("rawinput", "touch update called on non HID device");
|
log_warning("rawinput", "touch update called on non HID device");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user