Compare commits

...

7 Commits

Author SHA1 Message Date
Margen67 b84fe29736
Merge d1be412836 into fe85be8817 2024-12-30 21:37:27 +00:00
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
Adrian 3dac88113f [XBDM] Implemented DmSetMemory and DmGetMemory 2024-12-29 18:35:44 +01:00
The-Little-Wolf 160d80d5cc [Xam/Enum] Implement EnumerateMediaObjects Functions
According to xam versions 8955 and 12611 all EnumerateMediaObjects are the same function and only return 0x80004001
2024-12-29 17:08:43 +01:00
Margen67 d1be412836 Add /Qpar
See https://learn.microsoft.com/en-us/cpp/build/reference/qpar-auto-parallelizer?view=msvc-170
2024-12-16 21:35:12 -08:00
7 changed files with 157 additions and 37 deletions

View File

@ -66,6 +66,7 @@ filter({"configurations:Release", "platforms:Windows"})
buildoptions({
"/Gw",
"/Ob3",
"/Qpar",
})
filter("configurations:Debug")

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,
Args... args) {
std::vector<std::unique_ptr<T>> instances;
if (!name.empty() && name != "any") {
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));
}
}
#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 {
// "Any" path
if (name.empty() || name == "any") {
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)...);
if (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;
}

View File

@ -38,7 +38,12 @@ using WaitItem = TimerQueueWaitItem;
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 {
public:

View File

@ -167,6 +167,18 @@ dword_result_t XamProfileEnumerate_entry(dword_t handle, dword_t flags,
}
DECLARE_XAM_EXPORT1(XamProfileEnumerate, kNone, kImplemented);
dword_result_t EnumerateMediaObjects_entry() { return X_E_NOT_IMPLEMENTED; }
DECLARE_XAM_EXPORT1(EnumerateMediaObjects, kNone, kStub);
dword_result_t EnumerateMediaObjects__entry() { return X_E_NOT_IMPLEMENTED; }
DECLARE_XAM_EXPORT1(EnumerateMediaObjects_, kNone, kStub);
dword_result_t EnumerateMediaObjects_0_entry() { return X_E_NOT_IMPLEMENTED; }
DECLARE_XAM_EXPORT1(EnumerateMediaObjects_0, kNone, kStub);
dword_result_t EnumerateMediaObjects_1_entry() { return X_E_NOT_IMPLEMENTED; }
DECLARE_XAM_EXPORT1(EnumerateMediaObjects_1, kNone, kStub);
} // namespace xam
} // namespace kernel
} // namespace xe

View File

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

View File

@ -171,6 +171,88 @@ dword_result_t DmGetSystemInfo_entry(pointer_t<XBDM_SYSTEM_INFO> info) {
}
DECLARE_XBDM_EXPORT1(DmGetSystemInfo, kDebug, kStub);
dword_result_t DmSetMemory_entry(lpvoid_t dest_ptr, dword_t buf_size,
lpvoid_t src_ptr, lpdword_t bytes_written) {
if (!dest_ptr || !src_ptr || !buf_size) {
return XBDM_UNSUCCESSFUL;
}
if (bytes_written) {
*bytes_written = 0;
}
const uint32_t dest_guest_address = dest_ptr.guest_address();
const uint32_t dest_guest_high_address = dest_guest_address + buf_size;
memory::PageAccess access = memory::PageAccess::kNoAccess;
BaseHeap* dest_heap_ptr =
kernel_state()->memory()->LookupHeap(dest_guest_address);
if (!dest_heap_ptr) {
return XBDM_UNSUCCESSFUL;
}
access = dest_heap_ptr->QueryRangeAccess(dest_guest_address,
dest_guest_high_address);
if (access == memory::PageAccess::kReadWrite) {
memcpy(dest_ptr, src_ptr, buf_size);
if (bytes_written) {
*bytes_written = static_cast<uint32_t>(buf_size);
}
} else {
XELOGE("DmSetMemory failed with page access {}",
static_cast<uint32_t>(access));
return XBDM_UNSUCCESSFUL;
}
return XBDM_SUCCESSFUL;
}
DECLARE_XBDM_EXPORT1(DmSetMemory, kDebug, kImplemented);
dword_result_t DmGetMemory_entry(lpvoid_t src_ptr, dword_t buf_size,
lpvoid_t dest_ptr, lpdword_t bytes_written) {
if (!dest_ptr || !src_ptr || !buf_size) {
return XBDM_UNSUCCESSFUL;
}
if (bytes_written) {
*bytes_written = 0;
}
const uint32_t dest_guest_address = dest_ptr.guest_address();
const uint32_t dest_guest_high_address = dest_guest_address + buf_size;
memory::PageAccess access = memory::PageAccess::kNoAccess;
BaseHeap* dest_heap_ptr =
kernel_state()->memory()->LookupHeap(dest_guest_address);
if (!dest_heap_ptr) {
return XBDM_UNSUCCESSFUL;
}
access = dest_heap_ptr->QueryRangeAccess(dest_guest_address,
dest_guest_high_address);
if (access == memory::PageAccess::kReadWrite) {
memcpy(dest_ptr, src_ptr, buf_size);
if (bytes_written) {
*bytes_written = static_cast<uint32_t>(buf_size);
}
} else {
XELOGE("DmGetMemory failed with page access {}",
static_cast<uint32_t>(access));
return XBDM_UNSUCCESSFUL;
}
return XBDM_SUCCESSFUL;
}
DECLARE_XBDM_EXPORT1(DmGetMemory, kDebug, kImplemented);
dword_result_t DmIsFastCAPEnabled_entry() { return XBDM_UNSUCCESSFUL; }
DECLARE_XBDM_EXPORT1(DmIsFastCAPEnabled, kDebug, kStub);

View File

@ -121,6 +121,7 @@ typedef uint32_t X_HRESULT;
#define X_E_FALSE static_cast<X_HRESULT>(0x80000000L)
#define X_E_SUCCESS X_HRESULT_FROM_WIN32(X_ERROR_SUCCESS)
#define X_E_NOT_IMPLEMENTED static_cast<X_HRESULT>(0x80004001L)
#define X_E_FAIL static_cast<X_HRESULT>(0x80004005L)
#define X_E_NO_MORE_FILES X_HRESULT_FROM_WIN32(X_ERROR_NO_MORE_FILES)
#define X_E_INVALIDARG X_HRESULT_FROM_WIN32(X_ERROR_INVALID_PARAMETER)