From fbac1c304a1737537395a3f9638b5b4d1fe4e8d0 Mon Sep 17 00:00:00 2001 From: scribam Date: Thu, 28 Dec 2017 22:38:29 +0100 Subject: [PATCH] Improve cellSearch implementation --- rpcs3/Emu/Cell/Modules/cellSearch.cpp | 364 ++++++++++++++++++++++---- rpcs3/Emu/Cell/Modules/cellSearch.h | 95 +++++-- 2 files changed, 398 insertions(+), 61 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellSearch.cpp b/rpcs3/Emu/Cell/Modules/cellSearch.cpp index 5316eee164..6ae255fb64 100644 --- a/rpcs3/Emu/Cell/Modules/cellSearch.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSearch.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Emu/System.h" +#include "Emu/IdManager.h" #include "Emu/Cell/PPUModule.h" #include "cellSearch.h" @@ -7,13 +8,62 @@ logs::channel cellSearch("cellSearch"); -s32 cellSearchInitialize(ppu_thread& ppu, CellSearchMode mode, u32 container, vm::ptr func, vm::ptr userData) +template<> +void fmt_class_string::format(std::string& out, u64 arg) { - cellSearch.warning("cellSearchInitialize()"); + 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; - // TODO: Store the arguments somewhere so we can use them later. - - //inform callback that search is alive sysutil_register_cb([=](ppu_thread& ppu) -> s32 { func(ppu, CELL_SEARCH_EVENT_INITIALIZE_RESULT, CELL_OK, vm::null, userData); @@ -23,124 +73,350 @@ s32 cellSearchInitialize(ppu_thread& ppu, CellSearchMode mode, u32 container, vm return CELL_OK; } -s32 cellSearchFinalize() +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; } -s32 cellSearchStartListSearch() +error_code cellSearchStartListSearch(CellSearchListSearchType type, CellSearchSortOrder sortOrder, vm::ptr outSearchId) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } -s32 cellSearchStartContentSearchInList() +error_code cellSearchStartContentSearchInList(vm::cptr listId, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr outSearchId) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } -s32 cellSearchStartContentSearch() +error_code cellSearchStartContentSearch(CellSearchContentSearchType type, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr outSearchId) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } -s32 cellSearchStartSceneSearchInVideo() +error_code cellSearchStartSceneSearchInVideo(vm::cptr videoId, CellSearchSceneSearchType searchType, CellSearchSortOrder sortOrder, vm::ptr outSearchId) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } -s32 cellSearchStartSceneSearch() +error_code cellSearchStartSceneSearch(CellSearchSceneSearchType searchType, vm::cptr gameTitle, vm::cpptr tags, u32 tagNum, CellSearchSortKey sortKey, CellSearchSortOrder sortOrder, vm::ptr outSearchId) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } -s32 cellSearchGetContentInfoByOffset() +error_code cellSearchGetContentInfoByOffset(CellSearchId searchId, s32 offset, vm::ptr infoBuffer, vm::ptr outContentType, vm::ptr outContentId) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } -s32 cellSearchGetContentInfoByContentId() +error_code cellSearchGetContentInfoByContentId(vm::cptr contentId, vm::ptr infoBuffer, vm::ptr outContentType) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } -s32 cellSearchGetOffsetByContentId() +error_code cellSearchGetOffsetByContentId(CellSearchId searchId, vm::cptr contentId, vm::ptr outOffset) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } -s32 cellSearchGetContentIdByOffset() +error_code cellSearchGetContentIdByOffset(CellSearchId searchId, s32 offset, vm::ptr outContentType, vm::ptr outContentId, vm::ptr outTimeInfo) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } -s32 cellSearchGetContentInfoGameComment() +error_code cellSearchGetContentInfoGameComment(vm::cptr contentId, vm::ptr gameComment) { - UNIMPLEMENTED_FUNC(cellSearch); + cellSearch.todo("cellSearchGetContentInfoGameComment(contentId=*0x%x, gameComment=*0x%x)", contentId, gameComment); + + if (!gameComment) + { + return CELL_SEARCH_ERROR_PARAM; + } + return CELL_OK; } -s32 cellSearchGetMusicSelectionContext() +error_code cellSearchGetMusicSelectionContext(CellSearchId searchId, vm::cptr contentId, CellSearchRepeatMode repeatMode, CellSearchContextOption option, vm::ptr outContext) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } -s32 cellSearchGetMusicSelectionContextOfSingleTrack() +error_code cellSearchGetMusicSelectionContextOfSingleTrack(vm::cptr contentId, vm::ptr outContext) { - UNIMPLEMENTED_FUNC(cellSearch); + cellSearch.todo("cellSearchGetMusicSelectionContextOfSingleTrack(contentId=*0x%x, outContext=*0x%x)", contentId, outContext); + + if (!contentId || !outContext) + { + return CELL_SEARCH_ERROR_PARAM; + } + return CELL_OK; } -s32 cellSearchGetContentInfoPath() +error_code cellSearchGetContentInfoPath(vm::cptr contentId, vm::ptr infoPath) { - UNIMPLEMENTED_FUNC(cellSearch); + cellSearch.todo("cellSearchGetContentInfoPath(contentId=*0x%x, infoPath=*0x%x)", contentId, infoPath); + + if (!infoPath) + { + return CELL_SEARCH_ERROR_PARAM; + } + return CELL_OK; } -s32 cellSearchGetContentInfoPathMovieThumb() +error_code cellSearchGetContentInfoPathMovieThumb(vm::cptr contentId, vm::ptr infoMt) { - UNIMPLEMENTED_FUNC(cellSearch); + cellSearch.todo("cellSearchGetContentInfoPathMovieThumb(contentId=*0x%x, infoMt=*0x%x)", contentId, infoMt); + + if (!infoMt) + { + return CELL_SEARCH_ERROR_PARAM; + } + return CELL_OK; } -s32 cellSearchPrepareFile() +error_code cellSearchPrepareFile(vm::cptr path) { - UNIMPLEMENTED_FUNC(cellSearch); + cellSearch.todo("cellSearchPrepareFile(path=%s)", path); + + if (!path) + { + return CELL_SEARCH_ERROR_PARAM; + } + return CELL_OK; } -s32 cellSearchGetContentInfoDeveloperData() +error_code cellSearchGetContentInfoDeveloperData(vm::cptr contentId, vm::ptr developerData) { - UNIMPLEMENTED_FUNC(cellSearch); + cellSearch.todo("cellSearchGetContentInfoDeveloperData(contentId=*0x%x, developerData=*0x%x)", contentId, developerData); + + if (!contentId || !developerData) + { + return CELL_SEARCH_ERROR_PARAM; + } + return CELL_OK; } -s32 cellSearchGetContentInfoSharable() +error_code cellSearchGetContentInfoSharable(vm::cptr contentId, vm::ptr sharable) { - UNIMPLEMENTED_FUNC(cellSearch); + cellSearch.todo("cellSearchGetContentInfoSharable(contentId=*0x%x, sharable=*0x%x)", contentId, sharable); + + if (!contentId || !sharable) + { + return CELL_SEARCH_ERROR_PARAM; + } + return CELL_OK; } -s32 cellSearchCancel() +error_code cellSearchCancel(CellSearchId searchId) { - UNIMPLEMENTED_FUNC(cellSearch); + cellSearch.todo("cellSearchCancel(searchId=0x%x)", searchId); + + const auto searchObject = idm::get(searchId); + + if (!searchObject) + { + return CELL_SEARCH_ERROR_INVALID_SEARCHID; + } + return CELL_OK; } -s32 cellSearchEnd() +error_code cellSearchEnd(CellSearchId searchId) { - UNIMPLEMENTED_FUNC(cellSearch); + 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; } diff --git a/rpcs3/Emu/Cell/Modules/cellSearch.h b/rpcs3/Emu/Cell/Modules/cellSearch.h index 2b63c6527a..bef91358ca 100644 --- a/rpcs3/Emu/Cell/Modules/cellSearch.h +++ b/rpcs3/Emu/Cell/Modules/cellSearch.h @@ -1,9 +1,7 @@ #pragma once -namespace vm { using namespace ps3; } - // Error Codes -enum +enum CellSearchError : u32 { CELL_SEARCH_CANCELED = 1, CELL_SEARCH_ERROR_PARAM = 0x8002C801, @@ -30,17 +28,20 @@ enum // Constants enum { - CELL_SEARCH_CONTENT_ID_SIZE = 16, - CELL_SEARCH_TITLE_LEN_MAX = 384, - CELL_SEARCH_TAG_NUM_MAX = 6, - CELL_SEARCH_TAG_LEN_MAX = 63, - CELL_MUSIC_SELECTION_CONTEXT_SIZE = 2048, - CELL_SEARCH_PATH_LEN_MAX = 63, - CELL_SEARCH_MTOPTION_LEN_MAX = 63, + CELL_SEARCH_CONTENT_ID_SIZE = 16, + CELL_SEARCH_TITLE_LEN_MAX = 384, + CELL_SEARCH_TAG_NUM_MAX = 6, + CELL_SEARCH_TAG_LEN_MAX = 63, + CELL_MUSIC_SELECTION_CONTEXT_SIZE = 2048, + CELL_SEARCH_PATH_LEN_MAX = 63, + CELL_SEARCH_MTOPTION_LEN_MAX = 63, + CELL_SEARCH_DEVELOPERDATA_LEN_MAX = 64, + CELL_SEARCH_GAMECOMMENT_SIZE_MAX = 1024, + CELL_SEARCH_CONTENT_BUFFER_SIZE_MAX = 2048, }; // Sort keys -enum : s32 +enum CellSearchSortKey : s32 { CELL_SEARCH_SORTKEY_NONE = 0, CELL_SEARCH_SORTKEY_DEFAULT = 1, @@ -56,15 +57,15 @@ enum : s32 }; // Sort order -enum : s32 +enum CellSearchSortOrder : s32 { CELL_SEARCH_SORTORDER_NONE = 0, CELL_SEARCH_SORTORDER_ASCENDING = 1, - CELL_SEARCH_SOFTORDER_DESCENDING = 2, + CELL_SEARCH_SORTORDER_DESCENDING = 2, }; // Content types -enum : s32 +enum CellSearchContentType : s32 { CELL_SEARCH_CONTENTTYPE_NONE = 0, CELL_SEARCH_CONTENTTYPE_MUSIC = 1, @@ -122,15 +123,22 @@ enum CellSearchSceneType : s32 // List types enum CellSearchListType : s32 { + CELL_SEARCH_LISTTYPE_NONE = 0, CELL_SEARCH_LISTTYPE_MUSIC_ALBUM = 1, CELL_SEARCH_LISTTYPE_MUSIC_GENRE = 2, CELL_SEARCH_LISTTYPE_MUSIC_ARTIST = 3, + CELL_SEARCH_LISTTYPE_PHOTO_YEAR = 4, + CELL_SEARCH_LISTTYPE_PHOTO_MONTH = 5, + CELL_SEARCH_LISTTYPE_PHOTO_ALBUM = 6, + CELL_SEARCH_LISTTYPE_PHOTO_PLAYLIST = 7, + CELL_SEARCH_LISTTYPE_VIDEO_ALBUM = 8, CELL_SEARCH_LISTTYPE_MUSIC_PLAYLIST = 9, }; // Content status enum CellSearchContentStatus : s32 { + CELL_SEARCH_CONTENTSTATUS_NONE, CELL_SEARCH_CONTENTSTATUS_AVAILABLE, CELL_SEARCH_CONTENTSTATUS_NOT_SUPPORTED, CELL_SEARCH_CONTENTSTATUS_BROKEN, @@ -139,7 +147,7 @@ enum CellSearchContentStatus : s32 // Search orientation enum CellSearchOrientation : s32 { - CELL_SEARCH_ORIENTATION_UNKNOWN, + CELL_SEARCH_ORIENTATION_UNKNOWN = 0, CELL_SEARCH_ORIENTATION_TOP_LEFT, CELL_SEARCH_ORIENTATION_TOP_RIGHT, CELL_SEARCH_ORIENTATION_BOTTOM_RIGHT, @@ -165,7 +173,60 @@ enum CellSearchEvent : s32 CELL_SEARCH_EVENT_SCENESEARCH_RESULT, }; -using CellSearchSystemCallback = void(CellSearchEvent event, s32 result, vm::cptr param, vm::ptr userData); +enum CellSearchListSearchType : s32 +{ + CELL_SEARCH_LISTSEARCHTYPE_NONE = 0, + CELL_SEARCH_LISTSEARCHTYPE_MUSIC_ALBUM, + CELL_SEARCH_LISTSEARCHTYPE_MUSIC_GENRE, + CELL_SEARCH_LISTSEARCHTYPE_MUSIC_ARTIST, + CELL_SEARCH_LISTSEARCHTYPE_PHOTO_YEAR, + CELL_SEARCH_LISTSEARCHTYPE_PHOTO_MONTH, + CELL_SEARCH_LISTSEARCHTYPE_PHOTO_ALBUM, + CELL_SEARCH_LISTSEARCHTYPE_PHOTO_PLAYLIST, + CELL_SEARCH_LISTSEARCHTYPE_VIDEO_ALBUM, + CELL_SEARCH_LISTSEARCHTYPE_MUSIC_PLAYLIST, +}; + +enum CellSearchContentSearchType : s32 +{ + CELL_SEARCH_CONTENTSEARCHTYPE_NONE = 0, + CELL_SEARCH_CONTENTSEARCHTYPE_MUSIC_ALL, + CELL_SEARCH_CONTENTSEARCHTYPE_PHOTO_ALL, + CELL_SEARCH_CONTENTSEARCHTYPE_VIDEO_ALL, +}; + +enum CellSearchSceneSearchType : s32 +{ + CELL_SEARCH_SCENESEARCHTYPE_NONE = 0, + CELL_SEARCH_SCENESEARCHTYPE_CHAPTER, + CELL_SEARCH_SCENESEARCHTYPE_CLIP_HIGHLIGHT, + CELL_SEARCH_SCENESEARCHTYPE_CLIP_USER, + CELL_SEARCH_SCENESEARCHTYPE_CLIP, + CELL_SEARCH_SCENESEARCHTYPE_ALL, +}; + +enum CellSearchRepeatMode : s32 +{ + CELL_SEARCH_REPEATMODE_NONE = 0, + CELL_SEARCH_REPEATMODE_REPEAT1, + CELL_SEARCH_REPEATMODE_ALL, + CELL_SEARCH_REPEATMODE_NOREPEAT1, +}; + +enum CellSearchContextOption : s32 +{ + CELL_SEARCH_CONTEXTOPTION_NONE = 0, + CELL_SEARCH_CONTEXTOPTION_SHUFFLE, +}; + +enum CellSearchSharableType : s32 +{ + CELL_SEARCH_SHARABLETYPE_PROHIBITED = 0, + CELL_SEARCH_SHARABLETYPE_PERMITTED, +}; + +using CellSearchId = s32; +using CellSearchSystemCallback = void(CellSearchEvent event, s32 result, vm::ps3::cptr param, vm::ps3::ptr userData); struct CellSearchContentId { @@ -174,7 +235,7 @@ struct CellSearchContentId struct CellSearchResultParam { - be_t searchId; + be_t searchId; be_t resultNum; };