mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Correct scePsmfPlayerCreate() based on tests.
Mostly error codes. Report duplicates which don't work on the PSP.
This commit is contained in:
parent
aed5615d97
commit
fb82310c9a
2 changed files with 66 additions and 27 deletions
|
@ -66,7 +66,10 @@ enum PsmfPlayerError {
|
|||
ERROR_PSMF_INVALID_VALUE = 0x806151fe,
|
||||
ERROR_PSMF_INVALID_TIMESTAMP = 0x80615500,
|
||||
ERROR_PSMF_INVALID_PSMF = 0x80615501,
|
||||
|
||||
ERROR_PSMFPLAYER_NOT_INITIALIZED = 0x80616001,
|
||||
ERROR_PSMFPLAYER_BUFFER_SIZE = 0x80616005,
|
||||
ERROR_PSMFPLAYER_INVALID_PARAM = 0x80616008,
|
||||
ERROR_PSMFPLAYER_NO_MORE_DATA = 0x8061600c,
|
||||
};
|
||||
|
||||
|
@ -99,6 +102,12 @@ struct PsmfData {
|
|||
u32_le unk2;
|
||||
};
|
||||
|
||||
struct PsmfPlayerCreateData {
|
||||
PSPPointer<u8> buffer;
|
||||
u32 bufferSize;
|
||||
int threadPriority;
|
||||
};
|
||||
|
||||
struct PsmfPlayerData {
|
||||
s32_le videoCodec;
|
||||
s32_le videoStreamNum;
|
||||
|
@ -181,7 +190,7 @@ class PsmfPlayer {
|
|||
public:
|
||||
// For savestates only.
|
||||
PsmfPlayer() { mediaengine = new MediaEngine; filehandle = 0;}
|
||||
PsmfPlayer(u32 data);
|
||||
PsmfPlayer(const PsmfPlayerCreateData *data);
|
||||
~PsmfPlayer() { if (mediaengine) delete mediaengine; pspFileSystem.CloseFile(filehandle);}
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
|
@ -314,20 +323,24 @@ Psmf::~Psmf() {
|
|||
streamMap.clear();
|
||||
}
|
||||
|
||||
PsmfPlayer::PsmfPlayer(u32 data) {
|
||||
videoCodec = Memory::Read_U32(data);
|
||||
videoStreamNum = Memory::Read_U32(data + 4);
|
||||
audioCodec = Memory::Read_U32(data + 8);
|
||||
audioStreamNum = Memory::Read_U32(data + 12);
|
||||
playMode = Memory::Read_U32(data+ 16);
|
||||
playSpeed = Memory::Read_U32(data + 20);
|
||||
psmfPlayerLastTimestamp = getMpegTimeStamp(Memory::GetPointer(data + PSMF_LAST_TIMESTAMP_OFFSET)) ;
|
||||
PsmfPlayer::PsmfPlayer(const PsmfPlayerCreateData *data) {
|
||||
videoCodec = 0;
|
||||
videoStreamNum = 0;
|
||||
audioCodec = 0;
|
||||
audioStreamNum = 0;
|
||||
playMode = 0;
|
||||
playSpeed = 0;
|
||||
psmfPlayerLastTimestamp = 0;
|
||||
status = PSMF_PLAYER_STATUS_INIT;
|
||||
mediaengine = new MediaEngine;
|
||||
filehandle = 0;
|
||||
fileoffset = 0;
|
||||
readSize = 0;
|
||||
streamSize = 0;
|
||||
|
||||
displayBuffer = data->buffer.ptr;
|
||||
displayBufferSize = data->bufferSize;
|
||||
playbackThreadPriority = data->threadPriority;
|
||||
}
|
||||
|
||||
void Psmf::DoState(PointerWrap &p) {
|
||||
|
@ -872,27 +885,51 @@ u32 scePsmfGetEPidWithTimestamp(u32 psmfStruct, u32 ts)
|
|||
return epid;
|
||||
}
|
||||
|
||||
int scePsmfPlayerCreate(u32 psmfPlayer, u32 psmfPlayerDataAddr)
|
||||
int scePsmfPlayerCreate(u32 psmfPlayer, u32 dataPtr)
|
||||
{
|
||||
WARN_LOG(ME, "scePsmfPlayerCreate(%08x, %08x)", psmfPlayer, psmfPlayerDataAddr);
|
||||
auto player = PSPPointer<u32>::Create(psmfPlayer);
|
||||
const auto data = PSPPointer<const PsmfPlayerCreateData>::Create(dataPtr);
|
||||
|
||||
if (!player.IsValid() || !data.IsValid()) {
|
||||
ERROR_LOG_REPORT(ME, "scePsmfPlayerCreate(%08x, %08x): bad pointers", psmfPlayer, dataPtr);
|
||||
// Crashes on a PSP.
|
||||
return SCE_KERNEL_ERROR_ILLEGAL_ADDRESS;
|
||||
}
|
||||
if (!data->buffer.IsValid()) {
|
||||
ERROR_LOG_REPORT(ME, "scePsmfPlayerCreate(%08x, %08x): invalid buffer address %08x", psmfPlayer, dataPtr, data->buffer.ptr);
|
||||
// Also crashes on a PSP.
|
||||
*player = 0;
|
||||
return SCE_KERNEL_ERROR_ILLEGAL_ADDRESS;
|
||||
}
|
||||
if (data->bufferSize < 0x00300000) {
|
||||
ERROR_LOG_REPORT(ME, "scePsmfPlayerCreate(%08x, %08x): buffer too small %08x", psmfPlayer, dataPtr, data->bufferSize);
|
||||
*player = 0;
|
||||
return ERROR_PSMFPLAYER_BUFFER_SIZE;
|
||||
}
|
||||
if (data->threadPriority < 0x10 || data->threadPriority >= 0x6E) {
|
||||
ERROR_LOG_REPORT(ME, "scePsmfPlayerCreate(%08x, %08x): bad thread priority %02x", psmfPlayer, dataPtr, data->threadPriority);
|
||||
*player = 0;
|
||||
return ERROR_PSMFPLAYER_INVALID_PARAM;
|
||||
}
|
||||
if (!psmfPlayerMap.empty()) {
|
||||
ERROR_LOG_REPORT(ME, "scePsmfPlayerCreate(%08x, %08x): already have an active player", psmfPlayer, dataPtr);
|
||||
// TODO: Tests show this is what we should do. Leaving it off for now to see if safe.
|
||||
//*player = 0;
|
||||
//return ERROR_MPEG_ALREADY_INIT;
|
||||
}
|
||||
|
||||
INFO_LOG(ME, "scePsmfPlayerCreate(%08x, %08x)", psmfPlayer, dataPtr);
|
||||
PsmfPlayer *psmfplayer = getPsmfPlayer(psmfPlayer);
|
||||
if (!psmfplayer) {
|
||||
// TODO: This is the wrong data. PsmfPlayer needs a new interface.
|
||||
psmfplayer = new PsmfPlayer(psmfPlayerDataAddr);
|
||||
psmfplayer = new PsmfPlayer(data);
|
||||
if (psmfPlayerMap.find(psmfPlayer) != psmfPlayerMap.end())
|
||||
delete psmfPlayerMap[psmfPlayer];
|
||||
psmfPlayerMap[psmfPlayer] = psmfplayer;
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(psmfPlayerDataAddr)) {
|
||||
psmfplayer->displayBuffer = Memory::Read_U32(psmfPlayerDataAddr);
|
||||
psmfplayer->displayBufferSize = Memory::Read_U32(psmfPlayerDataAddr + 4);
|
||||
psmfplayer->playbackThreadPriority = Memory::Read_U32(psmfPlayerDataAddr + 8);
|
||||
}
|
||||
|
||||
psmfplayer->psmfMaxAheadTimestamp = getMaxAheadTimestamp(581);
|
||||
psmfplayer->status = PSMF_PLAYER_STATUS_INIT;
|
||||
return 0;
|
||||
return hleDelayResult(0, "player create", 20000);
|
||||
}
|
||||
|
||||
int scePsmfPlayerStop(u32 psmfPlayer)
|
||||
|
@ -1086,13 +1123,6 @@ int scePsmfPlayerStart(u32 psmfPlayer, u32 psmfPlayerData, int initPts)
|
|||
return ERROR_PSMFPLAYER_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!psmfplayer) {
|
||||
psmfplayer = new PsmfPlayer(psmfPlayerData);
|
||||
if (psmfPlayerMap.find(psmfPlayer) != psmfPlayerMap.end())
|
||||
delete psmfPlayerMap[psmfPlayer];
|
||||
psmfPlayerMap[psmfPlayer] = psmfplayer;
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(psmfPlayerData)) {
|
||||
PsmfPlayerData data = {0};
|
||||
Memory::ReadStruct(psmfPlayerData, &data);
|
||||
|
|
|
@ -387,6 +387,15 @@ struct PSPPointer
|
|||
#endif
|
||||
}
|
||||
|
||||
inline operator const T*() const
|
||||
{
|
||||
#if defined(_M_IX86) || defined(_M_ARM32) || defined (_XBOX)
|
||||
return (const T *)(Memory::base + (ptr & Memory::MEMVIEW32_MASK));
|
||||
#else
|
||||
return (const T *)(Memory::base + ptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsValid() const
|
||||
{
|
||||
return Memory::IsValidAddress(ptr);
|
||||
|
|
Loading…
Add table
Reference in a new issue