Skip to content

Commit

Permalink
Update the menu video from a separate thread and respect window resizes
Browse files Browse the repository at this point in the history
  • Loading branch information
Assumeru committed Jul 11, 2024
1 parent 5553b00 commit de59d79
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 39 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
92 changes: 57 additions & 35 deletions apps/openmw/mwgui/mainmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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")
Expand All @@ -32,8 +83,6 @@ namespace MWGui
, mVFS(vfs)
, mButtonBox(nullptr)
, mBackground(nullptr)
, mVideoBackground(nullptr)
, mVideo(nullptr)
{
getWidget(mVersionText, "VersionText");
mVersionText->setCaption(versionDescription);
Expand All @@ -51,6 +100,8 @@ namespace MWGui
mHeight = h;

updateMenu();
if (mVideo)
mVideo->resize(w, h);
}

void MainMenu::setVisible(bool visible)
Expand Down Expand Up @@ -146,9 +197,7 @@ namespace MWGui
{
if (mVideo && !show)
{
MyGUI::Gui::getInstance().destroyWidget(mVideoBackground);
mVideoBackground = nullptr;
mVideo = nullptr;
mVideo.reset();
}
if (mBackground && !show)
{
Expand All @@ -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
{
Expand All @@ -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())
Expand Down
21 changes: 17 additions & 4 deletions apps/openmw/mwgui/mainmenu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#define OPENMW_GAME_MWGUI_MAINMENU_H

#include <memory>
#include <optional>
#include <thread>

#include "savegamedialog.hpp"
#include "windowbase.hpp"
Expand All @@ -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
{
Expand All @@ -36,8 +52,6 @@ namespace MWGui

void setVisible(bool visible) override;

void onFrame(float dt) override;

bool exit() override;

private:
Expand All @@ -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;

Expand Down

0 comments on commit de59d79

Please sign in to comment.