mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-03-27 22:05:25 -06:00
Merge branch 'main' into user_and_settings
This commit is contained in:
commit
a9df50cc9b
@ -227,6 +227,8 @@ find_package(fmt 10.2.0 CONFIG)
|
||||
find_package(glslang 15 CONFIG)
|
||||
find_package(half 1.12.0 MODULE)
|
||||
find_package(magic_enum 0.9.7 CONFIG)
|
||||
find_package(miniz 3.1 CONFIG)
|
||||
find_package(nlohmann_json 3.12 CONFIG)
|
||||
find_package(PNG 1.6 MODULE)
|
||||
find_package(OpenAL CONFIG)
|
||||
find_package(RenderDoc 1.6.0 MODULE)
|
||||
@ -1120,7 +1122,7 @@ create_target_directory_groups(shadps4)
|
||||
|
||||
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG)
|
||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 SDL3_mixer::SDL3_mixer pugixml::pugixml)
|
||||
target_link_libraries(shadps4 PRIVATE stb::headers libusb::usb lfreist-hwinfo::hwinfo nlohmann_json::nlohmann_json miniz fdk-aac CLI11::CLI11 OpenAL::OpenAL Cpp_Httplib)
|
||||
target_link_libraries(shadps4 PRIVATE stb::headers libusb::usb lfreist-hwinfo::hwinfo nlohmann_json::nlohmann_json miniz::miniz fdk-aac CLI11::CLI11 OpenAL::OpenAL Cpp_Httplib)
|
||||
|
||||
target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h")
|
||||
target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h")
|
||||
|
||||
@ -73,6 +73,8 @@ You can configure the emulator by editing the `config.toml` file found in the `u
|
||||
- Examples:
|
||||
- If the log is being spammed with messages coming from Lib.Pad, you can use `Lib.Pad:Critical` to only log critical-level messages.
|
||||
- If you'd like to mute everything, but still want to receive messages from Vulkan rendering: `*:Critical Render.Vulkan:Info`
|
||||
- `isIdenticalLogGrouped`: Group same logs in one line with a counter (`true`/`false`)
|
||||
- By default, the emulator will not rewrite the same line, and instead add a counter.
|
||||
|
||||
- `Fullscreen`: Display the game in a full screen borderless window.
|
||||
|
||||
|
||||
7
externals/CMakeLists.txt
vendored
7
externals/CMakeLists.txt
vendored
@ -259,16 +259,19 @@ if (WIN32)
|
||||
add_subdirectory(ext-wepoll)
|
||||
endif()
|
||||
|
||||
if (NOT TARGET fdk-aac)
|
||||
add_subdirectory(aacdec)
|
||||
endif()
|
||||
|
||||
#nlohmann json
|
||||
if (NOT TARGET nlohmann_json::nlohmann_json)
|
||||
set(JSON_BuildTests OFF CACHE INTERNAL "")
|
||||
add_subdirectory(json)
|
||||
endif()
|
||||
|
||||
# miniz
|
||||
if (NOT TARGET miniz::miniz)
|
||||
add_subdirectory(miniz)
|
||||
add_library(miniz::miniz ALIAS miniz)
|
||||
endif()
|
||||
|
||||
# cli11
|
||||
if (NOT TARGET CLI11::CLI11)
|
||||
|
||||
@ -211,41 +211,62 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_lock entry_loc(_mutex);
|
||||
|
||||
if (_last_entry.message == message) {
|
||||
++_last_entry.counter;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_last_entry.counter >= 2) {
|
||||
_last_entry.message += " x" + std::to_string(_last_entry.counter);
|
||||
}
|
||||
|
||||
if (_last_entry.counter >= 1) {
|
||||
if (EmulatorSettings::GetInstance()->GetLogType() == "async") {
|
||||
message_queue.EmplaceWait(_last_entry);
|
||||
} else {
|
||||
ForEachBackend([this](auto& backend) { backend.Write(this->_last_entry); });
|
||||
std::fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::microseconds;
|
||||
using std::chrono::steady_clock;
|
||||
|
||||
this->_last_entry = {
|
||||
.timestamp = duration_cast<microseconds>(steady_clock::now() - time_origin),
|
||||
.log_class = log_class,
|
||||
.log_level = log_level,
|
||||
.filename = filename,
|
||||
.line_num = line_num,
|
||||
.function = function,
|
||||
.message = message,
|
||||
.thread = Common::GetCurrentThreadName(),
|
||||
.counter = 1,
|
||||
};
|
||||
if (Config::groupIdenticalLogs()) {
|
||||
std::unique_lock entry_loc(_mutex);
|
||||
|
||||
if (_last_entry.message == message) {
|
||||
++_last_entry.counter;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_last_entry.counter >= 2) {
|
||||
_last_entry.message += " x" + std::to_string(_last_entry.counter);
|
||||
}
|
||||
|
||||
if (_last_entry.counter >= 1) {
|
||||
if (Config::getLogType() == "async") {
|
||||
message_queue.EmplaceWait(_last_entry);
|
||||
} else {
|
||||
ForEachBackend([this](auto& backend) { backend.Write(this->_last_entry); });
|
||||
std::fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
this->_last_entry = {
|
||||
.timestamp = duration_cast<microseconds>(steady_clock::now() - time_origin),
|
||||
.log_class = log_class,
|
||||
.log_level = log_level,
|
||||
.filename = filename,
|
||||
.line_num = line_num,
|
||||
.function = function,
|
||||
.message = message,
|
||||
.thread = Common::GetCurrentThreadName(),
|
||||
.counter = 1,
|
||||
};
|
||||
} else {
|
||||
const Entry entry = {
|
||||
.timestamp = duration_cast<microseconds>(steady_clock::now() - time_origin),
|
||||
.log_class = log_class,
|
||||
.log_level = log_level,
|
||||
.filename = filename,
|
||||
.line_num = line_num,
|
||||
.function = function,
|
||||
.message = message,
|
||||
.thread = Common::GetCurrentThreadName(),
|
||||
.counter = 1,
|
||||
};
|
||||
|
||||
if (Config::getLogType() == "async") {
|
||||
message_queue.EmplaceWait(entry);
|
||||
} else {
|
||||
ForEachBackend([&entry](auto& backend) { backend.Write(entry); });
|
||||
std::fflush(stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@ -277,21 +298,23 @@ private:
|
||||
}
|
||||
|
||||
void StopBackendThread() {
|
||||
// log last message
|
||||
if (_last_entry.counter >= 2) {
|
||||
_last_entry.message += " x" + std::to_string(_last_entry.counter);
|
||||
}
|
||||
|
||||
if (_last_entry.counter >= 1) {
|
||||
if (EmulatorSettings::GetInstance()->GetLogType() == "async") {
|
||||
message_queue.EmplaceWait(_last_entry);
|
||||
} else {
|
||||
ForEachBackend([this](auto& backend) { backend.Write(this->_last_entry); });
|
||||
std::fflush(stdout);
|
||||
if (Config::groupIdenticalLogs()) {
|
||||
// log last message
|
||||
if (_last_entry.counter >= 2) {
|
||||
_last_entry.message += " x" + std::to_string(_last_entry.counter);
|
||||
}
|
||||
}
|
||||
|
||||
this->_last_entry = {};
|
||||
if (_last_entry.counter >= 1) {
|
||||
if (Config::getLogType() == "async") {
|
||||
message_queue.EmplaceWait(_last_entry);
|
||||
} else {
|
||||
ForEachBackend([this](auto& backend) { backend.Write(this->_last_entry); });
|
||||
std::fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
this->_last_entry = {};
|
||||
}
|
||||
|
||||
backend_thread.request_stop();
|
||||
if (backend_thread.joinable()) {
|
||||
|
||||
@ -2053,7 +2053,7 @@ int PS4_SYSV_ABI sceGnmSqttWaitForEvent() {
|
||||
}
|
||||
|
||||
static inline s32 PatchFlipRequest(u32* cmdbuf, u32 size, u32 vo_handle, u32 buf_idx, u32 flip_mode,
|
||||
u32 flip_arg, void* unk) {
|
||||
s64 flip_arg, void* unk) {
|
||||
// check for `prepareFlip` packet
|
||||
cmdbuf += size - 64;
|
||||
ASSERT_MSG(cmdbuf[0] == 0xc03e1000, "Can't find `prepareFlip` packet");
|
||||
@ -2139,7 +2139,7 @@ static inline s32 PatchFlipRequest(u32* cmdbuf, u32 size, u32 vo_handle, u32 buf
|
||||
s32 PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffers(u32 count, u32* dcb_gpu_addrs[],
|
||||
u32* dcb_sizes_in_bytes, u32* ccb_gpu_addrs[],
|
||||
u32* ccb_sizes_in_bytes, u32 vo_handle,
|
||||
u32 buf_idx, u32 flip_mode, u32 flip_arg) {
|
||||
u32 buf_idx, u32 flip_mode, s64 flip_arg) {
|
||||
return sceGnmSubmitAndFlipCommandBuffersForWorkload(
|
||||
count, count, dcb_gpu_addrs, dcb_sizes_in_bytes, ccb_gpu_addrs, ccb_sizes_in_bytes,
|
||||
vo_handle, buf_idx, flip_mode, flip_arg);
|
||||
@ -2147,7 +2147,7 @@ s32 PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffers(u32 count, u32* dcb_gpu_addrs
|
||||
|
||||
s32 PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffersForWorkload(
|
||||
u32 workload, u32 count, u32* dcb_gpu_addrs[], u32* dcb_sizes_in_bytes, u32* ccb_gpu_addrs[],
|
||||
u32* ccb_sizes_in_bytes, u32 vo_handle, u32 buf_idx, u32 flip_mode, u32 flip_arg) {
|
||||
u32* ccb_sizes_in_bytes, u32 vo_handle, u32 buf_idx, u32 flip_mode, s64 flip_arg) {
|
||||
LOG_DEBUG(Lib_GnmDriver, "called [buf = {}]", buf_idx);
|
||||
|
||||
auto* cmdbuf = dcb_gpu_addrs[count - 1];
|
||||
|
||||
@ -211,10 +211,10 @@ int PS4_SYSV_ABI sceGnmSqttWaitForEvent();
|
||||
s32 PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffers(u32 count, u32* dcb_gpu_addrs[],
|
||||
u32* dcb_sizes_in_bytes, u32* ccb_gpu_addrs[],
|
||||
u32* ccb_sizes_in_bytes, u32 vo_handle,
|
||||
u32 buf_idx, u32 flip_mode, u32 flip_arg);
|
||||
u32 buf_idx, u32 flip_mode, s64 flip_arg);
|
||||
int PS4_SYSV_ABI sceGnmSubmitAndFlipCommandBuffersForWorkload(
|
||||
u32 workload, u32 count, u32* dcb_gpu_addrs[], u32* dcb_sizes_in_bytes, u32* ccb_gpu_addrs[],
|
||||
u32* ccb_sizes_in_bytes, u32 vo_handle, u32 buf_idx, u32 flip_mode, u32 flip_arg);
|
||||
u32* ccb_sizes_in_bytes, u32 vo_handle, u32 buf_idx, u32 flip_mode, s64 flip_arg);
|
||||
s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffers(u32 count, const u32* dcb_gpu_addrs[],
|
||||
u32* dcb_sizes_in_bytes, const u32* ccb_gpu_addrs[],
|
||||
u32* ccb_sizes_in_bytes);
|
||||
|
||||
@ -32,6 +32,14 @@ bool EqueueInternal::AddEvent(EqueueEvent& event) {
|
||||
event.timer_interval = std::chrono::microseconds(event.event.data - offset);
|
||||
}
|
||||
|
||||
// Remove add flag from event
|
||||
event.event.flags &= ~SceKernelEvent::Flags::Add;
|
||||
|
||||
// Clear flag is appended to most event types internally.
|
||||
if (event.event.filter != SceKernelEvent::Filter::User) {
|
||||
event.event.flags |= SceKernelEvent::Flags::Clear;
|
||||
}
|
||||
|
||||
const auto& it = std::ranges::find(m_events, event);
|
||||
if (it != m_events.cend()) {
|
||||
*it = std::move(event);
|
||||
@ -165,10 +173,6 @@ int EqueueInternal::GetTriggeredEvents(SceKernelEvent* ev, int num) {
|
||||
for (auto it = m_events.begin(); it != m_events.end();) {
|
||||
if (it->IsTriggered()) {
|
||||
ev[count++] = it->event;
|
||||
|
||||
// Event should not trigger again
|
||||
it->ResetTriggerState();
|
||||
|
||||
if (it->event.flags & SceKernelEvent::Flags::Clear) {
|
||||
it->Clear();
|
||||
}
|
||||
|
||||
@ -84,11 +84,8 @@ struct EqueueEvent {
|
||||
std::chrono::microseconds timer_interval;
|
||||
std::unique_ptr<boost::asio::steady_timer> timer;
|
||||
|
||||
void ResetTriggerState() {
|
||||
is_triggered = false;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
is_triggered = false;
|
||||
event.fflags = 0;
|
||||
event.data = 0;
|
||||
}
|
||||
@ -101,14 +98,13 @@ struct EqueueEvent {
|
||||
|
||||
void TriggerUser(void* data) {
|
||||
is_triggered = true;
|
||||
event.fflags++;
|
||||
event.udata = data;
|
||||
}
|
||||
|
||||
void TriggerDisplay(void* data) {
|
||||
is_triggered = true;
|
||||
if (data != nullptr) {
|
||||
auto event_data = static_cast<OrbisVideoOutEventData>(event.data);
|
||||
auto event_data = std::bit_cast<OrbisVideoOutEventData>(event.data);
|
||||
auto event_hint_raw = reinterpret_cast<u64>(data);
|
||||
auto event_hint = static_cast<OrbisVideoOutEventHint>(event_hint_raw);
|
||||
if (event_hint.event_id == event.ident && event.ident != 0xfe) {
|
||||
|
||||
@ -218,7 +218,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, s64*
|
||||
}
|
||||
|
||||
auto event_data = ev->data >> 0x10;
|
||||
if (ev->ident != static_cast<s32>(OrbisVideoOutInternalEventId::Flip) || ev->data == 0) {
|
||||
if (ev->ident != static_cast<s32>(OrbisVideoOutInternalEventId::Flip) || ev->data >= 0) {
|
||||
*data = event_data;
|
||||
} else {
|
||||
*data = event_data | 0xffff000000000000;
|
||||
@ -339,7 +339,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetBufferLabelAddress(s32 handle, uintptr_t* label_a
|
||||
return 16;
|
||||
}
|
||||
|
||||
s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, u32 arg, void** unk) {
|
||||
s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, s64 flip_arg, void** unk) {
|
||||
auto* port = driver->GetPort(handle);
|
||||
if (!port) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE;
|
||||
@ -349,7 +349,7 @@ s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, u32 arg, void** u
|
||||
Platform::InterruptId::GfxFlip, [=](Platform::InterruptId irq) {
|
||||
ASSERT_MSG(irq == Platform::InterruptId::GfxFlip, "An unexpected IRQ occured");
|
||||
ASSERT_MSG(port->buffer_labels[buf_id] == 1, "Out of order flip IRQ");
|
||||
const auto result = driver->SubmitFlip(port, buf_id, arg, true);
|
||||
const auto result = driver->SubmitFlip(port, buf_id, flip_arg, true);
|
||||
ASSERT_MSG(result, "EOP flip submission failed");
|
||||
});
|
||||
|
||||
|
||||
@ -139,7 +139,7 @@ s32 PS4_SYSV_ABI sceVideoOutColorSettingsSetGamma(SceVideoOutColorSettings* sett
|
||||
s32 PS4_SYSV_ABI sceVideoOutAdjustColor(s32 handle, const SceVideoOutColorSettings* settings);
|
||||
|
||||
// Internal system functions
|
||||
s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, u32 arg, void** unk);
|
||||
s32 sceVideoOutSubmitEopFlip(s32 handle, u32 buf_id, u32 mode, s64 flip_arg, void** unk);
|
||||
|
||||
void RegisterLib(Core::Loader::SymbolsResolver* sym);
|
||||
|
||||
|
||||
@ -61,7 +61,10 @@ template <class ReturnType, class... FuncArgs, class... CallArgs>
|
||||
ReturnType ExecuteGuest(PS4_SYSV_ABI ReturnType (*func)(FuncArgs...), CallArgs&&... args) {
|
||||
EnsureThreadInitialized();
|
||||
// clear stack to avoid trash from EnsureThreadInitialized
|
||||
ClearStack<12_KB>();
|
||||
auto* tcb = GetTcbBase();
|
||||
if (tcb != nullptr && tcb->tcb_fiber == nullptr) {
|
||||
ClearStack<12_KB>();
|
||||
}
|
||||
return func(std::forward<CallArgs>(args)...);
|
||||
}
|
||||
|
||||
|
||||
@ -240,6 +240,7 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> args,
|
||||
LOG_INFO(Config, "Game-specific config exists: {}", has_game_config);
|
||||
|
||||
LOG_INFO(Config, "General LogType: {}", EmulatorSettings::GetInstance()->GetLogType());
|
||||
LOG_INFO(Config, "General isIdenticalLogGrouped: {}", Config::groupIdenticalLogs());
|
||||
LOG_INFO(Config, "General isNeo: {}", EmulatorSettings::GetInstance()->IsNeo());
|
||||
LOG_INFO(Config, "General isDevKit: {}", EmulatorSettings::GetInstance()->IsDevKit());
|
||||
LOG_INFO(Config, "General isConnectedToNetwork: {}",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user