Add intial support for displaying the splashscreen when using as a system menu replacement

This commit is contained in:
Maschell 2020-02-24 20:19:21 +01:00
parent 7815e5b3fc
commit 96fa65a5ff
5 changed files with 154 additions and 12 deletions

View File

@ -168,9 +168,9 @@ bool Application::procUI(void) {
case PROCUI_STATUS_RELEASE_FOREGROUND: { case PROCUI_STATUS_RELEASE_FOREGROUND: {
DEBUG_FUNCTION_LINE("PROCUI_STATUS_RELEASE_FOREGROUND\n"); DEBUG_FUNCTION_LINE("PROCUI_STATUS_RELEASE_FOREGROUND\n");
if(video != NULL) { if(video != NULL) {
// we can turn of the screen but we don't need to and it will display the last image // we can turn ofF the screen but we don't need to and it will display the last image
video->tvEnable(false); video->tvEnable(true);
video->drcEnable(false); video->drcEnable(true);
DEBUG_FUNCTION_LINE("delete fontSystem\n"); DEBUG_FUNCTION_LINE("delete fontSystem\n");
delete fontSystem; delete fontSystem;
@ -274,9 +274,19 @@ void Application::executeThread(void) {
video->waitForVSync(); video->waitForVSync();
} }
if(bgMusic) {
bgMusic->SetVolume(0);
}
//! in case we exit to a homebrew let's smoothly fade out //! in case we exit to a homebrew let's smoothly fade out
if(video) { if(video) {
fadeOut(); uint64_t titleID = OSGetTitleID();
if (titleID == HBL_TITLE_ID ||
titleID == MII_MAKER_JPN_TITLE_ID ||
titleID == MII_MAKER_USA_TITLE_ID ||
titleID == MII_MAKER_EUR_TITLE_ID) {
fadeOut();
}
} }
DEBUG_FUNCTION_LINE("delete mainWindow\n"); DEBUG_FUNCTION_LINE("delete mainWindow\n");

View File

@ -0,0 +1,66 @@
#include "GameSplashScreen.h"
#include "utils/logger.h"
#include "common/common.h"
#include "fs/FSUtils.h"
#include "utils/AsyncExecutor.h"
GameSplashScreen::GameSplashScreen(int32_t w, int32_t h, gameInfo * info, bool onTV) : GuiFrame(w, h),
bgImageColor(w, h, (GX2Color) {
0, 0, 0, 0
}) {
bgImageColor.setImageColor((GX2Color) {
79, 153, 239, 255
}, 0);
bgImageColor.setImageColor((GX2Color) {
79, 153, 239, 255
}, 1);
bgImageColor.setImageColor((GX2Color) {
59, 159, 223, 255
}, 2);
bgImageColor.setImageColor((GX2Color) {
59, 159, 223, 255
}, 3);
append(&bgImageColor);
this->onTV = onTV;
this->info = info;
std::string filepath = "fs:" + info->gamePath + META_PATH + "/bootDRCTex.tga";
if(onTV) {
filepath = "fs:" + info->gamePath + META_PATH + "/bootTVTex.tga";
}
uint8_t *buffer = NULL;
uint32_t bufferSize = 0;
int iResult = FSUtils::LoadFileToMem(filepath.c_str(), &buffer, &bufferSize);
if(iResult > 0) {
splashScreenData = new GuiImageData(buffer, bufferSize, GX2_TEX_CLAMP_MODE_MIRROR);
if(splashScreenData) {
bgImageColor.setImageData(splashScreenData);
bgImageColor.setScale(((float) h) / splashScreenData->getHeight());
}
//! free original image buffer which is converted to texture now and not needed anymore
free(buffer);
}
this->effectFinished.connect(this, &GameSplashScreen::OnSplashScreenFadeInDone);
}
void GameSplashScreen::OnSplashScreenFadeInDone(GuiElement *element) {
// we need to wait one more frame becaus the effects get calculated before drawing.
launchGame = true;
}
void GameSplashScreen::draw(CVideo * v) {
GuiFrame::draw(v);
if(launchGame && frameCounter++ > 1) {
DEBUG_FUNCTION_LINE("Launch game %d\n", onTV);
gameGameSplashScreenFinished(this, info, onTV);
}
}
GameSplashScreen::~GameSplashScreen() {
DEBUG_FUNCTION_LINE("Destroy me\n");
if(splashScreenData) {
AsyncExecutor::pushForDelete(splashScreenData);
}
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "game/GameList.h"
#include <gui/GuiImage.h>
#include <gui/GuiFrame.h>
class GameSplashScreen : public GuiFrame, public sigslot::has_slots<> {
public:
GameSplashScreen(int32_t w, int32_t h, gameInfo * info, bool onTV);
virtual ~GameSplashScreen();
void OnSplashScreenFadeInDone(GuiElement * element);
virtual void draw(CVideo * v);
sigslot::signal3<GuiElement *, gameInfo *, bool> gameGameSplashScreenFinished;
private:
GuiImage bgImageColor;
GuiImageData* splashScreenData = NULL;
gameInfo * info = NULL;
bool launchGame = false;
uint32_t frameCounter = 0;
bool onTV = false;
};

View File

@ -26,6 +26,7 @@
#include <future> #include <future>
#include <coreinit/title.h> #include <coreinit/title.h>
#include "utils/AsyncExecutor.h" #include "utils/AsyncExecutor.h"
#include "GameSplashScreen.h"
MainWindow::MainWindow(int32_t w, int32_t h) MainWindow::MainWindow(int32_t w, int32_t h)
: width(w) : width(w)
@ -251,11 +252,11 @@ void MainWindow::SetupMainView() {
if(currentTvFrame != currentDrcFrame) { if(currentTvFrame != currentDrcFrame) {
currentTvFrame->gameSelectionChanged.connect(this, &MainWindow::OnGameSelectionChange); currentTvFrame->gameSelectionChanged.connect(this, &MainWindow::OnGameSelectionChange);
currentTvFrame->gameLaunchClicked.connect(this, &MainWindow::OnGameLaunch); currentTvFrame->gameLaunchClicked.connect(this, &MainWindow::OnGameLaunchSplashScreen);
} }
currentDrcFrame->gameSelectionChanged.connect(this, &MainWindow::OnGameSelectionChange); currentDrcFrame->gameSelectionChanged.connect(this, &MainWindow::OnGameSelectionChange);
currentDrcFrame->gameLaunchClicked.connect(this, &MainWindow::OnGameLaunch); currentDrcFrame->gameLaunchClicked.connect(this, &MainWindow::OnGameLaunchSplashScreen);
mainSwitchButtonFrame = new MainDrcButtonsFrame(width, height); mainSwitchButtonFrame = new MainDrcButtonsFrame(width, height);
mainSwitchButtonFrame->settingsButtonClicked.connect(this, &MainWindow::OnSettingsButtonClicked); mainSwitchButtonFrame->settingsButtonClicked.connect(this, &MainWindow::OnSettingsButtonClicked);
@ -338,9 +339,9 @@ void MainWindow::OnLayoutSwitchEffectFinish(GuiElement *element) {
currentDrcFrame->gameLaunchClicked.disconnect(this); currentDrcFrame->gameLaunchClicked.disconnect(this);
currentTvFrame->gameSelectionChanged.connect(this, &MainWindow::OnGameSelectionChange); currentTvFrame->gameSelectionChanged.connect(this, &MainWindow::OnGameSelectionChange);
currentTvFrame->gameLaunchClicked.connect(this, &MainWindow::OnGameLaunch); currentTvFrame->gameLaunchClicked.connect(this, &MainWindow::OnGameLaunchSplashScreen);
currentDrcFrame->gameSelectionChanged.connect(this, &MainWindow::OnGameSelectionChange); currentDrcFrame->gameSelectionChanged.connect(this, &MainWindow::OnGameSelectionChange);
currentDrcFrame->gameLaunchClicked.connect(this, &MainWindow::OnGameLaunch); currentDrcFrame->gameLaunchClicked.connect(this, &MainWindow::OnGameLaunchSplashScreen);
} }
void MainWindow::OnOpenEffectFinish(GuiElement *element) { void MainWindow::OnOpenEffectFinish(GuiElement *element) {
@ -377,11 +378,52 @@ void MainWindow::OnGameSelectionChange(GuiTitleBrowser *element, uint64_t select
extern "C" void _SYSLaunchTitleByPathFromLauncher(const char * path, int len, int); extern "C" void _SYSLaunchTitleByPathFromLauncher(const char * path, int len, int);
void MainWindow::OnGameLaunch(GuiTitleBrowser *element, uint64_t titleID) { void MainWindow::OnGameLaunchSplashScreen(GuiTitleBrowser * element, uint64_t titleID) {
gameInfo * info = gameList.getGameInfo(titleID);
if(info != NULL) {
uint64_t ownTitleId = OSGetTitleID();
if (ownTitleId == HBL_TITLE_ID ||
ownTitleId == MII_MAKER_JPN_TITLE_ID ||
ownTitleId == MII_MAKER_USA_TITLE_ID ||
ownTitleId == MII_MAKER_EUR_TITLE_ID) {
OnGameLaunch(titleID);
} else {
GameSplashScreen * gameSettingsDRC = new GameSplashScreen(width,height,info, false);
gameSettingsDRC->setEffect(EFFECT_FADE, 15, 255);
gameSettingsDRC->setState(GuiElement::STATE_DISABLED);
gameSettingsDRC->effectFinished.connect(this, &MainWindow::OnOpenEffectFinish);
gameSettingsDRC->gameGameSplashScreenFinished.connect(this, &MainWindow::OnGameLaunchSplashScreenFinished);
appendDrc(gameSettingsDRC);
GameSplashScreen * gameSettingsTV = new GameSplashScreen(width,height,info, true);
gameSettingsTV->setEffect(EFFECT_FADE, 15, 255);
gameSettingsTV->setState(GuiElement::STATE_DISABLED);
gameSettingsTV->effectFinished.connect(this, &MainWindow::OnOpenEffectFinish);
gameSettingsTV->gameGameSplashScreenFinished.connect(this, &MainWindow::OnGameLaunchSplashScreenFinished);
appendTv(gameSettingsTV);
}
} else {
DEBUG_FUNCTION_LINE("Failed to find gameInfo for titleId %016llX\n", titleID);
}
}
void MainWindow::OnGameLaunchSplashScreenFinished(GuiElement * element, gameInfo * info, bool launchGame) {
if(info == NULL) {
return;
}
if(launchGame) {
OnGameLaunch(info->titleId);
}
if(element) {
element->setState(GuiElement::STATE_DISABLED);
element->setEffect(EFFECT_FADE, 15, 255);
element->effectFinished.connect(this, &MainWindow::OnCloseEffectFinish);
}
}
void MainWindow::OnGameLaunch(uint64_t titleID) {
gameInfo * info = gameList.getGameInfo(titleID); gameInfo * info = gameList.getGameInfo(titleID);
if(info != NULL) { if(info != NULL) {
uint64_t titleID = OSGetTitleID(); uint64_t titleID = OSGetTitleID();
if (titleID == HBL_TITLE_ID || if (titleID == HBL_TITLE_ID ||
titleID == MII_MAKER_JPN_TITLE_ID || titleID == MII_MAKER_JPN_TITLE_ID ||
titleID == MII_MAKER_USA_TITLE_ID || titleID == MII_MAKER_USA_TITLE_ID ||
@ -391,5 +433,7 @@ void MainWindow::OnGameLaunch(GuiTitleBrowser *element, uint64_t titleID) {
const char* path = info->gamePath.c_str(); const char* path = info->gamePath.c_str();
_SYSLaunchTitleByPathFromLauncher(path, strlen(path),0); _SYSLaunchTitleByPathFromLauncher(path, strlen(path),0);
} }
} else {
DEBUG_FUNCTION_LINE("Failed to find gameInfo for titleId %016llX\n", titleID);
} }
} }

View File

@ -117,8 +117,11 @@ private:
void OnOpenEffectFinish(GuiElement *element); void OnOpenEffectFinish(GuiElement *element);
void OnCloseEffectFinish(GuiElement *element); void OnCloseEffectFinish(GuiElement *element);
void OnGameLaunch(GuiTitleBrowser *element, uint64_t gameIdx); void OnGameLaunch(uint64_t titleId);
void OnGameSelectionChange(GuiTitleBrowser *element, uint64_t selectedIdx); void OnGameLaunchSplashScreenFinished(GuiElement * element, gameInfo * info, bool launchGame);
void OnGameLaunchSplashScreen(GuiTitleBrowser *element, uint64_t titleId);
void OnGameSelectionChange(GuiTitleBrowser *element, uint64_t titleId);
void OnSettingsButtonClicked(GuiElement *element); void OnSettingsButtonClicked(GuiElement *element);
void OnLayoutSwitchClicked(GuiElement *element); void OnLayoutSwitchClicked(GuiElement *element);