Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion aurora-main
3 changes: 3 additions & 0 deletions runtime/include/audio_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ class AudioBackend {
// Applied to the final host output, covering both AX and direct AI DMA.
void SetMasterVolume(float volume);
void SetMuted(bool muted);
// Mutes output without touching the user's persisted mute setting.
void SetSilenced(bool silenced);

private:
AudioBackend() = default;
Expand All @@ -43,6 +45,7 @@ class AudioBackend {
bool m_initialized = false;
float m_masterVolume = 1.0f;
bool m_muted = false;
bool m_silenced = false;
bool m_reportedDroppedBlock = false;
std::vector<int16_t> m_convertBuffer;
};
1 change: 1 addition & 0 deletions runtime/include/boot_race.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
namespace BootRace {
// False when `arg` is not a boot-race option; throws on a malformed one.
bool ParseArgument(std::string_view arg);
bool Requested();
} // namespace BootRace
8 changes: 7 additions & 1 deletion runtime/src/audio_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ AudioBackend& AudioBackend::Instance() {
}

float AudioBackend::EffectiveGainLocked() const {
return m_muted ? 0.0f : m_masterVolume;
return m_muted || m_silenced ? 0.0f : m_masterVolume;
}

void AudioBackend::ApplyGainLocked() {
Expand All @@ -36,6 +36,12 @@ void AudioBackend::SetMuted(bool muted) {
ApplyGainLocked();
}

void AudioBackend::SetSilenced(bool silenced) {
std::lock_guard<std::mutex> lock(m_mutex);
m_silenced = silenced;
ApplyGainLocked();
}

bool AudioBackend::EnsureInitializedLocked(uint32_t sampleRate, uint32_t channels) {
if (m_initialized && m_sampleRate == sampleRate && m_channels == channels) {
return true;
Expand Down
4 changes: 4 additions & 0 deletions runtime/src/hle/boot_race.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ bool ParseArgument(std::string_view arg) {
return true;
}

bool Requested() {
return g_course.has_value();
}

} // namespace BootRace

// ArgumentParser::parse, picks the boot section in SectionMgr::Init.
Expand Down
26 changes: 21 additions & 5 deletions runtime/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#endif

#include "abi_bridge.h"
#include "audio_backend.h"
#include "boot_race.h"
#include "guest_abi/guest_region.h"
#include "guest_flat_memory.h"
Expand Down Expand Up @@ -167,6 +168,7 @@ std::atomic_bool g_auroraInitialized{false};
std::atomic_flag g_abortSignalHandled = ATOMIC_FLAG_INIT;
std::atomic_bool g_fatalErrorReported{false};
std::atomic_bool g_fatalPopupShown{false};
bool g_headless = false;
std::atomic<int> g_lastExitCode{0};
std::atomic_bool g_exitCodeSet{false};

Expand Down Expand Up @@ -773,7 +775,7 @@ void MarkFatalErrorReported() {
}

void ShowRuntimeFatalPopup(std::string_view category, std::string_view details) noexcept {
if (g_fatalPopupShown.exchange(true, std::memory_order_acq_rel)) {
if (g_headless || g_fatalPopupShown.exchange(true, std::memory_order_acq_rel)) {
return;
}

Expand Down Expand Up @@ -1345,15 +1347,25 @@ int RuntimeMain(int argc, char** argv) {

std::string currentEntryLabel;

// `--headless`: with a boot race, run without a window, sound or dialogs.
g_headless = std::any_of(argv + 1, argv + argc,
[](const char* arg) { return std::string_view(arg) == "--headless"; });

try {
for (int i = 1; i < argc; ++i) {
if (!BootRace::ParseArgument(argv[i])) {
if (std::string_view(argv[i]) != "--headless" && !BootRace::ParseArgument(argv[i])) {
throw std::invalid_argument(std::string("Unknown command-line option '") + argv[i] +
"'; the game runtime only accepts --race[=<course id>] and --race-cpu, use Config.toml through the installed host.");
"'; the game runtime only accepts --race[=<course id>], --race-cpu and --headless, use Config.toml through the installed host.");
}
}
if (g_headless && !BootRace::Requested()) {
throw std::invalid_argument("--headless needs --race[=<course id>] or --race-cpu");
}
if (g_headless) {
AudioBackend::Instance().SetSilenced(true);
}
RuntimeConfigFile::LogLoadedConfig();
if (RuntimeConfigFile::DiscordPresenceEnabled()) {
if (!g_headless && RuntimeConfigFile::DiscordPresenceEnabled()) {
DiscordPresence::Initialize(RuntimeConfigFile::DiscordClientId(), "Mario Kart Wii");
}
SystemBridge::Initialize();
Expand Down Expand Up @@ -1387,7 +1399,8 @@ int RuntimeMain(int argc, char** argv) {
auroraConfig.windowHeight = RuntimeConfigFile::WindowHeight(auroraConfig.windowHeight);
auroraConfig.hasWindowPosition = RuntimeConfigFile::WindowPosition(
auroraConfig.windowPosX, auroraConfig.windowPosY);
auroraConfig.allowJoystickBackgroundEvents = true;
auroraConfig.allowJoystickBackgroundEvents = !g_headless;
Comment thread
coderabbitai[bot] marked this conversation as resolved.
auroraConfig.startHidden = g_headless;
auroraConfig.disableCopyFilter = RuntimeConfigFile::DisableCopyFilter(true);
// Dolphin-style custom textures. Aurora indexes <userPath>/texture_replacements
// once during aurora_initialize, so both knobs only take effect on the next launch.
Expand Down Expand Up @@ -1466,6 +1479,9 @@ int RuntimeMain(int argc, char** argv) {
UpdateMkwDynamicAspectSurface(auroraInfo.windowSize.native_fb_width,
auroraInfo.windowSize.native_fb_height);
settings_overlay::InitializeRuntimeSettings();
if (BootRace::Requested()) {
aurora_set_skip_unready_pipelines(false);
}
RT_LOG(RT_TAG_CONFIG) << "video.widescreen=" << (configWidescreen ? "true" : "false")
<< " force_16_9=" << (forceAspect169 ? "true" : "false")
<< " SCGetAspectRatio=" << (configWidescreen || forceAspect169 ? 1 : 0)
Expand Down
Loading