Compare commits
7 Commits
7b74a70a86
...
b84fe29736
Author | SHA1 | Date |
---|---|---|
Margen67 | b84fe29736 | |
Gliniak | fe85be8817 | |
Gliniak | c3301d9281 | |
Gliniak | 1ba30c519c | |
Adrian | 3dac88113f | |
The-Little-Wolf | 160d80d5cc | |
Margen67 | d1be412836 |
|
@ -66,6 +66,7 @@ filter({"configurations:Release", "platforms:Windows"})
|
||||||
buildoptions({
|
buildoptions({
|
||||||
"/Gw",
|
"/Gw",
|
||||||
"/Ob3",
|
"/Ob3",
|
||||||
|
"/Qpar",
|
||||||
})
|
})
|
||||||
|
|
||||||
filter("configurations:Debug")
|
filter("configurations:Debug")
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -167,6 +167,18 @@ dword_result_t XamProfileEnumerate_entry(dword_t handle, dword_t flags,
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT1(XamProfileEnumerate, kNone, kImplemented);
|
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 xam
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -171,6 +171,88 @@ dword_result_t DmGetSystemInfo_entry(pointer_t<XBDM_SYSTEM_INFO> info) {
|
||||||
}
|
}
|
||||||
DECLARE_XBDM_EXPORT1(DmGetSystemInfo, kDebug, kStub);
|
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; }
|
dword_result_t DmIsFastCAPEnabled_entry() { return XBDM_UNSUCCESSFUL; }
|
||||||
DECLARE_XBDM_EXPORT1(DmIsFastCAPEnabled, kDebug, kStub);
|
DECLARE_XBDM_EXPORT1(DmIsFastCAPEnabled, kDebug, kStub);
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,7 @@ typedef uint32_t X_HRESULT;
|
||||||
|
|
||||||
#define X_E_FALSE static_cast<X_HRESULT>(0x80000000L)
|
#define X_E_FALSE static_cast<X_HRESULT>(0x80000000L)
|
||||||
#define X_E_SUCCESS X_HRESULT_FROM_WIN32(X_ERROR_SUCCESS)
|
#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_FAIL static_cast<X_HRESULT>(0x80004005L)
|
||||||
#define X_E_NO_MORE_FILES X_HRESULT_FROM_WIN32(X_ERROR_NO_MORE_FILES)
|
#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)
|
#define X_E_INVALIDARG X_HRESULT_FROM_WIN32(X_ERROR_INVALID_PARAMETER)
|
||||||
|
|
Loading…
Reference in New Issue