mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-05 08:10:40 -07:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7335d07e30 | |||
| 9f99b71112 | |||
| 5c3921a99c | |||
| 9fc397b8bc | |||
| ddc8061268 |
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "external/robin_hood.h"
|
#include "external/robin_hood.h"
|
||||||
#include "launcher/logger.h"
|
#include "launcher/logger.h"
|
||||||
|
#include "launcher/signal.h"
|
||||||
#include "util/detour.h"
|
#include "util/detour.h"
|
||||||
#include "util/fileutils.h"
|
#include "util/fileutils.h"
|
||||||
#include "util/libutils.h"
|
#include "util/libutils.h"
|
||||||
@@ -1736,7 +1737,13 @@ namespace avs {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_dir(
|
static void avs_dir_err(const std::filesystem::path &src_path)
|
||||||
|
{
|
||||||
|
launcher::signal::AVS_DIR_CREATION_FAILURE = TRUE;
|
||||||
|
launcher::signal::AVS_SRC_PATH = src_path.string();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void create_avs_dir(
|
||||||
const std::string_view &avs_path,
|
const std::string_view &avs_path,
|
||||||
const std::string_view &src_path)
|
const std::string_view &src_path)
|
||||||
{
|
{
|
||||||
@@ -1745,6 +1752,7 @@ namespace avs {
|
|||||||
auto real_path = std::filesystem::absolute(src_path, err);
|
auto real_path = std::filesystem::absolute(src_path, err);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
avs_dir_err(real_path);
|
||||||
log_warning("avs-core", "failed to resolve '{}' path: {}", avs_path, err.message());
|
log_warning("avs-core", "failed to resolve '{}' path: {}", avs_path, err.message());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1754,7 +1762,9 @@ namespace avs {
|
|||||||
if (created) {
|
if (created) {
|
||||||
log_info("avs-core", "created '{}' at '{}'", avs_path, real_path.string());
|
log_info("avs-core", "created '{}' at '{}'", avs_path, real_path.string());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
|
avs_dir_err(real_path);
|
||||||
log_warning("avs-core", "failed to create '{}' folder at '{}': {}",
|
log_warning("avs-core", "failed to create '{}' folder at '{}': {}",
|
||||||
avs_path,
|
avs_path,
|
||||||
real_path.string(),
|
real_path.string(),
|
||||||
@@ -1815,7 +1825,7 @@ namespace avs {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
create_dir(avs_path, device_path);
|
create_avs_dir(avs_path, device_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void create_avs_config_fs_table(
|
static void create_avs_config_fs_table(
|
||||||
@@ -1870,7 +1880,7 @@ namespace avs {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
create_dir(dst_path, src_path);
|
create_avs_dir(dst_path, src_path);
|
||||||
} while ((vfs_node = property_node_traversal(vfs_node, TRAVERSE_NEXT_SEARCH_RESULT)));
|
} while ((vfs_node = property_node_traversal(vfs_node, TRAVERSE_NEXT_SEARCH_RESULT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
09/28/2025 [spice2x]
|
||||||
|
IIDX: auto apply ASIO compatibility fix for IIDX32+
|
||||||
|
Misc diagnosability updates
|
||||||
|
|
||||||
09/22/2025 [spice2x]
|
09/22/2025 [spice2x]
|
||||||
Add Polaris Chord lights
|
Add Polaris Chord lights
|
||||||
Add boot.dll to Gitadora patches target
|
Add boot.dll to Gitadora patches target
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "games/iidx/legacy_camera.h"
|
#include "games/iidx/legacy_camera.h"
|
||||||
|
|
||||||
|
#include "hooks/audio/audio.h"
|
||||||
#include "hooks/avshook.h"
|
#include "hooks/avshook.h"
|
||||||
#include "hooks/cfgmgr32hook.h"
|
#include "hooks/cfgmgr32hook.h"
|
||||||
#include "hooks/devicehook.h"
|
#include "hooks/devicehook.h"
|
||||||
@@ -376,7 +377,11 @@ namespace games::iidx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_audio_hacks();
|
if (hooks::audio::ENABLED) {
|
||||||
|
apply_audio_hacks();
|
||||||
|
} else {
|
||||||
|
log_warning("iidx", "skipping audio hooks; disabled by user");
|
||||||
|
}
|
||||||
|
|
||||||
// ASIO device hook
|
// ASIO device hook
|
||||||
RegCloseKey_orig = detour::iat_try(
|
RegCloseKey_orig = detour::iat_try(
|
||||||
@@ -766,22 +771,26 @@ namespace games::iidx {
|
|||||||
0);
|
0);
|
||||||
|
|
||||||
// attempt to detect ASIO support
|
// attempt to detect ASIO support
|
||||||
|
// <=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+: only has XONAR (ASIO by default, signature patch can be used to force WASAPI - for now)
|
||||||
|
|
||||||
if (!has_SOUND_OUTPUT_DEVICE && !has_XONAR_SOUND_CARD) {
|
if (!has_SOUND_OUTPUT_DEVICE && !has_XONAR_SOUND_CARD) {
|
||||||
|
// iidx 25-26
|
||||||
log_info("iidx", "This game only uses WASAPI audio engine");
|
log_info("iidx", "This game only uses WASAPI audio engine");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_SOUND_OUTPUT_DEVICE && has_XONAR_SOUND_CARD) {
|
if (has_SOUND_OUTPUT_DEVICE && has_XONAR_SOUND_CARD) {
|
||||||
|
// iidx 27-30
|
||||||
log_info("iidx", "This game accepts SOUND_OUTPUT_DEVICE environment variable");
|
log_info("iidx", "This game accepts SOUND_OUTPUT_DEVICE environment variable");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_info("iidx", "This game supports ASIO but does not accept SOUND_OUTPUT_DEVICE environment variable");
|
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") {
|
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,
|
||||||
@@ -800,6 +809,41 @@ 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
|
||||||
|
// only do this if NOT wasapi (as opposed to checking if it's asio)
|
||||||
|
// 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)
|
||||||
|
if (avs::game::is_ext(2024090100, MAXINT) &&
|
||||||
|
!(SOUND_OUTPUT_DEVICE_IN_EFFECT.has_value() && SOUND_OUTPUT_DEVICE_IN_EFFECT.value() == "wasapi")) {
|
||||||
|
|
||||||
|
// in iidx32 final:
|
||||||
|
// ff 50 08 call QWORD PTR [rax+0x8] ; ASIO instance AddRef
|
||||||
|
// 48 8b 4b 08 mov rcx,QWORD PTR [rbx+0x8]
|
||||||
|
// 48 8b 01 mov rax,QWORD PTR [rcx]
|
||||||
|
// ff 50 08 call QWORD PTR [rax+0x8] ; ASIO instance AddRef
|
||||||
|
|
||||||
|
intptr_t result = replace_pattern(
|
||||||
|
avs::game::DLL_INSTANCE,
|
||||||
|
"FF50????????????????FF50??4533C94533C0418D51",
|
||||||
|
"????????????????????909090??????????????????",
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
if (result == 0) {
|
||||||
|
log_warning(
|
||||||
|
"iidx",
|
||||||
|
"Failed to apply ASIO compatibility fix for iidx32+. "
|
||||||
|
"Unless patches are applied, your ASIO device ({}) may hang or fail to work",
|
||||||
|
ASIO_DRIVER->c_str());
|
||||||
|
} else {
|
||||||
|
log_info(
|
||||||
|
"iidx",
|
||||||
|
"Successfully applied ASIO compatibility fix for iidx32+ using signature matching @ 0x{:x}.",
|
||||||
|
result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -85,12 +85,19 @@ namespace games::iidx {
|
|||||||
&m_pwszSymbolicLink,
|
&m_pwszSymbolicLink,
|
||||||
&m_cchSymbolicLink
|
&m_cchSymbolicLink
|
||||||
);
|
);
|
||||||
if (FAILED(hr)) { goto done; }
|
if (FAILED(hr)) {
|
||||||
|
log_warning("iidx:camhook", "[{}] GetAllocatedString failed with {:#x}", m_name, (ULONG)hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
log_misc("iidx:camhook", "[{}] Symlink: {}", m_name, GetSymLink());
|
log_misc("iidx:camhook", "[{}] Symlink: {}", m_name, GetSymLink());
|
||||||
|
|
||||||
// Create the media source object.
|
// Create the media source object.
|
||||||
hr = pActivate->ActivateObject(IID_PPV_ARGS(&m_pSource));
|
hr = pActivate->ActivateObject(IID_PPV_ARGS(&m_pSource));
|
||||||
if (FAILED(hr)) { goto done; }
|
if (FAILED(hr)) {
|
||||||
|
log_warning("iidx:camhook", "[{}] ActivateObject failed with {:#x}", m_name, (ULONG)hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
// Retain reference to the camera
|
// Retain reference to the camera
|
||||||
m_pSource->AddRef();
|
m_pSource->AddRef();
|
||||||
@@ -98,13 +105,22 @@ namespace games::iidx {
|
|||||||
|
|
||||||
// Create an attribute store to hold initialization settings.
|
// Create an attribute store to hold initialization settings.
|
||||||
hr = WrappedMFCreateAttributes(&pAttributes, 2);
|
hr = WrappedMFCreateAttributes(&pAttributes, 2);
|
||||||
if (FAILED(hr)) { goto done; }
|
if (FAILED(hr)) {
|
||||||
|
log_warning("iidx:camhook", "[{}] MFCreateAttributes failed with {:#x}", m_name, (ULONG)hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
hr = pAttributes->SetUnknown(MF_SOURCE_READER_D3D_MANAGER, pD3DManager);
|
hr = pAttributes->SetUnknown(MF_SOURCE_READER_D3D_MANAGER, pD3DManager);
|
||||||
if (FAILED(hr)) { goto done; }
|
if (FAILED(hr)) {
|
||||||
|
log_warning("iidx:camhook", "[{}] SetUnknown(MF_SOURCE_READER_D3D_MANAGER) failed with {:#x}", m_name, (ULONG)hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
hr = pAttributes->SetUINT32(MF_SOURCE_READER_DISABLE_DXVA, FALSE);
|
hr = pAttributes->SetUINT32(MF_SOURCE_READER_DISABLE_DXVA, FALSE);
|
||||||
if (FAILED(hr)) { goto done; }
|
if (FAILED(hr)) {
|
||||||
|
log_warning("iidx:camhook", "[{}] SetUINT32(MF_SOURCE_READER_DISABLE_DXVA) failed with {:#x}", m_name, (ULONG)hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Color space conversion
|
// TODO: Color space conversion
|
||||||
// if (SUCCEEDED(hr)) {
|
// if (SUCCEEDED(hr)) {
|
||||||
@@ -120,11 +136,18 @@ namespace games::iidx {
|
|||||||
pAttributes,
|
pAttributes,
|
||||||
&m_pSourceReader
|
&m_pSourceReader
|
||||||
);
|
);
|
||||||
if (FAILED(hr)) { goto done; }
|
if (FAILED(hr)) {
|
||||||
|
log_warning("iidx:camhook", "[{}] MFCreateSourceReaderFromMediaSource failed with {:#x}", m_name, (ULONG)hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
log_misc("iidx:camhook", "[{}] Created source reader", m_name);
|
log_misc("iidx:camhook", "[{}] Created source reader", m_name);
|
||||||
|
|
||||||
hr = InitTargetTexture();
|
hr = InitTargetTexture();
|
||||||
if (FAILED(hr)) { goto done; }
|
if (FAILED(hr)) {
|
||||||
|
log_warning("iidx:camhook", "[{}] InitTargetTexture failed with {:#x}", m_name, (ULONG)hr);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
// Camera should be still usable even if camera control is not supported
|
// Camera should be still usable even if camera control is not supported
|
||||||
InitCameraControl();
|
InitCameraControl();
|
||||||
@@ -134,7 +157,7 @@ namespace games::iidx {
|
|||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
log_misc("iidx:camhook", "[{}] Initialized", m_name);
|
log_misc("iidx:camhook", "[{}] Initialized", m_name);
|
||||||
} else {
|
} else {
|
||||||
log_warning("iidx:camhook", "[{}] Failed to create camera: {}", m_name, hr);
|
log_warning("iidx:camhook", "[{}] Failed to create camera: {:#x}", m_name, (ULONG)hr);
|
||||||
}
|
}
|
||||||
SafeRelease(&pAttributes);
|
SafeRelease(&pAttributes);
|
||||||
LeaveCriticalSection(&m_critsec);
|
LeaveCriticalSection(&m_critsec);
|
||||||
@@ -165,7 +188,7 @@ namespace games::iidx {
|
|||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
if (hr != MF_E_NO_MORE_TYPES) {
|
if (hr != MF_E_NO_MORE_TYPES) {
|
||||||
log_warning("iidx:camhook", "[{}] Cannot get media type {} {}", m_name, i, hr);
|
log_warning("iidx:camhook", "[{}] Cannot get media type {} {:#x}", m_name, i, (ULONG)hr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -584,7 +607,7 @@ namespace games::iidx {
|
|||||||
* Return values:
|
* Return values:
|
||||||
* S_OK: this is a "better" media type than the existing one
|
* S_OK: this is a "better" media type than the existing one
|
||||||
* S_FALSE: valid media type, but not "better"
|
* S_FALSE: valid media type, but not "better"
|
||||||
* E_*: invalid meia type
|
* E_*: invalid media type
|
||||||
*/
|
*/
|
||||||
HRESULT IIDXLocalCamera::TryMediaType(IMFMediaType *pType, UINT32 *pBestWidth, double *pBestFrameRate) {
|
HRESULT IIDXLocalCamera::TryMediaType(IMFMediaType *pType, UINT32 *pBestWidth, double *pBestFrameRate) {
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
@@ -595,13 +618,13 @@ namespace games::iidx {
|
|||||||
hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype);
|
hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype);
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
log_warning("iidx:camhook", "[{}] Failed to get subtype: {}", m_name, hr);
|
log_warning("iidx:camhook", "[{}] Failed to get subtype: {:#x}", m_name, (ULONG)hr);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &width, &height);
|
hr = MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &width, &height);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
log_warning("iidx:camhook", "[{}] Failed to get frame size: {}", m_name, hr);
|
log_warning("iidx:camhook", "[{}] Failed to get frame size: {:#x}", m_name, (ULONG)hr);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,7 +642,7 @@ namespace games::iidx {
|
|||||||
(UINT32*)&frameRate.Denominator
|
(UINT32*)&frameRate.Denominator
|
||||||
);
|
);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
log_warning("iidx:camhook", "[{}] Failed to get frame rate: {}", m_name, hr);
|
log_warning("iidx:camhook", "[{}] Failed to get frame rate: {:#x}", m_name, (ULONG)hr);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
double frameRateValue = frameRate.Numerator / frameRate.Denominator;
|
double frameRateValue = frameRate.Numerator / frameRate.Denominator;
|
||||||
@@ -696,7 +719,7 @@ namespace games::iidx {
|
|||||||
if (SUCCEEDED(hr)) {
|
if (SUCCEEDED(hr)) {
|
||||||
log_misc("iidx:camhook", "[{}] Created texture", m_name);
|
log_misc("iidx:camhook", "[{}] Created texture", m_name);
|
||||||
} else {
|
} else {
|
||||||
log_warning("iidx:camhook", "[{}] Failed to create texture: {}", m_name, hr);
|
log_warning("iidx:camhook", "[{}] Failed to create texture: {:#x}", m_name, (ULONG)hr);
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
@@ -785,7 +808,7 @@ namespace games::iidx {
|
|||||||
FlushDrawCommands();
|
FlushDrawCommands();
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
log_warning("iidx:camhook", "Error in DrawSample {}", hr);
|
log_warning("iidx:camhook", "Error in DrawSample {:#x}", (ULONG)hr);
|
||||||
}
|
}
|
||||||
SafeRelease(&pCameraSurf);
|
SafeRelease(&pCameraSurf);
|
||||||
LeaveCriticalSection(&m_critsec);
|
LeaveCriticalSection(&m_critsec);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#include "signal.h"
|
#include "signal.h"
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <dbghelp.h>
|
#include <dbghelp.h>
|
||||||
|
|
||||||
|
#include "avs/core.h"
|
||||||
#include "acio/acio.h"
|
#include "acio/acio.h"
|
||||||
#include "external/stackwalker/stackwalker.h"
|
#include "external/stackwalker/stackwalker.h"
|
||||||
#include "hooks/libraryhook.h"
|
#include "hooks/libraryhook.h"
|
||||||
@@ -32,6 +32,8 @@ namespace launcher::signal {
|
|||||||
|
|
||||||
// states
|
// states
|
||||||
bool SUPERSTEP_SOUND_ERROR = false;
|
bool SUPERSTEP_SOUND_ERROR = false;
|
||||||
|
bool AVS_DIR_CREATION_FAILURE = false;
|
||||||
|
std::string AVS_SRC_PATH;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define V(variant) case variant: return #variant
|
#define V(variant) case variant: return #variant
|
||||||
@@ -121,6 +123,18 @@ static LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *Exception
|
|||||||
log_warning("signal", " fix your audio device, double check your audio options/patches, and try again");
|
log_warning("signal", " fix your audio device, double check your audio options/patches, and try again");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (launcher::signal::AVS_DIR_CREATION_FAILURE) {
|
||||||
|
log_warning("signal",
|
||||||
|
"AVS filesystem initialization failure was previously detected during boot!");
|
||||||
|
log_warning("signal",
|
||||||
|
" ERROR: directory could not be created: {}",
|
||||||
|
launcher::signal::AVS_SRC_PATH.c_str());
|
||||||
|
log_warning("signal",
|
||||||
|
" this crash may have been caused by bad <mounttable> contents in {}",
|
||||||
|
avs::core::CFG_PATH.c_str());
|
||||||
|
log_warning("signal", " fix the XML file and try again");
|
||||||
|
}
|
||||||
|
|
||||||
// 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) {
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace launcher::signal {
|
namespace launcher::signal {
|
||||||
|
|
||||||
// settings
|
// settings
|
||||||
extern bool DISABLE;
|
extern bool DISABLE;
|
||||||
extern bool USE_VEH_WORKAROUND;
|
extern bool USE_VEH_WORKAROUND;
|
||||||
extern bool SUPERSTEP_SOUND_ERROR;
|
extern bool SUPERSTEP_SOUND_ERROR;
|
||||||
|
extern bool AVS_DIR_CREATION_FAILURE;
|
||||||
|
extern std::string AVS_XML_PATH;
|
||||||
|
extern std::string AVS_SRC_PATH;
|
||||||
|
|
||||||
//void print_stacktrace();
|
//void print_stacktrace();
|
||||||
void attach();
|
void attach();
|
||||||
|
|||||||
@@ -29,19 +29,17 @@ std::filesystem::path libutils::module_file_name(HMODULE module) {
|
|||||||
|
|
||||||
static inline void load_library_fail(const std::string &file_name, bool fatal) {
|
static inline void load_library_fail(const std::string &file_name, bool fatal) {
|
||||||
std::string info_str { fmt::format(
|
std::string info_str { fmt::format(
|
||||||
"\n\nPlease check if {} exists and the permissions are fine.\n"
|
"DLL failed to load - this is a common error. Please carefully read ALL of the following steps for a fix:\n"
|
||||||
"\n"
|
" 1. Confirm if the file ({}) exists on the disk and check the file permissions.\n"
|
||||||
"* If the problem still persists, try installing things on this list:\n"
|
" 2. Follow this link and install DLL prerequisites on this list:\n"
|
||||||
" https://github.com/spice2x/spice2x.github.io/wiki/DLL-Dependencies \n"
|
" https://github.com/spice2x/spice2x.github.io/wiki/DLL-Dependencies \n"
|
||||||
"\n"
|
" 3. Still have problems after installing from above and rebooting PC?\n"
|
||||||
"* Still have problems after installing from above and rebooting PC?\n"
|
" a. Avoid manually specifying DLL path (-exec) and module directory (-modules); let spice2x auto-detect unless you have a good reason not to\n"
|
||||||
" Avoid manually specifying DLL path (-exec) and module directory (-modules); let spice2x auto-detect unless you have a good reason not to\n"
|
" b. Ensure you do NOT have multiple copies of the game DLLs (e.g., in contents and in contents\\modules)\n"
|
||||||
" Ensure you do NOT have multiple copies of the game DLLs (e.g., in contents and in contents\\modules)\n"
|
" c. Certain games require specific NVIDIA DLLs when running with AMD/Intel GPUs (hint: look inside stub directory for DLLs)\n"
|
||||||
" Certain games require specific NVIDIA DLLs when running with AMD/Intel GPUs (hint: look inside stub directory for DLLs)\n"
|
" 4. (For advanced users) if none of the above helps, find the missing dependency using:\n"
|
||||||
"\n"
|
" a. https://github.com/lucasg/Dependencies (recommended for most) \n"
|
||||||
"* (For advanced users) if none of the above helps, find the missing dependency using:\n"
|
" b. http://www.dependencywalker.com/ (for old OS) \n"
|
||||||
" https://github.com/lucasg/Dependencies (recommended for most) \n"
|
|
||||||
" http://www.dependencywalker.com/ (for old OS) \n"
|
|
||||||
, file_name) };
|
, file_name) };
|
||||||
if (fatal) {
|
if (fatal) {
|
||||||
log_fatal("libutils", "{}", info_str);
|
log_fatal("libutils", "{}", info_str);
|
||||||
|
|||||||
Reference in New Issue
Block a user