mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-29 00:33:01 +00:00
cellSubDisplay: add error checks
This commit is contained in:
parent
92b08a4faf
commit
4446d9ce4b
@ -1,5 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/IdManager.h"
|
||||
|
||||
#include "cellSubDisplay.h"
|
||||
|
||||
@ -27,15 +28,147 @@ void fmt_class_string<CellSubDisplayError>::format(std::string& out, u64 arg)
|
||||
});
|
||||
}
|
||||
|
||||
enum class sub_display_status : u32
|
||||
{
|
||||
uninitialized = 0,
|
||||
stopped = 1,
|
||||
started = 2
|
||||
};
|
||||
|
||||
struct sub_display_manager
|
||||
{
|
||||
shared_mutex mutex;
|
||||
sub_display_status status = sub_display_status::uninitialized;
|
||||
CellSubDisplayParam param{};
|
||||
vm::ptr<CellSubDisplayHandler> func = vm::null;
|
||||
vm::ptr<void> userdata = vm::null;
|
||||
|
||||
// Video data
|
||||
vm::ptr<void> video_buffer = vm::null;
|
||||
u32 buf_size = 0;
|
||||
|
||||
// Audio data
|
||||
bool audio_is_busy = false;
|
||||
|
||||
// Touch data
|
||||
std::array<CellSubDisplayTouchInfo, CELL_SUBDISPLAY_TOUCH_MAX_TOUCH_INFO> touch_info{};
|
||||
};
|
||||
|
||||
|
||||
error_code check_param(CellSubDisplayParam* param)
|
||||
{
|
||||
if (!param ||
|
||||
param->version < CELL_SUBDISPLAY_VERSION_0001 ||
|
||||
param->version > CELL_SUBDISPLAY_VERSION_0003 ||
|
||||
param->mode != CELL_SUBDISPLAY_MODE_REMOTEPLAY ||
|
||||
param->nGroup != 1 ||
|
||||
param->nPeer != 1 ||
|
||||
param->audioParam.ch != 2 ||
|
||||
param->audioParam.audioMode < CELL_SUBDISPLAY_AUDIO_MODE_SETDATA ||
|
||||
param->audioParam.audioMode > CELL_SUBDISPLAY_AUDIO_MODE_CAPTURE)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
switch (param->videoParam.format)
|
||||
{
|
||||
case CELL_SUBDISPLAY_VIDEO_FORMAT_A8R8G8B8:
|
||||
case CELL_SUBDISPLAY_VIDEO_FORMAT_R8G8B8A8:
|
||||
{
|
||||
if (param->version == CELL_SUBDISPLAY_VERSION_0003 ||
|
||||
param->videoParam.width != 480 ||
|
||||
param->videoParam.height != 272 ||
|
||||
(param->videoParam.pitch != 1920 && param->videoParam.pitch != 2048) ||
|
||||
param->videoParam.aspectRatio < CELL_SUBDISPLAY_VIDEO_ASPECT_RATIO_16_9 ||
|
||||
param->videoParam.aspectRatio > CELL_SUBDISPLAY_VIDEO_ASPECT_RATIO_4_3 ||
|
||||
param->videoParam.videoMode < CELL_SUBDISPLAY_VIDEO_MODE_SETDATA ||
|
||||
param->videoParam.videoMode > CELL_SUBDISPLAY_VIDEO_MODE_CAPTURE)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CELL_SUBDISPLAY_VIDEO_FORMAT_YUV420:
|
||||
{
|
||||
if (param->version != CELL_SUBDISPLAY_VERSION_0003 ||
|
||||
param->videoParam.width != CELL_SUBDISPLAY_0003_WIDTH ||
|
||||
param->videoParam.height != CELL_SUBDISPLAY_0003_HEIGHT ||
|
||||
param->videoParam.pitch != CELL_SUBDISPLAY_0003_PITCH ||
|
||||
param->videoParam.aspectRatio != CELL_SUBDISPLAY_VIDEO_ASPECT_RATIO_16_9 ||
|
||||
param->videoParam.videoMode != CELL_SUBDISPLAY_VIDEO_MODE_SETDATA)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayInit(vm::ptr<CellSubDisplayParam> pParam, vm::ptr<CellSubDisplayHandler> func, vm::ptr<void> userdata, u32 container)
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayInit(pParam=*0x%x, func=*0x%x, userdata=*0x%x, container=0x%x)", pParam, func, userdata, container);
|
||||
return CELL_SUBDISPLAY_ERROR_ZERO_REGISTERED;
|
||||
|
||||
auto& manager = g_fxo->get<sub_display_manager>();
|
||||
std::lock_guard lock(manager.mutex);
|
||||
|
||||
if (manager.func)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (error_code error = check_param(pParam.get_ptr()))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
if (!func)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
manager.param = *pParam;
|
||||
manager.func = func;
|
||||
manager.userdata = userdata;
|
||||
|
||||
if (true) // TODO
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_ZERO_REGISTERED;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayEnd()
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayEnd()");
|
||||
|
||||
auto& manager = g_fxo->get<sub_display_manager>();
|
||||
std::lock_guard lock(manager.mutex);
|
||||
|
||||
if (!manager.func)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (manager.status == sub_display_status::started)
|
||||
{
|
||||
// TODO:
|
||||
// cellSubDisplayStop();
|
||||
}
|
||||
|
||||
manager.param = {};
|
||||
manager.func = vm::null;
|
||||
manager.userdata = vm::null;
|
||||
manager.status = sub_display_status::uninitialized;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -43,6 +176,11 @@ error_code cellSubDisplayGetRequiredMemory(vm::ptr<CellSubDisplayParam> pParam)
|
||||
{
|
||||
cellSubDisplay.warning("cellSubDisplayGetRequiredMemory(pParam=*0x%x)", pParam);
|
||||
|
||||
if (error_code error = check_param(pParam.get_ptr()))
|
||||
{
|
||||
return error;
|
||||
}
|
||||
|
||||
switch (pParam->version)
|
||||
{
|
||||
case CELL_SUBDISPLAY_VERSION_0001: return not_an_error(CELL_SUBDISPLAY_0001_MEMORY_CONTAINER_SIZE);
|
||||
@ -57,18 +195,61 @@ error_code cellSubDisplayGetRequiredMemory(vm::ptr<CellSubDisplayParam> pParam)
|
||||
error_code cellSubDisplayStart()
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayStart()");
|
||||
|
||||
auto& manager = g_fxo->get<sub_display_manager>();
|
||||
std::lock_guard lock(manager.mutex);
|
||||
|
||||
if (manager.status == sub_display_status::uninitialized)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
manager.status = sub_display_status::started;
|
||||
|
||||
// TODO
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayStop()
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayStop()");
|
||||
|
||||
auto& manager = g_fxo->get<sub_display_manager>();
|
||||
std::lock_guard lock(manager.mutex);
|
||||
|
||||
if (manager.status == sub_display_status::uninitialized)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
manager.status = sub_display_status::stopped;
|
||||
|
||||
// TODO
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayGetVideoBuffer(s32 groupId, vm::pptr<void> ppVideoBuf, vm::ptr<u32> pSize)
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayGetVideoBuffer(groupId=%d, ppVideoBuf=**0x%x, pSize=*0x%x)", groupId, ppVideoBuf, pSize);
|
||||
|
||||
auto& manager = g_fxo->get<sub_display_manager>();
|
||||
std::lock_guard lock(manager.mutex);
|
||||
|
||||
if (manager.status == sub_display_status::uninitialized)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (groupId != 0 || !ppVideoBuf || !pSize)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
*pSize = manager.buf_size;
|
||||
*ppVideoBuf = manager.video_buffer;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -76,11 +257,26 @@ error_code cellSubDisplayAudioOutBlocking(s32 groupId, vm::ptr<void> pvData, s32
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayAudioOutBlocking(groupId=%d, pvData=*0x%x, samples=%d)", groupId, pvData, samples);
|
||||
|
||||
auto& manager = g_fxo->get<sub_display_manager>();
|
||||
std::lock_guard lock(manager.mutex);
|
||||
|
||||
if (manager.status == sub_display_status::uninitialized)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (groupId != 0 || samples < 0)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if (samples % 1024)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_SET_SAMPLE;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -88,32 +284,110 @@ error_code cellSubDisplayAudioOutNonBlocking(s32 groupId, vm::ptr<void> pvData,
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayAudioOutNonBlocking(groupId=%d, pvData=*0x%x, samples=%d)", groupId, pvData, samples);
|
||||
|
||||
auto& manager = g_fxo->get<sub_display_manager>();
|
||||
std::lock_guard lock(manager.mutex);
|
||||
|
||||
if (manager.status == sub_display_status::uninitialized)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (groupId != 0 || samples < 0)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
if (samples % 1024)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_SET_SAMPLE;
|
||||
}
|
||||
|
||||
if (manager.audio_is_busy)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_AUDIOOUT_IS_BUSY;
|
||||
}
|
||||
|
||||
// TODO: fetch audio async
|
||||
// manager.audio_is_busy = true;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayGetPeerNum(s32 groupId)
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayGetPeerNum(groupId=%d)", groupId);
|
||||
return CELL_OK;
|
||||
|
||||
auto& manager = g_fxo->get<sub_display_manager>();
|
||||
std::lock_guard lock(manager.mutex);
|
||||
|
||||
if (manager.status == sub_display_status::uninitialized)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (groupId != 0)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
s32 peer_num = 0; // TODO
|
||||
|
||||
return not_an_error(peer_num);
|
||||
}
|
||||
|
||||
error_code cellSubDisplayGetPeerList(s32 groupId, vm::ptr<CellSubDisplayPeerInfo> pInfo, vm::ptr<s32> pNum)
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayGetPeerList(groupId=%d, pInfo=*0x%x, pNum=*0x%x)", groupId, pInfo, pNum);
|
||||
|
||||
auto& manager = g_fxo->get<sub_display_manager>();
|
||||
std::lock_guard lock(manager.mutex);
|
||||
|
||||
if (manager.status == sub_display_status::uninitialized)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (groupId != 0)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (!pInfo || !pNum || *pNum < 1)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
*pNum = 0;
|
||||
|
||||
// TODO
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayGetTouchInfo(s32 groupId, vm::ptr<CellSubDisplayTouchInfo> pTouchInfo, vm::ptr<s32> pNumTouchInfo)
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayGetTouchInfo(groupId=%d, pTouchInfo=*0x%x, pNumTouchInfo=*0x%x)", groupId, pTouchInfo, pNumTouchInfo);
|
||||
|
||||
if (groupId != 0 || !pNumTouchInfo || !pTouchInfo)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
auto& manager = g_fxo->get<sub_display_manager>();
|
||||
std::lock_guard lock(manager.mutex);
|
||||
|
||||
if (manager.param.version != CELL_SUBDISPLAY_VERSION_0003)
|
||||
{
|
||||
return CELL_SUBDISPLAY_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (*pNumTouchInfo > CELL_SUBDISPLAY_TOUCH_MAX_TOUCH_INFO)
|
||||
{
|
||||
*pNumTouchInfo = CELL_SUBDISPLAY_TOUCH_MAX_TOUCH_INFO;
|
||||
}
|
||||
|
||||
std::memcpy(pTouchInfo.get_ptr(), manager.touch_info.data(), *pNumTouchInfo * sizeof(CellSubDisplayTouchInfo));
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -20,25 +20,34 @@ enum
|
||||
CELL_SUBDISPLAY_STATUS_JOIN = 1,
|
||||
CELL_SUBDISPLAY_STATUS_LEAVE = 2,
|
||||
CELL_SUBDISPLAY_STATUS_FATALERROR = 3,
|
||||
|
||||
CELL_SUBDISPLAY_VERSION_0001 = 1,
|
||||
CELL_SUBDISPLAY_VERSION_0002 = 2,
|
||||
CELL_SUBDISPLAY_VERSION_0003 = 3,
|
||||
|
||||
CELL_SUBDISPLAY_MODE_REMOTEPLAY = 1,
|
||||
|
||||
CELL_SUBDISPLAY_VIDEO_FORMAT_A8R8G8B8 = 1,
|
||||
CELL_SUBDISPLAY_VIDEO_FORMAT_R8G8B8A8 = 2,
|
||||
CELL_SUBDISPLAY_VIDEO_FORMAT_YUV420 = 3,
|
||||
|
||||
CELL_SUBDISPLAY_VIDEO_ASPECT_RATIO_16_9 = 0,
|
||||
CELL_SUBDISPLAY_VIDEO_ASPECT_RATIO_4_3 = 1,
|
||||
|
||||
CELL_SUBDISPLAY_VIDEO_MODE_SETDATA = 0,
|
||||
CELL_SUBDISPLAY_VIDEO_MODE_CAPTURE = 1,
|
||||
|
||||
CELL_SUBDISPLAY_AUDIO_MODE_SETDATA = 0,
|
||||
CELL_SUBDISPLAY_AUDIO_MODE_CAPTURE = 1,
|
||||
|
||||
CELL_SUBDISPLAY_0001_MEMORY_CONTAINER_SIZE = 8 * 1024 * 1024,
|
||||
CELL_SUBDISPLAY_0002_MEMORY_CONTAINER_SIZE = 10 * 1024 * 1024,
|
||||
CELL_SUBDISPLAY_0003_MEMORY_CONTAINER_SIZE = 10 * 1024 * 1024,
|
||||
|
||||
CELL_SUBDISPLAY_0003_WIDTH = 864,
|
||||
CELL_SUBDISPLAY_0003_PITCH = 864,
|
||||
CELL_SUBDISPLAY_0003_HEIGHT = 480,
|
||||
|
||||
CELL_SUBDISPLAY_NICKNAME_LEN = 256,
|
||||
CELL_SUBDISPLAY_PSPID_LEN = 16,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user