Update the menu video from a separate thread and respect window resizes

pull/3236/head
Evil Eye 6 months ago
parent 5553b00b84
commit de59d79388

@ -185,6 +185,7 @@
Bug #8018: Potion effects should never explode and always apply on self
Bug #8021: Player's scale doesn't reset when starting a new game
Bug #8048: Actors can generate negative collision extents and have no collision
Bug #8063: menu_background.bik video with audio freezes the game forever
Bug #8064: Lua move360 script doesn't respect the enableZoom/disableZoom Camera interface setting
Feature #1415: Infinite fall failsafe
Feature #2566: Handle NAM9 records for manual cell references

@ -4,6 +4,7 @@
#include <MyGUI_RenderManager.h>
#include <MyGUI_TextBox.h>
#include <components/misc/frameratelimiter.hpp>
#include <components/settings/values.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/pathutil.hpp>
@ -24,6 +25,56 @@
namespace MWGui
{
void MenuVideo::run()
{
Misc::FrameRateLimiter frameRateLimiter
= Misc::makeFrameRateLimiter(MWBase::Environment::get().getFrameRateLimit());
while (mRunning)
{
// If finished playing, start again
if (!mVideo->update())
mVideo->playVideo("video\\menu_background.bik");
frameRateLimiter.limit();
}
}
MenuVideo::MenuVideo(const VFS::Manager* vfs)
: mRunning(true)
{
// Use black background to correct aspect ratio
mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal<MyGUI::ImageBox>(
"ImageBox", 0, 0, 1, 1, MyGUI::Align::Default, "MainMenuBackground");
mVideoBackground->setImageTexture("black");
mVideo = mVideoBackground->createWidget<VideoWidget>(
"ImageBox", 0, 0, 1, 1, MyGUI::Align::Stretch, "MainMenuBackground");
mVideo->setVFS(vfs);
mVideo->playVideo("video\\menu_background.bik");
mThread = std::thread([this] { run(); });
}
void MenuVideo::resize(int screenWidth, int screenHeight)
{
const bool stretch = Settings::gui().mStretchMenuBackground;
mVideoBackground->setSize(screenWidth, screenHeight);
mVideo->autoResize(stretch);
mVideo->setVisible(true);
}
MenuVideo::~MenuVideo()
{
mRunning = false;
mThread.join();
try
{
MyGUI::Gui::getInstance().destroyWidget(mVideoBackground);
}
catch (const MyGUI::Exception& e)
{
Log(Debug::Error) << "Error in the destructor: " << e.what();
}
}
MainMenu::MainMenu(int w, int h, const VFS::Manager* vfs, const std::string& versionDescription)
: WindowBase("openmw_mainmenu.layout")
@ -32,8 +83,6 @@ namespace MWGui
, mVFS(vfs)
, mButtonBox(nullptr)
, mBackground(nullptr)
, mVideoBackground(nullptr)
, mVideo(nullptr)
{
getWidget(mVersionText, "VersionText");
mVersionText->setCaption(versionDescription);
@ -51,6 +100,8 @@ namespace MWGui
mHeight = h;
updateMenu();
if (mVideo)
mVideo->resize(w, h);
}
void MainMenu::setVisible(bool visible)
@ -146,9 +197,7 @@ namespace MWGui
{
if (mVideo && !show)
{
MyGUI::Gui::getInstance().destroyWidget(mVideoBackground);
mVideoBackground = nullptr;
mVideo = nullptr;
mVideo.reset();
}
if (mBackground && !show)
{
@ -164,27 +213,12 @@ namespace MWGui
if (mHasAnimatedMenu)
{
if (!mVideo)
{
// Use black background to correct aspect ratio
mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal<MyGUI::ImageBox>(
"ImageBox", 0, 0, 1, 1, MyGUI::Align::Default, "MainMenuBackground");
mVideoBackground->setImageTexture("black");
mVideo = mVideoBackground->createWidget<VideoWidget>(
"ImageBox", 0, 0, 1, 1, MyGUI::Align::Stretch, "MainMenuBackground");
mVideo->setVFS(mVFS);
mVideo.emplace(mVFS);
mVideo->playVideo("video\\menu_background.bik");
}
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
const auto& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
int screenWidth = viewSize.width;
int screenHeight = viewSize.height;
mVideoBackground->setSize(screenWidth, screenHeight);
mVideo->autoResize(stretch);
mVideo->setVisible(true);
mVideo->resize(screenWidth, screenHeight);
}
else
{
@ -198,18 +232,6 @@ namespace MWGui
}
}
void MainMenu::onFrame(float dt)
{
if (mVideo)
{
if (!mVideo->update())
{
// If finished playing, start again
mVideo->playVideo("video\\menu_background.bik");
}
}
}
bool MainMenu::exit()
{
if (MWBase::Environment::get().getWindowManager()->isSettingsWindowVisible())

@ -2,6 +2,8 @@
#define OPENMW_GAME_MWGUI_MAINMENU_H
#include <memory>
#include <optional>
#include <thread>
#include "savegamedialog.hpp"
#include "windowbase.hpp"
@ -21,6 +23,20 @@ namespace MWGui
class BackgroundImage;
class VideoWidget;
class MenuVideo
{
MyGUI::ImageBox* mVideoBackground;
VideoWidget* mVideo;
std::thread mThread;
bool mRunning;
void run();
public:
MenuVideo(const VFS::Manager* vfs);
void resize(int w, int h);
~MenuVideo();
};
class MainMenu : public WindowBase
{
@ -36,8 +52,6 @@ namespace MWGui
void setVisible(bool visible) override;
void onFrame(float dt) override;
bool exit() override;
private:
@ -48,8 +62,7 @@ namespace MWGui
BackgroundImage* mBackground;
MyGUI::ImageBox* mVideoBackground;
VideoWidget* mVideo; // For animated main menus
std::optional<MenuVideo> mVideo; // For animated main menus
std::map<std::string, Gui::ImageButton*, std::less<>> mButtons;

Loading…
Cancel
Save