Fix video playback in LocoRoco 2. scePsmfPlayerGetInfo had a couple more parameters.

Fixes #7887.
This commit is contained in:
Henrik Rydgard 2017-01-29 09:56:32 +01:00
parent a362af74c0
commit e9d5eb694b

View File

@ -25,6 +25,7 @@
#include "Core/HLE/FunctionWrappers.h"
#include "Core/HLE/scePsmf.h"
#include "Core/HLE/sceMpeg.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/HW/MediaEngine.h"
#include "GPU/GPUInterface.h"
#include "GPU/GPUState.h"
@ -206,7 +207,7 @@ public:
class PsmfPlayer {
public:
// For savestates only.
PsmfPlayer() : filehandle(0), finishThread(nullptr) {
PsmfPlayer() : filehandle(0), finishThread(nullptr), videoWidth(480), videoHeight(272) {
mediaengine = new MediaEngine();
}
PsmfPlayer(const PsmfPlayerCreateData *data);
@ -260,6 +261,9 @@ public:
int warmUp;
s64 seekDestTimeStamp;
int videoWidth;
int videoHeight;
SceMpegAu psmfPlayerAtracAu;
SceMpegAu psmfPlayerAvcAu;
PsmfPlayerStatus status;
@ -411,7 +415,7 @@ PsmfPlayer::PsmfPlayer(const PsmfPlayerCreateData *data) {
playSpeed = 1;
totalDurationTimestamp = 0;
status = PSMF_PLAYER_STATUS_INIT;
mediaengine = new MediaEngine;
mediaengine = new MediaEngine();
finishThread = nullptr;
filehandle = 0;
fileoffset = 0;
@ -480,7 +484,7 @@ void Psmf::DoState(PointerWrap &p) {
}
void PsmfPlayer::DoState(PointerWrap &p) {
auto s = p.Section("PsmfPlayer", 1, 7);
auto s = p.Section("PsmfPlayer", 1, 8);
if (!s)
return;
@ -549,6 +553,11 @@ void PsmfPlayer::DoState(PointerWrap &p) {
} else {
finishThread = NULL;
}
if (s >= 8) {
p.Do(videoWidth);
p.Do(videoHeight);
}
}
bool Psmf::setStreamNum(u32 psmfStruct, int num, bool updateCached) {
@ -1217,6 +1226,9 @@ static int _PsmfPlayerSetPsmfOffset(u32 psmfPlayer, const char *filename, int of
psmfplayer->totalVideoStreams = 0;
psmfplayer->totalAudioStreams = 0;
psmfplayer->videoWidth = buf[142] * 16;
psmfplayer->videoHeight = buf[143] * 16;
psmfplayer->playerVersion = PSMF_PLAYER_VERSION_FULL;
for (u16 i = 0; i < numStreams; i++) {
const u8 *currentStreamAddr = buf + 0x82 + i * 16;
@ -1725,8 +1737,7 @@ static u32 scePsmfPlayerGetCurrentPts(u32 psmfPlayer, u32 currentPtsAddr)
return 0;
}
static u32 scePsmfPlayerGetPsmfInfo(u32 psmfPlayer, u32 psmfInfoAddr)
{
static u32 scePsmfPlayerGetPsmfInfo(u32 psmfPlayer, u32 psmfInfoAddr, u32 widthAddr, u32 heightAddr) {
auto info = PSPPointer<PsmfInfo>::Create(psmfInfoAddr);
if (!Memory::IsValidAddress(psmfPlayer) || !info.IsValid()) {
ERROR_LOG(ME, "scePsmfPlayerGetPsmfInfo(%08x, %08x): invalid addresses", psmfPlayer, psmfInfoAddr);
@ -1753,6 +1764,18 @@ static u32 scePsmfPlayerGetPsmfInfo(u32 psmfPlayer, u32 psmfInfoAddr)
info->numPCMStreams = 0;
info->playerVersion = psmfplayer->playerVersion;
if (psmfPlayerLibVersion >= 0x03090510) {
// LocoRoco 2 depends on these for sizing its video output. Without this, its height is zero
// and nothing is drawn.
// Can't ask mediaengine for width/height here, it's too early, so we grabbed it from the
// header in scePsmfPlayerSetPsmf.
if (Memory::IsValidAddress(widthAddr) && psmfplayer->videoWidth) {
Memory::Write_U32(psmfplayer->videoWidth, widthAddr);
}
if (Memory::IsValidAddress(heightAddr) && psmfplayer->videoHeight) {
Memory::Write_U32(psmfplayer->videoHeight, heightAddr);
}
}
return 0;
}
@ -2123,7 +2146,7 @@ const HLEFunction scePsmfPlayer[] =
{0XA3D81169, &WrapU_UII<scePsmfPlayerChangePlayMode>, "scePsmfPlayerChangePlayMode", 'x', "xii"},
{0XB8D10C56, &WrapU_U<scePsmfPlayerSelectAudio>, "scePsmfPlayerSelectAudio", 'x', "x" },
{0XB9848A74, &WrapI_UU<scePsmfPlayerGetAudioData>, "scePsmfPlayerGetAudioData", 'i', "xx" },
{0XDF089680, &WrapU_UU<scePsmfPlayerGetPsmfInfo>, "scePsmfPlayerGetPsmfInfo", 'x', "xx" },
{0XDF089680, &WrapU_UUUU<scePsmfPlayerGetPsmfInfo>, "scePsmfPlayerGetPsmfInfo", 'x', "xxxx" },
{0XE792CD94, &WrapI_U<scePsmfPlayerReleasePsmf>, "scePsmfPlayerReleasePsmf", 'i', "x" },
{0XF3EFAA91, &WrapU_UUU<scePsmfPlayerGetCurrentPlayMode>, "scePsmfPlayerGetCurrentPlayMode", 'x', "xxx"},
{0XF8EF08A6, &WrapI_U<scePsmfPlayerGetCurrentStatus>, "scePsmfPlayerGetCurrentStatus", 'i', "x" },