mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 06:21:26 +12:00
447 lines
13 KiB
C++
447 lines
13 KiB
C++
#include "stdafx.h"
|
|
#include "Emu/System.h"
|
|
#include "Emu/IdManager.h"
|
|
#include "Emu/Cell/PPUModule.h"
|
|
#include "cellMusic.h"
|
|
#include "cellSysutil.h"
|
|
|
|
#include "cellSearch.h"
|
|
|
|
logs::channel cellSearch("cellSearch");
|
|
|
|
template<>
|
|
void fmt_class_string<CellSearchError>::format(std::string& out, u64 arg)
|
|
{
|
|
format_enum(out, arg, [](auto error)
|
|
{
|
|
switch (error)
|
|
{
|
|
STR_CASE(CELL_SEARCH_CANCELED);
|
|
STR_CASE(CELL_SEARCH_ERROR_PARAM);
|
|
STR_CASE(CELL_SEARCH_ERROR_BUSY);
|
|
STR_CASE(CELL_SEARCH_ERROR_NO_MEMORY);
|
|
STR_CASE(CELL_SEARCH_ERROR_UNKNOWN_MODE);
|
|
STR_CASE(CELL_SEARCH_ERROR_ALREADY_INITIALIZED);
|
|
STR_CASE(CELL_SEARCH_ERROR_NOT_INITIALIZED);
|
|
STR_CASE(CELL_SEARCH_ERROR_FINALIZING);
|
|
STR_CASE(CELL_SEARCH_ERROR_NOT_SUPPORTED_SEARCH);
|
|
STR_CASE(CELL_SEARCH_ERROR_CONTENT_OBSOLETE);
|
|
STR_CASE(CELL_SEARCH_ERROR_CONTENT_NOT_FOUND);
|
|
STR_CASE(CELL_SEARCH_ERROR_NOT_LIST);
|
|
STR_CASE(CELL_SEARCH_ERROR_OUT_OF_RANGE);
|
|
STR_CASE(CELL_SEARCH_ERROR_INVALID_SEARCHID);
|
|
STR_CASE(CELL_SEARCH_ERROR_ALREADY_GOT_RESULT);
|
|
STR_CASE(CELL_SEARCH_ERROR_NOT_SUPPORTED_CONTEXT);
|
|
STR_CASE(CELL_SEARCH_ERROR_INVALID_CONTENTTYPE);
|
|
STR_CASE(CELL_SEARCH_ERROR_DRM);
|
|
STR_CASE(CELL_SEARCH_ERROR_TAG);
|
|
STR_CASE(CELL_SEARCH_ERROR_GENERIC);
|
|
}
|
|
|
|
return unknown;
|
|
});
|
|
}
|
|
|
|
struct search_t
|
|
{
|
|
vm::ptr<CellSearchSystemCallback> func;
|
|
vm::ptr<void> userData;
|
|
};
|
|
|
|
struct search_object_t
|
|
{
|
|
// TODO: Figured out the correct values to set here
|
|
static const u32 id_base = 1;
|
|
static const u32 id_step = 1;
|
|
static const u32 id_count = 64;
|
|
static const u32 invalid = 0xFFFFFFFF;
|
|
};
|
|
|
|
error_code cellSearchInitialize(CellSearchMode mode, u32 container, vm::ptr<CellSearchSystemCallback> func, vm::ptr<void> userData)
|
|
{
|
|
cellSearch.warning("cellSearchInitialize(mode=0x%x, container=0x%x, func=*0x%x, userData=*0x%x)", (u32) mode, container, func, userData);
|
|
|
|
const auto search = fxm::make_always<search_t>();
|
|
search->func = func;
|
|
search->userData = userData;
|
|
|
|
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
|
{
|
|
func(ppu, CELL_SEARCH_EVENT_INITIALIZE_RESULT, CELL_OK, vm::null, userData);
|
|
return CELL_OK;
|
|
});
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchFinalize()
|
|
{
|
|
cellSearch.warning("cellSearchFinalize()");
|
|
|
|
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
|
{
|
|
const auto search = fxm::get_always<search_t>();
|
|
|
|
search->func(ppu, CELL_SEARCH_EVENT_FINALIZE_RESULT, CELL_OK, vm::null, search->userData);
|
|
return CELL_OK;
|
|
});
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchStartListSearch(CellSearchListSearchType type, CellSearchSortOrder sortOrder, vm::ptr<CellSearchId> outSearchId)
|
|
{
|
|
cellSearch.todo("cellSearchStartListSearch(type=0x%x, sortOrder=0x%x, outSearchId=*0x%x)", (u32) type, (u32) sortOrder, outSearchId);
|
|
|
|
if (!outSearchId)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
*outSearchId = idm::make<search_object_t>();
|
|
|
|
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
|
{
|
|
const auto search = fxm::get_always<search_t>();
|
|
|
|
vm::var<CellSearchResultParam> resultParam;
|
|
resultParam->searchId = *outSearchId;
|
|
resultParam->resultNum = 0; // TODO
|
|
|
|
search->func(ppu, CELL_SEARCH_EVENT_LISTSEARCH_RESULT, CELL_OK, vm::cast(resultParam.addr()), search->userData);
|
|
return CELL_OK;
|
|
});
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchStartContentSearchInList(vm::cptr<CellSearchContentId> listId, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr<CellSearchId> outSearchId)
|
|
{
|
|
cellSearch.todo("cellSearchStartContentSearchInList(listId=*0x%x, sortKey=0x%x, sortOrder=0x%x, outSearchId=*0x%x)", listId, (u32) sortKey, (u32) sortOrder, outSearchId);
|
|
|
|
if (!listId || !outSearchId)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
*outSearchId = idm::make<search_object_t>();
|
|
|
|
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
|
{
|
|
const auto search = fxm::get_always<search_t>();
|
|
|
|
vm::var<CellSearchResultParam> resultParam;
|
|
resultParam->searchId = *outSearchId;
|
|
resultParam->resultNum = 0; // TODO
|
|
|
|
search->func(ppu, CELL_SEARCH_EVENT_CONTENTSEARCH_INLIST_RESULT, CELL_OK, vm::cast(resultParam.addr()), search->userData);
|
|
return CELL_OK;
|
|
});
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchStartContentSearch(CellSearchContentSearchType type, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr<CellSearchId> outSearchId)
|
|
{
|
|
cellSearch.todo("cellSearchStartContentSearch(type=0x%x, sortKey=0x%x, sortOrder=0x%x, outSearchId=*0x%x)", (u32) type, (u32) sortKey, (u32) sortOrder, outSearchId);
|
|
|
|
if (!outSearchId)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
*outSearchId = idm::make<search_object_t>();
|
|
|
|
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
|
{
|
|
const auto search = fxm::get_always<search_t>();
|
|
|
|
vm::var<CellSearchResultParam> resultParam;
|
|
resultParam->searchId = *outSearchId;
|
|
resultParam->resultNum = 0; // TODO
|
|
|
|
search->func(ppu, CELL_SEARCH_EVENT_CONTENTSEARCH_RESULT, CELL_OK, vm::cast(resultParam.addr()), search->userData);
|
|
return CELL_OK;
|
|
});
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchStartSceneSearchInVideo(vm::cptr<CellSearchContentId> videoId, CellSearchSceneSearchType searchType, CellSearchSortOrder sortOrder, vm::ptr<CellSearchId> outSearchId)
|
|
{
|
|
cellSearch.todo("cellSearchStartSceneSearchInVideo(videoId=*0x%x, searchType=0x%x, sortOrder=0x%x, outSearchId=*0x%x)", videoId, (u32) searchType, (u32) sortOrder, outSearchId);
|
|
|
|
if (!videoId || !outSearchId)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
*outSearchId = idm::make<search_object_t>();
|
|
|
|
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
|
{
|
|
const auto search = fxm::get_always<search_t>();
|
|
|
|
vm::var<CellSearchResultParam> resultParam;
|
|
resultParam->searchId = *outSearchId;
|
|
resultParam->resultNum = 0; // TODO
|
|
|
|
search->func(ppu, CELL_SEARCH_EVENT_SCENESEARCH_INVIDEO_RESULT, CELL_OK, vm::cast(resultParam.addr()), search->userData);
|
|
return CELL_OK;
|
|
});
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchStartSceneSearch(CellSearchSceneSearchType searchType, vm::cptr<char> gameTitle, vm::cpptr<char> tags, u32 tagNum, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr<CellSearchId> outSearchId)
|
|
{
|
|
cellSearch.todo("cellSearchStartSceneSearch(searchType=0x%x, gameTitle=%s, tags=**0x%x, tagNum=0x%x, sortKey=0x%x, sortOrder=0x%x, outSearchId=*0x%x)", (u32) searchType, gameTitle, tags, tagNum, (u32) sortKey, (u32) sortOrder, outSearchId);
|
|
|
|
if (!gameTitle || !outSearchId)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
*outSearchId = idm::make<search_object_t>();
|
|
|
|
sysutil_register_cb([=](ppu_thread& ppu) -> s32
|
|
{
|
|
const auto search = fxm::get_always<search_t>();
|
|
|
|
vm::var<CellSearchResultParam> resultParam;
|
|
resultParam->searchId = *outSearchId;
|
|
resultParam->resultNum = 0; // TODO
|
|
|
|
search->func(ppu, CELL_SEARCH_EVENT_SCENESEARCH_RESULT, CELL_OK, vm::cast(resultParam.addr()), search->userData);
|
|
return CELL_OK;
|
|
});
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetContentInfoByOffset(CellSearchId searchId, s32 offset, vm::ptr<void> infoBuffer, vm::ptr<CellSearchContentType> outContentType, vm::ptr<CellSearchContentId> outContentId)
|
|
{
|
|
cellSearch.todo("cellSearchGetContentInfoByOffset(searchId=0x%x, offset=0x%x, infoBuffer=*0x%x, outContentType=*0x%x, outContentId=*0x%x)", searchId, offset, infoBuffer, outContentType, outContentId);
|
|
|
|
if (!outContentType)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
const auto searchObject = idm::get<search_object_t>(searchId);
|
|
|
|
if (!searchObject)
|
|
{
|
|
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetContentInfoByContentId(vm::cptr<CellSearchContentId> contentId, vm::ptr<void> infoBuffer, vm::ptr<CellSearchContentType> outContentType)
|
|
{
|
|
cellSearch.todo("cellSearchGetContentInfoByContentId(contentId=*0x%x, infoBuffer=*0x%x, outContentType=*0x%x)", contentId, infoBuffer, outContentType);
|
|
|
|
if (!outContentType)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetOffsetByContentId(CellSearchId searchId, vm::cptr<CellSearchContentId> contentId, vm::ptr<s32> outOffset)
|
|
{
|
|
cellSearch.todo("cellSearchGetOffsetByContentId(searchId=0x%x, contentId=*0x%x, outOffset=*0x%x)", searchId, contentId, outOffset);
|
|
|
|
if (!outOffset)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
const auto searchObject = idm::get<search_object_t>(searchId);
|
|
|
|
if (!searchObject)
|
|
{
|
|
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetContentIdByOffset(CellSearchId searchId, s32 offset, vm::ptr<CellSearchContentType> outContentType, vm::ptr<CellSearchContentId> outContentId, vm::ptr<CellSearchTimeInfo> outTimeInfo)
|
|
{
|
|
cellSearch.todo("cellSearchGetContentIdByOffset(searchId=0x%x, offset=0x%x, outContentType=*0x%x, outContentId=*0x%x, outTimeInfo=*0x%x)", searchId, offset, outContentType, outContentId, outTimeInfo);
|
|
|
|
if (!outContentType || !outContentId)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
const auto searchObject = idm::get<search_object_t>(searchId);
|
|
|
|
if (!searchObject)
|
|
{
|
|
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetContentInfoGameComment(vm::cptr<CellSearchContentId> contentId, vm::ptr<char> gameComment)
|
|
{
|
|
cellSearch.todo("cellSearchGetContentInfoGameComment(contentId=*0x%x, gameComment=*0x%x)", contentId, gameComment);
|
|
|
|
if (!gameComment)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetMusicSelectionContext(CellSearchId searchId, vm::cptr<CellSearchContentId> contentId, CellSearchRepeatMode repeatMode, CellSearchContextOption option, vm::ptr<CellMusicSelectionContext> outContext)
|
|
{
|
|
cellSearch.todo("cellSearchGetMusicSelectionContext(searchId=0x%x, contentId=*0x%x, repeatMode=0x%x, option=0x%x, outContext=*0x%x)", searchId, contentId, (u32) repeatMode, (u32) option, outContext);
|
|
|
|
if (!outContext)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
const auto searchObject = idm::get<search_object_t>(searchId);
|
|
|
|
if (!searchObject)
|
|
{
|
|
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetMusicSelectionContextOfSingleTrack(vm::cptr<CellSearchContentId> contentId, vm::ptr<CellMusicSelectionContext> outContext)
|
|
{
|
|
cellSearch.todo("cellSearchGetMusicSelectionContextOfSingleTrack(contentId=*0x%x, outContext=*0x%x)", contentId, outContext);
|
|
|
|
if (!contentId || !outContext)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetContentInfoPath(vm::cptr<CellSearchContentId> contentId, vm::ptr<CellSearchContentInfoPath> infoPath)
|
|
{
|
|
cellSearch.todo("cellSearchGetContentInfoPath(contentId=*0x%x, infoPath=*0x%x)", contentId, infoPath);
|
|
|
|
if (!infoPath)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetContentInfoPathMovieThumb(vm::cptr<CellSearchContentId> contentId, vm::ptr<CellSearchContentInfoPathMovieThumb> infoMt)
|
|
{
|
|
cellSearch.todo("cellSearchGetContentInfoPathMovieThumb(contentId=*0x%x, infoMt=*0x%x)", contentId, infoMt);
|
|
|
|
if (!infoMt)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchPrepareFile(vm::cptr<char> path)
|
|
{
|
|
cellSearch.todo("cellSearchPrepareFile(path=%s)", path);
|
|
|
|
if (!path)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetContentInfoDeveloperData(vm::cptr<CellSearchContentId> contentId, vm::ptr<char> developerData)
|
|
{
|
|
cellSearch.todo("cellSearchGetContentInfoDeveloperData(contentId=*0x%x, developerData=*0x%x)", contentId, developerData);
|
|
|
|
if (!contentId || !developerData)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchGetContentInfoSharable(vm::cptr<CellSearchContentId> contentId, vm::ptr<CellSearchSharableType> sharable)
|
|
{
|
|
cellSearch.todo("cellSearchGetContentInfoSharable(contentId=*0x%x, sharable=*0x%x)", contentId, sharable);
|
|
|
|
if (!contentId || !sharable)
|
|
{
|
|
return CELL_SEARCH_ERROR_PARAM;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchCancel(CellSearchId searchId)
|
|
{
|
|
cellSearch.todo("cellSearchCancel(searchId=0x%x)", searchId);
|
|
|
|
const auto searchObject = idm::get<search_object_t>(searchId);
|
|
|
|
if (!searchObject)
|
|
{
|
|
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
|
|
}
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
error_code cellSearchEnd(CellSearchId searchId)
|
|
{
|
|
cellSearch.warning("cellSearchEnd(searchId=0x%x)", searchId);
|
|
|
|
const auto searchObject = idm::get<search_object_t>(searchId);
|
|
|
|
if (!searchObject)
|
|
{
|
|
return CELL_SEARCH_ERROR_INVALID_SEARCHID;
|
|
}
|
|
|
|
idm::remove<search_object_t>(searchId);
|
|
|
|
return CELL_OK;
|
|
}
|
|
|
|
DECLARE(ppu_module_manager::cellSearch)("cellSearchUtility", []()
|
|
{
|
|
REG_FUNC(cellSearchUtility, cellSearchInitialize);
|
|
REG_FUNC(cellSearchUtility, cellSearchFinalize);
|
|
REG_FUNC(cellSearchUtility, cellSearchStartListSearch);
|
|
REG_FUNC(cellSearchUtility, cellSearchStartContentSearchInList);
|
|
REG_FUNC(cellSearchUtility, cellSearchStartContentSearch);
|
|
REG_FUNC(cellSearchUtility, cellSearchStartSceneSearchInVideo);
|
|
REG_FUNC(cellSearchUtility, cellSearchStartSceneSearch);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoByOffset);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoByContentId);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetOffsetByContentId);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetContentIdByOffset);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoGameComment);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetMusicSelectionContext);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetMusicSelectionContextOfSingleTrack);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoPath);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoPathMovieThumb);
|
|
REG_FUNC(cellSearchUtility, cellSearchPrepareFile);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoDeveloperData);
|
|
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoSharable);
|
|
REG_FUNC(cellSearchUtility, cellSearchCancel);
|
|
REG_FUNC(cellSearchUtility, cellSearchEnd);
|
|
});
|