#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" LOG_CHANNEL(cellSearch); template<> void fmt_class_string::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 func; vm::ptr 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 func, vm::ptr 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->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->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 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(); sysutil_register_cb([=](ppu_thread& ppu) -> s32 { const auto search = fxm::get_always(); vm::var 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 listId, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr 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(); sysutil_register_cb([=](ppu_thread& ppu) -> s32 { const auto search = fxm::get_always(); vm::var 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 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(); sysutil_register_cb([=](ppu_thread& ppu) -> s32 { const auto search = fxm::get_always(); vm::var 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 videoId, CellSearchSceneSearchType searchType, CellSearchSortOrder sortOrder, vm::ptr 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(); sysutil_register_cb([=](ppu_thread& ppu) -> s32 { const auto search = fxm::get_always(); vm::var 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 gameTitle, vm::cpptr tags, u32 tagNum, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr 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(); sysutil_register_cb([=](ppu_thread& ppu) -> s32 { const auto search = fxm::get_always(); vm::var 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 infoBuffer, vm::ptr outContentType, vm::ptr 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(searchId); if (!searchObject) { return CELL_SEARCH_ERROR_INVALID_SEARCHID; } return CELL_OK; } error_code cellSearchGetContentInfoByContentId(vm::cptr contentId, vm::ptr infoBuffer, vm::ptr 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 contentId, vm::ptr 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(searchId); if (!searchObject) { return CELL_SEARCH_ERROR_INVALID_SEARCHID; } return CELL_OK; } error_code cellSearchGetContentIdByOffset(CellSearchId searchId, s32 offset, vm::ptr outContentType, vm::ptr outContentId, vm::ptr 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(searchId); if (!searchObject) { return CELL_SEARCH_ERROR_INVALID_SEARCHID; } return CELL_OK; } error_code cellSearchGetContentInfoGameComment(vm::cptr contentId, vm::ptr 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 contentId, CellSearchRepeatMode repeatMode, CellSearchContextOption option, vm::ptr 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(searchId); if (!searchObject) { return CELL_SEARCH_ERROR_INVALID_SEARCHID; } return CELL_OK; } error_code cellSearchGetMusicSelectionContextOfSingleTrack(vm::cptr contentId, vm::ptr 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 contentId, vm::ptr 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 contentId, vm::ptr 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 path) { cellSearch.todo("cellSearchPrepareFile(path=%s)", path); if (!path) { return CELL_SEARCH_ERROR_PARAM; } return CELL_OK; } error_code cellSearchGetContentInfoDeveloperData(vm::cptr contentId, vm::ptr 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 contentId, vm::ptr 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(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(searchId); if (!searchObject) { return CELL_SEARCH_ERROR_INVALID_SEARCHID; } idm::remove(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); });