From c60a43d00f6540d6b3c047b0755a064cd94fcf10 Mon Sep 17 00:00:00 2001 From: Mauro Junior <45118493+jetrotal@users.noreply.github.com> Date: Fri, 18 Aug 2023 04:59:12 -0300 Subject: [PATCH 1/2] videoPlayer - initial commit windows only, needs external .exe app. --- src/filefinder.cpp | 12 ++++++--- src/filefinder.h | 2 ++ src/game_interpreter_map.cpp | 4 +-- src/game_screen.cpp | 48 ++++++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/filefinder.cpp b/src/filefinder.cpp index b7885e48a5..f432126398 100644 --- a/src/filefinder.cpp +++ b/src/filefinder.cpp @@ -53,9 +53,9 @@ #endif namespace { -#ifdef SUPPORT_MOVIES - auto MOVIE_TYPES = { ".avi", ".mpg" }; -#endif +//#ifdef SUPPORT_MOVIES + constexpr const auto MOVIE_TYPES = Utils::MakeSvArray( ".mov", ".mp4", ".webm", ".ogv"); //".avi", ".mpg" not supported by web standards +//#endif std::string fonts_path; std::shared_ptr root_fs; @@ -358,6 +358,12 @@ std::string FileFinder::FindMusic(StringView name) { } +std::string FileFinder::FindMovie(StringView name) { + DirectoryTree::Args args = { MakePath("Movie", name), MOVIE_TYPES, 1, true }; + return find_generic(args); + +} + std::string FileFinder::FindSound(StringView name) { DirectoryTree::Args args = { MakePath("Sound", name), SOUND_TYPES, 1, false }; return find_generic(args); diff --git a/src/filefinder.h b/src/filefinder.h index 8f6be1ed68..c663ee2852 100644 --- a/src/filefinder.h +++ b/src/filefinder.h @@ -89,6 +89,8 @@ namespace FileFinder { */ std::string FindMusic(StringView name); + std::string FindMovie(StringView name); + /** * Finds a sound file in the current RPG Maker game. * diff --git a/src/game_interpreter_map.cpp b/src/game_interpreter_map.cpp index 8d6a26537a..e01e16a02f 100644 --- a/src/game_interpreter_map.cpp +++ b/src/game_interpreter_map.cpp @@ -616,10 +616,10 @@ bool Game_Interpreter_Map::CommandPlayMovie(lcf::rpg::EventCommand const& com) { int res_x = com.parameters[3]; int res_y = com.parameters[4]; - Output::Warning("Couldn't play movie: {}. Movie playback is not implemented (yet).", filename); + //Output::Warning("Couldn't play movie: {}. Movie playback is not implemented (yet).", filename); Main_Data::game_screen->PlayMovie(filename, pos_x, pos_y, res_x, res_y); - + _state.wait_time = 5; return true; } diff --git a/src/game_screen.cpp b/src/game_screen.cpp index 7890357142..19606e7311 100644 --- a/src/game_screen.cpp +++ b/src/game_screen.cpp @@ -35,6 +35,9 @@ #include "flash.h" #include "shake.h" #include "rand.h" +#include // For system function +#include +#include "baseui.h" Game_Screen::Game_Screen() { @@ -170,12 +173,53 @@ void Game_Screen::SetWeatherEffect(int type, int strength) { } void Game_Screen::PlayMovie(std::string filename, - int pos_x, int pos_y, int res_x, int res_y) { - movie_filename = std::move(filename); + int pos_x, int pos_y, int res_x, int res_y) { + movie_pos_x = pos_x; movie_pos_y = pos_y; movie_res_x = res_x; movie_res_y = res_y; + movie_filename = filename; + + Rect metrics = DisplayUi->GetWindowMetrics(); + int w = metrics.width; + int h = metrics.height; + int x = metrics.x; + int y = metrics.y; + + const auto& config = DisplayUi->GetConfig(); + int fs = DisplayUi->IsFullscreen(); + int stretch = config.stretch.Get(); + int zoom = config.window_zoom.Get(); + + std::string path = FileFinder::GetFullFilesystemPath(FileFinder::Game()); + if (path.empty()) path = "%cd%"; + + std::string movie_src = path + "/" + FileFinder::FindMovie(movie_filename); + std::string pluginPath = path + "/Plugins/PageOverlay.exe"; + std::string htmlPath = path + "/Plugins/Pages/videoPlayer.html"; + + std::string appParams = fmt::format("-a \"{}\"", + htmlPath); + + std::string windowParams = fmt::format("-w \"{};{};{};{};{};{};{};{};{}\"", + w, h, x, y, fs, stretch, zoom, SCREEN_TARGET_WIDTH, SCREEN_TARGET_HEIGHT); + + std::string videoParams = fmt::format("-v \"{};{};{};{};{};{}\"", + movie_src, movie_res_x, movie_res_y, movie_pos_x, movie_pos_y, movie_filename); + + std::string asyncFlag; + //asyncFlag = "start /B"; + + std::string command = fmt::format("{} call \"{}\" {} {} {}", + asyncFlag, pluginPath, appParams, windowParams, videoParams); + + Output::Debug("\n\ncmd: {}\n\n", command); + + int result = std::system(command.c_str()); + Player::Resume(); + + if (result != 0) Output::Warning("Error ID: {}", result); } static double interpolate(double d, double x0, double x1) From 164b4ad63ff73ac3cc2cee56a0122d223827e419 Mon Sep 17 00:00:00 2001 From: Mauro Junior <45118493+jetrotal@users.noreply.github.com> Date: Thu, 2 Nov 2023 23:25:28 -0300 Subject: [PATCH 2/2] Video Player Now uses FFplay.exe changes : - "Plugins" folder, is now "Plugin" - Instead of my custom webplayer, FFplay.exe is now used. - Fastfoward button and hold to exit are removed. Since IDK how to make them inside ffplay. - Classic File Format Are back (.avi, ,mpeg). --- src/filefinder.cpp | 2 +- src/game_screen.cpp | 65 +++++++++++++++++++++++++++++++-------------- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/src/filefinder.cpp b/src/filefinder.cpp index f432126398..60e14a0bb3 100644 --- a/src/filefinder.cpp +++ b/src/filefinder.cpp @@ -54,7 +54,7 @@ namespace { //#ifdef SUPPORT_MOVIES - constexpr const auto MOVIE_TYPES = Utils::MakeSvArray( ".mov", ".mp4", ".webm", ".ogv"); //".avi", ".mpg" not supported by web standards + constexpr const auto MOVIE_TYPES = Utils::MakeSvArray( ".mov", ".mp4", ".webm", ".ogv", ".avi", ".mpg"); //#endif std::string fonts_path; diff --git a/src/game_screen.cpp b/src/game_screen.cpp index 19606e7311..91ec1e1315 100644 --- a/src/game_screen.cpp +++ b/src/game_screen.cpp @@ -35,7 +35,7 @@ #include "flash.h" #include "shake.h" #include "rand.h" -#include // For system function +#include //#include // For system function #include #include "baseui.h" @@ -188,38 +188,63 @@ void Game_Screen::PlayMovie(std::string filename, int y = metrics.y; const auto& config = DisplayUi->GetConfig(); - int fs = DisplayUi->IsFullscreen(); - int stretch = config.stretch.Get(); + std::string fs = int(DisplayUi->IsFullscreen()) ? "-fs" : ""; + std::string stretch = int(config.stretch.Get()) ? "-vf \"setdar = 16 / 9\"" : ""; int zoom = config.window_zoom.Get(); std::string path = FileFinder::GetFullFilesystemPath(FileFinder::Game()); if (path.empty()) path = "%cd%"; std::string movie_src = path + "/" + FileFinder::FindMovie(movie_filename); - std::string pluginPath = path + "/Plugins/PageOverlay.exe"; - std::string htmlPath = path + "/Plugins/Pages/videoPlayer.html"; - std::string appParams = fmt::format("-a \"{}\"", - htmlPath); + std::string pluginPath = path + "/Plugin/ffplay.exe"; - std::string windowParams = fmt::format("-w \"{};{};{};{};{};{};{};{};{}\"", - w, h, x, y, fs, stretch, zoom, SCREEN_TARGET_WIDTH, SCREEN_TARGET_HEIGHT); + std::string xtraParams = "-noborder -autoexit -fast -nostats -alwaysontop -exitonmousedown -exitonkeydown"; - std::string videoParams = fmt::format("-v \"{};{};{};{};{};{}\"", - movie_src, movie_res_x, movie_res_y, movie_pos_x, movie_pos_y, movie_filename); - - std::string asyncFlag; - //asyncFlag = "start /B"; - - std::string command = fmt::format("{} call \"{}\" {} {} {}", - asyncFlag, pluginPath, appParams, windowParams, videoParams); + std::string command = fmt::format( + "{} -i \"{}\" -left {} -top {} -x {} -y {} {} {} {}" , + pluginPath, movie_src, x, y, w, h, fs, stretch, xtraParams); Output::Debug("\n\ncmd: {}\n\n", command); - int result = std::system(command.c_str()); - Player::Resume(); + // Define a structure to set up the startup information + STARTUPINFO startupInfo; + PROCESS_INFORMATION processInfo; + + HWND oldWindow = GetForegroundWindow(); + + ZeroMemory(&startupInfo, sizeof(startupInfo)); + startupInfo.cb = sizeof(startupInfo); + startupInfo.dwFlags = STARTF_USESHOWWINDOW; + startupInfo.wShowWindow = SW_SHOWNORMAL; // Show the window normally + ZeroMemory(&processInfo, sizeof(processInfo)); + + std::wstring wideCommand = std::wstring(command.begin(), command.end()); + if (CreateProcess(nullptr, + const_cast(wideCommand.c_str()), // Command to execute + nullptr, // Process handle not inheritable + nullptr, // Thread handle not inheritable + FALSE, // Set handle inheritance to FALSE + 0, // No creation flags + nullptr, // Use parent's environment block + nullptr, // Use parent's starting directory + &startupInfo, // Pointer to STARTUPINFO structure + &processInfo) // Pointer to PROCESS_INFORMATION structure) + ) { + WaitForSingleObject(processInfo.hProcess, INFINITE); + + // Close handles + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); + + // Bring focus back to the old window + SetForegroundWindow(oldWindow); + } + else { + Output::Warning("CreateProcess failed, Error Code: {}", GetLastError()); + } - if (result != 0) Output::Warning("Error ID: {}", result); + Player::Resume(); } static double interpolate(double d, double x0, double x1)