115 lines
3.6 KiB
C++
115 lines
3.6 KiB
C++
/**
|
|
******************************************************************************
|
|
* Xenia : Xbox 360 Emulator Research Project *
|
|
******************************************************************************
|
|
* Copyright 2020 Ben Vanik. All rights reserved. *
|
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
|
******************************************************************************
|
|
*/
|
|
|
|
#include "xenia/helper/sdl/sdl_helper.h"
|
|
|
|
// On linux we likely build on an "outdated" system but still want to control
|
|
// these features when available on a newer system.
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 14)
|
|
#define SDL_HINT_AUDIO_DEVICE_APP_NAME "SDL_AUDIO_DEVICE_APP_NAME"
|
|
#endif
|
|
|
|
#include "xenia/base/assert.h"
|
|
#include "xenia/base/logging.h"
|
|
|
|
namespace xe {
|
|
namespace helper {
|
|
namespace sdl {
|
|
bool SDLHelper::is_prepared_ = false;
|
|
|
|
bool SDLHelper::Prepare() {
|
|
if (is_prepared_) {
|
|
return true;
|
|
}
|
|
is_prepared_ = true;
|
|
|
|
is_prepared_ &= SetHints();
|
|
is_prepared_ &= RedirectLog();
|
|
|
|
SDL_version ver = {};
|
|
SDL_GetVersion(&ver);
|
|
XELOGI("SDL Version {}.{}.{} initialized.", ver.major, ver.minor, ver.patch);
|
|
|
|
return is_prepared_;
|
|
}
|
|
|
|
bool SDLHelper::SetHints() {
|
|
bool suc = true;
|
|
|
|
const auto setHint = [](const char* name, const char* value,
|
|
bool override_ = false) -> bool {
|
|
// Setting hints with normal priority fails when the hint is set via env
|
|
// vars or a hint with override priority is set, which does not conclude a
|
|
// failure.
|
|
if (SDL_FALSE ==
|
|
SDL_SetHintWithPriority(
|
|
name, value, override_ ? SDL_HINT_OVERRIDE : SDL_HINT_NORMAL)) {
|
|
const char* msg_fmt =
|
|
"SDLHelper: Unable to set hint \"{}\" to value \"{}\".";
|
|
if (override_) {
|
|
XELOGE(msg_fmt, name, value);
|
|
return false;
|
|
} else {
|
|
XELOGI(msg_fmt, name, value);
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
|
|
// SDL calls timeBeginPeriod(1) but xenia sets this to a lower value before
|
|
// using NtSetTimerResolution(). Having that value overwritten causes overall
|
|
// fps drops. Use override priority as timer resolution should always be
|
|
// managed by xenia. https://bugzilla.libsdl.org/show_bug.cgi?id=5104
|
|
suc &= setHint(SDL_HINT_TIMER_RESOLUTION, "0", true);
|
|
|
|
suc &= setHint(SDL_HINT_AUDIO_CATEGORY, "playback");
|
|
|
|
suc &= setHint(SDL_HINT_AUDIO_DEVICE_APP_NAME, "xenia emulator");
|
|
|
|
return suc;
|
|
}
|
|
|
|
bool SDLHelper::RedirectLog() {
|
|
// Redirect SDL_Log* output (internal library stuff) to our log system.
|
|
SDL_LogSetOutputFunction(
|
|
[](void* userdata, int category, SDL_LogPriority priority,
|
|
const char* message) {
|
|
const char* msg_fmt = "SDL: {}";
|
|
switch (priority) {
|
|
case SDL_LOG_PRIORITY_VERBOSE:
|
|
case SDL_LOG_PRIORITY_DEBUG:
|
|
XELOGD(msg_fmt, message);
|
|
break;
|
|
case SDL_LOG_PRIORITY_INFO:
|
|
XELOGI(msg_fmt, message);
|
|
break;
|
|
case SDL_LOG_PRIORITY_WARN:
|
|
XELOGW(msg_fmt, message);
|
|
break;
|
|
case SDL_LOG_PRIORITY_ERROR:
|
|
case SDL_LOG_PRIORITY_CRITICAL:
|
|
XELOGE(msg_fmt, message);
|
|
break;
|
|
default:
|
|
XELOGI(msg_fmt, message);
|
|
assert_always("SDL: Unknown log priority");
|
|
break;
|
|
}
|
|
},
|
|
nullptr);
|
|
// SDL itself isn't that talkative. Additionally to this settings there are
|
|
// hints that can be switched on to output additional internal logging
|
|
// information.
|
|
SDL_LogSetAllPriority(SDL_LogPriority::SDL_LOG_PRIORITY_VERBOSE);
|
|
return true;
|
|
}
|
|
} // namespace sdl
|
|
} // namespace helper
|
|
} // namespace xe
|