mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-20 22:05:12 +00:00
EXCEPTION() macro usage, sceNpTrophy improved
This commit is contained in:
parent
6f1e76198a
commit
32d3d1fbe5
32 changed files with 477 additions and 609 deletions
|
|
@ -1,6 +1,7 @@
|
|||
#include "stdafx.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/SysCalls/Modules.h"
|
||||
#include "Emu/SysCalls/CB_FUNC.h"
|
||||
|
||||
|
|
@ -18,156 +19,157 @@
|
|||
extern Module sceNpTrophy;
|
||||
|
||||
// Internal Structs
|
||||
struct sceNpTrophyInternalContext
|
||||
struct trophy_context_t
|
||||
{
|
||||
// TODO
|
||||
const u32 id;
|
||||
|
||||
std::string trp_name;
|
||||
std::unique_ptr<vfsStream> trp_stream;
|
||||
|
||||
std::unique_ptr<TROPUSRLoader> tropusr;
|
||||
|
||||
// TODO: remove the following code when Visual C++ no longer generates
|
||||
// compiler errors for it. All of this should be auto-generated
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
||||
sceNpTrophyInternalContext()
|
||||
: trp_stream(),
|
||||
tropusr()
|
||||
trophy_context_t()
|
||||
: id(Emu.GetIdManager().get_current_id())
|
||||
{
|
||||
}
|
||||
|
||||
sceNpTrophyInternalContext(sceNpTrophyInternalContext&& other)
|
||||
{
|
||||
std::swap(trp_stream,other.trp_stream);
|
||||
std::swap(tropusr, other.tropusr);
|
||||
std::swap(trp_name, other.trp_name);
|
||||
}
|
||||
|
||||
sceNpTrophyInternalContext& operator =(sceNpTrophyInternalContext&& other)
|
||||
{
|
||||
std::swap(trp_stream, other.trp_stream);
|
||||
std::swap(tropusr, other.tropusr);
|
||||
std::swap(trp_name, other.trp_name);
|
||||
return *this;
|
||||
}
|
||||
|
||||
sceNpTrophyInternalContext(sceNpTrophyInternalContext& other) = delete;
|
||||
sceNpTrophyInternalContext& operator =(sceNpTrophyInternalContext& other) = delete;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
struct sceNpTrophyInternal
|
||||
struct trophy_handle_t
|
||||
{
|
||||
bool m_bInitialized;
|
||||
std::vector<sceNpTrophyInternalContext> contexts;
|
||||
const u32 id;
|
||||
|
||||
sceNpTrophyInternal()
|
||||
: m_bInitialized(false)
|
||||
trophy_handle_t()
|
||||
: id(Emu.GetIdManager().get_current_id())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
sceNpTrophyInternal sceNpTrophyInstance;
|
||||
|
||||
static sceNpTrophyInternalContext& getContext(u32 context) {
|
||||
// The invalid context is 0, so remap contexts 1... to indices 0...
|
||||
if (context == 0)
|
||||
throw "getContext: context == 0";
|
||||
return sceNpTrophyInstance.contexts[context - 1];
|
||||
}
|
||||
|
||||
// Functions
|
||||
int sceNpTrophyInit(u32 pool_addr, u32 poolSize, u32 containerId, u64 options)
|
||||
s32 sceNpTrophyInit(vm::ptr<void> pool, u32 poolSize, u32 containerId, u64 options)
|
||||
{
|
||||
sceNpTrophy.Log("sceNpTrophyInit(pool_addr=0x%x, poolSize=%d, containerId=0x%x, options=0x%llx)", pool_addr, poolSize, containerId, options);
|
||||
|
||||
if (sceNpTrophyInstance.m_bInitialized)
|
||||
return SCE_NP_TROPHY_ERROR_ALREADY_INITIALIZED;
|
||||
if (options)
|
||||
return SCE_NP_TROPHY_ERROR_NOT_SUPPORTED;
|
||||
|
||||
sceNpTrophyInstance.m_bInitialized = true;
|
||||
sceNpTrophy.Warning("sceNpTrophyInit(pool=*0x%x, poolSize=0x%x, containerId=0x%x, options=0x%llx)", pool, poolSize, containerId, options);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyCreateContext(vm::ptr<u32> context, vm::cptr<SceNpCommunicationId> commID, vm::cptr<SceNpCommunicationSignature> commSign, u64 options)
|
||||
s32 sceNpTrophyTerm()
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyCreateContext(context=*0x%x, commID=*0x%x, commSign=*0x%x, options=0x%llx)", context, commID, commSign, options);
|
||||
sceNpTrophy.Warning("sceNpTrophyTerm()");
|
||||
|
||||
if (!sceNpTrophyInstance.m_bInitialized)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTrophyCreateHandle(vm::ptr<u32> handle)
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyCreateHandle(handle=*0x%x)", handle);
|
||||
|
||||
if (!handle)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
return SCE_NP_TROPHY_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (options & ~1)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
// TODO: There are other possible errors
|
||||
*handle = Emu.GetIdManager().make<trophy_handle_t>();
|
||||
|
||||
// TODO: Is the TROPHY.TRP file necessarily located in this path?
|
||||
if (!Emu.GetVFS().ExistsDir("/app_home/../TROPDIR/"))
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTrophyDestroyHandle(u32 handle)
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyDestroyHandle(handle=0x%x)", handle);
|
||||
|
||||
const auto hndl = Emu.GetIdManager().get<trophy_handle_t>(handle);
|
||||
|
||||
if (!hndl)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().remove<trophy_handle_t>(handle);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTrophyAbortHandle(u32 handle)
|
||||
{
|
||||
sceNpTrophy.Todo("sceNpTrophyAbortHandle(handle=0x%x)", handle);
|
||||
|
||||
const auto hndl = Emu.GetIdManager().get<trophy_handle_t>(handle);
|
||||
|
||||
if (!hndl)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTrophyCreateContext(vm::ptr<u32> context, vm::cptr<SceNpCommunicationId> commId, vm::cptr<SceNpCommunicationSignature> commSign, u64 options)
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyCreateContext(context=*0x%x, commId=*0x%x, commSign=*0x%x, options=0x%llx)", context, commId, commSign, options);
|
||||
|
||||
// rough checks for further fmt::format call
|
||||
if (commId->term || commId->num > 99)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_INVALID_NP_COMM_ID;
|
||||
}
|
||||
|
||||
// generate trophy context name
|
||||
std::string name = fmt::format("%s_%02d", commId->data, commId->num);
|
||||
|
||||
// open trophy pack file
|
||||
std::unique_ptr<vfsStream> stream(Emu.GetVFS().OpenFile("/app_home/../TROPDIR/" + name + "/TROPHY.TRP", vfsRead));
|
||||
|
||||
// check if exists and opened
|
||||
if (!stream || !stream->IsOpened())
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
// TODO: Following method will retrieve the TROPHY.TRP of the first folder that contains such file
|
||||
for (const auto entry : vfsDir("/app_home/../TROPDIR/"))
|
||||
{
|
||||
if (entry->flags & DirEntry_TypeDir)
|
||||
{
|
||||
vfsStream* stream = Emu.GetVFS().OpenFile("/app_home/../TROPDIR/" + entry->name + "/TROPHY.TRP", vfsRead);
|
||||
// create trophy context
|
||||
const auto ctxt = Emu.GetIdManager().make_ptr<trophy_context_t>();
|
||||
|
||||
if (stream && stream->IsOpened())
|
||||
{
|
||||
sceNpTrophyInstance.contexts.emplace_back();
|
||||
sceNpTrophyInternalContext& ctxt = sceNpTrophyInstance.contexts.back();
|
||||
ctxt.trp_stream.reset(stream);
|
||||
ctxt.trp_name = entry->name;
|
||||
stream = nullptr;
|
||||
*context = sceNpTrophyInstance.contexts.size(); // contexts start from 1
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
int sceNpTrophyCreateHandle(vm::ptr<u32> handle)
|
||||
{
|
||||
sceNpTrophy.Todo("sceNpTrophyCreateHandle(handle_addr=0x%x)", handle.addr());
|
||||
|
||||
if (!sceNpTrophyInstance.m_bInitialized)
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
// TODO: There are other possible errors
|
||||
|
||||
// TODO: ?
|
||||
// set trophy context parameters (could be passed to constructor through make_ptr call)
|
||||
ctxt->trp_name = std::move(name);
|
||||
ctxt->trp_stream = std::move(stream);
|
||||
*context = ctxt->id;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyRegisterContext(PPUThread& CPU, u32 context, u32 handle, vm::ptr<SceNpTrophyStatusCallback> statusCb, u32 arg_addr, u64 options)
|
||||
s32 sceNpTrophyDestroyContext(u32 context)
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyRegisterContext(context=0x%x, handle=0x%x, statusCb_addr=0x%x, arg_addr=0x%x, options=0x%llx)",
|
||||
context, handle, statusCb.addr(), arg_addr, options);
|
||||
sceNpTrophy.Warning("sceNpTrophyDestroyContext(context=0x%x)", context);
|
||||
|
||||
if (!(sceNpTrophyInstance.m_bInitialized))
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
if (options & (~(u64)1))
|
||||
return SCE_NP_TROPHY_ERROR_NOT_SUPPORTED;
|
||||
if (context == 0 || context > sceNpTrophyInstance.contexts.size()) {
|
||||
sceNpTrophy.Warning("sceNpTrophyRegisterContext: invalid context (%d)", context);
|
||||
const auto ctxt = Emu.GetIdManager().get<trophy_context_t>(context);
|
||||
|
||||
if (!ctxt)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT;
|
||||
}
|
||||
// TODO: There are other possible errors
|
||||
|
||||
sceNpTrophyInternalContext& ctxt = getContext(context);
|
||||
if (!ctxt.trp_stream)
|
||||
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
|
||||
Emu.GetIdManager().remove<trophy_context_t>(context);
|
||||
|
||||
TRPLoader trp(*(ctxt.trp_stream));
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTrophyRegisterContext(PPUThread& CPU, u32 context, u32 handle, vm::ptr<SceNpTrophyStatusCallback> statusCb, vm::ptr<u32> arg, u64 options)
|
||||
{
|
||||
sceNpTrophy.Error("sceNpTrophyRegisterContext(context=0x%x, handle=0x%x, statusCb=*0x%x, arg=*0x%x, options=0x%llx)", context, handle, statusCb, arg, options);
|
||||
|
||||
const auto ctxt = Emu.GetIdManager().get<trophy_context_t>(context);
|
||||
|
||||
if (!ctxt)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT;
|
||||
}
|
||||
|
||||
const auto hndl = Emu.GetIdManager().get<trophy_handle_t>(handle);
|
||||
|
||||
if (!hndl)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
TRPLoader trp(*ctxt->trp_stream);
|
||||
if (!trp.LoadHeader())
|
||||
return SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE;
|
||||
|
||||
|
|
@ -191,14 +193,14 @@ int sceNpTrophyRegisterContext(PPUThread& CPU, u32 context, u32 handle, vm::ptr<
|
|||
}
|
||||
|
||||
// Discard unnecessary TROP_XX.SFM files
|
||||
for (int i=0; i<=18; i++) {
|
||||
for (s32 i=0; i<=18; i++) {
|
||||
strcpy_trunc(target, fmt::Format("TROP_%02d.SFM", i));
|
||||
if (i != Ini.SysLanguage.GetValue())
|
||||
trp.RemoveEntry(target);
|
||||
}
|
||||
|
||||
// TODO: Get the path of the current user
|
||||
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name;
|
||||
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name;
|
||||
if (!trp.Install(trophyPath))
|
||||
return SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE;
|
||||
|
||||
|
|
@ -206,79 +208,67 @@ int sceNpTrophyRegisterContext(PPUThread& CPU, u32 context, u32 handle, vm::ptr<
|
|||
std::string trophyUsrPath = trophyPath + "/TROPUSR.DAT";
|
||||
std::string trophyConfPath = trophyPath + "/TROPCONF.SFM";
|
||||
tropusr->Load(trophyUsrPath, trophyConfPath);
|
||||
ctxt.tropusr.reset(tropusr);
|
||||
ctxt->tropusr.reset(tropusr);
|
||||
|
||||
// TODO: Callbacks
|
||||
statusCb(CPU, context, SCE_NP_TROPHY_STATUS_INSTALLED, 100, 100, arg_addr);
|
||||
statusCb(CPU, context, SCE_NP_TROPHY_STATUS_PROCESSING_COMPLETE, 100, 100, arg_addr);
|
||||
statusCb(CPU, context, SCE_NP_TROPHY_STATUS_INSTALLED, 100, 100, arg);
|
||||
statusCb(CPU, context, SCE_NP_TROPHY_STATUS_PROCESSING_COMPLETE, 100, 100, arg);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyGetGameProgress()
|
||||
s32 sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, vm::ptr<u64> reqspace, u64 options)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTrophy);
|
||||
return CELL_OK;
|
||||
}
|
||||
sceNpTrophy.Error("sceNpTrophyGetRequiredDiskSpace(context=0x%x, handle=0x%x, reqspace*=0x%x, options=0x%llx)", context, handle, reqspace, options);
|
||||
|
||||
int sceNpTrophySetSoundLevel()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTrophy);
|
||||
return CELL_OK;
|
||||
}
|
||||
const auto ctxt = Emu.GetIdManager().get<trophy_context_t>(context);
|
||||
|
||||
int sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, vm::ptr<u64> reqspace, u64 options)
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyGetRequiredDiskSpace(context=0x%x, handle=0x%x, reqspace_addr=0x%x, options=0x%llx)",
|
||||
context, handle, reqspace.addr(), options);
|
||||
|
||||
if (!sceNpTrophyInstance.m_bInitialized)
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
if (context == 0 || context > sceNpTrophyInstance.contexts.size()) {
|
||||
sceNpTrophy.Warning("sceNpTrophyGetRequiredDiskSpace: invalid context (%d)", context);
|
||||
if (!ctxt)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT;
|
||||
}
|
||||
// TODO: There are other possible errors
|
||||
|
||||
const sceNpTrophyInternalContext& ctxt = getContext(context);
|
||||
if (!ctxt.trp_stream)
|
||||
return SCE_NP_TROPHY_ERROR_CONF_DOES_NOT_EXIST;
|
||||
const auto hndl = Emu.GetIdManager().get<trophy_handle_t>(handle);
|
||||
|
||||
*reqspace = ctxt.trp_stream->GetSize(); // TODO: This is not accurate. It's just an approximation of the real value
|
||||
return CELL_OK;
|
||||
}
|
||||
if (!hndl)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
int sceNpTrophyDestroyContext()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTrophy);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyAbortHandle(u32 handle)
|
||||
{
|
||||
sceNpTrophy.Todo("sceNpTrophyAbortHandle(handle=0x%x)", handle);
|
||||
|
||||
// TODO: ?
|
||||
|
||||
if (!sceNpTrophyInstance.m_bInitialized)
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
// TODO: This is not accurate. It's just an approximation of the real value
|
||||
*reqspace = ctxt->trp_stream->GetSize();
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr<SceNpTrophyGameDetails> details, vm::ptr<SceNpTrophyGameData> data)
|
||||
s32 sceNpTrophySetSoundLevel(u32 context, u32 handle, u32 level, u64 options)
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyGetGameInfo(context=0x%x, handle=0x%x, details_addr=0x%x, data_addr=0x%x)",
|
||||
context, handle, details.addr(), data.addr());
|
||||
sceNpTrophy.Todo("sceNpTrophySetSoundLevel(context=0x%x, handle=0x%x, level=%d, options=0x%llx)", context, handle, level, options);
|
||||
|
||||
if (!sceNpTrophyInstance.m_bInitialized)
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
// TODO: There are other possible errors
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr<SceNpTrophyGameDetails> details, vm::ptr<SceNpTrophyGameData> data)
|
||||
{
|
||||
sceNpTrophy.Error("sceNpTrophyGetGameInfo(context=0x%x, handle=0x%x, details=*0x%x, data=*0x%x)", context, handle, details, data);
|
||||
|
||||
const auto ctxt = Emu.GetIdManager().get<trophy_context_t>(context);
|
||||
|
||||
if (!ctxt)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT;
|
||||
}
|
||||
|
||||
const auto hndl = Emu.GetIdManager().get<trophy_handle_t>(handle);
|
||||
|
||||
if (!hndl)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
std::string path;
|
||||
rXmlDocument doc;
|
||||
const sceNpTrophyInternalContext& ctxt = getContext(context);
|
||||
Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user
|
||||
Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user
|
||||
doc.Load(path);
|
||||
|
||||
std::string titleName;
|
||||
|
|
@ -300,7 +290,7 @@ int sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr<SceNpTrophyGameDetai
|
|||
case 'P': details->numPlatinum++; break;
|
||||
}
|
||||
|
||||
if (ctxt.tropusr->GetTrophyUnlockState(trophy_id))
|
||||
if (ctxt->tropusr->GetTrophyUnlockState(trophy_id))
|
||||
{
|
||||
data->unlockedTrophies++;
|
||||
switch (n->GetAttribute("ttype")[0]) {
|
||||
|
|
@ -313,77 +303,71 @@ int sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr<SceNpTrophyGameDetai
|
|||
}
|
||||
}
|
||||
|
||||
memcpy(details->title, titleName.c_str(), std::min((size_t) SCE_NP_TROPHY_NAME_MAX_SIZE, titleName.length() + 1));
|
||||
memcpy(details->description, titleDetail.c_str(), std::min((size_t) SCE_NP_TROPHY_DESCR_MAX_SIZE, titleDetail.length() + 1));
|
||||
strcpy_trunc(details->title, titleName);
|
||||
strcpy_trunc(details->description, titleDetail);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyDestroyHandle()
|
||||
s32 sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::ptr<u32> platinumId)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTrophy);
|
||||
return CELL_OK;
|
||||
}
|
||||
sceNpTrophy.Error("sceNpTrophyUnlockTrophy(context=0x%x, handle=0x%x, trophyId=%d, platinumId=*0x%x)", context, handle, trophyId, platinumId);
|
||||
|
||||
int sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::ptr<u32> platinumId)
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyUnlockTrophy(context=0x%x, handle=0x%x, trophyId=%d, platinumId_addr=0x%x)",
|
||||
context, handle, trophyId, platinumId.addr());
|
||||
|
||||
if (!sceNpTrophyInstance.m_bInitialized)
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
// TODO: There are other possible errors
|
||||
const auto ctxt = Emu.GetIdManager().get<trophy_context_t>(context);
|
||||
|
||||
sceNpTrophyInternalContext& ctxt = getContext(context);
|
||||
if (trophyId >= (s32)ctxt.tropusr->GetTrophiesCount())
|
||||
if (!ctxt)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT;
|
||||
}
|
||||
|
||||
const auto hndl = Emu.GetIdManager().get<trophy_handle_t>(handle);
|
||||
|
||||
if (!hndl)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
if (trophyId >= (s32)ctxt->tropusr->GetTrophiesCount())
|
||||
return SCE_NP_TROPHY_ERROR_INVALID_TROPHY_ID;
|
||||
if (ctxt.tropusr->GetTrophyUnlockState(trophyId))
|
||||
if (ctxt->tropusr->GetTrophyUnlockState(trophyId))
|
||||
return SCE_NP_TROPHY_ERROR_ALREADY_UNLOCKED;
|
||||
|
||||
u64 timestamp1 = get_system_time(); // TODO: Either timestamp1 or timestamp2 is wrong
|
||||
u64 timestamp2 = get_system_time(); // TODO: Either timestamp1 or timestamp2 is wrong
|
||||
ctxt.tropusr->UnlockTrophy(trophyId, timestamp1, timestamp2);
|
||||
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name + "/TROPUSR.DAT";
|
||||
ctxt.tropusr->Save(trophyPath);
|
||||
ctxt->tropusr->UnlockTrophy(trophyId, timestamp1, timestamp2);
|
||||
std::string trophyPath = "/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPUSR.DAT";
|
||||
ctxt->tropusr->Save(trophyPath);
|
||||
|
||||
*platinumId = SCE_NP_TROPHY_INVALID_TROPHY_ID; // TODO
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyTerm()
|
||||
s32 sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptr<SceNpTrophyFlagArray> flags, vm::ptr<u32> count)
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyTerm()");
|
||||
sceNpTrophy.Error("sceNpTrophyGetTrophyUnlockState(context=0x%x, handle=0x%x, flags=*0x%x, count=*0x%x)", context, handle, flags, count);
|
||||
|
||||
if (!sceNpTrophyInstance.m_bInitialized)
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
const auto ctxt = Emu.GetIdManager().get<trophy_context_t>(context);
|
||||
|
||||
sceNpTrophyInstance.m_bInitialized = false;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptr<SceNpTrophyFlagArray> flags, vm::ptr<u32> count)
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState(context=0x%x, handle=0x%x, flags_addr=0x%x, count_addr=0x%x)",
|
||||
context, handle, flags.addr(), count.addr());
|
||||
|
||||
if (!sceNpTrophyInstance.m_bInitialized)
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
if (context == 0 || context > sceNpTrophyInstance.contexts.size()) {
|
||||
sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState: invalid context (%d)", context);
|
||||
if (!ctxt)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT;
|
||||
}
|
||||
// TODO: There are other possible errors
|
||||
|
||||
const sceNpTrophyInternalContext& ctxt = getContext(context);
|
||||
u32 count_ = ctxt.tropusr->GetTrophiesCount();
|
||||
const auto hndl = Emu.GetIdManager().get<trophy_handle_t>(handle);
|
||||
|
||||
if (!hndl)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
u32 count_ = ctxt->tropusr->GetTrophiesCount();
|
||||
*count = count_;
|
||||
if (count_ > 128)
|
||||
sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState: More than 128 trophies detected!");
|
||||
sceNpTrophy.Error("sceNpTrophyGetTrophyUnlockState: More than 128 trophies detected!");
|
||||
|
||||
// Pack up to 128 bools in u32 flag_bits[4]
|
||||
for (u32 id = 0; id < count_; id++)
|
||||
{
|
||||
if (ctxt.tropusr->GetTrophyUnlockState(id))
|
||||
if (ctxt->tropusr->GetTrophyUnlockState(id))
|
||||
flags->flag_bits[id/32] |= 1<<(id%32);
|
||||
else
|
||||
flags->flag_bits[id/32] &= ~(1<<(id%32));
|
||||
|
|
@ -392,25 +376,27 @@ int sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptr<SceNpTrophy
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyGetTrophyIcon()
|
||||
s32 sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr<SceNpTrophyDetails> details, vm::ptr<SceNpTrophyData> data)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTrophy);
|
||||
return CELL_OK;
|
||||
}
|
||||
sceNpTrophy.Warning("sceNpTrophyGetTrophyInfo(context=0x%x, handle=0x%x, trophyId=%d, details=*0x%x, data=*0x%x)", context, handle, trophyId, details, data);
|
||||
|
||||
int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr<SceNpTrophyDetails> details, vm::ptr<SceNpTrophyData> data)
|
||||
{
|
||||
sceNpTrophy.Warning("sceNpTrophyGetTrophyInfo(context=0x%x, handle=0x%x, trophyId=%d, details_addr=0x%x, data_addr=0x%x)",
|
||||
context, handle, trophyId, details.addr(), data.addr());
|
||||
const auto ctxt = Emu.GetIdManager().get<trophy_context_t>(context);
|
||||
|
||||
if (!sceNpTrophyInstance.m_bInitialized)
|
||||
return SCE_NP_TROPHY_ERROR_NOT_INITIALIZED;
|
||||
// TODO: There are other possible errors
|
||||
if (!ctxt)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_CONTEXT;
|
||||
}
|
||||
|
||||
const auto hndl = Emu.GetIdManager().get<trophy_handle_t>(handle);
|
||||
|
||||
if (!hndl)
|
||||
{
|
||||
return SCE_NP_TROPHY_ERROR_UNKNOWN_HANDLE;
|
||||
}
|
||||
|
||||
std::string path;
|
||||
rXmlDocument doc;
|
||||
const sceNpTrophyInternalContext& ctxt = getContext(context);
|
||||
Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt.trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user
|
||||
Emu.GetVFS().GetDevice("/dev_hdd0/home/00000001/trophy/" + ctxt->trp_name + "/TROPCONF.SFM", path); // TODO: Get the path of the current user
|
||||
doc.Load(path);
|
||||
|
||||
std::string name;
|
||||
|
|
@ -437,8 +423,8 @@ int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr<SceN
|
|||
}
|
||||
|
||||
data->trophyId = trophyId;
|
||||
data->unlocked = ctxt.tropusr->GetTrophyUnlockState(trophyId) ? true : false; // ???
|
||||
data->timestamp.tick = ctxt.tropusr->GetTrophyTimestamp(trophyId);
|
||||
data->unlocked = ctxt->tropusr->GetTrophyUnlockState(trophyId) != 0; // ???
|
||||
data->timestamp = ctxt->tropusr->GetTrophyTimestamp(trophyId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -447,16 +433,30 @@ int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr<SceN
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int sceNpTrophyGetGameIcon()
|
||||
s32 sceNpTrophyGetGameProgress(u32 context, u32 handle, vm::ptr<s32> percentage)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTrophy);
|
||||
sceNpTrophy.Todo("sceNpTrophyGetGameProgress(context=0x%x, handle=0x%x, percentage=*0x%x)", context, handle, percentage);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTrophyGetGameIcon(u32 context, u32 handle, vm::ptr<void> buffer, vm::ptr<u32> size)
|
||||
{
|
||||
sceNpTrophy.Todo("sceNpTrophyGetGameIcon(context=0x%x, handle=0x%x, buffer=*0x%x, size=*0x%x)", context, handle, buffer, size);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTrophyGetTrophyIcon(u32 context, u32 handle, s32 trophyId, vm::ptr<void> buffer, vm::ptr<u32> size)
|
||||
{
|
||||
sceNpTrophy.Todo("sceNpTrophyGetTrophyIcon(context=0x%x, handle=0x%x, trophyId=%d, buffer=*0x%x, size=*0x%x)", context, handle, trophyId, buffer, size);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
Module sceNpTrophy("sceNpTrophy", []()
|
||||
{
|
||||
sceNpTrophyInstance.m_bInitialized = false;
|
||||
|
||||
REG_FUNC(sceNpTrophy, sceNpTrophyGetGameProgress);
|
||||
REG_FUNC(sceNpTrophy, sceNpTrophyRegisterContext);
|
||||
REG_FUNC(sceNpTrophy, sceNpTrophyCreateHandle);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue