From 3f004eca0486f649cc68b94218230b58dd25ef05 Mon Sep 17 00:00:00 2001 From: VDm Date: Sat, 26 Apr 2025 02:19:47 +0400 Subject: [PATCH] feat(ui): add CSimpleMovieFrame::UpdateTiming implementation --- src/ui/CSimpleMovieFrame.cpp | 70 ++++++++++++++++++++++++++++++++++-- src/ui/CSimpleMovieFrame.hpp | 13 ++++++- 2 files changed, 79 insertions(+), 4 deletions(-) diff --git a/src/ui/CSimpleMovieFrame.cpp b/src/ui/CSimpleMovieFrame.cpp index 1fb67da..6d078e0 100644 --- a/src/ui/CSimpleMovieFrame.cpp +++ b/src/ui/CSimpleMovieFrame.cpp @@ -1,6 +1,7 @@ #include "ui/CSimpleMovieFrame.hpp" #include "ui/CSimpleMovieFrameScript.hpp" #include "util/SFile.hpp" +#include int32_t CSimpleMovieFrame::s_metatable; int32_t CSimpleMovieFrame::s_objectType; @@ -27,8 +28,8 @@ void CSimpleMovieFrame::RegisterScriptMethods(lua_State* L) { void CSimpleMovieFrame::RenderMovie(void* param) { auto movieFrame = reinterpret_cast(param); if (movieFrame->m_isPlaying) { - // movieFrame->UpdateTiming(); - // movieFrame->Render(); + movieFrame->UpdateTiming(); + movieFrame->Render(); } } @@ -100,7 +101,7 @@ void CSimpleMovieFrame::StopMovie() { // UnloadDivxDecoder // CloseAudio // CloseCaptions - this->m_isStopped = 0; + this->m_isInterrupted = 0; this->m_isPlaying = 0; if (this->m_onMovieFinished.luaRef) { this->RunScript(this->m_onMovieFinished, 0, nullptr); @@ -275,6 +276,8 @@ int32_t CSimpleMovieFrame::ParseAVIFile(const char* filename) { offset += 16; } + this->m_currentFrameData = this->m_videoData; + SFile::Close(videoFile); return dataSize > 0; } @@ -282,3 +285,64 @@ int32_t CSimpleMovieFrame::ParseAVIFile(const char* filename) { int32_t CSimpleMovieFrame::OpenVideo() { return 0; } + +int32_t CSimpleMovieFrame::UpdateTiming() { + bool isAudioPlaying = false; /* SE2::IsPlaying(this->m_audioChannel) */ + + if (isAudioPlaying) { + //this->m_elapsedTime = SE2::GetPositionInMS(this->m_audioChannel); + //this->m_startTime = OsGetAsyncTimeMs() - this->m_elapsedTime; + } else { + this->m_elapsedTime = OsGetAsyncTimeMs() - this->m_startTime; + } + + uint32_t currentFrame = static_cast(this->m_elapsedTime * this->m_frameRate * 0.001 + 0.5); + + if (isAudioPlaying) { + // TODO + } + + currentFrame += this->m_frameAudioSync; + if (currentFrame <= this->m_prevFrame) { + currentFrame = this->m_prevFrame; + } + + this->m_currentFrame = currentFrame; + + if (currentFrame >= this->m_numFrames) { + this->m_isInterrupted = 1; + } + + if (this->m_isInterrupted) { + this->StopMovie(); + return 0; + } + + if (currentFrame == this->m_prevFrame) { + return 0; + } + + if (currentFrame != this->m_prevFrame + 1) { + ++this->m_lastKeyFrame; + } + + while (this->m_prevFrame < this->m_currentFrame - 1) { + this->DecodeFrame(false); + ++this->m_prevFrame; + } + + if (!this->DecodeFrame(true)) { + this->m_isInterrupted = 1; + } + + this->m_prevFrame = this->m_currentFrame; + + // TODO: Subtitle stuff +} + +int32_t CSimpleMovieFrame::DecodeFrame(bool unk) { + return 0; +} + +void CSimpleMovieFrame::Render() { +} diff --git a/src/ui/CSimpleMovieFrame.hpp b/src/ui/CSimpleMovieFrame.hpp index be7c2bb..900fc78 100644 --- a/src/ui/CSimpleMovieFrame.hpp +++ b/src/ui/CSimpleMovieFrame.hpp @@ -20,8 +20,9 @@ class CSimpleMovieFrame : public CSimpleFrame { static void RenderMovie(void* param); // Member variables + void* m_audioChannel = nullptr; int32_t m_isPlaying = 0; - int32_t m_isStopped = 0; + int32_t m_isInterrupted = 0; int32_t m_enableSubtitles = 0; char m_filename[256]; int32_t m_volume = 100; @@ -33,9 +34,16 @@ class CSimpleMovieFrame : public CSimpleFrame { uint32_t m_videoHeight = 0; uint32_t m_numFrames = 0; char* m_videoData = nullptr; + char* m_currentFrameData = nullptr; uint32_t m_videoBytes = 0; char* m_audioData = nullptr; uint32_t m_audioBytes = 0; + uint64_t m_startTime = 0; + uint32_t m_prevFrame = 0; + uint32_t m_currentFrame = 0; + uint32_t m_frameAudioSync = 0; + uint32_t m_lastKeyFrame = 0; + uint64_t m_elapsedTime = 0; // Virtual member functions virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data); @@ -49,6 +57,9 @@ class CSimpleMovieFrame : public CSimpleFrame { void StopMovie(); int32_t ParseAVIFile(const char* filename); int32_t OpenVideo(); + int32_t UpdateTiming(); + int32_t DecodeFrame(bool unk); + void Render(); }; #endif