Working CMoviePlayer (video only for now)

This commit is contained in:
Jack Andersen 2016-03-07 12:48:54 -10:00
parent b2ccf420f8
commit bba30a25bf
10 changed files with 158 additions and 66 deletions

View File

@ -19,6 +19,7 @@ ProjectResourceFactory::ProjectResourceFactory()
void ProjectResourceFactory::BuildObjectMap(const hecl::Database::Project::ProjectDataSpec &spec) void ProjectResourceFactory::BuildObjectMap(const hecl::Database::Project::ProjectDataSpec &spec)
{ {
#if 0
m_tagToPath.clear(); m_tagToPath.clear();
m_catalogNameToTag.clear(); m_catalogNameToTag.clear();
hecl::SystemString catalogPath = hecl::ProjectPath(spec.cookedPath, hecl::SystemString(spec.spec.m_name) + _S("/catalog.yaml")).getAbsolutePath(); hecl::SystemString catalogPath = hecl::ProjectPath(spec.cookedPath, hecl::SystemString(spec.spec.m_name) + _S("/catalog.yaml")).getAbsolutePath();
@ -45,6 +46,7 @@ void ProjectResourceFactory::BuildObjectMap(const hecl::Database::Project::Proje
{ {
RecursiveAddDirObjects(spec.cookedPath); RecursiveAddDirObjects(spec.cookedPath);
} }
#endif
} }
std::unique_ptr<urde::IObj> ProjectResourceFactory::Build(const urde::SObjectTag& tag, std::unique_ptr<urde::IObj> ProjectResourceFactory::Build(const urde::SObjectTag& tag,

View File

@ -30,8 +30,7 @@ void ViewManager::BuildTestPART(urde::IObjectStore& objStore)
m_lineRenderer.reset(new urde::CLineRenderer(urde::CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true)); m_lineRenderer.reset(new urde::CLineRenderer(urde::CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true));
*/ */
m_particleView.reset(new ParticleView(*this, m_viewResources, *m_rootView)); m_particleView.reset(new ParticleView(*this, m_viewResources, *m_rootView));
hecl::ProjectPath thpPath(m_projManager.project()->getProjectWorkingPath(), _S("out/MP1/Video/creditBG.thp")); m_moviePlayer.reset(new CMoviePlayer("Video/00_first_start.thp", -1.f, true, false));
m_moviePlayer.reset(new CMoviePlayer(thpPath.getAbsolutePathUTF8().c_str(), 0.f, true, true));
//m_rootView->accessContentViews().clear(); //m_rootView->accessContentViews().clear();
m_rootView->accessContentViews().push_back(m_particleView.get()); m_rootView->accessContentViews().push_back(m_particleView.get());
@ -70,6 +69,11 @@ void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ)
m_vm.m_lineRenderer->Render(); m_vm.m_lineRenderer->Render();
*/ */
} }
if (m_vm.m_moviePlayer)
{
m_vm.m_moviePlayer->Update(1.f / 60.f);
m_vm.m_moviePlayer->DrawFrame();
}
} }
specter::View* ViewManager::BuildSpaceViews() specter::View* ViewManager::BuildSpaceViews()
@ -280,6 +284,7 @@ bool ViewManager::proc()
m_rootSpaceView->setMultiplyColor(zeus::CColor::lerp({1,1,1,0}, {1,1,1,1}, m_editorFrames / 30.0)); m_rootSpaceView->setMultiplyColor(zeus::CColor::lerp({1,1,1,0}, {1,1,1,1}, m_editorFrames / 30.0));
m_rootView->draw(gfxQ); m_rootView->draw(gfxQ);
CGraphics::EndScene();
gfxQ->execute(); gfxQ->execute();
m_mainWindow->waitForRetrace(); m_mainWindow->waitForRetrace();
@ -291,6 +296,7 @@ void ViewManager::stop()
CElementGen::Shutdown(); CElementGen::Shutdown();
CMoviePlayer::Shutdown(); CMoviePlayer::Shutdown();
CLineRenderer::Shutdown(); CLineRenderer::Shutdown();
CDvdFile::Shutdown();
m_iconsToken.doDestroy(); m_iconsToken.doDestroy();
m_viewResources.destroyResData(); m_viewResources.destroyResData();
m_fontCache.destroyAtlases(); m_fontCache.destroyAtlases();

View File

@ -7,6 +7,16 @@
#include "ViewManager.hpp" #include "ViewManager.hpp"
#include "Runtime/Particle/CElementGen.hpp" #include "Runtime/Particle/CElementGen.hpp"
static logvisor::Module AthenaLog("Athena");
static void AthenaExc(athena::error::Level level, const char* file,
const char*, int line, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
AthenaLog.reportSource(logvisor::Level(level), file, line, fmt, ap);
va_end(ap);
}
namespace urde namespace urde
{ {
static logvisor::Module Log{"URDE"}; static logvisor::Module Log{"URDE"};
@ -101,6 +111,7 @@ int main(int argc, const boo::SystemChar** argv)
#endif #endif
{ {
logvisor::RegisterConsoleLogger(); logvisor::RegisterConsoleLogger();
atSetExceptionHandler(AthenaExc);
urde::Application appCb; urde::Application appCb;
int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto, int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto,
appCb, _S("urde"), _S("URDE"), argc, argv, false); appCb, _S("urde"), _S("URDE"), argc, argv, false);

View File

@ -25,7 +25,7 @@ public:
{ {
while (!m_complete && !m_cancel) while (!m_complete && !m_cancel)
{ {
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex); std::unique_lock<std::mutex> lk(CDvdFile::m_WaitMutex);
} }
} }
bool IsComplete() {return m_complete;} bool IsComplete() {return m_complete;}
@ -61,6 +61,7 @@ public:
std::thread CDvdFile::m_WorkerThread; std::thread CDvdFile::m_WorkerThread;
std::mutex CDvdFile::m_WorkerMutex; std::mutex CDvdFile::m_WorkerMutex;
std::condition_variable CDvdFile::m_WorkerCV; std::condition_variable CDvdFile::m_WorkerCV;
std::mutex CDvdFile::m_WaitMutex;
bool CDvdFile::m_WorkerRun = false; bool CDvdFile::m_WorkerRun = false;
std::vector<std::shared_ptr<IDvdRequest>> CDvdFile::m_RequestQueue; std::vector<std::shared_ptr<IDvdRequest>> CDvdFile::m_RequestQueue;
void CDvdFile::WorkerProc() void CDvdFile::WorkerProc()
@ -68,26 +69,30 @@ void CDvdFile::WorkerProc()
while (m_WorkerRun) while (m_WorkerRun)
{ {
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex); std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex);
if (CDvdFile::m_RequestQueue.size()) while (CDvdFile::m_RequestQueue.size())
{ {
std::vector<std::shared_ptr<IDvdRequest>> swapQueue; std::vector<std::shared_ptr<IDvdRequest>> swapQueue;
swapQueue.swap(CDvdFile::m_RequestQueue); swapQueue.swap(CDvdFile::m_RequestQueue);
lk.unlock(); lk.unlock();
std::unique_lock<std::mutex> waitlk(CDvdFile::m_WaitMutex);
for (std::shared_ptr<IDvdRequest>& req : swapQueue) for (std::shared_ptr<IDvdRequest>& req : swapQueue)
{ {
CFileDvdRequest& concreteReq = static_cast<CFileDvdRequest&>(*req); CFileDvdRequest& concreteReq = static_cast<CFileDvdRequest&>(*req);
concreteReq.DoRequest(); concreteReq.DoRequest();
} }
waitlk.unlock();
lk.lock(); lk.lock();
} }
if (!m_WorkerRun)
break;
m_WorkerCV.wait(lk); m_WorkerCV.wait(lk);
} }
} }
std::shared_ptr<IDvdRequest> CDvdFile::AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off) std::shared_ptr<IDvdRequest> CDvdFile::AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off)
{ {
CFileDvdRequest* req = new CFileDvdRequest(*this, buf, len, whence, off); std::shared_ptr<IDvdRequest> ret =
std::shared_ptr<IDvdRequest> ret(req); std::make_shared<CFileDvdRequest>(*this, buf, len, whence, off);
std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex); std::unique_lock<std::mutex> lk(CDvdFile::m_WorkerMutex);
m_RequestQueue.emplace_back(ret); m_RequestQueue.emplace_back(ret);
lk.unlock(); lk.unlock();

View File

@ -33,6 +33,7 @@ class CDvdFile
static std::thread m_WorkerThread; static std::thread m_WorkerThread;
static std::mutex m_WorkerMutex; static std::mutex m_WorkerMutex;
static std::condition_variable m_WorkerCV; static std::condition_variable m_WorkerCV;
static std::mutex m_WaitMutex;
static bool m_WorkerRun; static bool m_WorkerRun;
static std::vector<std::shared_ptr<IDvdRequest>> m_RequestQueue; static std::vector<std::shared_ptr<IDvdRequest>> m_RequestQueue;
static void WorkerProc(); static void WorkerProc();

View File

@ -71,7 +71,15 @@ void CGraphics::EndScene()
/* ++g_NumBreakpointsWaiting; */ /* ++g_NumBreakpointsWaiting; */
/* GXCopyDisp to g_CurrenFrameBuf with clear enabled */ /* GXCopyDisp to g_CurrenFrameBuf with clear enabled */
/* Register next breakpoint with GP FIFO */ /* Register next breakpoint with GP FIFO */
/* g_LastFrameUsedAbove = g_InterruptLastFrameUsedAbove; */
/* Yup, GX had fences long before D3D12 and Vulkan
* (same functionality implemented in boo's execute method) */
/* This usually comes from VI register during interrupt;
* we don't care in the era of progressive-scan dominance,
* so simulate field-flipping with XOR instead */
g_InterruptLastFrameUsedAbove ^= 1;
g_LastFrameUsedAbove = g_InterruptLastFrameUsedAbove;
} }
void CGraphics::SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1) void CGraphics::SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1)

View File

@ -7,8 +7,6 @@
#include "CDvdRequest.hpp" #include "CDvdRequest.hpp"
#include <turbojpeg.h> #include <turbojpeg.h>
#define THP_BUFFER_FRAMES 30
namespace urde namespace urde
{ {
@ -124,7 +122,7 @@ SPECTER_METAL_VIEW_VERT_BLOCK
static const char* FS_METAL_YUV = static const char* FS_METAL_YUV =
"#include <metal_stdlib>\n" "#include <metal_stdlib>\n"
"using namespace metal;\n" "using namespace metal;\n"
"constexpr sampler samp(address::repeat);\n" "constexpr sampler samp(address::repeat, filter::linear);\n"
"struct VertToFrag\n" "struct VertToFrag\n"
"{\n" "{\n"
" float4 position [[ position ]];\n" " float4 position [[ position ]];\n"
@ -269,7 +267,7 @@ void CMoviePlayer::THPAudioFrameHeader::swapBig()
} }
} }
/* Slightly modified THPAudioDecode present in SDK, always interleaves */ /* Slightly modified from THPAudioDecode present in SDK; always interleaves */
u32 CMoviePlayer::THPAudioDecode(s16* buffer, const u8* audioFrame, bool stereo) u32 CMoviePlayer::THPAudioDecode(s16* buffer, const u8* audioFrame, bool stereo)
{ {
THPAudioFrameHeader header = *((const THPAudioFrameHeader*)audioFrame); THPAudioFrameHeader header = *((const THPAudioFrameHeader*)audioFrame);
@ -350,6 +348,11 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo
} }
} }
xb4_nextReadOff = x28_thpHead.firstFrameOffset;
xb0_nextReadSize = x28_thpHead.firstFrameSize;
xb8_readSizeWrapped = x28_thpHead.firstFrameSize;
xbc_readOffWrapped = x28_thpHead.firstFrameOffset;
xe4_totalSeconds = x28_thpHead.numFrames / x28_thpHead.fps; xe4_totalSeconds = x28_thpHead.numFrames / x28_thpHead.fps;
if (xec_preLoadSeconds < 0.f) if (xec_preLoadSeconds < 0.f)
{ {
@ -368,15 +371,18 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo
if (xf0_preLoadFrames > 0) if (xf0_preLoadFrames > 0)
xa0_bufferQueue.reserve(xf0_preLoadFrames); xa0_bufferQueue.reserve(xf0_preLoadFrames);
m_blockBuf = CGraphics::g_BooFactory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(m_viewVertBlock), 1); m_blockBuf = CGraphics::g_BooFactory->newDynamicBuffer(boo::BufferUse::Uniform,
sizeof(m_viewVertBlock), 1);
m_vertBuf = CGraphics::g_BooFactory->newDynamicBuffer(boo::BufferUse::Vertex,
sizeof(specter::View::TexShaderVert), 4);
boo::IVertexFormat* vtxFmt = YUVVTXFmt; boo::IVertexFormat* vtxFmt = YUVVTXFmt;
if (CGraphics::g_BooFactory->bindingNeedsVertexFormat()) if (CGraphics::g_BooFactory->bindingNeedsVertexFormat())
{ {
boo::VertexElementDescriptor texvdescs[] = boo::VertexElementDescriptor texvdescs[] =
{ {
{m_blockBuf, nullptr, boo::VertexSemantic::Position4}, {m_vertBuf, nullptr, boo::VertexSemantic::Position4},
{m_blockBuf, nullptr, boo::VertexSemantic::UV4} {m_vertBuf, nullptr, boo::VertexSemantic::UV4}
}; };
vtxFmt = CGraphics::g_BooFactory->newVertexFormat(2, texvdescs); vtxFmt = CGraphics::g_BooFactory->newVertexFormat(2, texvdescs);
} }
@ -405,7 +411,7 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo
for (int j=0 ; j<2 ; ++j) for (int j=0 ; j<2 ; ++j)
{ {
boo::ITexture* texs[] = {set.Y[j], set.U, set.V}; boo::ITexture* texs[] = {set.Y[j], set.U, set.V};
set.binding[j] = CGraphics::g_BooFactory->newShaderDataBinding(YUVShaderPipeline, vtxFmt, m_blockBuf, set.binding[j] = CGraphics::g_BooFactory->newShaderDataBinding(YUVShaderPipeline, vtxFmt, m_vertBuf,
nullptr, nullptr, 1, bufs, 3, texs); nullptr, nullptr, 1, bufs, 3, texs);
} }
} }
@ -423,7 +429,7 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo
boo::IGraphicsBuffer* bufs[] = {m_blockBuf}; boo::IGraphicsBuffer* bufs[] = {m_blockBuf};
boo::ITexture* texs[] = {set.Y[0], set.U, set.V}; boo::ITexture* texs[] = {set.Y[0], set.U, set.V};
set.binding[0] = CGraphics::g_BooFactory->newShaderDataBinding(YUVShaderPipeline, vtxFmt, m_blockBuf, set.binding[0] = CGraphics::g_BooFactory->newShaderDataBinding(YUVShaderPipeline, vtxFmt, m_vertBuf,
nullptr, nullptr, 1, bufs, 3, texs); nullptr, nullptr, 1, bufs, 3, texs);
} }
if (xf4_25_hasAudio) if (xf4_25_hasAudio)
@ -434,6 +440,14 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo
m_token = CGraphics::CommitResources(); m_token = CGraphics::CommitResources();
PostDVDReadRequestIfNeeded(); PostDVDReadRequestIfNeeded();
m_frame[0].m_uv = {0.f, 0.f};
m_frame[1].m_uv = {0.f, 1.f};
m_frame[2].m_uv = {1.f, 0.f};
m_frame[3].m_uv = {1.f, 1.f};
SetFrame({-0.5f, 0.5f, 0.f}, {-0.5f, -0.5f, 0.f}, {0.5f, -0.5f, 0.f}, {0.5f, 0.5f, 0.f});
m_blockBuf->load(&m_viewVertBlock, sizeof(m_viewVertBlock));
} }
void CMoviePlayer::VerifyCallbackStatus() void CMoviePlayer::VerifyCallbackStatus()
@ -467,34 +481,51 @@ void CMoviePlayer::Rewind()
xb0_nextReadSize = x28_thpHead.firstFrameSize; xb0_nextReadSize = x28_thpHead.firstFrameSize;
xb4_nextReadOff = x28_thpHead.firstFrameOffset; xb4_nextReadOff = x28_thpHead.firstFrameOffset;
xb8_readSize = x28_thpHead.firstFrameSize; xb8_readSizeWrapped = x28_thpHead.firstFrameSize;
xbc_readOff = x28_thpHead.firstFrameOffset; xbc_readOffWrapped = x28_thpHead.firstFrameOffset;
xc0_loadedFrames = 0; xc0_curLoadFrame = 0;
xc4_ = 0; xc4_requestFrameWrapped = 0;
xc8_curFrame = 0; xc8_curFrame = 0;
xcc_decodedTexSlot = 0; xcc_decodedTexSlot = 0;
xd0_ = -1; xd0_drawTexSlot = -1;
xd4_ = -1; xd4_ = -1;
xd8_ = 0; xd8_decodedTexCount = 0;
xdc_frameRem = 0.f; xdc_frameRem = 0.f;
xe8_curSeconds = 0.f; xe8_curSeconds = 0.f;
} }
void CMoviePlayer::DrawFrame(const CVector3f& a, const CVector3f& b, void CMoviePlayer::SetFrame(const zeus::CVector3f& a, const zeus::CVector3f& b,
const CVector3f& c, const CVector3f& d) const zeus::CVector3f& c, const zeus::CVector3f& d)
{ {
m_frame[0].m_pos = a;
m_frame[1].m_pos = b;
m_frame[2].m_pos = d;
m_frame[3].m_pos = c;
m_vertBuf->load(m_frame, sizeof(m_frame));
}
void CMoviePlayer::DrawFrame()
{
if (xd0_drawTexSlot == -1)
return;
CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot];
CGraphics::g_BooMainCommandQueue->setShaderDataBinding(tex.binding[m_deinterlace ? xf4_26_fieldFlip : 0]);
CGraphics::g_BooMainCommandQueue->draw(0, 4);
if (!xfc_fieldIndex && CGraphics::g_LastFrameUsedAbove)
xf4_26_fieldFlip = true;
++xfc_fieldIndex;
} }
void CMoviePlayer::Update(float dt) void CMoviePlayer::Update(float dt)
{ {
if (xc0_loadedFrames < xf0_preLoadFrames) if (xc0_curLoadFrame < xf0_preLoadFrames)
{ {
if (x98_request && x98_request->IsComplete()) if (x98_request && x98_request->IsComplete())
{ {
ReadCompleted(); ReadCompleted();
if (xc0_loadedFrames >= xa0_bufferQueue.size() && if (xc0_curLoadFrame >= xa0_bufferQueue.size() &&
xc0_loadedFrames < xf0_preLoadFrames && xc0_curLoadFrame < xf0_preLoadFrames &&
xa0_bufferQueue.size() < x28_thpHead.numFrames) xa0_bufferQueue.size() < x28_thpHead.numFrames)
{ {
PostDVDReadRequestIfNeeded(); PostDVDReadRequestIfNeeded();
@ -506,17 +537,18 @@ void CMoviePlayer::Update(float dt)
if (x98_request) if (x98_request)
{ {
bool flag = false; bool flag = false;
if (xc4_ >= xa0_bufferQueue.size() && xc0_loadedFrames >= xa0_bufferQueue.size()) if (xc4_requestFrameWrapped >= xa0_bufferQueue.size() &&
xc0_curLoadFrame >= xa0_bufferQueue.size())
flag = true; flag = true;
if (x98_request->IsComplete() && xd8_ < 2 && flag) if (x98_request->IsComplete() && xd8_decodedTexCount < 2 && flag)
{ {
DecodeFromRead(x90_requestBuf.get()); DecodeFromRead(x90_requestBuf.get());
ReadCompleted(); ReadCompleted();
PostDVDReadRequestIfNeeded(); PostDVDReadRequestIfNeeded();
++xd8_; ++xd8_decodedTexCount;
++xc4_; ++xc4_requestFrameWrapped;
if (xc4_ >= x28_thpHead.numFrames && xf4_24_loop) if (xc4_requestFrameWrapped >= x28_thpHead.numFrames && xf4_24_loop)
xc4_ = 0; xc4_requestFrameWrapped = 0;
} }
} }
} }
@ -527,23 +559,23 @@ void CMoviePlayer::Update(float dt)
PostDVDReadRequestIfNeeded(); PostDVDReadRequestIfNeeded();
} }
if (xd8_ < 2) if (xd8_decodedTexCount < 2)
{ {
if (xe0_playMode == EPlayMode::Playing && xc4_ < xf0_preLoadFrames) if (xe0_playMode == EPlayMode::Playing && xc4_requestFrameWrapped < xf0_preLoadFrames)
{ {
u32 minFrame = std::min(u32(xa0_bufferQueue.size()) - 1, xc4_); u32 minFrame = std::min(u32(xa0_bufferQueue.size()) - 1, xc4_requestFrameWrapped);
if (minFrame == -1) if (minFrame == -1)
return; return;
std::unique_ptr<uint8_t[]>& frameData = xa0_bufferQueue[minFrame]; std::unique_ptr<uint8_t[]>& frameData = xa0_bufferQueue[minFrame];
DecodeFromRead(frameData.get()); DecodeFromRead(frameData.get());
++xd8_; ++xd8_decodedTexCount;
++xc4_; ++xc4_requestFrameWrapped;
if (xc4_ >= x28_thpHead.numFrames && xf4_24_loop) if (xc4_requestFrameWrapped >= x28_thpHead.numFrames && xf4_24_loop)
xc4_ = 0; xc4_requestFrameWrapped = 0;
} }
} }
if (xd8_ <= 0 || xe0_playMode != EPlayMode::Playing) if (xd8_decodedTexCount <= 0 || xe0_playMode != EPlayMode::Playing)
return; return;
xe8_curSeconds += dt; xe8_curSeconds += dt;
@ -558,17 +590,17 @@ void CMoviePlayer::Update(float dt)
{ {
if (!xf4_26_fieldFlip) if (!xf4_26_fieldFlip)
{ {
++xd0_; ++xd0_drawTexSlot;
if (xd0_ >= x80_textures.size()) if (xd0_drawTexSlot >= x80_textures.size())
xd0_ = 0; xd0_drawTexSlot = 0;
if (xd4_ == -1) if (xd4_ == -1)
xd4_ = 0; xd4_ = 0;
--xd8_; --xd8_decodedTexCount;
++xc8_curFrame; ++xc8_curFrame;
if (xc8_curFrame == x28_thpHead.numFrames && xf4_24_loop) if (xc8_curFrame == x28_thpHead.numFrames && xf4_24_loop)
xc8_curFrame = 0; xc8_curFrame = 0;
rem += frameDt; rem += frameDt;
xfc_ = 0; xfc_fieldIndex = 0;
} }
else else
{ {
@ -650,11 +682,40 @@ void CMoviePlayer::DecodeFromRead(const void* data)
void CMoviePlayer::ReadCompleted() void CMoviePlayer::ReadCompleted()
{ {
const THPFrameHeader* frameHeader =
reinterpret_cast<const THPFrameHeader*>(x90_requestBuf.get());
if (xc0_curLoadFrame == xa0_bufferQueue.size() && xf0_preLoadFrames > xc0_curLoadFrame)
xa0_bufferQueue.push_back(std::move(x90_requestBuf));
xb4_nextReadOff += xb0_nextReadSize;
xb0_nextReadSize = hecl::SBig(frameHeader->nextSize);
++xc0_curLoadFrame;
if (xc0_curLoadFrame == xf0_preLoadFrames)
{
if (x28_thpHead.numFrames == xc0_curLoadFrame)
{
xb8_readSizeWrapped = x28_thpHead.firstFrameSize;
xbc_readOffWrapped = x28_thpHead.firstFrameOffset;
}
else
{
xb8_readSizeWrapped = xb0_nextReadSize;
xbc_readOffWrapped = xb4_nextReadOff;
}
}
if (xc0_curLoadFrame >= x28_thpHead.numFrames && xf4_24_loop)
{
xb4_nextReadOff = xbc_readOffWrapped;
xb0_nextReadSize = xb8_readSizeWrapped;
xc0_curLoadFrame = xf0_preLoadFrames;
}
} }
void CMoviePlayer::PostDVDReadRequestIfNeeded() void CMoviePlayer::PostDVDReadRequestIfNeeded()
{ {
if (xc0_loadedFrames < x28_thpHead.numFrames) if (xc0_curLoadFrame < x28_thpHead.numFrames)
{ {
x90_requestBuf.reset(new uint8_t[xb0_nextReadSize]); x90_requestBuf.reset(new uint8_t[xb0_nextReadSize]);
x98_request = AsyncSeekRead(x90_requestBuf.get(), xb0_nextReadSize, x98_request = AsyncSeekRead(x90_requestBuf.get(), xb0_nextReadSize,

View File

@ -5,10 +5,10 @@
#include "CDvdFile.hpp" #include "CDvdFile.hpp"
#include "boo/graphicsdev/IGraphicsDataFactory.hpp" #include "boo/graphicsdev/IGraphicsDataFactory.hpp"
#include "specter/View.hpp" #include "specter/View.hpp"
#include "zeus/CVector3f.hpp"
namespace urde namespace urde
{ {
class CVector3f;
class CMoviePlayer : public CDvdFile class CMoviePlayer : public CDvdFile
{ {
@ -96,15 +96,15 @@ private:
u32 xb0_nextReadSize = 0; u32 xb0_nextReadSize = 0;
u32 xb4_nextReadOff = 0; u32 xb4_nextReadOff = 0;
u32 xb8_readSize = 0; u32 xb8_readSizeWrapped = 0;
u32 xbc_readOff = 0; u32 xbc_readOffWrapped = 0;
u32 xc0_loadedFrames = 0; u32 xc0_curLoadFrame = 0;
u32 xc4_ = 0; u32 xc4_requestFrameWrapped = 0;
u32 xc8_curFrame = 0; u32 xc8_curFrame = 0;
u32 xcc_decodedTexSlot = 0; u32 xcc_decodedTexSlot = 0;
u32 xd0_ = 0; u32 xd0_drawTexSlot = -1;
u32 xd4_ = 0; u32 xd4_ = -1;
s32 xd8_ = 0; s32 xd8_decodedTexCount = 0;
float xdc_frameRem = 0.f; float xdc_frameRem = 0.f;
EPlayMode xe0_playMode = EPlayMode::Playing; EPlayMode xe0_playMode = EPlayMode::Playing;
float xe4_totalSeconds = 0.f; float xe4_totalSeconds = 0.f;
@ -112,7 +112,7 @@ private:
float xec_preLoadSeconds; float xec_preLoadSeconds;
u32 xf0_preLoadFrames = 0; u32 xf0_preLoadFrames = 0;
u32 xf8_ = 0; u32 xf8_ = 0;
u32 xfc_ = 0; u32 xfc_fieldIndex = 0;
boo::GraphicsDataToken m_token; boo::GraphicsDataToken m_token;
std::unique_ptr<uint8_t[]> m_yuvBuf; std::unique_ptr<uint8_t[]> m_yuvBuf;
@ -127,15 +127,11 @@ private:
u8 m_dummy = 0; u8 m_dummy = 0;
}; };
struct ViewBlock specter::View::ViewBlock m_viewVertBlock;
{
zeus::CMatrix4f m_mv;
zeus::CColor m_color = zeus::CColor::skWhite;
} m_viewVertBlock;
boo::IGraphicsBufferD* m_blockBuf; boo::IGraphicsBufferD* m_blockBuf;
boo::IGraphicsBufferD* m_vertBuf;
uint64_t m_loadedFrameCount = 0; specter::View::TexShaderVert m_frame[4];
uint64_t m_playedFrameCount = 0;
public: public:
@ -161,7 +157,9 @@ public:
float GetPlayedSeconds() const {return xdc_frameRem + xe8_curSeconds;} float GetPlayedSeconds() const {return xdc_frameRem + xe8_curSeconds;}
float GetTotalSeconds() const {return xe4_totalSeconds;} float GetTotalSeconds() const {return xe4_totalSeconds;}
void SetPlayMode(EPlayMode mode) {xe0_playMode = mode;} void SetPlayMode(EPlayMode mode) {xe0_playMode = mode;}
void DrawFrame(const CVector3f& a, const CVector3f& b, const CVector3f& c, const CVector3f& d); void SetFrame(const zeus::CVector3f& a, const zeus::CVector3f& b,
const zeus::CVector3f& c, const zeus::CVector3f& d);
void DrawFrame();
void Update(float dt); void Update(float dt);
void DecodeFromRead(const void* data); void DecodeFromRead(const void* data);
void ReadCompleted(); void ReadCompleted();

2
hecl

@ -1 +1 @@
Subproject commit 3e3e34414087d9427bf98cef992dad279ebd988e Subproject commit f1f3bb641d52a584011bfe2113a797833421ba92

@ -1 +1 @@
Subproject commit 3b1128bbfa4602888e7d08d1b58ed64737f12640 Subproject commit ba1b4ecc5120455bd6c65a76f18fd6abf93e049c