mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-10-02 19:57:57 +03:00
## Link to GitHub Issue or related Pull Request, if one exists n/a ## Description of change This new option, `-wasapishared`, detects when the game opens WASAPI Exclusive stream and forcibly opens a shared mode stream instead on the real device. #### Benefits of this: 1. No need for `force wasapi shared` patches 2. No need to change sample rate of audio devices before starting up games 3. Adds ability to boot in shared mode even for games that do not have shared wasapi changes (old GITADORA, popn HC) As a result, this option is strictly better than `shared wasapi` patches available for many games. #### Downsides: 1. OS resampling will add a small latency, but not big enough to be noticeable. 2. Using shared mode instead of exclusive mode adds latency, of course. (If you cared about latency, you would use the low latency option, or use exclusive or asio) Basically it's the "make things work" button for audio that should work for almost all games that we support. The option has no effect if the game opens in shared mode. ## Testing SDVX7 - ok GITADORA GW - ok popn HC - ok IIDX - ok
108 lines
4.0 KiB
C++
108 lines
4.0 KiB
C++
#include <mutex>
|
|
#include <atomic>
|
|
|
|
#include "build/defs.h"
|
|
#include "deferlog.h"
|
|
#include "util/logging.h"
|
|
|
|
namespace deferredlogs {
|
|
|
|
const std::initializer_list<std::string> SUPERSTEP_SOUND_ERROR_MESSAGE = {
|
|
"audio initialization error was detected during boot!",
|
|
" this crash is most likely related to audio init failure",
|
|
" * try enabling WASAPI Force Shared Mode (-wasapishared)",
|
|
" * check if the default audio device has changed",
|
|
" * double check your spice audio options and patches",
|
|
" * ensure no other application is using the device in exclusive mode"
|
|
};
|
|
|
|
std::mutex deferred_errors_mutex;
|
|
std::vector<std::vector<std::string>> deferred_errors;
|
|
|
|
std::mutex softid_mutex;
|
|
std::string softid;
|
|
|
|
void set_softid(const std::string& softid_new) {
|
|
std::lock_guard<std::mutex> lock(softid_mutex);
|
|
softid = softid_new;
|
|
}
|
|
|
|
void defer_error_messages(std::initializer_list<std::string> messages) {
|
|
std::lock_guard<std::mutex> lock(deferred_errors_mutex);
|
|
deferred_errors.emplace_back(messages);
|
|
}
|
|
|
|
void report_fatal_message() {
|
|
static std::once_flag printed;
|
|
std::call_once(printed, []() {
|
|
deferredlogs::defer_error_messages({
|
|
"game reported FATAL error(s)",
|
|
" look for messages containing F: in the log",
|
|
});
|
|
});
|
|
}
|
|
|
|
void dump_to_logger(bool is_crash) {
|
|
static std::once_flag printed;
|
|
std::call_once(printed, [is_crash]() {
|
|
|
|
// move to a local vector under lock first
|
|
// this is to avoid holding a lock while emitting to the logger, which may deadlock
|
|
// due to recursive calls (e.g., via log hooks used for failure detection which then
|
|
// again calls into defer_error_messages), and std::mutex cannot be acquired recursively
|
|
std::vector<std::vector<std::string>> errors;
|
|
{
|
|
std::lock_guard<std::mutex> lock(deferred_errors_mutex);
|
|
if (deferred_errors.empty() && !is_crash) {
|
|
return;
|
|
}
|
|
errors = std::move(deferred_errors);
|
|
}
|
|
|
|
std::string msg;
|
|
msg += "\n\n";
|
|
msg += "/-------------------------- spice2x auto-troubleshooter -----------------------\\\n";
|
|
msg += "\n";
|
|
msg += " spice2x version: " + to_string(VERSION_STRING_CFG) + "\n";
|
|
|
|
// soft ID
|
|
{
|
|
std::lock_guard<std::mutex> lock(softid_mutex);
|
|
if (!softid.empty()) {
|
|
msg += " game version: " + softid + "\n";
|
|
} else {
|
|
msg += " game version: unknown\n";
|
|
}
|
|
}
|
|
|
|
msg += "\n";
|
|
|
|
if (is_crash) {
|
|
msg += " the game has crashed\n";
|
|
msg += " * share this entire log file with someone for troubleshooting (log.txt)\n";
|
|
msg += " * spice will also attempt to create a minidump (minidump.dmp)\n";
|
|
msg += " minidump should only be shared with people you trust as it may contain\n";
|
|
msg += " sensitive data (PCBID, card ID, etc)\n";
|
|
msg += "\n";
|
|
}
|
|
|
|
for (const auto &messages : errors) {
|
|
for (const auto &message : messages) {
|
|
msg += " " + message + "\n";
|
|
}
|
|
msg += "\n";
|
|
}
|
|
|
|
msg += " unsure what to do next?\n";
|
|
msg += " * update to the latest version:\n";
|
|
msg += " https://github.com/spice2x/spice2x.github.io/releases\n";
|
|
msg += " * check the FAQ:\n";
|
|
msg += " https://github.com/spice2x/spice2x.github.io/wiki/Known-issues\n";
|
|
msg += "\n";
|
|
msg += "\\------------------------- spice2x auto-troubleshooter ------------------------/\n";
|
|
|
|
log_special("troubleshooter", "{}", msg);
|
|
});
|
|
}
|
|
}
|