Merge pull request #213 from shadps4-emu/hle/trophies
A better stub for trophies
This commit is contained in:
commit
8f45be7d44
|
@ -12,7 +12,7 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
namespace VideoCore {
|
namespace Common {
|
||||||
|
|
||||||
struct SlotId {
|
struct SlotId {
|
||||||
static constexpr u32 INVALID_INDEX = std::numeric_limits<u32>::max();
|
static constexpr u32 INVALID_INDEX = std::numeric_limits<u32>::max();
|
||||||
|
@ -54,6 +54,10 @@ public:
|
||||||
return values[id.index].object;
|
return values[id.index].object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_allocated(SlotId id) const {
|
||||||
|
return ReadStorageBit(id.index);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
template <typename... Args>
|
||||||
[[nodiscard]] SlotId insert(Args&&... args) noexcept {
|
[[nodiscard]] SlotId insert(Args&&... args) noexcept {
|
||||||
const u32 index = FreeValueIndex();
|
const u32 index = FreeValueIndex();
|
||||||
|
@ -107,7 +111,7 @@ private:
|
||||||
stored_bitset[index / 64] &= ~(u64(1) << (index % 64));
|
stored_bitset[index / 64] &= ~(u64(1) << (index % 64));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadStorageBit(u32 index) noexcept {
|
bool ReadStorageBit(u32 index) const noexcept {
|
||||||
return ((stored_bitset[index / 64] >> (index % 64)) & 1) != 0;
|
return ((stored_bitset[index / 64] >> (index % 64)) & 1) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,11 +166,11 @@ private:
|
||||||
std::vector<u32> free_list;
|
std::vector<u32> free_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace VideoCore
|
} // namespace Common
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct std::hash<VideoCore::SlotId> {
|
struct std::hash<Common::SlotId> {
|
||||||
std::size_t operator()(const VideoCore::SlotId& id) const noexcept {
|
std::size_t operator()(const Common::SlotId& id) const noexcept {
|
||||||
return std::hash<u32>{}(id.index);
|
return std::hash<u32>{}(id.index);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -446,3 +446,10 @@ constexpr int ORBIS_USER_SERVICE_ERROR_BUFFER_TOO_SHORT = 0x8096000A;
|
||||||
|
|
||||||
// SystemService library
|
// SystemService library
|
||||||
constexpr int ORBIS_SYSTEM_SERVICE_ERROR_PARAMETER = 0x80A10003;
|
constexpr int ORBIS_SYSTEM_SERVICE_ERROR_PARAMETER = 0x80A10003;
|
||||||
|
|
||||||
|
// NpTrophy library
|
||||||
|
constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_ARGUMENT = 0x80551604;
|
||||||
|
constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_HANDLE = 0x80551608;
|
||||||
|
constexpr int ORBIS_NP_TROPHY_ERROR_HANDLE_EXCEEDS_MAX = 0x80551624;
|
||||||
|
constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_ALREADY_EXISTS = 0x80551613;
|
||||||
|
constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_EXCEEDS_MAX = 0x80551622;
|
||||||
|
|
|
@ -53,7 +53,7 @@ struct AscQueueInfo {
|
||||||
u32* read_addr;
|
u32* read_addr;
|
||||||
u32 ring_size_dw;
|
u32 ring_size_dw;
|
||||||
};
|
};
|
||||||
static VideoCore::SlotVector<AscQueueInfo> asc_queues{};
|
static Common::SlotVector<AscQueueInfo> asc_queues{};
|
||||||
static constexpr VAddr tessellation_factors_ring_addr = 0xFF0000000ULL;
|
static constexpr VAddr tessellation_factors_ring_addr = 0xFF0000000ULL;
|
||||||
|
|
||||||
static void DumpCommandList(std::span<const u32> cmd_list, const std::string& postfix) {
|
static void DumpCommandList(std::span<const u32> cmd_list, const std::string& postfix) {
|
||||||
|
|
|
@ -1278,6 +1278,7 @@ int PS4_SYSV_ABI scePthreadOnce(int* once_control, void (*init_routine)(void)) {
|
||||||
|
|
||||||
[[noreturn]] void PS4_SYSV_ABI scePthreadExit(void* value_ptr) {
|
[[noreturn]] void PS4_SYSV_ABI scePthreadExit(void* value_ptr) {
|
||||||
pthread_exit(value_ptr);
|
pthread_exit(value_ptr);
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
void pthreadSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
|
|
@ -2,13 +2,33 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
// Generated By moduleGenerator
|
// Generated By moduleGenerator
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/slot_vector.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
#include "np_trophy.h"
|
#include "np_trophy.h"
|
||||||
|
|
||||||
namespace Libraries::NpTrophy {
|
namespace Libraries::NpTrophy {
|
||||||
|
|
||||||
|
static constexpr auto MaxTrophyHandles = 4u;
|
||||||
|
static constexpr auto MaxTrophyContexts = 8u;
|
||||||
|
|
||||||
|
using ContextKey = std::pair<u32, u32>; // <user_id, service label>
|
||||||
|
struct ContextKeyHash {
|
||||||
|
size_t operator()(const ContextKey& key) const {
|
||||||
|
return key.first + (u64(key.second) << 32u);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TrophyContext {
|
||||||
|
u32 context_id;
|
||||||
|
};
|
||||||
|
static Common::SlotVector<u32> trophy_handles{};
|
||||||
|
static Common::SlotVector<ContextKey> trophy_contexts{};
|
||||||
|
static std::unordered_map<ContextKey, TrophyContext, ContextKeyHash> contexts_internal{};
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpTrophyAbortHandle() {
|
int PS4_SYSV_ABI sceNpTrophyAbortHandle() {
|
||||||
LOG_ERROR(Lib_NpTrophy, "(STUBBED) called");
|
LOG_ERROR(Lib_NpTrophy, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -64,14 +84,43 @@ int PS4_SYSV_ABI sceNpTrophyConfigHasGroupFeature() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpTrophyCreateContext() {
|
s32 PS4_SYSV_ABI sceNpTrophyCreateContext(u32* context, u32 user_id, u32 service_label,
|
||||||
LOG_ERROR(Lib_NpTrophy, "(STUBBED) called");
|
u64 options) {
|
||||||
|
ASSERT(options == 0ull);
|
||||||
|
if (!context) {
|
||||||
|
return ORBIS_NP_TROPHY_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trophy_contexts.size() >= MaxTrophyContexts) {
|
||||||
|
return ORBIS_NP_TROPHY_ERROR_CONTEXT_EXCEEDS_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& key = ContextKey{user_id, service_label};
|
||||||
|
if (contexts_internal.contains(key)) {
|
||||||
|
return ORBIS_NP_TROPHY_ERROR_CONTEXT_ALREADY_EXISTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ctx_id = trophy_contexts.insert(user_id, service_label);
|
||||||
|
contexts_internal[key].context_id = ctx_id.index;
|
||||||
|
LOG_INFO(Lib_NpTrophy, "New context = {}, user_id = {} service label = {}", ctx_id.index,
|
||||||
|
user_id, service_label);
|
||||||
|
*context = ctx_id.index;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpTrophyCreateHandle() {
|
s32 PS4_SYSV_ABI sceNpTrophyCreateHandle(u32* handle) {
|
||||||
LOG_ERROR(Lib_NpTrophy, "(STUBBED) called");
|
if (!handle) {
|
||||||
return -1;
|
return ORBIS_NP_TROPHY_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trophy_handles.size() >= MaxTrophyHandles) {
|
||||||
|
return ORBIS_NP_TROPHY_ERROR_HANDLE_EXCEEDS_MAX;
|
||||||
|
}
|
||||||
|
const auto handle_id = trophy_handles.insert();
|
||||||
|
LOG_INFO(Lib_NpTrophy, "New handle = {}", handle_id.index);
|
||||||
|
|
||||||
|
*handle = handle_id.index;
|
||||||
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpTrophyDestroyContext() {
|
int PS4_SYSV_ABI sceNpTrophyDestroyContext() {
|
||||||
|
@ -79,8 +128,13 @@ int PS4_SYSV_ABI sceNpTrophyDestroyContext() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpTrophyDestroyHandle() {
|
s32 PS4_SYSV_ABI sceNpTrophyDestroyHandle(u32 handle) {
|
||||||
LOG_ERROR(Lib_NpTrophy, "(STUBBED) called");
|
if (!trophy_handles.is_allocated({handle})) {
|
||||||
|
return ORBIS_NP_TROPHY_ERROR_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
trophy_handles.erase({handle});
|
||||||
|
LOG_INFO(Lib_NpTrophy, "Handle {} destroyed", handle);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,8 +168,10 @@ int PS4_SYSV_ABI sceNpTrophyGetTrophyInfo() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNpTrophyGetTrophyUnlockState() {
|
s32 PS4_SYSV_ABI sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, u32* flags, u32* count) {
|
||||||
LOG_ERROR(Lib_NpTrophy, "(STUBBED) called");
|
LOG_ERROR(Lib_NpTrophy, "(STUBBED) called");
|
||||||
|
*flags = 0u;
|
||||||
|
*count = 0;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,17 +22,18 @@ int PS4_SYSV_ABI sceNpTrophyConfigGetTrophySetInfoInGroup();
|
||||||
int PS4_SYSV_ABI sceNpTrophyConfigGetTrophySetVersion();
|
int PS4_SYSV_ABI sceNpTrophyConfigGetTrophySetVersion();
|
||||||
int PS4_SYSV_ABI sceNpTrophyConfigGetTrophyTitleDetails();
|
int PS4_SYSV_ABI sceNpTrophyConfigGetTrophyTitleDetails();
|
||||||
int PS4_SYSV_ABI sceNpTrophyConfigHasGroupFeature();
|
int PS4_SYSV_ABI sceNpTrophyConfigHasGroupFeature();
|
||||||
int PS4_SYSV_ABI sceNpTrophyCreateContext();
|
s32 PS4_SYSV_ABI sceNpTrophyCreateContext(u32* context, u32 user_id, u32 service_label,
|
||||||
int PS4_SYSV_ABI sceNpTrophyCreateHandle();
|
u64 options);
|
||||||
|
s32 PS4_SYSV_ABI sceNpTrophyCreateHandle(u32* handle);
|
||||||
int PS4_SYSV_ABI sceNpTrophyDestroyContext();
|
int PS4_SYSV_ABI sceNpTrophyDestroyContext();
|
||||||
int PS4_SYSV_ABI sceNpTrophyDestroyHandle();
|
s32 PS4_SYSV_ABI sceNpTrophyDestroyHandle(u32 handle);
|
||||||
int PS4_SYSV_ABI sceNpTrophyGetGameIcon();
|
int PS4_SYSV_ABI sceNpTrophyGetGameIcon();
|
||||||
int PS4_SYSV_ABI sceNpTrophyGetGameInfo();
|
int PS4_SYSV_ABI sceNpTrophyGetGameInfo();
|
||||||
int PS4_SYSV_ABI sceNpTrophyGetGroupIcon();
|
int PS4_SYSV_ABI sceNpTrophyGetGroupIcon();
|
||||||
int PS4_SYSV_ABI sceNpTrophyGetGroupInfo();
|
int PS4_SYSV_ABI sceNpTrophyGetGroupInfo();
|
||||||
int PS4_SYSV_ABI sceNpTrophyGetTrophyIcon();
|
int PS4_SYSV_ABI sceNpTrophyGetTrophyIcon();
|
||||||
int PS4_SYSV_ABI sceNpTrophyGetTrophyInfo();
|
int PS4_SYSV_ABI sceNpTrophyGetTrophyInfo();
|
||||||
int PS4_SYSV_ABI sceNpTrophyGetTrophyUnlockState();
|
s32 PS4_SYSV_ABI sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, u32* flags, u32* count);
|
||||||
int PS4_SYSV_ABI sceNpTrophyGroupArrayGetNum();
|
int PS4_SYSV_ABI sceNpTrophyGroupArrayGetNum();
|
||||||
int PS4_SYSV_ABI sceNpTrophyIntAbortHandle();
|
int PS4_SYSV_ABI sceNpTrophyIntAbortHandle();
|
||||||
int PS4_SYSV_ABI sceNpTrophyIntCheckNetSyncTitles();
|
int PS4_SYSV_ABI sceNpTrophyIntCheckNetSyncTitles();
|
||||||
|
|
|
@ -100,7 +100,7 @@ private:
|
||||||
vk::Image image{};
|
vk::Image image{};
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr SlotId NULL_IMAGE_ID{0};
|
constexpr Common::SlotId NULL_IMAGE_ID{0};
|
||||||
|
|
||||||
struct Image {
|
struct Image {
|
||||||
explicit Image(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler,
|
explicit Image(const Vulkan::Instance& instance, Vulkan::Scheduler& scheduler,
|
||||||
|
|
|
@ -140,8 +140,8 @@ private:
|
||||||
Vulkan::Scheduler& scheduler;
|
Vulkan::Scheduler& scheduler;
|
||||||
Vulkan::StreamBuffer staging;
|
Vulkan::StreamBuffer staging;
|
||||||
TileManager tile_manager;
|
TileManager tile_manager;
|
||||||
SlotVector<Image> slot_images;
|
Common::SlotVector<Image> slot_images;
|
||||||
SlotVector<ImageView> slot_image_views;
|
Common::SlotVector<ImageView> slot_image_views;
|
||||||
tsl::robin_map<u64, Sampler> samplers;
|
tsl::robin_map<u64, Sampler> samplers;
|
||||||
tsl::robin_pg_map<u64, std::vector<ImageId>> page_table;
|
tsl::robin_pg_map<u64, std::vector<ImageId>> page_table;
|
||||||
boost::icl::interval_map<VAddr, s32> cached_pages;
|
boost::icl::interval_map<VAddr, s32> cached_pages;
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
namespace VideoCore {
|
namespace VideoCore {
|
||||||
|
|
||||||
using ImageId = SlotId;
|
using ImageId = Common::SlotId;
|
||||||
using ImageViewId = SlotId;
|
using ImageViewId = Common::SlotId;
|
||||||
|
|
||||||
struct Offset2D {
|
struct Offset2D {
|
||||||
s32 x;
|
s32 x;
|
||||||
|
|
Loading…
Reference in New Issue