From e83dfedff9e8bb83f867bf649f78da29579e5d9b Mon Sep 17 00:00:00 2001 From: Megamouse Date: Wed, 18 Dec 2019 23:48:23 +0100 Subject: [PATCH] stub cellRemotePlay and cellResc and cellStorage --- rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp | 43 +++- rpcs3/Emu/Cell/Modules/cellRemotePlay.h | 23 ++ rpcs3/Emu/Cell/Modules/cellResc.cpp | 269 ++++++++++++++++++++-- rpcs3/Emu/Cell/Modules/cellResc.h | 36 ++- rpcs3/Emu/Cell/Modules/cellStorage.cpp | 21 +- rpcs3/Emu/Cell/Modules/cellStorage.h | 37 +++ rpcs3/emucore.vcxproj | 4 +- rpcs3/emucore.vcxproj.filters | 8 +- 8 files changed, 382 insertions(+), 59 deletions(-) create mode 100644 rpcs3/Emu/Cell/Modules/cellRemotePlay.h create mode 100644 rpcs3/Emu/Cell/Modules/cellStorage.h diff --git a/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp b/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp index deb40b6f8d..89482c8ffd 100644 --- a/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp +++ b/rpcs3/Emu/Cell/Modules/cellRemotePlay.cpp @@ -1,51 +1,72 @@ -#include "stdafx.h" +#include "stdafx.h" #include "Emu/Cell/PPUModule.h" +#include "cellRemotePlay.h" LOG_CHANNEL(cellRemotePlay); -s32 cellRemotePlayGetStatus() +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](CellRemotePlayError value) + { + switch (value) + { + STR_CASE(CELL_REMOTEPLAY_ERROR_INTERNAL); + } + + return unknown; + }); +} + +error_code cellRemotePlayGetStatus() { cellRemotePlay.todo("cellRemotePlayGetStatus()"); return CELL_OK; } -s32 cellRemotePlaySetComparativeVolume() +error_code cellRemotePlaySetComparativeVolume(f32 comparativeAudioVolume) { - cellRemotePlay.todo("cellRemotePlaySetComparativeVolume()"); + cellRemotePlay.todo("cellRemotePlaySetComparativeVolume(comparativeAudioVolume=%f)", comparativeAudioVolume); return CELL_OK; } -s32 cellRemotePlayGetPeerInfo() +error_code cellRemotePlayGetPeerInfo() { cellRemotePlay.todo("cellRemotePlayGetPeerInfo()"); return CELL_OK; } -s32 cellRemotePlayGetSharedMemory() +error_code cellRemotePlayGetSharedMemory() { cellRemotePlay.todo("cellRemotePlayGetSharedMemory()"); return CELL_OK; } -s32 cellRemotePlayEncryptAllData() +error_code cellRemotePlayEncryptAllData() { cellRemotePlay.todo("cellRemotePlayEncryptAllData()"); return CELL_OK; } -s32 cellRemotePlayStopPeerVideoOut() +error_code cellRemotePlayStopPeerVideoOut() { cellRemotePlay.todo("cellRemotePlayStopPeerVideoOut()"); return CELL_OK; } -s32 cellRemotePlayGetComparativeVolume() +error_code cellRemotePlayGetComparativeVolume(vm::ptr pComparativeAudioVolume) { - cellRemotePlay.todo("cellRemotePlayGetComparativeVolume()"); + cellRemotePlay.todo("cellRemotePlayGetComparativeVolume(pComparativeAudioVolume=*0x%x)", pComparativeAudioVolume); + + if (pComparativeAudioVolume) + { + *pComparativeAudioVolume = 1.f; + } + return CELL_OK; } -s32 cellRemotePlayBreak() +error_code cellRemotePlayBreak() { cellRemotePlay.todo("cellRemotePlayBreak()"); return CELL_OK; diff --git a/rpcs3/Emu/Cell/Modules/cellRemotePlay.h b/rpcs3/Emu/Cell/Modules/cellRemotePlay.h new file mode 100644 index 0000000000..24ba98c90e --- /dev/null +++ b/rpcs3/Emu/Cell/Modules/cellRemotePlay.h @@ -0,0 +1,23 @@ +#pragma once + +enum CellRemotePlayError : u32 +{ + CELL_REMOTEPLAY_ERROR_INTERNAL = 0x80029830 +}; + +enum +{ + CELL_REMOTEPLAY_STATUS_LOADING = 0x00000000, + CELL_REMOTEPLAY_STATUS_WAIT = 0x00000001, + CELL_REMOTEPLAY_STATUS_RUNNING = 0x00000002, + CELL_REMOTEPLAY_STATUS_UNLOADING = 0x00000003, + CELL_REMOTEPLAY_STATUS_FATALERROR = 0x00000004, + CELL_REMOTEPLAY_STATUS_PREMOEND = 0x00000005, +}; + +enum +{ + CELL_REMOTEPLAY_M4V_MEMORY_CONTAINER_SIZE = 8 * 1024 * 1024, + CELL_REMOTEPLAY_AVC_MEMORY_CONTAINER_SIZE = 10 * 1024 * 1024, + CELL_REMOTEPLAY_480P_MEMORY_CONTAINER_SIZE = 10 * 1024 * 1024, +}; diff --git a/rpcs3/Emu/Cell/Modules/cellResc.cpp b/rpcs3/Emu/Cell/Modules/cellResc.cpp index 2e689cfeb6..00d8925f92 100644 --- a/rpcs3/Emu/Cell/Modules/cellResc.cpp +++ b/rpcs3/Emu/Cell/Modules/cellResc.cpp @@ -1,106 +1,325 @@ -#include "stdafx.h" +#include "stdafx.h" #include "Emu/System.h" #include "Emu/IdManager.h" #include "Emu/Cell/PPUModule.h" #include "Emu/RSX/GCM.h" #include "cellResc.h" +#include "cellVideoOut.h" LOG_CHANNEL(cellResc); -s32 cellRescInit(vm::ptr initConfig) +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](CellRescError value) + { + switch (value) + { + STR_CASE(CELL_RESC_ERROR_NOT_INITIALIZED); + STR_CASE(CELL_RESC_ERROR_REINITIALIZED); + STR_CASE(CELL_RESC_ERROR_BAD_ALIGNMENT); + STR_CASE(CELL_RESC_ERROR_BAD_ARGUMENT); + STR_CASE(CELL_RESC_ERROR_LESS_MEMORY); + STR_CASE(CELL_RESC_ERROR_GCM_FLIP_QUE_FULL); + STR_CASE(CELL_RESC_ERROR_BAD_COMBINATION); + STR_CASE(CELL_RESC_ERROR_x308); + } + + return unknown; + }); +} + +error_code cellRescInit(vm::cptr initConfig) { cellResc.todo("cellRescInit(initConfig=*0x%x)", initConfig); + auto resc_manager = g_fxo->get(); + + if (resc_manager->is_initialized) + { + return CELL_RESC_ERROR_REINITIALIZED; + } + + if (!initConfig || initConfig->size > 28) // TODO: more checks + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } + + resc_manager->config = + { + initConfig->size, + initConfig->resourcePolicy, + initConfig->supportModes, + initConfig->ratioMode, + initConfig->palTemporalMode, + initConfig->interlaceMode, + initConfig->flipMode + }; + resc_manager->is_initialized = true; + return CELL_OK; } void cellRescExit() { cellResc.todo("cellRescExit()"); + + auto resc_manager = g_fxo->get(); + resc_manager->is_initialized = false; } -s32 cellRescVideoOutResolutionId2RescBufferMode(u32 resolutionId, vm::ptr bufferMode) +error_code cellRescVideoOutResolutionId2RescBufferMode(u32 resolutionId, vm::cptr bufferMode) { cellResc.todo("cellRescVideoOutResolutionId2RescBufferMode(resolutionId=%d, bufferMode=*0x%x)", resolutionId, bufferMode); + if (!bufferMode || !resolutionId || resolutionId > CELL_VIDEO_OUT_RESOLUTION_576) + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } + return CELL_OK; } -s32 cellRescSetDsts(u32 dstsMode, vm::ptr dsts) +error_code cellRescSetDsts(u32 bufferMode, vm::cptr dsts) { - cellResc.todo("cellRescSetDsts(dstsMode=%d, dsts=*0x%x)", dstsMode, dsts); + cellResc.todo("cellRescSetDsts(bufferMode=%d, dsts=*0x%x)", bufferMode, dsts); + + auto resc_manager = g_fxo->get(); + + if (!resc_manager->is_initialized) + { + return CELL_RESC_ERROR_NOT_INITIALIZED; + } + + if (!dsts || !bufferMode || bufferMode > CELL_RESC_1920x1080) // TODO: is the bufferMode check correct? + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } return CELL_OK; } -s32 cellRescSetDisplayMode(u32 displayMode) +error_code cellRescSetDisplayMode(u32 bufferMode) { - cellResc.todo("cellRescSetDisplayMode(displayMode=%d)", displayMode); + cellResc.todo("cellRescSetDisplayMode(bufferMode=%d)", bufferMode); + + auto resc_manager = g_fxo->get(); + + if (!resc_manager->is_initialized) + { + return CELL_RESC_ERROR_NOT_INITIALIZED; + } + + if (!bufferMode || bufferMode > CELL_RESC_1920x1080 || !(resc_manager->config.support_modes & bufferMode)) // TODO: is the bufferMode check correct? + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } + + if (bufferMode == CELL_RESC_720x576) + { + const u32 pal_mode = resc_manager->config.pal_temporal_mode; + const u32 flip_mode = resc_manager->config.flip_mode; + + // Check if palTemporalMode is any INTERPOLATE mode or CELL_RESC_PAL_60_DROP + if ((pal_mode - CELL_RESC_PAL_60_INTERPOLATE) <= CELL_RESC_PAL_60_INTERPOLATE || pal_mode == CELL_RESC_PAL_60_DROP) + { + if (flip_mode == CELL_RESC_DISPLAY_HSYNC) + { + return CELL_RESC_ERROR_BAD_COMBINATION; + } + } + + if (pal_mode == CELL_RESC_PAL_60_FOR_HSYNC) + { + if (flip_mode == CELL_RESC_DISPLAY_VSYNC) + { + return CELL_RESC_ERROR_BAD_COMBINATION; + } + } + } + + resc_manager->buffer_mode = bufferMode; return CELL_OK; } -s32 cellRescAdjustAspectRatio(f32 horizontal, f32 vertical) +error_code cellRescAdjustAspectRatio(f32 horizontal, f32 vertical) { cellResc.todo("cellRescAdjustAspectRatio(horizontal=%f, vertical=%f)", horizontal, vertical); + auto resc_manager = g_fxo->get(); + + if (!resc_manager->is_initialized) + { + return CELL_RESC_ERROR_NOT_INITIALIZED; + } + + if (horizontal < 0.5f || horizontal > 2.0f || vertical < 0.5f || vertical > 2.0f) + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } + return CELL_OK; } -s32 cellRescSetPalInterpolateDropFlexRatio(f32 ratio) +error_code cellRescSetPalInterpolateDropFlexRatio(f32 ratio) { cellResc.todo("cellRescSetPalInterpolateDropFlexRatio(ratio=%f)", ratio); + auto resc_manager = g_fxo->get(); + + if (!resc_manager->is_initialized) + { + return CELL_RESC_ERROR_NOT_INITIALIZED; + } + + if (ratio < 0.0f || ratio > 1.0f) + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } + return CELL_OK; } -s32 cellRescGetBufferSize(vm::ptr colorBuffers, vm::ptr vertexArray, vm::ptr fragmentShader) +error_code cellRescGetBufferSize(vm::ptr colorBuffers, vm::ptr vertexArray, vm::ptr fragmentShader) { cellResc.todo("cellRescGetBufferSize(colorBuffers=*0x%x, vertexArray=*0x%x, fragmentShader=*0x%x)", colorBuffers, vertexArray, fragmentShader); + auto resc_manager = g_fxo->get(); + + if (!resc_manager->is_initialized) + { + return CELL_RESC_ERROR_NOT_INITIALIZED; + } + + //if (something) + //{ + // return CELL_RESC_ERROR_x308; + //} + + //if (colorBuffers) + //{ + // colorBuffers = something + //} + + //if (vertexArray) + //{ + // vertexArray = something + //} + + //if (fragmentShader) + //{ + // fragmentShader = something + //} + return CELL_OK; } -s32 cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, u32 reserved) +s32 cellRescGetNumColorBuffers(u32 dstMode, u32 palTemporalMode, s32 reserved) { cellResc.todo("cellRescGetNumColorBuffers(dstMode=%d, palTemporalMode=%d, reserved=%d)", dstMode, palTemporalMode, reserved); + if (reserved != 0) + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } + + if (dstMode == CELL_RESC_720x576) + { + // Check if palTemporalMode is any INTERPOLATE mode + if ((palTemporalMode - CELL_RESC_PAL_60_INTERPOLATE) <= CELL_RESC_PAL_60_INTERPOLATE) + { + return 6; + } + + if (palTemporalMode == CELL_RESC_PAL_60_DROP) + { + return 3; + } + } + return 2; } -s32 cellRescGcmSurface2RescSrc(vm::ptr gcmSurface, vm::ptr rescSrc) +error_code cellRescGcmSurface2RescSrc(vm::cptr gcmSurface, vm::cptr rescSrc) { cellResc.todo("cellRescGcmSurface2RescSrc(gcmSurface=*0x%x, rescSrc=*0x%x)", gcmSurface, rescSrc); + if (!gcmSurface || !rescSrc) + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } + return CELL_OK; } -s32 cellRescSetSrc(s32 idx, vm::ptr src) +error_code cellRescSetSrc(s32 idx, vm::cptr src) { cellResc.todo("cellRescSetSrc(idx=0x%x, src=*0x%x)", idx, src); + auto resc_manager = g_fxo->get(); + + if (!resc_manager->is_initialized) + { + return CELL_RESC_ERROR_NOT_INITIALIZED; + } + + if (idx >= SRC_BUFFER_NUM || !src || !src->width || !src->height || src->height > 4096) // TODO: is this correct? + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } + return CELL_OK; } -s32 cellRescSetConvertAndFlip(ppu_thread& ppu, vm::ptr cntxt, s32 idx) +error_code cellRescSetConvertAndFlip(ppu_thread& ppu, vm::ptr con, s32 idx) { - cellResc.todo("cellRescSetConvertAndFlip(cntxt=*0x%x, idx=0x%x)", cntxt, idx); + cellResc.todo("cellRescSetConvertAndFlip(con=*0x%x, idx=0x%x)", con, idx); + + auto resc_manager = g_fxo->get(); + + if (!resc_manager->is_initialized) + { + return CELL_RESC_ERROR_NOT_INITIALIZED; + } + + if (idx >= SRC_BUFFER_NUM) + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } return CELL_OK; } -s32 cellRescSetWaitFlip() +error_code cellRescSetWaitFlip(vm::ptr con) { - cellResc.todo("cellRescSetWaitFlip()"); + cellResc.todo("cellRescSetWaitFlip(con=*0x%x)", con); return CELL_OK; } -s32 cellRescSetBufferAddress(vm::ptr colorBuffers, vm::ptr vertexArray, vm::ptr fragmentShader) +error_code cellRescSetBufferAddress(vm::cptr colorBuffers, vm::cptr vertexArray, vm::cptr fragmentShader) { cellResc.todo("cellRescSetBufferAddress(colorBuffers=*0x%x, vertexArray=*0x%x, fragmentShader=*0x%x)", colorBuffers, vertexArray, fragmentShader); + auto resc_manager = g_fxo->get(); + + if (!resc_manager->is_initialized) + { + return CELL_RESC_ERROR_NOT_INITIALIZED; + } + + if (!colorBuffers || !vertexArray || !fragmentShader) + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } + + if (!colorBuffers.aligned(128) || !vertexArray.aligned(4) || !fragmentShader.aligned(64)) // clrlwi with 25, 30, 26 + { + return CELL_RESC_ERROR_BAD_ALIGNMENT; + } + return CELL_OK; } @@ -144,10 +363,22 @@ void cellRescSetVBlankHandler(vm::ptr handler) cellResc.todo("cellRescSetVBlankHandler(handler=*0x%x)", handler); } -s32 cellRescCreateInterlaceTable(u32 ea_addr, f32 srcH, CellRescTableElement depth, s32 length) +error_code cellRescCreateInterlaceTable(vm::ptr ea_addr, f32 srcH, CellRescTableElement depth, s32 length) { cellResc.todo("cellRescCreateInterlaceTable(ea_addr=0x%x, srcH=%f, depth=%d, length=%d)", ea_addr, srcH, +depth, length); + if (!ea_addr || srcH <= 0.0f || depth > CELL_RESC_ELEMENT_FLOAT || length <= 0) // TODO: srcH check correct? + { + return CELL_RESC_ERROR_BAD_ARGUMENT; + } + + auto resc_manager = g_fxo->get(); + + if (!resc_manager->buffer_mode) + { + return CELL_RESC_ERROR_BAD_COMBINATION; + } + return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/cellResc.h b/rpcs3/Emu/Cell/Modules/cellResc.h index af35fe0daa..d487b705eb 100644 --- a/rpcs3/Emu/Cell/Modules/cellResc.h +++ b/rpcs3/Emu/Cell/Modules/cellResc.h @@ -1,16 +1,17 @@ -#pragma once +#pragma once #include "Utilities/BEType.h" -enum +enum CellRescError : u32 { - CELL_RESC_ERROR_NOT_INITIALIZED = 0x80210301, - CELL_RESC_ERROR_REINITIALIZED = 0x80210302, - CELL_RESC_ERROR_BAD_ALIGNMENT = 0x80210303, - CELL_RESC_ERROR_BAD_ARGUMENT = 0x80210304, - CELL_RESC_ERROR_LESS_MEMORY = 0x80210305, + CELL_RESC_ERROR_NOT_INITIALIZED = 0x80210301, + CELL_RESC_ERROR_REINITIALIZED = 0x80210302, + CELL_RESC_ERROR_BAD_ALIGNMENT = 0x80210303, + CELL_RESC_ERROR_BAD_ARGUMENT = 0x80210304, + CELL_RESC_ERROR_LESS_MEMORY = 0x80210305, CELL_RESC_ERROR_GCM_FLIP_QUE_FULL = 0x80210306, - CELL_RESC_ERROR_BAD_COMBINATION = 0x80210307, + CELL_RESC_ERROR_BAD_COMBINATION = 0x80210307, + CELL_RESC_ERROR_x308 = 0x80210308, // TODO: find proper name }; enum @@ -66,6 +67,7 @@ enum CellRescResourcePolicy { CELL_RESC_CONSTANT_VRAM = 0x0, CELL_RESC_MINIMUM_VRAM = 0x1, + CELL_RESC_CONSTANT_GPU_LOAD = 0x0, CELL_RESC_MINIMUM_GPU_LOAD = 0x2, }; @@ -104,3 +106,21 @@ struct CellRescSrc be_t height; be_t offset; }; + +struct cell_resc_manager +{ + atomic_t is_initialized = false; + + u32 buffer_mode{}; + + struct + { + u32 size{}; + u32 resource_policy{}; + u32 support_modes{}; + u32 ratio_mode{}; + u32 pal_temporal_mode{}; + u32 interlace_mode{}; + u32 flip_mode{}; + } config; +}; diff --git a/rpcs3/Emu/Cell/Modules/cellStorage.cpp b/rpcs3/Emu/Cell/Modules/cellStorage.cpp index eea3280730..a1848d0cbb 100644 --- a/rpcs3/Emu/Cell/Modules/cellStorage.cpp +++ b/rpcs3/Emu/Cell/Modules/cellStorage.cpp @@ -1,28 +1,11 @@ -#include "stdafx.h" +#include "stdafx.h" #include "Emu/Cell/PPUModule.h" #include "cellSysutil.h" +#include "cellStorage.h" extern logs::channel cellSysutil; -enum CellStorageError : u32 -{ - CELL_STORAGEDATA_ERROR_BUSY = 0x8002be01, - CELL_STORAGEDATA_ERROR_INTERNAL = 0x8002be02, - CELL_STORAGEDATA_ERROR_PARAM = 0x8002be03, - CELL_STORAGEDATA_ERROR_ACCESS_ERROR = 0x8002be04, - CELL_STORAGEDATA_ERROR_FAILURE = 0x8002be05 -}; - -struct CellStorageDataSetParam -{ - be_t fileSizeMax; - vm::bptr title; - vm::bptr reserved; -}; - -using CellStorageDataFinishCallback = void(s32 result, vm::ptr userdata); - template <> void fmt_class_string::format(std::string& out, u64 arg) { diff --git a/rpcs3/Emu/Cell/Modules/cellStorage.h b/rpcs3/Emu/Cell/Modules/cellStorage.h new file mode 100644 index 0000000000..6883171e9e --- /dev/null +++ b/rpcs3/Emu/Cell/Modules/cellStorage.h @@ -0,0 +1,37 @@ +#pragma once + +enum CellStorageError : u32 +{ + CELL_STORAGEDATA_ERROR_BUSY = 0x8002be01, + CELL_STORAGEDATA_ERROR_INTERNAL = 0x8002be02, + CELL_STORAGEDATA_ERROR_PARAM = 0x8002be03, + CELL_STORAGEDATA_ERROR_ACCESS_ERROR = 0x8002be04, + CELL_STORAGEDATA_ERROR_FAILURE = 0x8002be05 +}; + +enum CellStorageDataVersion +{ + CELL_STORAGEDATA_VERSION_CURRENT = 0, + CELL_STORAGEDATA_VERSION_DST_FILENAME = 1, +}; + +enum CellStorageDataParamSize +{ + CELL_STORAGEDATA_HDD_PATH_MAX = 1055, + CELL_STORAGEDATA_MEDIA_PATH_MAX = 1024, + CELL_STORAGEDATA_FILENAME_MAX = 64, + CELL_STORAGEDATA_FILESIZE_MAX = 1024 * 1024 * 1024, + CELL_STORAGEDATA_TITLE_MAX = 256 +}; + +const char* CELL_STORAGEDATA_IMPORT_FILENAME = "IMPORT.BIN"; +const char* CELL_STORAGEDATA_EXPORT_FILENAME = "EXPORT.BIN"; + +struct CellStorageDataSetParam +{ + be_t fileSizeMax; + vm::bptr title; + vm::bptr reserved; +}; + +using CellStorageDataFinishCallback = void(s32 result, vm::ptr userdata); diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 5da8364384..ab583b869d 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -389,7 +389,9 @@ + + @@ -649,4 +651,4 @@ - + \ No newline at end of file diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index c8cfad1337..49246ff690 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1579,5 +1579,11 @@ Emu\Cell\Modules + + Emu\Cell\Modules + + + Emu\Cell\Modules + - + \ No newline at end of file