metaforce/Runtime/Graphics/CMoviePlayer.hpp

148 lines
3.9 KiB
C++
Raw Normal View History

2018-10-06 20:42:33 -07:00
#pragma once
2016-03-06 19:12:32 -08:00
#include <memory>
#include <vector>
#include "Runtime/CDvdFile.hpp"
#include "Runtime/RetroTypes.hpp"
2022-01-31 16:06:54 -08:00
#include "Runtime/Graphics/CGraphics.hpp"
2021-05-23 22:06:51 -07:00
#include <zeus/CColor.hpp>
#include <zeus/CVector3f.hpp>
2016-03-06 19:12:32 -08:00
2021-04-10 01:42:06 -07:00
namespace metaforce {
2016-03-06 19:12:32 -08:00
2018-12-07 21:30:43 -08:00
class CMoviePlayer : public CDvdFile {
2016-03-06 19:12:32 -08:00
public:
2018-12-07 21:30:43 -08:00
enum class EPlayMode { Stopped, Playing };
2016-03-06 19:12:32 -08:00
2018-12-07 21:30:43 -08: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-23 22:06:51 -07:00
} x28_thpHead{};
2018-12-07 21:30:43 -08:00
struct THPComponents {
u32 numComponents;
enum class Type : u8 { Video = 0x0, Audio = 0x1, None = 0xff } comps[16];
void swapBig();
2021-05-23 22:06:51 -07:00
} x58_thpComponents{};
2018-12-07 21:30:43 -08:00
struct THPVideoInfo {
u32 width;
u32 height;
void swapBig();
2021-05-23 22:06:51 -07:00
} x6c_videoInfo{};
2018-12-07 21:30:43 -08:00
struct THPAudioInfo {
u32 numChannels;
u32 sampleRate;
u32 numSamples;
void swapBig();
2021-05-23 22:06:51 -07:00
} x74_audioInfo{};
2018-12-07 21:30:43 -08: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-02-15 21:21:24 -08:00
std::shared_ptr<aurora::gfx::TextureHandle> Y[2];
std::shared_ptr<aurora::gfx::TextureHandle> U;
std::shared_ptr<aurora::gfx::TextureHandle> V;
2018-12-07 21:30:43 -08: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;
bool xf4_24_loop : 1;
bool xf4_25_hasAudio : 1 = false;
bool xf4_26_fieldFlip : 1 = false;
bool m_deinterlace : 1;
2018-12-07 21:30:43 -08:00
u32 xf8_ = 0;
u32 xfc_fieldIndex = 0;
std::unique_ptr<uint8_t[]> m_yuvBuf;
2022-02-07 22:54:05 -08:00
float m_hpad;
float m_vpad;
2016-03-06 19:12:32 -08:00
2018-12-07 21:30:43 -08:00
static u32 THPAudioDecode(s16* buffer, const u8* audioFrame, bool stereo);
void DecodeFromRead(const void* data);
void ReadCompleted();
void PostDVDReadRequestIfNeeded();
2016-03-06 19:12:32 -08:00
2016-03-09 19:47:37 -08:00
public:
2018-12-07 21:30:43 -08: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-02-07 22:54:05 -08:00
void SetFrame(float hpad, float vpad);
2018-12-07 21:30:43 -08:00
void DrawFrame();
void Update(float dt);
std::pair<u32, u32> GetVideoDimensions() const { return {x6c_videoInfo.width, x6c_videoInfo.height}; }
2022-01-31 16:06:54 -08:00
static void Initialize();
2018-12-07 21:30:43 -08:00
static void Shutdown();
2016-03-06 19:12:32 -08:00
};
2021-04-10 01:42:06 -07:00
} // namespace metaforce