Compare commits

...

3 Commits

Author SHA1 Message Date
Gliniak fe85be8817 [XAM] Fixed possible crash caused by printing invalid characters in XamUserGetGamerTag and XamUserGetName 2024-12-30 19:47:10 +01:00
Gliniak c3301d9281 [Base] Fixed issue with initialization deadlock on Proton
For whatever reason Proton doesn't like it when Xenia is compiled with 2022 MSVC
2024-12-30 16:41:47 +01:00
Gliniak 1ba30c519c [HID] Fixed issues with double input in specific config HID configuration.
This was the case in hid set to "any" or to "winkey" and game that requires input from any user
2024-12-30 15:43:40 +01:00
3 changed files with 61 additions and 37 deletions

View File

@ -176,36 +176,50 @@ class EmulatorApp final : public xe::ui::WindowedApp {
std::vector<std::unique_ptr<T>> CreateAll(const std::string_view name, std::vector<std::unique_ptr<T>> CreateAll(const std::string_view name,
Args... args) { Args... args) {
std::vector<std::unique_ptr<T>> instances; std::vector<std::unique_ptr<T>> instances;
if (!name.empty() && name != "any") {
auto it = std::find_if( // "Any" path
creators_.cbegin(), creators_.cend(), if (name.empty() || name == "any") {
[&name](const auto& f) { return name.compare(f.name) == 0; });
if (it != creators_.cend() && (*it).is_available()) {
auto instance = (*it).instantiate(std::forward<Args>(args)...);
if (instance) {
instances.emplace_back(std::move(instance));
}
}
#if XE_PLATFORM_WIN32
// Always add winkey for passthrough
it = std::find_if(
creators_.cbegin(), creators_.cend(),
[&name](const auto& f) { return f.name.compare("winkey") == 0; });
if (it != creators_.cend() && (*it).is_available()) {
auto instance = (*it).instantiate(std::forward<Args>(args)...);
if (instance) {
instances.emplace_back(std::move(instance));
}
}
#endif
} else {
for (const auto& creator : creators_) { for (const auto& creator : creators_) {
if (!creator.is_available()) continue; if (!creator.is_available()) {
continue;
}
// Skip xinput for "any" and use SDL
if (creator.name.compare("xinput") == 0) {
continue;
}
auto instance = creator.instantiate(std::forward<Args>(args)...); auto instance = creator.instantiate(std::forward<Args>(args)...);
if (instance) { if (instance) {
instances.emplace_back(std::move(instance)); instances.emplace_back(std::move(instance));
} }
} }
return instances;
}
// "Specified" path. Winkey is always added on windows.
if (name != "winkey") {
auto it = std::find_if(
creators_.cbegin(), creators_.cend(),
[&name](const auto& f) { return name.compare(f.name) == 0; });
if (it != creators_.cend() && (*it).is_available()) {
auto instance = (*it).instantiate(std::forward<Args>(args)...);
if (instance) {
instances.emplace_back(std::move(instance));
}
}
}
// Always add winkey for passthrough.
auto it = std::find_if(
creators_.cbegin(), creators_.cend(),
[&name](const auto& f) { return f.name.compare("winkey") == 0; });
if (it != creators_.cend() && (*it).is_available()) {
auto instance = (*it).instantiate(std::forward<Args>(args)...);
if (instance) {
instances.emplace_back(std::move(instance));
}
} }
return instances; return instances;
} }

View File

@ -38,7 +38,12 @@ using WaitItem = TimerQueueWaitItem;
condition_variable::wait_until) but now builds condition_variable::wait_until) but now builds
*/ */
using WaitStrat = dp::blocking_wait_strategy;
/*
edit2: (30.12.2024) After uplifting version of MSVC compiler Xenia cannot be
correctly initialized if you're using proton.
*/
using WaitStrat = dp::spin_wait_strategy;
class TimerQueue { class TimerQueue {
public: public:

View File

@ -139,28 +139,30 @@ X_HRESULT_result_t XamUserGetSigninInfo_entry(
} }
DECLARE_XAM_EXPORT1(XamUserGetSigninInfo, kUserProfiles, kImplemented); DECLARE_XAM_EXPORT1(XamUserGetSigninInfo, kUserProfiles, kImplemented);
dword_result_t XamUserGetName_entry(dword_t user_index, lpstring_t buffer, dword_result_t XamUserGetName_entry(dword_t user_index, dword_t buffer,
dword_t buffer_len) { dword_t buffer_len) {
if (user_index >= XUserMaxUserCount) { if (user_index >= XUserMaxUserCount) {
return X_ERROR_INVALID_PARAMETER; return X_ERROR_INVALID_PARAMETER;
} }
if (kernel_state()->xam_state()->IsUserSignedIn(user_index)) { char* str_buffer = kernel_memory()->TranslateVirtual<char*>(buffer);
const auto& user_profile =
kernel_state()->xam_state()->GetUserProfile(user_index); if (!kernel_state()->xam_state()->IsUserSignedIn(user_index)) {
const auto& user_name = user_profile->name(); *str_buffer = 0;
xe::string_util::copy_truncating(
buffer, user_name, std::min(buffer_len.value(), uint32_t(16)));
} else {
*buffer = 0;
return X_ERROR_NO_SUCH_USER; return X_ERROR_NO_SUCH_USER;
} }
const auto& user_profile =
kernel_state()->xam_state()->GetUserProfile(user_index);
const auto& user_name = user_profile->name();
xe::string_util::copy_truncating(str_buffer, user_name,
std::min(buffer_len.value(), uint32_t(16)));
return X_ERROR_SUCCESS; return X_ERROR_SUCCESS;
} }
DECLARE_XAM_EXPORT1(XamUserGetName, kUserProfiles, kImplemented); DECLARE_XAM_EXPORT1(XamUserGetName, kUserProfiles, kImplemented);
dword_result_t XamUserGetGamerTag_entry(dword_t user_index, dword_result_t XamUserGetGamerTag_entry(dword_t user_index, dword_t buffer,
lpu16string_t buffer,
dword_t buffer_len) { dword_t buffer_len) {
if (!buffer || buffer_len < 16) { if (!buffer || buffer_len < 16) {
return X_E_INVALIDARG; return X_E_INVALIDARG;
@ -177,8 +179,11 @@ dword_result_t XamUserGetGamerTag_entry(dword_t user_index,
const auto& user_profile = const auto& user_profile =
kernel_state()->xam_state()->GetUserProfile(user_index); kernel_state()->xam_state()->GetUserProfile(user_index);
auto user_name = xe::to_utf16(user_profile->name()); auto user_name = xe::to_utf16(user_profile->name());
char16_t* str_buffer = kernel_memory()->TranslateVirtual<char16_t*>(buffer);
xe::string_util::copy_and_swap_truncating( xe::string_util::copy_and_swap_truncating(
buffer, user_name, std::min(buffer_len.value(), uint32_t(16))); str_buffer, user_name, std::min(buffer_len.value(), uint32_t(16)));
return X_E_SUCCESS; return X_E_SUCCESS;
} }
DECLARE_XAM_EXPORT1(XamUserGetGamerTag, kUserProfiles, kImplemented); DECLARE_XAM_EXPORT1(XamUserGetGamerTag, kUserProfiles, kImplemented);