Compare commits

...

22 Commits

Author SHA1 Message Date
sp2xdev c96f4330d2 Merge branch 'main' of https://github.com/spice2x/spice2x.github.io 2025-08-21 08:29:33 -07:00
sp2xdev 26a2a0f481 update changelog 2025-08-21 08:29:27 -07:00
bicarus-dev 11b9790e6c cfg: rearrange options (#357)
## Link to GitHub Issue, if one exists
n/a

## Description of change
In an attempt to make the Options tab smaller, move out more options to
advanced / development tabs.

## Testing
n/a
2025-08-19 02:41:56 -07:00
bicarus-dev 1dfcf8c087 ddr: check for common DLL errors (#355)
## Link to GitHub Issue, if one exists
#345 

## Description of change
Check if the path to codecs directory contains non-ASCII characters, and
display a giant warning. This is to help with troubleshooting, since
registration of xactengine silently fails (creates a bad registry entry)
if the path contains non-ASCII chars.

Log the size of codec DLLs, and log any failures from `regsvr32`.

Detect the case where user specified `-exec gamemdx.dll` for DDR which
seems to be a common pitfall. This doesn't work because gamemdx.dll does
not have a DLL entry, but for some reason people are really tempted to
do this.

## Testing
Validated the error cases.
2025-08-18 00:00:38 -07:00
bicarus-dev 5c7ad0d51e ea3: supply default pcbid if not present (#356)
## Link to GitHub Issue, if one exists
#345 

## Description of change
If ea3 xml is missing pcbid node, AND there is no pcbid override, supply
a default value. Useful for quickly getting offline clients up &
running.

## Testing
Tested with/without pcbid override, with/without pcbid node in xml.
2025-08-17 23:52:15 -07:00
sp2xdev 587ae86341 update changelog 2025-08-16 19:22:28 -07:00
bicarus-dev 926f2ef2a0 ddr: enclose file path in quotes & use wchar when registering codecs (#354)
## Link to GitHub Issue, if one exists
#345 

## Description of change
Account for the path to codec DLL having spaces in it and use wide
chars.

## Testing
Testing 32 and 64 bits.
2025-08-16 19:18:15 -07:00
sp2xdev d262e02f8c update changelog 2025-08-11 00:20:04 -07:00
bicarus-dev f6b63473a0 ddr: automatically register codecs on launch (#351)
## Link to GitHub Issue, if one exists
#345 

## Description of change
On launch of spice.exe / spice64.exe, call `regsvr32` on known codecs in
the `com` directory.

Add an option to skip this (`-ddrnocodec`) as a chicken bit.

## Testing
Tested 32 and 64 bit DDR.
2025-08-09 20:53:09 -07:00
bicarus-dev 1ad45edd6e sdvx: remove -sdvxdisablecams, simplify camera hook (#350)
## Link to GitHub Issue, if one exists
#345

## Description of change
Simplify camera hook in SDVX5/6. Camera hook will always be installed
and return 0 cameras.

Deprecate `-sdvxdisablecams` option as it is no longer needed as a
result of this change.

## Testing
Tested SDVX5 final, SDVX6 year 1, and a recent SDVX6 build.
2025-08-09 03:01:10 -07:00
bicarus-dev e79de3b117 Dump button and analog bindings to log on launch (#349)
## Link to GitHub Issue, if one exists
#345 

## Description of change
On launch of spice/spice64, dump bindings in Buttons and Analog tab

## Testing
Tested on 32 bit and 64 bit
2025-08-04 21:40:09 -07:00
sp2xdev f783a5a1cd clarify wording for -loglevel 2025-08-02 14:19:56 -07:00
sp2xdev 7848d5c237 detect custom msvcr100.dll 2025-07-25 18:36:55 -07:00
Emma cec735a81b Check for IFS LayeredFS after loading hooks (#342)
## Link to GitHub Issue, if one exists
N/A

## Description of change
Minor fix for a warning in the log. Moves the check for IFS LayeredFS
_after_ loading hooks. Also checks for the module with `GetModuleHandle`
instead, which should cover all paths as long as `ifs_hook.dll` hasn't
been renamed. 😅

## Testing

Before:
```
[2025/07/19 15:59:56] W:launcher: data_mods directory was found, but ifs_hook.dll is not present; your mods will not load
[2025/07/19 15:59:56] W:launcher: to fix this, download ifs_layeredfs and add it as a DLL hook (-k)
[2025/07/19 15:59:56] W:launcher: https://github.com/mon/ifs_layeredfs
[2025/07/19 15:59:56] I:launcher: msvcrt!__argc value before: 0
[2025/07/19 15:59:56] I:launcher: msvcrt!__argc value after: 57
[2025/07/19 15:59:56] I:launcher: loading hook DLL C:\Users\Emma\AppData\Local\Programs\SpiceTools\hooks\64\ifs_hook.dll
[2025/07/19 15:59:56] I:libraryhook: LibraryHook Attach
```

After changes - no warning observed:
```
[2025/07/19 15:59:08] I:launcher: msvcrt!__argc value before: 0
[2025/07/19 15:59:08] I:launcher: msvcrt!__argc value after: 57
[2025/07/19 15:59:08] I:launcher: loading hook DLL C:\Users\Emma\AppData\Local\Programs\SpiceTools\hooks\64\ifs_hook.dll
[2025/07/19 15:59:08] I:libraryhook: LibraryHook Attach
```
2025-07-19 16:17:07 -07:00
sp2xdev 753702e32e Fix build break due to upstream header file changes 2025-07-19 15:36:21 -07:00
sp2xdev 7bd7503951 Update README.md 2025-06-25 01:03:39 -07:00
sp2xdev d0c38956bf update changelog 2025-06-02 17:51:04 -07:00
bicarus-dev 77bca2baee patcher: add gitadora libshare-pj.dll to extra DLL list (#335)
## Link to GitHub Issue, if one exists
n/a

## Description of change
Allow importing patches for `libshare-pj.dll`

## Testing
Observed patch for the new DLL being attempted to be imported in the
logs.
2025-06-02 02:56:04 -07:00
bicarus-dev 46e8c8a5a5 acio: detect crash during acio init due to RTSS/Afterburner and complain (#334)
## Link to GitHub Issue, if one exists
n/a

## Description of change
When an exception is caught during ACIO hook init, print a special
message to suggest the user to disable RTSS and MSI Afterburner, since
they are known to cause issues.

## Testing
Tried with RTSS enabled with High detection and with it disabled. Also
tried to crash the game a different way and check that the message is
not printed and the callstack is shown propeerly.
2025-06-01 14:52:13 -07:00
sp2xdev 4d58e5d080 Merge branch 'main' of https://github.com/spice2x/spice2x.github.io 2025-05-30 22:21:11 -07:00
sp2xdev 168084d672 update changelog 2025-05-30 22:21:03 -07:00
bicarus-dev 740ed90d95 iidx: fix windowed subscreen mouse clicks being ignored when overlay is active (#333)
## Link to GitHub Issue, if one exists
n/a

## Description of change
Fix an issue when clicking on the TDJ windowed subscreen with overlay
active will occasionally drop all future mouse clicks, until the overlay
is completely hidden.

## Testing
Tested TDJ windowed subscreen, with poke, with auto-pin, and with
spicecompanion.

SDVX: this was never an issue for UFC mode, but this change doesn't make
any functional difference either.
2025-05-30 22:20:03 -07:00
19 changed files with 322 additions and 175 deletions
+1
View File
@@ -36,6 +36,7 @@ please do not ask for these, as it will never happen here.
Rules for filing a new issue or adding comments to existing issues in the tracker: Rules for filing a new issue or adding comments to existing issues in the tracker:
* Low effort submissions will be simply deleted, and repeated attempts will get you banned.
* Check the [known issues](https://github.com/spice2x/spice2x.github.io/wiki/Known-issues) page first before reporting a new issue. If you have some new information or workarounds for a known issue, you can file a documentation bug as well. * Check the [known issues](https://github.com/spice2x/spice2x.github.io/wiki/Known-issues) page first before reporting a new issue. If you have some new information or workarounds for a known issue, you can file a documentation bug as well.
* Use the search function and see if there is an existing issue. * Use the search function and see if there is an existing issue.
* This is not the place to obtain a guide or receive basic troubleshooting. * This is not the place to obtain a guide or receive basic troubleshooting.
+4
View File
@@ -41,6 +41,7 @@
namespace acio { namespace acio {
HINSTANCE DLL_INSTANCE = nullptr; HINSTANCE DLL_INSTANCE = nullptr;
std::vector<acio::ACIOModule *> MODULES; std::vector<acio::ACIOModule *> MODULES;
std::atomic<bool> IO_INIT_IN_PROGRESS = false;
} }
/* /*
@@ -58,6 +59,7 @@ static inline acio::HookMode get_hookmode() {
void acio::attach() { void acio::attach() {
log_info("acio", "SpiceTools ACIO"); log_info("acio", "SpiceTools ACIO");
IO_INIT_IN_PROGRESS = true;
// load settings and instance // load settings and instance
acio::DLL_INSTANCE = LoadLibraryA("libacio.dll"); acio::DLL_INSTANCE = LoadLibraryA("libacio.dll");
@@ -111,6 +113,8 @@ void acio::attach() {
for (auto &module : MODULES) { for (auto &module : MODULES) {
module->attach(); module->attach();
} }
IO_INIT_IN_PROGRESS = false;
} }
void acio::attach_icca() { void acio::attach_icca() {
+2
View File
@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <atomic>
#include <vector> #include <vector>
#include <windows.h> #include <windows.h>
@@ -11,6 +12,7 @@ namespace acio {
// globals // globals
extern HINSTANCE DLL_INSTANCE; extern HINSTANCE DLL_INSTANCE;
extern std::vector<acio::ACIOModule *> MODULES; extern std::vector<acio::ACIOModule *> MODULES;
extern std::atomic<bool> IO_INIT_IN_PROGRESS;
void attach(); void attach();
void attach_icca(); void attach_icca();
+1
View File
@@ -4,6 +4,7 @@
#include <cstddef> #include <cstddef>
#include <string> #include <string>
#include <windows.h> #include <windows.h>
#include <sys/stat.h>
namespace avs { namespace avs {
namespace core { namespace core {
+7 -1
View File
@@ -356,6 +356,12 @@ namespace avs {
} }
} }
// fall back to default PCBID if node is not found
if (!EA3_PCBID[0] && PCBID_CUSTOM.empty()) {
log_warning("avs-ea3", "no PCBID set, falling back to default PCBID value (04040000000000000000)");
PCBID_CUSTOM = "04040000000000000000";
}
// custom PCBID // custom PCBID
if (!PCBID_CUSTOM.empty()) { if (!PCBID_CUSTOM.empty()) {
@@ -399,7 +405,7 @@ namespace avs {
avs::core::NODE_TYPE_str, "/ea3/id/accountid", &EA3_ACCOUNTID); avs::core::NODE_TYPE_str, "/ea3/id/accountid", &EA3_ACCOUNTID);
} }
// check if PCBID is defined // check if PCBID is defined - should never hit, left for sanity check only
if (avs::core::property_search(ea3_config, nullptr, "/ea3/id/pcbid") == nullptr) { if (avs::core::property_search(ea3_config, nullptr, "/ea3/id/pcbid") == nullptr) {
log_fatal("avs-ea3", "node not found: /ea3/id/pcbid (try using -p to specify PCBID)"); log_fatal("avs-ea3", "node not found: /ea3/id/pcbid (try using -p to specify PCBID)");
} else if (strlen(EA3_PCBID) == 0) { } else if (strlen(EA3_PCBID) == 0) {
+18 -2
View File
@@ -80,7 +80,7 @@ namespace avs {
if (130 <= dll_path_s.length()) { if (130 <= dll_path_s.length()) {
log_warning( log_warning(
"avs-game", "avs-game",
"PATH TOO LONG WARNING\n\n\n" "PATH TOO LONG WARNING\n\n"
"-------------------------------------------------------------------\n" "-------------------------------------------------------------------\n"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
"WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING\n" "WARNING - WARNING - WARNING - WARNING - WARNING - WARNING - WARNING\n"
@@ -95,10 +95,26 @@ namespace avs {
"-------------------------------------------------------------------\n\n", "-------------------------------------------------------------------\n\n",
dll_path_s, dll_path_s.length()); dll_path_s, dll_path_s.length());
} }
// ddr gamemdx.dll user error
if (avs::game::is_model("MDX") && DLL_NAME == "gamemdx.dll") {
log_fatal(
"ddr",
"BAD GAME DLL ERROR\n\n"
"!!! !!!\n"
"!!! -exec gamemdx.dll was specified !!!\n"
"!!! this is the wrong DLL; the game will not load !!!\n"
"!!! remove -exec argument and try again. !!!\n"
"!!! !!!\n"
);
}
// file not found on disk
if (!fileutils::file_exists(dll_path)) { if (!fileutils::file_exists(dll_path)) {
log_warning("avs-game", "game DLL could not be found on disk: {}", dll_path.string().c_str()); log_warning("avs-game", "game DLL could not be found on disk: {}", dll_path.string().c_str());
log_warning("avs-game", "double check -exec and -modules parameters; unless you know what you're doing, leave them blank"); log_warning("avs-game", "double check -exec and -modules parameters; unless you know what you're doing, leave them blank");
} }
if (fileutils::verify_header_pe(dll_path)) { if (fileutils::verify_header_pe(dll_path)) {
DLL_INSTANCE = libutils::load_library(dll_path); DLL_INSTANCE = libutils::load_library(dll_path);
} }
@@ -106,7 +122,7 @@ namespace avs {
// load entry points // load entry points
dll_entry_init = (ENTRY_INIT_T) libutils::get_proc(DLL_INSTANCE, ENTRY_INIT_NAME); dll_entry_init = (ENTRY_INIT_T) libutils::get_proc(DLL_INSTANCE, ENTRY_INIT_NAME);
dll_entry_main = (ENTRY_MAIN_T) libutils::get_proc(DLL_INSTANCE, ENTRY_MAIN_NAME); dll_entry_main = (ENTRY_MAIN_T) libutils::get_proc(DLL_INSTANCE, ENTRY_MAIN_NAME);
log_info("avs-game", "loaded successfully ({})", fmt::ptr(DLL_INSTANCE)); log_info("avs-game", "loaded {} successfully ({})", DLL_NAME, fmt::ptr(DLL_INSTANCE));
} }
bool entry_init(char *sid_code, void *app_param) { bool entry_init(char *sid_code, void *app_param) {
+19 -1
View File
@@ -1,7 +1,25 @@
08/21/2025 [spice2x]
DDR: check for common DLL errors
Supply default PCBID if absent
Rearrange options
08/17/2025 [spice2x]
DDR: fix codec registration failure when path contains spaces
08/11/2025 [spice2x]
SDVX: fix camera hook, remove -sdvxdisablecams
DDR: automatically register codecs in com folder on boot
06/03/2025 [spice2x]
Add libshare-pj.dll to Gitadora patch import
Detect ACIO init failures
05/31/2025 [spice2x] 05/31/2025 [spice2x]
IIDX: fix windowed subscreen not accepting mouse clicks when
overlay is active
IIDX: tape LED over API IIDX: tape LED over API
UI tweaks
Option to make command line args take precedence Option to make command line args take precedence
UI tweaks
05/09/2025 [spice2x] 05/09/2025 [spice2x]
Check for window focus when processing input (-inputfocus) Check for window focus when processing input (-inputfocus)
+82
View File
@@ -27,6 +27,7 @@ namespace games::ddr {
// settings // settings
bool SDMODE = false; bool SDMODE = false;
bool NO_CODEC_REGISTRATION = false;
uint8_t DDR_TAPELEDS[TAPELED_DEVICE_COUNT][50][3] {}; uint8_t DDR_TAPELEDS[TAPELED_DEVICE_COUNT][50][3] {};
@@ -49,9 +50,79 @@ namespace games::ddr {
return SendMessage_real(hWnd, Msg, wParam, lParam); return SendMessage_real(hWnd, Msg, wParam, lParam);
} }
bool contains_only_ascii(const std::string& str) {
for (auto c: str) {
if (static_cast<unsigned char>(c) > 127) {
return false;
}
}
return true;
}
DDRGame::DDRGame() : Game("Dance Dance Revolution") { DDRGame::DDRGame() : Game("Dance Dance Revolution") {
} }
void DDRGame::register_codecs() {
// find where spice.exe / spice64.exe is located
const auto &spice_bin_path = libutils::module_file_name(nullptr).parent_path();
// find the com directory
std::filesystem::path dir = "";
if (MODULE_PATH == spice_bin_path) {
// try: \com
dir = spice_bin_path / "com";
} else {
// try: modules\..\com
dir = MODULE_PATH / ".." / "com";
}
if (fileutils::dir_exists(dir)) {
log_info("ddr", "looking for codecs in this directory: {}", dir.string());
} else {
log_info("ddr", "codecs directory not found: {}", dir.string());
return;
}
for (const auto &file : std::filesystem::directory_iterator(dir)) {
const auto &filename = file.path().filename();
const auto extension = strtolower(filename.extension().string());
if (extension != ".dll") {
continue;
}
log_info("ddr", "found DLL: {}, size: {} bytes", filename.string(), file.file_size());
if (filename == "k-clvsd.dll" || filename.string().find("xactengine") == 0) {
const std::wstring wcmd = L"regsvr32.exe /s \"" + file.path().wstring() + L"\"";
const std::string cmd = "regsvr32.exe /s \"" + file.path().string() + "\"";
int result = 0;
std::thread t([wcmd, &result]() {
result = _wsystem(wcmd.c_str());
});
t.join();
if (result == 0) {
log_info("ddr", "`{}` returned {}", cmd, result);
} else {
log_warning("ddr", "`{}` failed, returned {}", cmd, result);
}
if (!contains_only_ascii(file.path().string())) {
log_warning(
"ddr",
"BAD PATH ERROR\n\n\n"
"!!! !!!\n"
"!!! filesystem path to codec contains non-ASCII characters! !!!\n"
"!!! this may cause the game to crash! !!!\n"
"!!! !!!\n"
);
}
}
}
}
void DDRGame::pre_attach() { void DDRGame::pre_attach() {
if (!cfg::CONFIGURATOR_STANDALONE && avs::game::is_model("TDX")) { if (!cfg::CONFIGURATOR_STANDALONE && avs::game::is_model("TDX")) {
log_fatal( log_fatal(
@@ -87,6 +158,17 @@ namespace games::ddr {
"!!! !!!\n\n\n" "!!! !!!\n\n\n"
); );
} }
if (!cfg::CONFIGURATOR_STANDALONE) {
if (!NO_CODEC_REGISTRATION) {
this->register_codecs();
} else {
log_warning(
"ddr",
"skipping codec registration (-ddrnocodec), "
"game may crash if you didn't register codecs before launching the game");
}
}
} }
void DDRGame::attach() { void DDRGame::attach() {
+4
View File
@@ -7,6 +7,7 @@ namespace games::ddr {
// settings // settings
extern bool SDMODE; extern bool SDMODE;
extern bool NO_CODEC_REGISTRATION;
// Buffers to store RGB data for tape LEDs on gold cabinets // Buffers to store RGB data for tape LEDs on gold cabinets
const size_t TAPELED_DEVICE_COUNT = 11; const size_t TAPELED_DEVICE_COUNT = 11;
@@ -18,5 +19,8 @@ namespace games::ddr {
virtual void pre_attach() override; virtual void pre_attach() override;
virtual void attach() override; virtual void attach() override;
virtual void detach() override; virtual void detach() override;
private:
void register_codecs();
}; };
} }
+6 -116
View File
@@ -14,134 +14,24 @@
#include <mfidl.h> #include <mfidl.h>
#include "avs/game.h" #include "avs/game.h"
#include "hooks/cfgmgr32hook.h"
#include "util/detour.h" #include "util/detour.h"
#include "util/memutils.h"
#include "util/utils.h" #include "util/utils.h"
static VTBL_TYPE(IMFActivate, GetAllocatedString) GetAllocatedString_orig = nullptr;
static decltype(MFEnumDeviceSources) *MFEnumDeviceSources_orig = nullptr;
namespace games::sdvx { namespace games::sdvx {
static std::wstring CAMERA0_ID;
static HRESULT WINAPI GetAllocatedString_hook(IMFActivate* This, REFGUID guidKey, LPWSTR *ppwszValue,
UINT32 *pcchLength) {
// call the original
HRESULT result = GetAllocatedString_orig(This, guidKey, ppwszValue, pcchLength);
// try first camera
wchar_t *pwc = nullptr;
if (CAMERA0_ID.length() == 23)
pwc = wcsstr(*ppwszValue, CAMERA0_ID.c_str());
// check if camera could be identified
if (pwc) {
// fake the USB IDs
pwc[4] = L'2';
pwc[5] = L'8';
pwc[6] = L'8';
pwc[7] = L'c';
pwc[13] = L'0';
pwc[14] = L'0';
pwc[15] = L'0';
pwc[16] = L'2';
pwc[21] = L'0';
pwc[22] = L'0';
}
// return original result
return result;
}
static void hook_camera(IMFActivate* camera, size_t no, std::wstring camera_id, std::string camera_instance) {
// don't hook if camera 0 is already hooked
if (CAMERA0_ID.length() > 0)
return;
// save the camera ID
CAMERA0_ID = camera_id;
// cfgmgr hook
CFGMGR32_HOOK_SETTING camera_setting;
camera_setting.device_instance = 0xDEADBEEF;
camera_setting.parent_instance = ~camera_setting.device_instance;
camera_setting.device_id = "USB\\VEN_1022&DEV_7908";
camera_setting.device_node_id = "USB\\VID_288C&PID_0002&MI_00\\?&????????&?&????";
if (camera_instance.length() == 17) {
for (int i = 0; i < 17; i++) {
camera_setting.device_node_id[28 + i] = camera_instance[i];
}
}
cfgmgr32hook_add(camera_setting);
// save original method for later use
if (GetAllocatedString_orig == nullptr) {
GetAllocatedString_orig = camera->lpVtbl->GetAllocatedString;
}
// hook allocated string method for camera identification
memutils::VProtectGuard camera_guard(camera->lpVtbl);
camera->lpVtbl->GetAllocatedString = GetAllocatedString_hook;
}
static HRESULT WINAPI MFEnumDeviceSources_hook(IMFAttributes *pAttributes, IMFActivate ***pppSourceActivate, static HRESULT WINAPI MFEnumDeviceSources_hook(IMFAttributes *pAttributes, IMFActivate ***pppSourceActivate,
UINT32 *pcSourceActivate) { UINT32 *pcSourceActivate) {
// call original function *pppSourceActivate = nullptr;
HRESULT result_orig = MFEnumDeviceSources_orig(pAttributes, pppSourceActivate, pcSourceActivate); *pcSourceActivate = 0;
log_misc("sdvx", "MFEnumDeviceSources_hook called, returning 0 cameras");
// check for capture devices return S_OK;
if (FAILED(result_orig) || !*pcSourceActivate) {
return result_orig;
}
// iterate cameras
size_t cam_hook_num = 0;
for (size_t cam_num = 0; cam_num < *pcSourceActivate && cam_hook_num < 1; cam_num++) {
// flip
size_t cam_num_flipped = cam_num;
// get camera link
IMFActivate *camera = (*pppSourceActivate)[cam_num_flipped];
LPWSTR camera_link_lpwstr;
UINT32 camera_link_length;
if (SUCCEEDED(camera->lpVtbl->GetAllocatedString(
camera,
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK,
&camera_link_lpwstr,
&camera_link_length))) {
// cut name to make ID
std::wstring camera_link_ws = std::wstring(camera_link_lpwstr);
std::wstring camera_id = camera_link_ws.substr(8, 23);
// get camera instance
std::string camera_link = ws2s(camera_link_ws);
std::string camera_instance = camera_link.substr(32, 17);
// hook the camera
hook_camera(camera, cam_hook_num, camera_id, camera_instance);
// increase camera hook number
cam_hook_num++;
}
}
// return result
return result_orig;
} }
void camera_init() { void camera_init() {
// camera media framework hook // camera media framework hook
MFEnumDeviceSources_orig = detour::iat_try( log_info("sdvx", "installing camera hooks...");
"MFEnumDeviceSources", MFEnumDeviceSources_hook, avs::game::DLL_INSTANCE); detour::iat_try("MFEnumDeviceSources", MFEnumDeviceSources_hook, avs::game::DLL_INSTANCE);
} }
} }
+6 -7
View File
@@ -39,7 +39,6 @@ namespace games::sdvx {
const char *ORIGINAL_ASIO_DEVICE_NAME = "XONAR SOUND CARD(64)"; const char *ORIGINAL_ASIO_DEVICE_NAME = "XONAR SOUND CARD(64)";
// settings // settings
bool DISABLECAMS = false;
bool NATIVETOUCH = false; bool NATIVETOUCH = false;
uint8_t DIGITAL_KNOB_SENS = 16; uint8_t DIGITAL_KNOB_SENS = 16;
SdvxOverlayPosition OVERLAY_POS = SDVX_OVERLAY_BOTTOM; SdvxOverlayPosition OVERLAY_POS = SDVX_OVERLAY_BOTTOM;
@@ -369,17 +368,17 @@ namespace games::sdvx {
winuser_hook_init(avs::game::DLL_INSTANCE); winuser_hook_init(avs::game::DLL_INSTANCE);
// hook camera // hook camera
if (!DISABLECAMS) { camera_init();
camera_init();
}
// RGB CAMERA error ignore // RGB CAMERA error ignore for SDVX5
if (!replace_pattern( // SDVX5: boot sequence triggers camera error if camera is not detected
// SDVX6: boots fine, but game title screen in attract loop will have camera error (cosmetic only)
if (replace_pattern(
avs::game::DLL_INSTANCE, avs::game::DLL_INSTANCE,
"418D480484C074218D51FD", "418D480484C074218D51FD",
"????????????9090??????", "????????????9090??????",
0, 0)) { 0, 0)) {
log_info("sdvx", "did not find matching signature for camera error patch"); log_info("sdvx", "applied camera error patch (sdvx5)");
} }
// remove log spam // remove log spam
-1
View File
@@ -17,7 +17,6 @@ namespace games::sdvx {
}; };
// settings // settings
extern bool DISABLECAMS;
extern bool NATIVETOUCH; extern bool NATIVETOUCH;
extern uint8_t DIGITAL_KNOB_SENS; extern uint8_t DIGITAL_KNOB_SENS;
extern std::optional<std::string> ASIO_DRIVER; extern std::optional<std::string> ASIO_DRIVER;
+89 -12
View File
@@ -150,6 +150,9 @@ static bool check_dll(const std::string &model) {
void update_msvcrt_args(int argc, char *argv[]); void update_msvcrt_args(int argc, char *argv[]);
void dump_button_bindings(std::vector<Button> *buttons);
void dump_analog_bindings();
int main_implementation(int argc, char *argv[]) { int main_implementation(int argc, char *argv[]) {
// remember argv, argv // remember argv, argv
@@ -430,9 +433,6 @@ int main_implementation(int argc, char *argv[]) {
if (options[launcher::Options::LoadSoundVoltexModule].value_bool()) { if (options[launcher::Options::LoadSoundVoltexModule].value_bool()) {
attach_sdvx = true; attach_sdvx = true;
} }
if (options[launcher::Options::SDVXDisableCameras].value_bool()) {
games::sdvx::DISABLECAMS = true;
}
if (options[launcher::Options::SDVXNativeTouch].value_bool()) { if (options[launcher::Options::SDVXNativeTouch].value_bool()) {
games::sdvx::NATIVETOUCH = true; games::sdvx::NATIVETOUCH = true;
} }
@@ -629,6 +629,9 @@ int main_implementation(int argc, char *argv[]) {
if (options[launcher::Options::DDR43Mode].value_bool()) { if (options[launcher::Options::DDR43Mode].value_bool()) {
games::ddr::SDMODE = true; games::ddr::SDMODE = true;
} }
if (options[launcher::Options::DDRSkipCodecRegisteration].value_bool()) {
games::ddr::NO_CODEC_REGISTRATION = true;
}
if (options[launcher::Options::LoadSteelChronicleModule].value_bool()) { if (options[launcher::Options::LoadSteelChronicleModule].value_bool()) {
attach_sc = true; attach_sc = true;
} }
@@ -1915,6 +1918,7 @@ int main_implementation(int argc, char *argv[]) {
libutils::warn_if_dll_exists("nvcuda.dll"); libutils::warn_if_dll_exists("nvcuda.dll");
libutils::warn_if_dll_exists("nvcuvid.dll"); libutils::warn_if_dll_exists("nvcuvid.dll");
libutils::warn_if_dll_exists("nvEncodeAPI64.dll"); libutils::warn_if_dll_exists("nvEncodeAPI64.dll");
libutils::warn_if_dll_exists("msvcr100.dll");
// complain loudly & early about dll load ordering issue // complain loudly & early about dll load ordering issue
libutils::check_duplicate_dlls(); libutils::check_duplicate_dlls();
@@ -1936,6 +1940,21 @@ int main_implementation(int argc, char *argv[]) {
// print devices // print devices
RI_MGR->devices_print(); RI_MGR->devices_print();
auto buttons = games::get_buttons(eamuse_get_game());
log_misc("rawinput", "Button mappings:");
dump_button_bindings(buttons);
log_misc("rawinput", "Keypad button mappings:");
auto keypads = games::get_buttons_keypads(eamuse_get_game());
dump_button_bindings(keypads);
log_misc("rawinput", "Overlay button mappings:");
auto overlay_buttons = games::get_buttons_overlay(eamuse_get_game());
dump_button_bindings(overlay_buttons);
log_misc("rawinput", "Analog mappings:");
dump_analog_bindings();
// for certain games, show cursor if no touch is available (must be called after RI_MGR is available) // for certain games, show cursor if no touch is available (must be called after RI_MGR is available)
if (show_cursor_if_no_touch && !is_touch_available("launcher::main_implementation")) { if (show_cursor_if_no_touch && !is_touch_available("launcher::main_implementation")) {
GRAPHICS_SHOW_CURSOR = true; GRAPHICS_SHOW_CURSOR = true;
@@ -2077,15 +2096,6 @@ int main_implementation(int argc, char *argv[]) {
networkhook_init(); networkhook_init();
} }
// layeredfs
if (fileutils::dir_exists("data_mods") &&
!fileutils::file_exists("ifs_hook.dll") &&
!fileutils::file_exists(MODULE_PATH / "ifs_hook.dll")) {
log_warning("launcher", "data_mods directory was found, but ifs_hook.dll is not present; your mods will not load");
log_warning("launcher", "to fix this, download ifs_layeredfs and add it as a DLL hook (-k)");
log_warning("launcher", "https://github.com/mon/ifs_layeredfs");
}
update_msvcrt_args(argc, argv); update_msvcrt_args(argc, argv);
// load hooks // load hooks
@@ -2099,6 +2109,14 @@ int main_implementation(int argc, char *argv[]) {
} }
} }
// layeredfs
if (fileutils::dir_exists("data_mods") &&
GetModuleHandleA("ifs_hook.dll") == nullptr) {
log_warning("launcher", "data_mods directory was found, but ifs_hook.dll is not present; your mods will not load");
log_warning("launcher", "to fix this, download ifs_layeredfs and add it as a DLL hook (-k)");
log_warning("launcher", "https://github.com/mon/ifs_layeredfs");
}
// apply patches // apply patches
{ {
overlay::windows::PatchManager patch_manager(nullptr, true); overlay::windows::PatchManager patch_manager(nullptr, true);
@@ -2321,6 +2339,65 @@ void update_msvcrt_args(int argc, char *argv[]) {
#endif #endif
} }
void dump_button_bindings(std::vector<Button> *buttons) {
if (!buttons) {
return;
}
for (auto button = buttons->begin(); button != buttons->end(); ++button) {
if (!button->isSet()) {
continue;
}
if (button->isNaive()) {
log_misc(
"rawinput", " [{}] dev=Naive, vkey={}",
button->getName(),
button->getVKey()
);
} else {
log_misc(
"rawinput", " [{}] dev={}, vkey={}, analogtype={}",
button->getName(),
button->getDeviceIdentifier(),
button->getVKey(),
button->getAnalogType()
);
}
for (auto& alt : button->getAlternatives()) {
if (alt.getVKey() == INVALID_VKEY) {
continue;
}
log_misc(
"rawinput", " [{}] (alt) dev={}, vkey={}, analogtype={}",
button->getName(),
alt.isNaive() ? "Naive" : alt.getDeviceIdentifier(),
alt.getVKey(),
alt.getAnalogType()
);
}
}
}
void dump_analog_bindings() {
auto analogs = games::get_analogs(eamuse_get_game());
if (!analogs) {
return;
}
for (auto& analog : *analogs) {
if (!analog.isSet()) {
continue;
}
log_misc(
"rawinput", " [{}] dev={}, index={}",
analog.getName(),
analog.getDeviceIdentifier(),
analog.getIndex()
);
}
}
#ifndef SPICETOOLS_SPICECFG_STANDALONE #ifndef SPICETOOLS_SPICECFG_STANDALONE
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
return main_implementation(argc, argv); return main_implementation(argc, argv);
+43 -29
View File
@@ -17,7 +17,6 @@ static const std::vector<std::string> CATEGORY_ORDER_BASIC = {
"Game Options", "Game Options",
"Common", "Common",
"Network", "Network",
"Overlay",
"Graphics (Common)", "Graphics (Common)",
"Graphics (Full Screen)", "Graphics (Full Screen)",
"Graphics (Windowed)", "Graphics (Windowed)",
@@ -26,18 +25,21 @@ static const std::vector<std::string> CATEGORY_ORDER_BASIC = {
static const std::vector<std::string> CATEGORY_ORDER_ADVANCED = { static const std::vector<std::string> CATEGORY_ORDER_ADVANCED = {
"Game Options (Advanced)", "Game Options (Advanced)",
"Overlay",
"Network (Advanced)", "Network (Advanced)",
"Performance", "Performance",
"Miscellaneous", "Miscellaneous",
"Paths",
"Touch Parameters", "Touch Parameters",
"I/O Options", "I/O Options",
"NFC Card Readers", "NFC Card Readers",
}; };
static const std::vector<std::string> CATEGORY_ORDER_DEV = { static const std::vector<std::string> CATEGORY_ORDER_DEV = {
"Network Adapters", "Paths",
"Network (Development)",
"Audio (Hacks)",
"I/O Modules", "I/O Modules",
"Development", "Development",
"Debug Log",
}; };
static const std::vector<std::string> CATEGORY_ORDER_NONE = { static const std::vector<std::string> CATEGORY_ORDER_NONE = {
"" ""
@@ -268,7 +270,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "nolegacy", .name = "nolegacy",
.desc = "Disables legacy key activation in-game.", .desc = "Disables legacy key activation in-game.",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Miscellaneous", .category = "I/O Options",
}, },
{ {
.title = "Discord Rich Presence", .title = "Discord Rich Presence",
@@ -310,7 +312,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.desc = "This is NOT the EA service URL; use -url for that. " .desc = "This is NOT the EA service URL; use -url for that. "
"Force the use of an adapter with the specified network. Must also provide -subnet", "Force the use of an adapter with the specified network. Must also provide -subnet",
.type = OptionType::Text, .type = OptionType::Text,
.category = "Network Adapters", .category = "Network (Development)",
.sensitive = true, .sensitive = true,
}, },
{ {
@@ -318,21 +320,21 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "subnet", .name = "subnet",
.desc = "Force the use of an adapter with the specified subnet. Must also provide -network", .desc = "Force the use of an adapter with the specified subnet. Must also provide -network",
.type = OptionType::Text, .type = OptionType::Text,
.category = "Network Adapters", .category = "Network (Development)",
}, },
{ {
.title = "Disable Network Fixes", .title = "Disable Network Fixes",
.name = "netfixdisable", .name = "netfixdisable",
.desc = "Force disables network fixes", .desc = "Force disables network fixes",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Network Adapters", .category = "Network (Development)",
}, },
{ {
.title = "HTTP/1.1", .title = "HTTP/1.1",
.name = "http11", .name = "http11",
.desc = "Sets EA3 http11 value", .desc = "Sets EA3 http11 value",
.type = OptionType::Enum, .type = OptionType::Enum,
.category = "Network (Advanced)", .category = "Network (Development)",
.elements = {{"0", "Off"}, {"1", "On"}}, .elements = {{"0", "Off"}, {"1", "On"}},
}, },
{ {
@@ -340,7 +342,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "ssldisable", .name = "ssldisable",
.desc = "Prevents the SSL protocol from being registered", .desc = "Prevents the SSL protocol from being registered",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Network (Advanced)", .category = "Network (Development)",
}, },
{ {
.title = "URL Slash", .title = "URL Slash",
@@ -355,7 +357,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "r", .name = "r",
.desc = "Set custom SOFTID override", .desc = "Set custom SOFTID override",
.type = OptionType::Text, .type = OptionType::Text,
.category = "Network (Advanced)", .category = "Network (Development)",
.sensitive = true, .sensitive = true,
}, },
{ {
@@ -717,10 +719,13 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.category = "Game Options (Advanced)", .category = "Game Options (Advanced)",
}, },
{ {
.title = "SDVX Disable Cameras", .title = "SDVX Disable Cameras (DEPRECATED - no longer needed)",
.name = "sdvxdisablecams", .name = "sdvxdisablecams",
.desc = "Disables cameras", .desc = "This option does nothing.\n\n"
"This option was used in the past to fix cameras in SDVX5 but this is no longer "
"needed as camera check will always be skipped with a built-in patch.",
.type = OptionType::Bool, .type = OptionType::Bool,
.hidden = true,
.game_name = "Sound Voltex", .game_name = "Sound Voltex",
.category = "Game Options", .category = "Game Options",
}, },
@@ -806,6 +811,15 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.game_name = "Dance Dance Revolution", .game_name = "Dance Dance Revolution",
.category = "Game Options", .category = "Game Options",
}, },
{
// DDRSkipCodecRegisteration
.title = "DDR Skip Codec Registration",
.name = "ddrnocodec",
.desc = "Prevent automatic registration of codecs in the com folder",
.type = OptionType::Bool,
.game_name = "Dance Dance Revolution",
.category = "Game Options (Advanced)",
},
{ {
.title = "Force Load Pop'n Music Module", .title = "Force Load Pop'n Music Module",
.name = "pnm", .name = "pnm",
@@ -1400,7 +1414,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "sextet", .name = "sextet",
.desc = "Use a SextetStream device on a given COM port", .desc = "Use a SextetStream device on a given COM port",
.type = OptionType::Text, .type = OptionType::Text,
.category = "Miscellaneous", .category = "I/O Options",
}, },
{ {
.title = "Enable BemaniTools 5 API", .title = "Enable BemaniTools 5 API",
@@ -1501,7 +1515,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
"you use a different backend instead of exclusive WASAPI).\n\n" "you use a different backend instead of exclusive WASAPI).\n\n"
"Check this if you want games to natively access your audio device", "Check this if you want games to natively access your audio device",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Audio", .category = "Audio (Hacks)",
}, },
{ {
// spice2x_DisableVolumeHook // spice2x_DisableVolumeHook
@@ -1513,7 +1527,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
"Default: off (prevent games from changing audio volume by hooking IAudioEndpointVolume).\n\n" "Default: off (prevent games from changing audio volume by hooking IAudioEndpointVolume).\n\n"
"Check this if you want games to freely change your volume", "Check this if you want games to freely change your volume",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Audio", .category = "Audio (Hacks)",
}, },
{ {
.title = "Spice Audio Hook Backend", .title = "Spice Audio Hook Backend",
@@ -1538,7 +1552,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
"This is automatically enabled when required and not normally needed", "This is automatically enabled when required and not normally needed",
.type = OptionType::Bool, .type = OptionType::Bool,
.hidden = true, .hidden = true,
.category = "Audio", .category = "Audio (Hacks)",
}, },
{ {
// DelayBy5Seconds // DelayBy5Seconds
@@ -1591,11 +1605,11 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.elements = {{"0", "90 (CW)"}, {"1", "270 (CCW)"}}, .elements = {{"0", "90 (CW)"}, {"1", "270 (CCW)"}},
}, },
{ {
.title = "Log Level", .title = "AVS Log Level",
.name = "loglevel", .name = "loglevel",
.desc = "Set the level of detail that gets written to the log", .desc = "Set the level of detail for AVS log messages written to the log. Does not affect logging from spice",
.type = OptionType::Enum, .type = OptionType::Enum,
.category = "Performance", .category = "Debug Log",
.elements = {{"fatal", ""}, {"warning", ""}, {"info", ""}, {"misc", ""}, {"all", ""}, {"disable", ""}}, .elements = {{"fatal", ""}, {"warning", ""}, {"info", ""}, {"misc", ""}, {"all", ""}, {"disable", ""}},
}, },
{ {
@@ -1603,14 +1617,14 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "automap", .name = "automap",
.desc = "Enable automap in patch configuration", .desc = "Enable automap in patch configuration",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Network (Development)",
}, },
{ {
.title = "EA Netdump", .title = "EA Netdump",
.name = "netdump", .name = "netdump",
.desc = "Enable automap in network dumping configuration", .desc = "Enable automap in network dumping configuration",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Network (Development)",
}, },
{ {
.title = "Discord RPC AppID Override", .title = "Discord RPC AppID Override",
@@ -1624,35 +1638,35 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "logblock", .name = "logblock",
.desc = "Slower but safer logging used for debugging", .desc = "Slower but safer logging used for debugging",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
.title = "Debug CreateFile", .title = "Debug CreateFile",
.name = "createfiledebug", .name = "createfiledebug",
.desc = "Outputs CreateFile debug prints", .desc = "Outputs CreateFile debug prints",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
.title = "Verbose Graphics Logging", .title = "Verbose Graphics Logging",
.name = "graphicsverbose", .name = "graphicsverbose",
.desc = "Enable the verbose logging of graphics hook code", .desc = "Enable the verbose logging of graphics hook code",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
.title = "Verbose AVS Logging", .title = "Verbose AVS Logging",
.name = "avsverbose", .name = "avsverbose",
.desc = "Enable the verbose logging of AVS filesystem functions", .desc = "Enable the verbose logging of AVS filesystem functions",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
.title = "Disable Colored Output", .title = "Disable Colored Output",
.name = "nocolor", .name = "nocolor",
.desc = "Disable terminal colors for log outputs to console", .desc = "Disable terminal colors for log outputs to console",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
.title = "Disable ACP Hook", .title = "Disable ACP Hook",
@@ -1687,7 +1701,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "pebprint", .name = "pebprint",
.desc = "Prints PEB on startup to console", .desc = "Prints PEB on startup to console",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Development", .category = "Debug Log",
}, },
{ {
// DumpSystemInfo // DumpSystemInfo
@@ -1695,7 +1709,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "sysdump", .name = "sysdump",
.desc = "Print system information to the log on startup. Default: basic", .desc = "Print system information to the log on startup. Default: basic",
.type = OptionType::Enum, .type = OptionType::Enum,
.category = "Development", .category = "Debug Log",
.elements = { .elements = {
{"none", "Nothing"}, {"none", "Nothing"},
{"basic", "OS, CPU, SMBIOS, GPU"}, {"basic", "OS, CPU, SMBIOS, GPU"},
@@ -1925,7 +1939,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.desc = "For certain buggy ASIO drivers, force unload of ASIO driver when audio stream stops. " .desc = "For certain buggy ASIO drivers, force unload of ASIO driver when audio stream stops. "
"Used for working around ASIO drivers that lock up after force quitting games", "Used for working around ASIO drivers that lock up after force quitting games",
.type = OptionType::Bool, .type = OptionType::Bool,
.category = "Audio", .category = "Audio (Hacks)",
}, },
{ {
// spice2x_IIDXNoESpec // spice2x_IIDXNoESpec
+1
View File
@@ -86,6 +86,7 @@ namespace launcher {
spice2x_SDVXSubRedraw, spice2x_SDVXSubRedraw,
LoadDDRModule, LoadDDRModule,
DDR43Mode, DDR43Mode,
DDRSkipCodecRegisteration,
LoadPopnMusicModule, LoadPopnMusicModule,
PopnMusicForceHDMode, PopnMusicForceHDMode,
PopnMusicForceSDMode, PopnMusicForceSDMode,
+14
View File
@@ -6,6 +6,7 @@
#include <windows.h> #include <windows.h>
#include <dbghelp.h> #include <dbghelp.h>
#include "acio/acio.h"
#include "external/stackwalker/stackwalker.h" #include "external/stackwalker/stackwalker.h"
#include "hooks/libraryhook.h" #include "hooks/libraryhook.h"
#include "launcher/shutdown.h" #include "launcher/shutdown.h"
@@ -97,6 +98,19 @@ static LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *Exception
// print signal // print signal
log_warning("signal", "exception raised: {}", exception_code(ExceptionRecord)); log_warning("signal", "exception raised: {}", exception_code(ExceptionRecord));
// check ACIO init failures
if (acio::IO_INIT_IN_PROGRESS) {
log_warning(
"signal",
"exception raised during ACIO init, this usually happens when a third party application interferes with hooks");
log_warning(
"signal",
" please check for the following, disable them, and try launching the game again:");
log_warning(
"signal",
" RivaTuner Statistics Server (RTSS), MSI Afterburner, kernel mode anti-cheat");
}
// walk the exception chain // walk the exception chain
struct _EXCEPTION_RECORD *record_cause = ExceptionRecord->ExceptionRecord; struct _EXCEPTION_RECORD *record_cause = ExceptionRecord->ExceptionRecord;
while (record_cause != nullptr) { while (record_cause != nullptr) {
+15 -2
View File
@@ -12,6 +12,7 @@
#include "touch/touch.h" #include "touch/touch.h"
#include "util/logging.h" #include "util/logging.h"
#include "util/utils.h" #include "util/utils.h"
#include "hooks/graphics/graphics.h"
#if !defined(IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS) || \ #if !defined(IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS) || \
!defined(IMGUI_DISABLE_DEFAULT_ALLOCATORS) || \ !defined(IMGUI_DISABLE_DEFAULT_ALLOCATORS) || \
@@ -175,10 +176,22 @@ static void ImGui_ImplSpice_UpdateMousePos() {
static_cast<int>(pos.y / io.DisplaySize.y * window_size.y)); static_cast<int>(pos.y / io.DisplaySize.y * window_size.y));
} }
const auto active_window = ::GetForegroundWindow();
// if the main focus is a windowed subscreen, put the imgui cursor in a place that won't
// trigger any overlay, don't process anything else
const auto is_windowed_subscreen =
(GRAPHICS_IIDX_WSUB && active_window == TDJ_SUBSCREEN_WINDOW) ||
(active_window == SDVX_SUBSCREEN_WINDOW);
if (is_windowed_subscreen) {
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
return;
}
// set mouse position // set mouse position
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
POINT pos; POINT pos;
if (HWND active_window = ::GetForegroundWindow()) { if (active_window) {
if (active_window == g_hWnd if (active_window == g_hWnd
|| ::IsChild(active_window, g_hWnd) || ::IsChild(active_window, g_hWnd)
|| ::IsChild(g_hWnd, active_window) || ::IsChild(g_hWnd, active_window)
@@ -208,7 +221,7 @@ static void ImGui_ImplSpice_UpdateMousePos() {
static size_t delay_touch = 0; static size_t delay_touch = 0;
static size_t delay_touch_target = 2; static size_t delay_touch_target = 2;
static DWORD last_touch_id = ~0u; static DWORD last_touch_id = ~0u;
if (!touch_points.empty()) { if (!touch_points.empty() && !is_windowed_subscreen) {
// use the first touch point // use the first touch point
auto &tp = touch_points[0]; auto &tp = touch_points[0];
@@ -80,7 +80,7 @@ namespace overlay::windows {
{"arkmmd.dll", {"gamemmd.dll"}}, {"arkmmd.dll", {"gamemmd.dll"}},
{"arkklp.dll", {"lpac.dll"}}, {"arkklp.dll", {"lpac.dll"}},
{"arknck.dll", {"weac.dll"}}, {"arknck.dll", {"weac.dll"}},
{"gdxg.dll", {"game.dll"}} {"gdxg.dll", {"game.dll", "libshare-pj.dll"}}
}; };
static size_t url_recent_idx = -1; static size_t url_recent_idx = -1;
+9 -3
View File
@@ -240,8 +240,11 @@ static LRESULT CALLBACK SpiceTouchWndProc(HWND hWnd, UINT msg, WPARAM wParam, LP
rawinput::touch::display_update(); rawinput::touch::display_update();
} }
const auto is_windowed_sub =
(GRAPHICS_IIDX_WSUB && hWnd == TDJ_SUBSCREEN_WINDOW) || (hWnd == SDVX_SUBSCREEN_WINDOW);
if (msg == WM_CLOSE) { if (msg == WM_CLOSE) {
if ((GRAPHICS_IIDX_WSUB && hWnd == TDJ_SUBSCREEN_WINDOW) || (hWnd == SDVX_SUBSCREEN_WINDOW)) { if (is_windowed_sub) {
log_misc("touch", "ignore WM_CLOSE for subscreen window"); log_misc("touch", "ignore WM_CLOSE for subscreen window");
return false; return false;
} }
@@ -461,11 +464,14 @@ static LRESULT CALLBACK SpiceTouchWndProc(HWND hWnd, UINT msg, WPARAM wParam, LP
}; };
// check if imgui is handling this mouse event // check if imgui is handling this mouse event
if (overlay::OVERLAY != nullptr && overlay::OVERLAY->get_active() && ImGui::GetIO().WantCaptureMouse) { if (is_windowed_sub) {
// do nothing, don't let imgui hijack clicks on the sub window
result.action = ACTION_PASS;
} else if (overlay::OVERLAY != nullptr && overlay::OVERLAY->get_active() && ImGui::GetIO().WantCaptureMouse) {
result.action = ACTION_RETURN_DEFAULT; result.action = ACTION_RETURN_DEFAULT;
} else if (TOUCH_HANDLER != nullptr) { } else if (TOUCH_HANDLER != nullptr) {
// call touch handler // call touch handler
TOUCH_HANDLER->handle_message(result, hWnd, msg, wParam, lParam); TOUCH_HANDLER->handle_message(result, hWnd, msg, wParam, lParam);
} }