2018-10-07 03:42:33 +00:00
|
|
|
#pragma once
|
2016-03-07 03:12:32 +00:00
|
|
|
|
2019-09-28 02:53:03 +00:00
|
|
|
#include <memory>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include "Runtime/CDvdFile.hpp"
|
|
|
|
#include "Runtime/RetroTypes.hpp"
|
2022-02-01 00:06:54 +00:00
|
|
|
#include "Runtime/Graphics/CGraphics.hpp"
|
2019-09-28 02:53:03 +00:00
|
|
|
|
2021-05-24 05:06:51 +00:00
|
|
|
#include <zeus/CColor.hpp>
|
2019-09-28 02:53:03 +00:00
|
|
|
#include <zeus/CVector3f.hpp>
|
2016-03-07 03:12:32 +00:00
|
|
|
|
2021-04-10 08:42:06 +00:00
|
|
|
namespace metaforce {
|
2016-03-07 03:12:32 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
class CMoviePlayer : public CDvdFile {
|
2016-03-07 03:12:32 +00:00
|
|
|
public:
|
2018-12-08 05:30:43 +00:00
|
|
|
enum class EPlayMode { Stopped, Playing };
|
2016-03-07 03:12:32 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
private:
|
|
|
|
struct THPHeader {
|
|
|
|
u32 magic;
|
|
|
|
u32 version;
|
|
|
|
u32 maxBufferSize;
|
|
|
|
u32 maxAudioSamples;
|
|
|
|
float fps;
|
|
|
|
u32 numFrames;
|
|
|
|
u32 firstFrameSize;
|
|
|
|
u32 dataSize;
|
|
|
|
u32 componentDataOffset;
|
|
|
|
u32 offsetsDataOffset;
|
|
|
|
u32 firstFrameOffset;
|
|
|
|
u32 lastFrameOffset;
|
|
|
|
void swapBig();
|
2021-05-24 05:06:51 +00:00
|
|
|
} x28_thpHead{};
|
2018-12-08 05:30:43 +00:00
|
|
|
|
|
|
|
struct THPComponents {
|
|
|
|
u32 numComponents;
|
|
|
|
enum class Type : u8 { Video = 0x0, Audio = 0x1, None = 0xff } comps[16];
|
|
|
|
void swapBig();
|
2021-05-24 05:06:51 +00:00
|
|
|
} x58_thpComponents{};
|
2018-12-08 05:30:43 +00:00
|
|
|
|
|
|
|
struct THPVideoInfo {
|
|
|
|
u32 width;
|
|
|
|
u32 height;
|
|
|
|
void swapBig();
|
2021-05-24 05:06:51 +00:00
|
|
|
} x6c_videoInfo{};
|
2018-12-08 05:30:43 +00:00
|
|
|
|
|
|
|
struct THPAudioInfo {
|
|
|
|
u32 numChannels;
|
|
|
|
u32 sampleRate;
|
|
|
|
u32 numSamples;
|
|
|
|
void swapBig();
|
2021-05-24 05:06:51 +00:00
|
|
|
} x74_audioInfo{};
|
2018-12-08 05:30:43 +00:00
|
|
|
|
|
|
|
struct THPFrameHeader {
|
|
|
|
u32 nextSize;
|
|
|
|
u32 prevSize;
|
|
|
|
u32 imageSize;
|
|
|
|
u32 audioSize;
|
|
|
|
void swapBig();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct THPAudioFrameHeader {
|
|
|
|
u32 channelSize;
|
|
|
|
u32 numSamples;
|
|
|
|
s16 channelCoefs[2][8][2];
|
|
|
|
s16 channelPrevs[2][2];
|
|
|
|
void swapBig();
|
|
|
|
};
|
|
|
|
|
|
|
|
struct CTHPTextureSet {
|
2022-07-29 20:16:55 +00:00
|
|
|
std::array<GXTexObj, 2> Y;
|
|
|
|
GXTexObj U;
|
|
|
|
GXTexObj V;
|
2018-12-08 05:30:43 +00:00
|
|
|
u32 playedSamples = 0;
|
|
|
|
u32 audioSamples = 0;
|
|
|
|
std::unique_ptr<s16[]> audioBuf;
|
|
|
|
};
|
|
|
|
std::vector<CTHPTextureSet> x80_textures;
|
|
|
|
std::unique_ptr<uint8_t[]> x90_requestBuf;
|
|
|
|
std::shared_ptr<IDvdRequest> x98_request;
|
|
|
|
std::vector<std::unique_ptr<uint8_t[]>> xa0_bufferQueue;
|
|
|
|
|
|
|
|
u32 xb0_nextReadSize = 0;
|
|
|
|
u32 xb4_nextReadOff = 0;
|
|
|
|
u32 xb8_readSizeWrapped = 0;
|
|
|
|
u32 xbc_readOffWrapped = 0;
|
|
|
|
u32 xc0_curLoadFrame = 0;
|
|
|
|
u32 xc4_requestFrameWrapped = 0;
|
|
|
|
u32 xc8_curFrame = 0;
|
|
|
|
u32 xcc_decodedTexSlot = 0;
|
|
|
|
u32 xd0_drawTexSlot = -1;
|
|
|
|
u32 xd4_audioSlot = -1;
|
|
|
|
s32 xd8_decodedTexCount = 0;
|
|
|
|
float xdc_frameRem = 0.f;
|
|
|
|
EPlayMode xe0_playMode = EPlayMode::Playing;
|
|
|
|
float xe4_totalSeconds = 0.f;
|
|
|
|
float xe8_curSeconds = 0.f;
|
|
|
|
float xec_preLoadSeconds;
|
|
|
|
u32 xf0_preLoadFrames = 0;
|
2020-04-10 19:03:31 +00:00
|
|
|
bool xf4_24_loop : 1;
|
2020-04-21 07:22:41 +00:00
|
|
|
bool xf4_25_hasAudio : 1 = false;
|
|
|
|
bool xf4_26_fieldFlip : 1 = false;
|
2020-04-10 19:03:31 +00:00
|
|
|
bool m_deinterlace : 1;
|
2018-12-08 05:30:43 +00:00
|
|
|
u32 xf8_ = 0;
|
|
|
|
u32 xfc_fieldIndex = 0;
|
|
|
|
|
|
|
|
std::unique_ptr<uint8_t[]> m_yuvBuf;
|
2022-02-08 06:54:05 +00:00
|
|
|
float m_hpad;
|
|
|
|
float m_vpad;
|
2016-03-07 03:12:32 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void DecodeFromRead(const void* data);
|
|
|
|
void PostDVDReadRequestIfNeeded();
|
2022-03-04 07:47:21 +00:00
|
|
|
void ReadCompleted();
|
|
|
|
|
|
|
|
static u32 THPAudioDecode(s16* buffer, const u8* audioFrame, bool stereo);
|
2016-03-07 03:12:32 +00:00
|
|
|
|
2016-03-10 03:47:37 +00:00
|
|
|
public:
|
2018-12-08 05:30:43 +00:00
|
|
|
CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bool deinterlace);
|
|
|
|
|
|
|
|
static void DisableStaticAudio() { SetStaticAudio(nullptr, 0, 0, 0); }
|
|
|
|
static void SetStaticAudioVolume(int vol);
|
|
|
|
static void SetStaticAudio(const void* data, u32 size, u32 loopBegin, u32 loopEnd);
|
|
|
|
static void SetSfxVolume(u8 volume);
|
|
|
|
static void MixStaticAudio(s16* out, const s16* in, u32 samples);
|
|
|
|
void MixAudio(s16* out, const s16* in, u32 samples);
|
|
|
|
void Rewind();
|
|
|
|
|
|
|
|
bool GetIsMovieFinishedPlaying() const {
|
|
|
|
if (xf4_24_loop)
|
|
|
|
return false;
|
|
|
|
return xc8_curFrame == x28_thpHead.numFrames;
|
|
|
|
}
|
|
|
|
bool IsLooping() const { return xf4_24_loop; }
|
|
|
|
bool GetIsFullyCached() const { return xa0_bufferQueue.size() >= xf0_preLoadFrames; }
|
|
|
|
float GetPlayedSeconds() const { return xdc_frameRem + xe8_curSeconds; }
|
|
|
|
float GetTotalSeconds() const { return xe4_totalSeconds; }
|
|
|
|
void SetPlayMode(EPlayMode mode) { xe0_playMode = mode; }
|
2022-05-24 00:26:35 +00:00
|
|
|
bool DrawVideo();
|
|
|
|
void DrawFrame(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3,
|
|
|
|
const zeus::CVector3f& v4);
|
2018-12-08 05:30:43 +00:00
|
|
|
void Update(float dt);
|
2022-05-24 00:26:35 +00:00
|
|
|
u32 GetWidth() const { return x6c_videoInfo.width; }
|
|
|
|
u32 GetHeight() const { return x6c_videoInfo.width; }
|
2018-12-08 05:30:43 +00:00
|
|
|
|
2022-02-01 00:06:54 +00:00
|
|
|
static void Initialize();
|
2018-12-08 05:30:43 +00:00
|
|
|
static void Shutdown();
|
2016-03-07 03:12:32 +00:00
|
|
|
};
|
|
|
|
|
2021-04-10 08:42:06 +00:00
|
|
|
} // namespace metaforce
|