2021-06-14 17:15:22 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
//
|
|
|
|
// EmulationStation Desktop Edition
|
|
|
|
// GuiLaunchScreen.cpp
|
|
|
|
//
|
|
|
|
// Screen shown when launching a game.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "guis/GuiLaunchScreen.h"
|
|
|
|
|
2021-07-07 18:03:42 +00:00
|
|
|
#include "FileData.h"
|
|
|
|
#include "SystemData.h"
|
2021-06-14 17:15:22 +00:00
|
|
|
#include "components/ComponentGrid.h"
|
|
|
|
#include "components/TextComponent.h"
|
|
|
|
#include "math/Misc.h"
|
|
|
|
#include "utils/StringUtil.h"
|
|
|
|
|
2021-07-07 18:03:42 +00:00
|
|
|
GuiLaunchScreen::GuiLaunchScreen(Window* window)
|
|
|
|
: GuiComponent(window)
|
|
|
|
, mBackground(window, ":/graphics/frame.svg")
|
|
|
|
, mGrid(nullptr)
|
|
|
|
, mMarquee(nullptr)
|
|
|
|
, mWindow(window)
|
2021-06-14 17:15:22 +00:00
|
|
|
{
|
|
|
|
addChild(&mBackground);
|
|
|
|
mWindow->setLaunchScreen(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
GuiLaunchScreen::~GuiLaunchScreen()
|
|
|
|
{
|
2021-07-07 18:03:42 +00:00
|
|
|
// This only executes when exiting the application.
|
2021-06-14 17:15:22 +00:00
|
|
|
closeLaunchScreen();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiLaunchScreen::displayLaunchScreen(FileData* game)
|
|
|
|
{
|
|
|
|
mGrid = new ComponentGrid(mWindow, Vector2i(3, 8));
|
|
|
|
addChild(mGrid);
|
|
|
|
|
|
|
|
mImagePath = game->getMarqueePath();
|
|
|
|
|
|
|
|
// We need to unload the image first as it may be cached at a modified resolution
|
|
|
|
// which would lead to the wrong size when using the image here.
|
|
|
|
if (mImagePath != "") {
|
|
|
|
TextureResource::manualUnload(mImagePath, false);
|
|
|
|
mMarquee = new ImageComponent(mWindow);
|
|
|
|
}
|
|
|
|
|
|
|
|
mScaleUp = 0.5f;
|
|
|
|
const float titleFontSize = 0.060f;
|
|
|
|
const float gameNameFontSize = 0.073f;
|
|
|
|
|
|
|
|
// Spacer row.
|
2021-07-07 18:03:42 +00:00
|
|
|
mGrid->setEntry(std::make_shared<GuiComponent>(mWindow), Vector2i(1, 0), false, false,
|
|
|
|
Vector2i(1, 1));
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
// Title.
|
2021-07-07 18:03:42 +00:00
|
|
|
mTitle = std::make_shared<TextComponent>(
|
|
|
|
mWindow, "LAUNCHING GAME",
|
|
|
|
Font::get(static_cast<int>(
|
|
|
|
titleFontSize * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth()))),
|
|
|
|
0x666666FF, ALIGN_CENTER);
|
2021-06-14 17:15:22 +00:00
|
|
|
mGrid->setEntry(mTitle, Vector2i(1, 1), false, true, Vector2i(1, 1));
|
|
|
|
|
|
|
|
// Spacer row.
|
2021-07-07 18:03:42 +00:00
|
|
|
mGrid->setEntry(std::make_shared<GuiComponent>(mWindow), Vector2i(1, 2), false, false,
|
|
|
|
Vector2i(1, 1));
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
// Row for the marquee.
|
2021-07-07 18:03:42 +00:00
|
|
|
mGrid->setEntry(std::make_shared<GuiComponent>(mWindow), Vector2i(1, 3), false, false,
|
|
|
|
Vector2i(1, 1));
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
// Spacer row.
|
2021-07-07 18:03:42 +00:00
|
|
|
mGrid->setEntry(std::make_shared<GuiComponent>(mWindow), Vector2i(1, 4), false, false,
|
|
|
|
Vector2i(1, 1));
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
// Game name.
|
2021-07-07 18:03:42 +00:00
|
|
|
mGameName = std::make_shared<TextComponent>(
|
|
|
|
mWindow, "GAME NAME",
|
|
|
|
Font::get(static_cast<int>(
|
|
|
|
gameNameFontSize * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth()))),
|
|
|
|
0x444444FF, ALIGN_CENTER);
|
2021-06-14 17:15:22 +00:00
|
|
|
mGrid->setEntry(mGameName, Vector2i(1, 5), false, true, Vector2i(1, 1));
|
|
|
|
|
|
|
|
// System name.
|
2021-07-07 18:03:42 +00:00
|
|
|
mSystemName = std::make_shared<TextComponent>(
|
|
|
|
mWindow, "SYSTEM NAME", Font::get(FONT_SIZE_MEDIUM), 0x666666FF, ALIGN_CENTER);
|
2021-06-14 17:15:22 +00:00
|
|
|
mGrid->setEntry(mSystemName, Vector2i(1, 6), false, true, Vector2i(1, 1));
|
|
|
|
|
|
|
|
// Spacer row.
|
2021-07-07 18:03:42 +00:00
|
|
|
mGrid->setEntry(std::make_shared<GuiComponent>(mWindow), Vector2i(1, 7), false, false,
|
|
|
|
Vector2i(1, 1));
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
// Left spacer.
|
2021-07-07 18:03:42 +00:00
|
|
|
mGrid->setEntry(std::make_shared<GuiComponent>(mWindow), Vector2i(0, 0), false, false,
|
|
|
|
Vector2i(1, 8));
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
// Right spacer.
|
2021-07-07 18:03:42 +00:00
|
|
|
mGrid->setEntry(std::make_shared<GuiComponent>(mWindow), Vector2i(2, 0), false, false,
|
|
|
|
Vector2i(1, 8));
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
// Adjust the width depending on the aspect ratio of the screen, to make the screen look
|
|
|
|
// somewhat coherent regardless of screen type. The 1.778 aspect ratio value is the 16:9
|
|
|
|
// reference.
|
|
|
|
float aspectValue = 1.778f / Renderer::getScreenAspectRatio();
|
|
|
|
|
|
|
|
float maxWidthModifier = Math::clamp(0.78f * aspectValue, 0.78f, 0.90f);
|
2021-06-15 19:15:37 +00:00
|
|
|
float minWidthModifier = Math::clamp(0.50f * aspectValue, 0.50f, 0.65f);
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
float maxWidth = static_cast<float>(Renderer::getScreenWidth()) * maxWidthModifier;
|
|
|
|
float minWidth = static_cast<float>(Renderer::getScreenWidth()) * minWidthModifier;
|
|
|
|
|
2021-07-07 18:03:42 +00:00
|
|
|
float fontWidth =
|
|
|
|
Font::get(static_cast<int>(gameNameFontSize * std::min(Renderer::getScreenHeight(),
|
|
|
|
Renderer::getScreenWidth())))
|
|
|
|
->sizeText(Utils::String::toUpper(game->getName()))
|
|
|
|
.x();
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
// Add a bit of width to compensate for the left and right spacers.
|
|
|
|
fontWidth += static_cast<float>(Renderer::getScreenWidth()) * 0.05f;
|
|
|
|
|
|
|
|
float width = Math::clamp(fontWidth, minWidth, maxWidth);
|
|
|
|
|
|
|
|
if (mImagePath != "")
|
|
|
|
setSize(width, static_cast<float>(Renderer::getScreenHeight()) * 0.60f);
|
|
|
|
else
|
2021-06-14 21:13:31 +00:00
|
|
|
setSize(width, static_cast<float>(Renderer::getScreenHeight()) * 0.38f);
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
// Set row heights.
|
2021-06-14 21:13:31 +00:00
|
|
|
if (mImagePath != "")
|
|
|
|
mGrid->setRowHeightPerc(0, 0.09f, false);
|
|
|
|
else
|
|
|
|
mGrid->setRowHeightPerc(0, 0.15f, false);
|
2021-06-14 17:15:22 +00:00
|
|
|
mGrid->setRowHeightPerc(1, mTitle->getFont()->getLetterHeight() * 1.70f / mSize.y(), false);
|
|
|
|
mGrid->setRowHeightPerc(2, 0.05f, false);
|
|
|
|
if (mImagePath != "")
|
|
|
|
mGrid->setRowHeightPerc(3, 0.35f, false);
|
|
|
|
else
|
2021-06-24 22:44:53 +00:00
|
|
|
mGrid->setRowHeightPerc(3, 0.01f, false);
|
2021-06-14 17:15:22 +00:00
|
|
|
mGrid->setRowHeightPerc(4, 0.05f, false);
|
|
|
|
mGrid->setRowHeightPerc(5, mGameName->getFont()->getHeight() * 0.80f / mSize.y(), false);
|
|
|
|
mGrid->setRowHeightPerc(6, mSystemName->getFont()->getHeight() * 0.90f / mSize.y(), false);
|
|
|
|
|
|
|
|
// Set left and right spacers column widths.
|
|
|
|
mGrid->setColWidthPerc(0, 0.025f);
|
|
|
|
mGrid->setColWidthPerc(2, 0.025f);
|
|
|
|
|
|
|
|
mGrid->setSize(mSize);
|
|
|
|
|
|
|
|
float totalRowHeight = 0.0f;
|
|
|
|
|
|
|
|
// Hack to adjust the window height to the row boundary.
|
|
|
|
for (int i = 0; i < 7; i++)
|
|
|
|
totalRowHeight += mGrid->getRowHeight(i);
|
|
|
|
|
|
|
|
setSize(mSize.x(), totalRowHeight);
|
|
|
|
|
|
|
|
mGameName->setText(Utils::String::toUpper(game->getName()));
|
|
|
|
mSystemName->setText(Utils::String::toUpper(game->getSystem()->getFullName()));
|
|
|
|
|
|
|
|
// For the marquee we strip away any transparent padding around the actual image.
|
|
|
|
// When doing this, we restrict the scale-up to a certain percentage of the screen
|
|
|
|
// width so that the sizes look somewhat consistent regardless of the aspect ratio
|
|
|
|
// of the images.
|
|
|
|
if (mImagePath != "") {
|
|
|
|
mMarquee->setImage(game->getMarqueePath(), false);
|
|
|
|
mMarquee->cropTransparentPadding(static_cast<float>(Renderer::getScreenWidth()) *
|
2021-07-07 18:03:42 +00:00
|
|
|
(0.25f * (1.778f / Renderer::getScreenAspectRatio())),
|
|
|
|
mGrid->getRowHeight(3));
|
2021-06-14 17:15:22 +00:00
|
|
|
|
|
|
|
mMarquee->setOrigin(0.5f, 0.5f);
|
|
|
|
Vector3f currentPos = mMarquee->getPosition();
|
|
|
|
Vector2f currentSize = mMarquee->getSize();
|
|
|
|
|
|
|
|
// Position the image in the middle of row four.
|
|
|
|
currentPos.x() = mSize.x() / 2.0f;
|
2021-07-07 18:03:42 +00:00
|
|
|
currentPos.y() = mGrid->getRowHeight(0) + mGrid->getRowHeight(1) + mGrid->getRowHeight(2) +
|
|
|
|
mGrid->getRowHeight(3) / 2.0f;
|
2021-06-14 17:15:22 +00:00
|
|
|
mMarquee->setPosition(currentPos);
|
|
|
|
}
|
|
|
|
|
2021-07-07 18:03:42 +00:00
|
|
|
setOrigin({ 0.5f, 0.5f });
|
2021-06-22 16:00:30 +00:00
|
|
|
|
|
|
|
// Center on the X axis and keep slightly off-center on the Y axis.
|
|
|
|
setPosition(static_cast<float>(Renderer::getScreenWidth()) / 2.0f,
|
2021-07-07 18:03:42 +00:00
|
|
|
static_cast<float>(Renderer::getScreenHeight()) / 2.25f);
|
2021-06-22 16:00:30 +00:00
|
|
|
|
2021-07-07 18:03:42 +00:00
|
|
|
mBackground.fitTo(mSize, Vector3f::Zero(), Vector2f(-32.0f, -32.0f));
|
2021-06-14 20:35:30 +00:00
|
|
|
mBackground.setEdgeColor(0xEEEEEEFF);
|
2021-06-14 17:15:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GuiLaunchScreen::closeLaunchScreen()
|
|
|
|
{
|
|
|
|
if (mGrid) {
|
|
|
|
delete mGrid;
|
|
|
|
mGrid = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mMarquee) {
|
|
|
|
delete mMarquee;
|
|
|
|
mMarquee = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
// An extra precaution.
|
|
|
|
if (mImagePath != "") {
|
|
|
|
TextureResource::manualUnload(mImagePath, false);
|
|
|
|
mImagePath = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiLaunchScreen::onSizeChanged()
|
|
|
|
{
|
2021-07-07 18:03:42 +00:00
|
|
|
// Update mGrid size.
|
2021-06-14 17:15:22 +00:00
|
|
|
mGrid->setSize(mSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiLaunchScreen::update(int deltaTime)
|
|
|
|
{
|
2021-06-22 16:00:30 +00:00
|
|
|
if (Settings::getInstance()->getString("MenuOpeningEffect") == "none")
|
|
|
|
mScaleUp = 1.0f;
|
|
|
|
else if (mScaleUp < 1.0f)
|
2021-06-14 17:15:22 +00:00
|
|
|
mScaleUp = Math::clamp(mScaleUp + 0.07f, 0.0f, 1.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GuiLaunchScreen::render()
|
|
|
|
{
|
|
|
|
// Scale up animation.
|
2021-06-22 16:00:30 +00:00
|
|
|
if (mScaleUp < 1.0f)
|
2021-06-14 17:15:22 +00:00
|
|
|
setScale(mScaleUp);
|
|
|
|
|
|
|
|
Transform4x4f trans = Transform4x4f::Identity() * getTransform();
|
|
|
|
Renderer::setMatrix(trans);
|
|
|
|
|
|
|
|
GuiComponent::renderChildren(trans);
|
|
|
|
|
|
|
|
if (mMarquee)
|
|
|
|
mMarquee->render(trans);
|
|
|
|
}
|