Compare commits
5 Commits
b991bc0a1e
...
25d11b8d77
Author | SHA1 | Date |
---|---|---|
Marco Rodolfi | 25d11b8d77 | |
Marco Rodolfi | 55bbb28a80 | |
Marco Rodolfi | d395891fc9 | |
The-Little-Wolf | 4d7b30e844 | |
Marco Rodolfi | d7ffa408dd |
|
@ -53,4 +53,7 @@ uint64_t Clock::QueryHostUptimeMillis() {
|
||||||
return host_tick_count_platform() * 1000 / host_tick_frequency_platform();
|
return host_tick_count_platform() * 1000 / host_tick_frequency_platform();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t Clock::QueryHostInterruptTime() {
|
||||||
|
return host_tick_count_platform();
|
||||||
|
}
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -24,5 +24,28 @@ bool CreateParentFolder(const std::filesystem::path& path) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<FileInfo> ListDirectories(const std::filesystem::path& path) {
|
||||||
|
std::vector<FileInfo> files = ListFiles(path);
|
||||||
|
std::vector<FileInfo> directories = {};
|
||||||
|
|
||||||
|
std::copy_if(
|
||||||
|
files.cbegin(), files.cend(), std::back_inserter(directories),
|
||||||
|
[](const FileInfo& file) { return file.type == FileInfo::Type::kDirectory; });
|
||||||
|
|
||||||
|
return std::move(directories);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<FileInfo> FilterByName(const std::vector<FileInfo>& files,
|
||||||
|
const std::regex pattern) {
|
||||||
|
std::vector<FileInfo> filtered_entries = {};
|
||||||
|
|
||||||
|
std::copy_if(files.cbegin(), files.cend(),
|
||||||
|
std::back_inserter(filtered_entries), [pattern](const FileInfo& file) {
|
||||||
|
return std::regex_match(file.name.filename().string(),
|
||||||
|
pattern);
|
||||||
|
});
|
||||||
|
return std::move(filtered_entries);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace filesystem
|
} // namespace filesystem
|
||||||
} // namespace xe
|
} // namespace xe
|
||||||
|
|
|
@ -192,20 +192,27 @@ std::unique_ptr<FileHandle> FileHandle::OpenExisting(
|
||||||
return std::make_unique<PosixFileHandle>(path, handle);
|
return std::make_unique<PosixFileHandle>(path, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetInfo(const std::filesystem::path& path, FileInfo* out_info) {
|
std::optional<FileInfo> GetInfo(const std::filesystem::path& path) {
|
||||||
|
FileInfo info{};
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(path.c_str(), &st) == 0) {
|
if (stat(path.c_str(), &st) == 0) {
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
out_info->type = FileInfo::Type::kDirectory;
|
info.type = FileInfo::Type::kDirectory;
|
||||||
|
// On Linux st.st_size can have non-zero size (generally 4096) so make 0
|
||||||
|
info.total_size = 0;
|
||||||
} else {
|
} else {
|
||||||
out_info->type = FileInfo::Type::kFile;
|
info.type = FileInfo::Type::kFile;
|
||||||
|
info.total_size = st.st_size;
|
||||||
|
|
||||||
}
|
}
|
||||||
out_info->create_timestamp = convertUnixtimeToWinFiletime(st.st_ctime);
|
info.path = path.parent_path();
|
||||||
out_info->access_timestamp = convertUnixtimeToWinFiletime(st.st_atime);
|
info.name = path.filename();
|
||||||
out_info->write_timestamp = convertUnixtimeToWinFiletime(st.st_mtime);
|
info.create_timestamp = convertUnixtimeToWinFiletime(st.st_ctime);
|
||||||
return true;
|
info.access_timestamp = convertUnixtimeToWinFiletime(st.st_atime);
|
||||||
|
info.write_timestamp = convertUnixtimeToWinFiletime(st.st_mtime);
|
||||||
|
return std::move(info);
|
||||||
}
|
}
|
||||||
return false;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<FileInfo> ListFiles(const std::filesystem::path& path) {
|
std::vector<FileInfo> ListFiles(const std::filesystem::path& path) {
|
||||||
|
@ -240,7 +247,7 @@ std::vector<FileInfo> ListFiles(const std::filesystem::path& path) {
|
||||||
result.push_back(info);
|
result.push_back(info);
|
||||||
}
|
}
|
||||||
closedir(dir);
|
closedir(dir);
|
||||||
return result;
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetAttributes(const std::filesystem::path& path, uint64_t attributes) {
|
bool SetAttributes(const std::filesystem::path& path, uint64_t attributes) {
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* Xenia : Xbox 360 Emulator Research Project *
|
||||||
|
******************************************************************************
|
||||||
|
* Copyright 2023 Ben Vanik. All rights reserved. *
|
||||||
|
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <gdk/gdk.h>
|
||||||
|
#include <xbyak/xbyak/xbyak_util.h>
|
||||||
|
|
||||||
|
#include "xenia/ui/window_gtk.h"
|
||||||
|
|
||||||
|
class StartupCpuFeatureCheck {
|
||||||
|
public:
|
||||||
|
StartupCpuFeatureCheck() {
|
||||||
|
Xbyak::util::Cpu cpu;
|
||||||
|
const char* error_message = nullptr;
|
||||||
|
if (!cpu.has(Xbyak::util::Cpu::tAVX)) {
|
||||||
|
error_message =
|
||||||
|
"Your CPU does not support AVX, which is required by Xenia. See "
|
||||||
|
"the "
|
||||||
|
"FAQ for system requirements at https://xenia.jp";
|
||||||
|
}
|
||||||
|
if (error_message == nullptr) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
GtkDialogFlags flags = GTK_DIALOG_DESTROY_WITH_PARENT;
|
||||||
|
auto dialog =
|
||||||
|
gtk_message_dialog_new(nullptr, flags, GTK_MESSAGE_ERROR,
|
||||||
|
GTK_BUTTONS_CLOSE,error_message);
|
||||||
|
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is a hack to get an instance of StartupAvxCheck
|
||||||
|
// constructed before any initialization code,
|
||||||
|
// where the AVX check then happens in the constructor.
|
||||||
|
// Ref:
|
||||||
|
// https://reviews.llvm.org/D12689#243295
|
||||||
|
__attribute__((init_priority(101)))
|
||||||
|
static StartupCpuFeatureCheck gStartupAvxCheck;
|
|
@ -402,6 +402,7 @@ class Timer : public WaitHandle {
|
||||||
virtual bool Cancel() = 0;
|
virtual bool Cancel() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if XE_PLATFORM_WINDOWS
|
||||||
struct ThreadPriority {
|
struct ThreadPriority {
|
||||||
static const int32_t kLowest = -2;
|
static const int32_t kLowest = -2;
|
||||||
static const int32_t kBelowNormal = -1;
|
static const int32_t kBelowNormal = -1;
|
||||||
|
@ -409,6 +410,15 @@ struct ThreadPriority {
|
||||||
static const int32_t kAboveNormal = 1;
|
static const int32_t kAboveNormal = 1;
|
||||||
static const int32_t kHighest = 2;
|
static const int32_t kHighest = 2;
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
struct ThreadPriority {
|
||||||
|
static const int32_t kLowest = 1;
|
||||||
|
static const int32_t kBelowNormal = 8;
|
||||||
|
static const int32_t kNormal = 16;
|
||||||
|
static const int32_t kAboveNormal = 24;
|
||||||
|
static const int32_t kHighest = 32;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
// Models a Win32-like thread object.
|
// Models a Win32-like thread object.
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682453(v=vs.85).aspx
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "logging.h"
|
||||||
|
|
||||||
#if XE_PLATFORM_ANDROID
|
#if XE_PLATFORM_ANDROID
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
@ -159,6 +161,10 @@ void Sleep(std::chrono::microseconds duration) {
|
||||||
} while (ret == -1 && errno == EINTR);
|
} while (ret == -1 && errno == EINTR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NanoSleep(int64_t duration) {
|
||||||
|
Sleep(std::chrono::nanoseconds(duration));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(bwrsandman) Implement by allowing alert interrupts from IO operations
|
// TODO(bwrsandman) Implement by allowing alert interrupts from IO operations
|
||||||
thread_local bool alertable_state_ = false;
|
thread_local bool alertable_state_ = false;
|
||||||
SleepResult AlertableSleep(std::chrono::microseconds duration) {
|
SleepResult AlertableSleep(std::chrono::microseconds duration) {
|
||||||
|
@ -660,8 +666,18 @@ class PosixCondition<Thread> : public PosixConditionBase {
|
||||||
WaitStarted();
|
WaitStarted();
|
||||||
sched_param param{};
|
sched_param param{};
|
||||||
param.sched_priority = new_priority;
|
param.sched_priority = new_priority;
|
||||||
if (pthread_setschedparam(thread_, SCHED_FIFO, ¶m) != 0)
|
int res = pthread_setschedparam(thread_, SCHED_FIFO, ¶m);
|
||||||
assert_always();
|
if (res != 0) {
|
||||||
|
switch (res) {
|
||||||
|
case EPERM:
|
||||||
|
XELOGW("Permission denied while setting priority");
|
||||||
|
break;
|
||||||
|
case EINVAL:
|
||||||
|
assert_always();
|
||||||
|
default:
|
||||||
|
XELOGW("Unknown error while setting priority");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QueueUserCallback(std::function<void()> callback) {
|
void QueueUserCallback(std::function<void()> callback) {
|
||||||
|
|
|
@ -799,6 +799,18 @@ dword_result_t XamUserGetUserFlagsFromXUID_entry(qword_t xuid) {
|
||||||
}
|
}
|
||||||
DECLARE_XAM_EXPORT1(XamUserGetUserFlagsFromXUID, kUserProfiles, kImplemented);
|
DECLARE_XAM_EXPORT1(XamUserGetUserFlagsFromXUID, kUserProfiles, kImplemented);
|
||||||
|
|
||||||
|
dword_result_t XamUserGetOnlineLanguageFromXUID_entry(qword_t xuid) {
|
||||||
|
/* Notes:
|
||||||
|
- Calls XamUserGetUserFlagsFromXUID and returns (ulonglong)(cached_flag <<
|
||||||
|
0x20) >> 0x39 & 0x1f;
|
||||||
|
- XamUserGetMembershipTierFromXUID and XamUserGetOnlineCountryFromXUID also
|
||||||
|
call it
|
||||||
|
- Removed in metro
|
||||||
|
*/
|
||||||
|
return cvars::user_language;
|
||||||
|
}
|
||||||
|
DECLARE_XAM_EXPORT1(XamUserGetOnlineLanguageFromXUID, kUserProfiles, kStub);
|
||||||
|
|
||||||
constexpr uint8_t kStatsMaxAmount = 64;
|
constexpr uint8_t kStatsMaxAmount = 64;
|
||||||
|
|
||||||
struct X_STATS_DETAILS {
|
struct X_STATS_DETAILS {
|
||||||
|
|
Loading…
Reference in New Issue