diff --git a/src/filefinder.cpp b/src/filefinder.cpp index b7885e48a5..60e14a0bb3 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"); +//#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..91ec1e1315 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 //#include // For system function +#include +#include "baseui.h" Game_Screen::Game_Screen() { @@ -170,12 +173,78 @@ 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(); + 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 + "/Plugin/ffplay.exe"; + + std::string xtraParams = "-noborder -autoexit -fast -nostats -alwaysontop -exitonmousedown -exitonkeydown"; + + 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); + + // 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()); + } + + Player::Resume(); } static double interpolate(double d, double x0, double x1)