mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-02 06:40:42 -07:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d262e02f8c | |||
| f6b63473a0 | |||
| 1ad45edd6e | |||
| e79de3b117 | |||
| f783a5a1cd | |||
| 7848d5c237 | |||
| cec735a81b | |||
| 753702e32e | |||
| 7bd7503951 | |||
| d0c38956bf | |||
| 77bca2baee | |||
| 46e8c8a5a5 | |||
| 4d58e5d080 | |||
| 168084d672 | |||
| 740ed90d95 |
@@ -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:
|
||||
|
||||
* 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.
|
||||
* 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.
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
namespace acio {
|
||||
HINSTANCE DLL_INSTANCE = nullptr;
|
||||
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() {
|
||||
log_info("acio", "SpiceTools ACIO");
|
||||
IO_INIT_IN_PROGRESS = true;
|
||||
|
||||
// load settings and instance
|
||||
acio::DLL_INSTANCE = LoadLibraryA("libacio.dll");
|
||||
@@ -111,6 +113,8 @@ void acio::attach() {
|
||||
for (auto &module : MODULES) {
|
||||
module->attach();
|
||||
}
|
||||
|
||||
IO_INIT_IN_PROGRESS = false;
|
||||
}
|
||||
|
||||
void acio::attach_icca() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
#include <windows.h>
|
||||
@@ -11,6 +12,7 @@ namespace acio {
|
||||
// globals
|
||||
extern HINSTANCE DLL_INSTANCE;
|
||||
extern std::vector<acio::ACIOModule *> MODULES;
|
||||
extern std::atomic<bool> IO_INIT_IN_PROGRESS;
|
||||
|
||||
void attach();
|
||||
void attach_icca();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
namespace avs {
|
||||
namespace core {
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
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]
|
||||
IIDX: fix windowed subscreen not accepting mouse clicks when
|
||||
overlay is active
|
||||
IIDX: tape LED over API
|
||||
UI tweaks
|
||||
Option to make command line args take precedence
|
||||
UI tweaks
|
||||
|
||||
05/09/2025 [spice2x]
|
||||
Check for window focus when processing input (-inputfocus)
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace games::ddr {
|
||||
|
||||
// settings
|
||||
bool SDMODE = false;
|
||||
bool NO_CODEC_REGISTRATION = false;
|
||||
|
||||
uint8_t DDR_TAPELEDS[TAPELED_DEVICE_COUNT][50][3] {};
|
||||
|
||||
@@ -52,6 +53,50 @@ namespace games::ddr {
|
||||
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: {}", filename.string());
|
||||
if (filename == "k-clvsd.dll" || filename.string().find("xactengine") == 0) {
|
||||
const std::string cmd = "regsvr32.exe /s " + file.path().string();
|
||||
|
||||
int result = 0;
|
||||
std::thread t([cmd, &result]() {
|
||||
result = system(cmd.c_str());
|
||||
});
|
||||
t.join();
|
||||
log_info("ddr", "`{}` returned {}", cmd, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DDRGame::pre_attach() {
|
||||
if (!cfg::CONFIGURATOR_STANDALONE && avs::game::is_model("TDX")) {
|
||||
log_fatal(
|
||||
@@ -87,6 +132,10 @@ namespace games::ddr {
|
||||
"!!! !!!\n\n\n"
|
||||
);
|
||||
}
|
||||
|
||||
if (!cfg::CONFIGURATOR_STANDALONE && !NO_CODEC_REGISTRATION) {
|
||||
this->register_codecs();
|
||||
}
|
||||
}
|
||||
|
||||
void DDRGame::attach() {
|
||||
|
||||
@@ -7,6 +7,7 @@ namespace games::ddr {
|
||||
|
||||
// settings
|
||||
extern bool SDMODE;
|
||||
extern bool NO_CODEC_REGISTRATION;
|
||||
|
||||
// Buffers to store RGB data for tape LEDs on gold cabinets
|
||||
const size_t TAPELED_DEVICE_COUNT = 11;
|
||||
@@ -18,5 +19,8 @@ namespace games::ddr {
|
||||
virtual void pre_attach() override;
|
||||
virtual void attach() override;
|
||||
virtual void detach() override;
|
||||
|
||||
private:
|
||||
void register_codecs();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,134 +14,24 @@
|
||||
#include <mfidl.h>
|
||||
|
||||
#include "avs/game.h"
|
||||
#include "hooks/cfgmgr32hook.h"
|
||||
#include "util/detour.h"
|
||||
#include "util/memutils.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
static VTBL_TYPE(IMFActivate, GetAllocatedString) GetAllocatedString_orig = nullptr;
|
||||
|
||||
static decltype(MFEnumDeviceSources) *MFEnumDeviceSources_orig = nullptr;
|
||||
|
||||
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,
|
||||
UINT32 *pcSourceActivate) {
|
||||
|
||||
// call original function
|
||||
HRESULT result_orig = MFEnumDeviceSources_orig(pAttributes, pppSourceActivate, pcSourceActivate);
|
||||
|
||||
// check for capture devices
|
||||
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;
|
||||
*pppSourceActivate = nullptr;
|
||||
*pcSourceActivate = 0;
|
||||
log_misc("sdvx", "MFEnumDeviceSources_hook called, returning 0 cameras");
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void camera_init() {
|
||||
|
||||
// camera media framework hook
|
||||
MFEnumDeviceSources_orig = detour::iat_try(
|
||||
"MFEnumDeviceSources", MFEnumDeviceSources_hook, avs::game::DLL_INSTANCE);
|
||||
log_info("sdvx", "installing camera hooks...");
|
||||
detour::iat_try("MFEnumDeviceSources", MFEnumDeviceSources_hook, avs::game::DLL_INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace games::sdvx {
|
||||
const char *ORIGINAL_ASIO_DEVICE_NAME = "XONAR SOUND CARD(64)";
|
||||
|
||||
// settings
|
||||
bool DISABLECAMS = false;
|
||||
bool NATIVETOUCH = false;
|
||||
uint8_t DIGITAL_KNOB_SENS = 16;
|
||||
SdvxOverlayPosition OVERLAY_POS = SDVX_OVERLAY_BOTTOM;
|
||||
@@ -369,17 +368,17 @@ namespace games::sdvx {
|
||||
winuser_hook_init(avs::game::DLL_INSTANCE);
|
||||
|
||||
// hook camera
|
||||
if (!DISABLECAMS) {
|
||||
camera_init();
|
||||
}
|
||||
camera_init();
|
||||
|
||||
// RGB CAMERA error ignore
|
||||
if (!replace_pattern(
|
||||
// RGB CAMERA error ignore for SDVX5
|
||||
// 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,
|
||||
"418D480484C074218D51FD",
|
||||
"????????????9090??????",
|
||||
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
|
||||
|
||||
@@ -17,7 +17,6 @@ namespace games::sdvx {
|
||||
};
|
||||
|
||||
// settings
|
||||
extern bool DISABLECAMS;
|
||||
extern bool NATIVETOUCH;
|
||||
extern uint8_t DIGITAL_KNOB_SENS;
|
||||
extern std::optional<std::string> ASIO_DRIVER;
|
||||
|
||||
@@ -150,6 +150,9 @@ static bool check_dll(const std::string &model) {
|
||||
|
||||
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[]) {
|
||||
|
||||
// remember argv, argv
|
||||
@@ -430,9 +433,6 @@ int main_implementation(int argc, char *argv[]) {
|
||||
if (options[launcher::Options::LoadSoundVoltexModule].value_bool()) {
|
||||
attach_sdvx = true;
|
||||
}
|
||||
if (options[launcher::Options::SDVXDisableCameras].value_bool()) {
|
||||
games::sdvx::DISABLECAMS = true;
|
||||
}
|
||||
if (options[launcher::Options::SDVXNativeTouch].value_bool()) {
|
||||
games::sdvx::NATIVETOUCH = true;
|
||||
}
|
||||
@@ -629,6 +629,9 @@ int main_implementation(int argc, char *argv[]) {
|
||||
if (options[launcher::Options::DDR43Mode].value_bool()) {
|
||||
games::ddr::SDMODE = true;
|
||||
}
|
||||
if (options[launcher::Options::DDRSkipCodecRegisteration].value_bool()) {
|
||||
games::ddr::NO_CODEC_REGISTRATION = true;
|
||||
}
|
||||
if (options[launcher::Options::LoadSteelChronicleModule].value_bool()) {
|
||||
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("nvcuvid.dll");
|
||||
libutils::warn_if_dll_exists("nvEncodeAPI64.dll");
|
||||
libutils::warn_if_dll_exists("msvcr100.dll");
|
||||
|
||||
// complain loudly & early about dll load ordering issue
|
||||
libutils::check_duplicate_dlls();
|
||||
@@ -1936,6 +1940,21 @@ int main_implementation(int argc, char *argv[]) {
|
||||
// print devices
|
||||
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)
|
||||
if (show_cursor_if_no_touch && !is_touch_available("launcher::main_implementation")) {
|
||||
GRAPHICS_SHOW_CURSOR = true;
|
||||
@@ -2077,15 +2096,6 @@ int main_implementation(int argc, char *argv[]) {
|
||||
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);
|
||||
|
||||
// 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
|
||||
{
|
||||
overlay::windows::PatchManager patch_manager(nullptr, true);
|
||||
@@ -2321,6 +2339,65 @@ void update_msvcrt_args(int argc, char *argv[]) {
|
||||
#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
|
||||
int main(int argc, char *argv[]) {
|
||||
return main_implementation(argc, argv);
|
||||
|
||||
@@ -717,10 +717,13 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
||||
.category = "Game Options (Advanced)",
|
||||
},
|
||||
{
|
||||
.title = "SDVX Disable Cameras",
|
||||
.title = "SDVX Disable Cameras (DEPRECATED - no longer needed)",
|
||||
.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,
|
||||
.hidden = true,
|
||||
.game_name = "Sound Voltex",
|
||||
.category = "Game Options",
|
||||
},
|
||||
@@ -806,6 +809,15 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
||||
.game_name = "Dance Dance Revolution",
|
||||
.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",
|
||||
.name = "pnm",
|
||||
@@ -1591,9 +1603,9 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
||||
.elements = {{"0", "90 (CW)"}, {"1", "270 (CCW)"}},
|
||||
},
|
||||
{
|
||||
.title = "Log Level",
|
||||
.title = "AVS Log Level",
|
||||
.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,
|
||||
.category = "Performance",
|
||||
.elements = {{"fatal", ""}, {"warning", ""}, {"info", ""}, {"misc", ""}, {"all", ""}, {"disable", ""}},
|
||||
|
||||
@@ -86,6 +86,7 @@ namespace launcher {
|
||||
spice2x_SDVXSubRedraw,
|
||||
LoadDDRModule,
|
||||
DDR43Mode,
|
||||
DDRSkipCodecRegisteration,
|
||||
LoadPopnMusicModule,
|
||||
PopnMusicForceHDMode,
|
||||
PopnMusicForceSDMode,
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include "acio/acio.h"
|
||||
#include "external/stackwalker/stackwalker.h"
|
||||
#include "hooks/libraryhook.h"
|
||||
#include "launcher/shutdown.h"
|
||||
@@ -97,6 +98,19 @@ static LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *Exception
|
||||
// print signal
|
||||
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
|
||||
struct _EXCEPTION_RECORD *record_cause = ExceptionRecord->ExceptionRecord;
|
||||
while (record_cause != nullptr) {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "touch/touch.h"
|
||||
#include "util/logging.h"
|
||||
#include "util/utils.h"
|
||||
#include "hooks/graphics/graphics.h"
|
||||
|
||||
#if !defined(IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS) || \
|
||||
!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));
|
||||
}
|
||||
|
||||
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
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
POINT pos;
|
||||
if (HWND active_window = ::GetForegroundWindow()) {
|
||||
if (active_window) {
|
||||
if (active_window == g_hWnd
|
||||
|| ::IsChild(active_window, g_hWnd)
|
||||
|| ::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_target = 2;
|
||||
static DWORD last_touch_id = ~0u;
|
||||
if (!touch_points.empty()) {
|
||||
if (!touch_points.empty() && !is_windowed_subscreen) {
|
||||
|
||||
// use the first touch point
|
||||
auto &tp = touch_points[0];
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace overlay::windows {
|
||||
{"arkmmd.dll", {"gamemmd.dll"}},
|
||||
{"arkklp.dll", {"lpac.dll"}},
|
||||
{"arknck.dll", {"weac.dll"}},
|
||||
{"gdxg.dll", {"game.dll"}}
|
||||
{"gdxg.dll", {"game.dll", "libshare-pj.dll"}}
|
||||
};
|
||||
|
||||
static size_t url_recent_idx = -1;
|
||||
|
||||
@@ -240,8 +240,11 @@ static LRESULT CALLBACK SpiceTouchWndProc(HWND hWnd, UINT msg, WPARAM wParam, LP
|
||||
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 ((GRAPHICS_IIDX_WSUB && hWnd == TDJ_SUBSCREEN_WINDOW) || (hWnd == SDVX_SUBSCREEN_WINDOW)) {
|
||||
if (is_windowed_sub) {
|
||||
log_misc("touch", "ignore WM_CLOSE for subscreen window");
|
||||
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
|
||||
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;
|
||||
|
||||
} else if (TOUCH_HANDLER != nullptr) {
|
||||
|
||||
// call touch handler
|
||||
TOUCH_HANDLER->handle_message(result, hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user