Compare commits

...

3 Commits

Author SHA1 Message Date
bicarus-dev 4e86cb16a2 cfg: tweaks to analog binding UI (#434)
## Link to GitHub Issue, if one exists
n/a

## Description of change
Add the raw device handle string to tooltip.
Add `Reset` button that clears all values.

## Testing
manual testing
2025-12-06 01:47:00 -08:00
bicarus-dev 76f401de95 iidx: rework wasapi/asio detection for iidx33+ (#433)
## Link to GitHub Issue, if one exists
Fixes #432 

## Description of change
Newer versions of iidx33+ reintroduces `SOUND_OUTPUT_DEVICE` env var.
iidx module must account for its return

## Testing
2025-12-05 15:33:09 -08:00
bicarus-dev 5947779502 iidx,sdvx: warn user when using -monitor with TDJ/UFC mode (#431)
## Link to GitHub Issue, if one exists
#345 

## Description of change
Warn user via warning message in log + auto-troubleshooter entry when
-monitor option is used in full screen with TDJ and UFC mode.

This covers yet another case where TDJ subscreen does not respond to
mouse clicks (because the game expects them to come through the primary
display). For UFC, -monitor usually results in a failure to create DX
adapter.

## Testing
Manual verification with TDJ/UFC modes and two monitors.
2025-12-04 21:57:36 -08:00
4 changed files with 96 additions and 19 deletions
+8 -3
View File
@@ -82,18 +82,23 @@ public:
return this->index != 0xFF; return this->index != 0xFF;
} }
inline void clearBindings() { inline void resetValues() {
device_identifier = "";
index = 0xFF;
setSensitivity(1.f); setSensitivity(1.f);
setDeadzone(0.f); setDeadzone(0.f);
invert = false; invert = false;
smoothing = false; smoothing = false;
deadzone_mirror = false;
setMultiplier(1); setMultiplier(1);
setRelativeMode(false); setRelativeMode(false);
setDelayBufferDepth(0); setDelayBufferDepth(0);
} }
inline void clearBindings() {
device_identifier = "";
index = 0xFF;
resetValues();
}
inline const std::string &getName() const { inline const std::string &getName() const {
return this->name; return this->name;
} }
+42 -15
View File
@@ -451,7 +451,7 @@ namespace games::iidx {
"!!! please do the following instead: !!!\n" "!!! please do the following instead: !!!\n"
"!!! !!!\n" "!!! !!!\n"
"!!! Revert your changes to XML file so it says !!!\n" "!!! Revert your changes to XML file so it says !!!\n"
"!!! <model __type=\"str\">LDJ</model> !!!\n" "!!! <model __type=\"str\">LDJ</model> !!!\n"
"!!! !!!\n" "!!! !!!\n"
"!!! In SpiceCfg, enable 'IIDX TDJ Mode' or provide -iidxtdj flag !!!\n" "!!! In SpiceCfg, enable 'IIDX TDJ Mode' or provide -iidxtdj flag !!!\n"
"!!! in command line !!!\n" "!!! in command line !!!\n"
@@ -463,6 +463,32 @@ namespace games::iidx {
log_fatal("iidx", "BAD MODEL NAME ERROR - TDJ specified, must be LDJ instead"); log_fatal("iidx", "BAD MODEL NAME ERROR - TDJ specified, must be LDJ instead");
} }
// check -monitor + TDJ mode
if (!GRAPHICS_WINDOWED &&
options->at(launcher::Options::DisplayAdapter).is_active() &&
TDJ_MODE) {
log_warning(
"iidx",
"\n\n!!! using -monitor option with TDJ is NOT recommended due to known !!!\n"
"!!! compatibility issues with the game !!!\n"
"!!! !!!\n"
"!!! * game may launch in wrong resolution or refresh rate !!!\n"
"!!! * touch / mouse input may stop working in subscreen / overlay !!!\n"
"!!! !!!\n"
"!!! recommendation is to NOT use -monitor and instead set the !!!\n"
"!!! primary monitor in Windows settings before launching the game !!!\n\n"
);
deferredlogs::defer_error_messages({
"-monitor option is NOT recommended when running with TDJ mode",
" due to known compatibility issues with the game:",
" * game may launch in wrong resolution or refresh rate",
" * touch / mouse input may stop working in subscreen / overlay",
" recommended fix is to NOT use -monitor and instead set the primary",
" monitor in Windows settings before launching the game"
});
}
} }
void IIDXGame::detach() { void IIDXGame::detach() {
@@ -787,7 +813,15 @@ namespace games::iidx {
// <=24 : 32-bit only // <=24 : 32-bit only
// 25-26: has neither (no patch needed - WASAPI Exclusive by default) // 25-26: has neither (no patch needed - WASAPI Exclusive by default)
// 27-30: has both (envvar will be respected, ASIO or WASAPI) // 27-30: has both (envvar will be respected, ASIO or WASAPI)
// 31+: only has XONAR (ASIO by default, signature patch can be used to force WASAPI - for now) // 31-32: only has XONAR (ASIO by default, signature patch can be used to force WASAPI - for now)
// 33 : early versions only have XONAR, but later datecodes have both; SOUND_OUTPUT_DEVICE
// returned and it works again when set as env var
log_info(
"iidx",
"has_SOUND_OUTPUT_DEVICE: {}, has_XONAR_SOUND_CARD: {}",
(has_SOUND_OUTPUT_DEVICE != 0),
(has_XONAR_SOUND_CARD != 0));
if (!has_SOUND_OUTPUT_DEVICE && !has_XONAR_SOUND_CARD) { if (!has_SOUND_OUTPUT_DEVICE && !has_XONAR_SOUND_CARD) {
// iidx 25-26 // iidx 25-26
@@ -795,16 +829,10 @@ namespace games::iidx {
return; return;
} }
if (has_SOUND_OUTPUT_DEVICE && has_XONAR_SOUND_CARD) { // if the game doesn't accept SOUND_OUTPUT_DEVICE, patch game to force wasapi
// iidx 27-30 if (!has_SOUND_OUTPUT_DEVICE &&
log_info("iidx", "This game accepts SOUND_OUTPUT_DEVICE environment variable"); SOUND_OUTPUT_DEVICE_IN_EFFECT.has_value() &&
return; SOUND_OUTPUT_DEVICE_IN_EFFECT.value() == "wasapi") {
}
log_info("iidx", "This game supports ASIO but does not accept SOUND_OUTPUT_DEVICE environment variable");
// patch game to force wasapi
if (SOUND_OUTPUT_DEVICE_IN_EFFECT.has_value() && SOUND_OUTPUT_DEVICE_IN_EFFECT.value() == "wasapi") {
intptr_t result = replace_pattern( intptr_t result = replace_pattern(
avs::game::DLL_INSTANCE, avs::game::DLL_INSTANCE,
"FF5008E8??????FF83780803740D", "FF5008E8??????FF83780803740D",
@@ -822,8 +850,6 @@ namespace games::iidx {
"Successfully forced WASAPI as audio engine using signature matching @ 0x{:x}.", "Successfully forced WASAPI as audio engine using signature matching @ 0x{:x}.",
result); result);
} }
} else {
log_info("iidx", "Not applying force wasapi patch; game will use ASIO");
} }
// patch iidx32+ for asio compatibility // patch iidx32+ for asio compatibility
@@ -831,7 +857,8 @@ namespace games::iidx {
// the patch is only really needed for (some) non-XONAR devices but since people sometimes disguise // the patch is only really needed for (some) non-XONAR devices but since people sometimes disguise
// other devices as a XONAR, don't check for the exact string (common ASIO workaround for INF) // other devices as a XONAR, don't check for the exact string (common ASIO workaround for INF)
if (avs::game::is_ext(2024090100, MAXINT) && if (avs::game::is_ext(2024090100, MAXINT) &&
!(SOUND_OUTPUT_DEVICE_IN_EFFECT.has_value() && SOUND_OUTPUT_DEVICE_IN_EFFECT.value() == "wasapi")) { !(SOUND_OUTPUT_DEVICE_IN_EFFECT.has_value() &&
SOUND_OUTPUT_DEVICE_IN_EFFECT.value() == "wasapi")) {
// in iidx32 final: // in iidx32 final:
// ff 50 08 call QWORD PTR [rax+0x8] ; ASIO instance AddRef // ff 50 08 call QWORD PTR [rax+0x8] ; ASIO instance AddRef
+34 -1
View File
@@ -4,6 +4,7 @@
#include "avs/game.h" #include "avs/game.h"
#include "games/shared/lcdhandle.h" #include "games/shared/lcdhandle.h"
#include "games/io.h"
#include "hooks/audio/audio.h" #include "hooks/audio/audio.h"
#include "hooks/graphics/graphics.h" #include "hooks/graphics/graphics.h"
#include "hooks/devicehook.h" #include "hooks/devicehook.h"
@@ -12,6 +13,7 @@
#include "hooks/powrprof.h" #include "hooks/powrprof.h"
#include "hooks/sleephook.h" #include "hooks/sleephook.h"
#include "hooks/winuser.h" #include "hooks/winuser.h"
#include "launcher/options.h"
#include "touch/touch.h" #include "touch/touch.h"
#include "util/deferlog.h" #include "util/deferlog.h"
#include "util/detour.h" #include "util/detour.h"
@@ -290,7 +292,38 @@ namespace games::sdvx {
log_fatal( log_fatal(
"sdvx", "sdvx",
"BAD MODEL NAME ERROR - model name set to UFC, must be KFC instead"); "BAD MODEL NAME ERROR - model name set to UFC, must be KFC instead");
} }
#ifdef SPICE64 // SDVX5+ specific code
bool isValkyrieCabinetMode = avs::game::SPEC[0] == 'G' || avs::game::SPEC[0] == 'H';
auto options = games::get_options(eamuse_get_game());
// check -monitor + UFC mode
if (!GRAPHICS_WINDOWED &&
options->at(launcher::Options::DisplayAdapter).is_active() &&
isValkyrieCabinetMode) {
log_warning(
"sdvx",
"\n\n!!! using -monitor option with VM mode is NOT recommended due to !!!\n"
"!!! known compatibility issues with the game !!!\n"
"!!! !!!\n"
"!!! * game may launch in wrong resolution or refresh rate !!!\n"
"!!! * touch / mouse input may stop working in subscreen / overlay !!!\n"
"!!! !!!\n"
"!!! recommendation is to NOT use -monitor and instead set the !!!\n"
"!!! primary monitor in Windows settings before launching the game !!!\n\n"
);
deferredlogs::defer_error_messages({
"-monitor option is NOT recommended when running with Valkyrie mode",
" due to known compatibility issues with the game:",
" * game may launch in wrong resolution or refresh rate",
" * touch / mouse input may stop working in subscreen / overlay",
" recommended fix is to NOT use -monitor and instead set the primary",
" monitor in Windows settings before launching the game"
});
}
#endif
} }
void SDVXGame::attach() { void SDVXGame::attach() {
+12
View File
@@ -1727,6 +1727,13 @@ namespace overlay::windows {
std::vector<int> analogs_midi_indices; std::vector<int> analogs_midi_indices;
if (this->analogs_devices_selected >= 0) { if (this->analogs_devices_selected >= 0) {
auto device = this->analogs_devices.at(this->analogs_devices_selected); auto device = this->analogs_devices.at(this->analogs_devices_selected);
// add a tooltip to devices selector
if (!device->name.empty()) {
ImGui::SameLine();
ImGui::HelpMarker(device->name.c_str());
}
switch (device->type) { switch (device->type) {
case rawinput::MOUSE: { case rawinput::MOUSE: {
@@ -2036,6 +2043,11 @@ namespace overlay::windows {
ImGui::CloseCurrentPopup(); ImGui::CloseCurrentPopup();
} }
ImGui::SameLine();
if (ImGui::Button("Reset")) {
analog.resetValues();
}
// clean up // clean up
ImGui::EndPopup(); ImGui::EndPopup();
} }