Improve disc launching in quick start menu

This commit is contained in:
Maschell 2023-04-02 11:59:16 +02:00
parent 603478ccc6
commit 803f2ca80b
6 changed files with 171 additions and 8 deletions

View File

@ -1,4 +1,4 @@
FROM ghcr.io/wiiu-env/devkitppc:20221228
FROM ghcr.io/wiiu-env/devkitppc:20230402
COPY --from=ghcr.io/wiiu-env/libmocha:20220919 /artifacts $DEVKITPRO

View File

@ -3,15 +3,19 @@
#include "DrawUtils.h"
#include "icon_png.h"
#include "logger.h"
#include "utils.h"
#include "version.h"
#include <coreinit/debug.h>
#include <coreinit/mcp.h>
#include <coreinit/screen.h>
#include <coreinit/thread.h>
#include <cstring>
#include <gx2/state.h>
#include <malloc.h>
#include <memory>
#include <nn/act/client_cpp.h>
#include <string>
#include <sysapp/title.h>
#include <vector>
#include <vpad/input.h>
@ -414,3 +418,111 @@ void handleUpdateWarningScreen() {
free(screenBuffer);
}
bool handleDiscInsertScreen(uint64_t expectedTitleId, uint64_t *titleIdToLaunch) {
if (titleIdToLaunch == nullptr) {
DEBUG_FUNCTION_LINE_ERR("titleIdToLaunch is NULL");
return false;
}
if (SYSCheckTitleExists(expectedTitleId)) {
*titleIdToLaunch = expectedTitleId;
return true;
}
auto result = false;
auto screenBuffer = DrawUtils::InitOSScreen();
if (!screenBuffer) {
OSFatal("Failed to alloc memory for screen");
}
uint32_t tvBufferSize = OSScreenGetBufferSizeEx(SCREEN_TV);
uint32_t drcBufferSize = OSScreenGetBufferSizeEx(SCREEN_DRC);
DrawUtils::initBuffers(screenBuffer, tvBufferSize, (void *) ((uint32_t) screenBuffer + tvBufferSize), drcBufferSize);
if (!DrawUtils::initFont()) {
OSFatal("Failed to init font");
}
DrawUtils::beginDraw();
DrawUtils::clear(COLOR_BACKGROUND);
DrawUtils::endDraw();
uint64_t titleIdOfDisc = 0;
bool discInserted;
uint32_t attempt = 0;
while (!GetTitleIdOfDisc(&titleIdOfDisc, &discInserted)) {
if (++attempt > 20) {
break;
}
OSSleepTicks(OSMillisecondsToTicks(100));
}
bool wrongDiscInserted = discInserted && (titleIdOfDisc != expectedTitleId);
if (discInserted && !wrongDiscInserted) {
*titleIdToLaunch = expectedTitleId;
DrawUtils::deinitFont();
free(screenBuffer);
return true;
}
DrawUtils::beginDraw();
DrawUtils::clear(COLOR_BACKGROUND);
DrawUtils::setFontColor(COLOR_TEXT);
DrawUtils::setFontSize(48);
if (wrongDiscInserted) {
const char *title = "The disc inserted into the console";
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(title) / 2, 40 + 48 + 8, title, true);
title = "is for a different software title.";
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(title) / 2, 40 + 2 * 48 + 8, title, true);
title = "Please change the disc.";
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(title) / 2, 40 + 4 * 48 + 8, title, true);
} else {
const char *title = "Please insert a disc.";
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(title) / 2, 40 + 48 + 8, title, true);
}
DrawUtils::setFontSize(18);
const char *exitHints = "\ue000 Launch Wii U Menu";
DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHints) / 2, SCREEN_HEIGHT - 8, exitHints, true);
DrawUtils::endDraw();
// When an unexpected disc was inserted we need to eject it first.
bool allowDisc = !wrongDiscInserted;
while (true) {
VPADStatus vpad{};
VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr);
if (vpad.trigger & VPAD_BUTTON_A) {
result = false;
break;
}
if (GetTitleIdOfDisc(&titleIdOfDisc, &discInserted)) {
if (discInserted) {
if (!allowDisc) {
continue;
}
*titleIdToLaunch = titleIdOfDisc;
DEBUG_FUNCTION_LINE("Disc inserted! %016llX", titleIdOfDisc);
result = true;
break;
}
} else {
allowDisc = true;
}
}
DrawUtils::clear(COLOR_BLACK);
DrawUtils::endDraw();
DrawUtils::deinitFont();
free(screenBuffer);
return result;
}

View File

@ -36,3 +36,5 @@ int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, c
nn::act::SlotNo handleAccountSelectScreen(const std::vector<std::shared_ptr<AccountInfo>> &data);
void handleUpdateWarningScreen();
bool handleDiscInsertScreen(uint64_t expectedTitleId, uint64_t *titleIdToLaunch);

View File

@ -1,6 +1,7 @@
#include <malloc.h>
#include "BootUtils.h"
#include "MenuUtils.h"
#include "QuickStartUtils.h"
#include "logger.h"
@ -124,8 +125,6 @@ bool getQuickBoot() {
return false;
}
DEBUG_FUNCTION_LINE("Trying to autoboot for titleId %016llX", info.titleId);
if (info.titleId == 0x0005001010040000L ||
info.titleId == 0x0005001010040100L ||
info.titleId == 0x0005001010040200L) {
@ -207,21 +206,36 @@ bool getQuickBoot() {
return true;
}
if (!SYSCheckTitleExists(info.titleId)) {
DEBUG_FUNCTION_LINE("Title %016llX doesn't exist", info.titleId);
return false;
uint64_t titleIdToLaunch = info.titleId;
switch (info.mediaType) {
case nn::sl::NN_SL_MEDIA_TYPE_ODD: {
if (!handleDiscInsertScreen(titleIdToLaunch, &titleIdToLaunch)) {
DEBUG_FUNCTION_LINE("Launch Wii U Menu!");
return false;
}
break;
}
default: {
if (!SYSCheckTitleExists(titleIdToLaunch)) {
DEBUG_FUNCTION_LINE("Title %016llX doesn't exist", titleIdToLaunch);
return false;
}
}
}
MCPTitleListType titleInfo;
int32_t handle = MCP_Open();
auto err = MCP_GetTitleInfo(handle, info.titleId, &titleInfo);
auto err = MCP_GetTitleInfo(handle, titleIdToLaunch, &titleInfo);
MCP_Close(handle);
if (err == 0) {
DEBUG_FUNCTION_LINE("Launch %016llX", titleIdToLaunch);
ACPAssignTitlePatch(&titleInfo);
_SYSLaunchTitleWithStdArgsInNoSplash(info.titleId, nullptr);
_SYSLaunchTitleWithStdArgsInNoSplash(titleIdToLaunch, nullptr);
return true;
}
DEBUG_FUNCTION_LINE("Launch Wii U Menu!");
return false;
} else {
DEBUG_FUNCTION_LINE("No quick start");

33
source/utils.cpp Normal file
View File

@ -0,0 +1,33 @@
#include "logger.h"
#include <coreinit/mcp.h>
bool GetTitleIdOfDisc(uint64_t *titleId, bool *discPresent) {
if (discPresent) {
*discPresent = false;
}
alignas(0x40) MCPTitleListType titles[4];
uint32_t count = 0;
int handle = MCP_Open();
if (handle < 0) {
DEBUG_FUNCTION_LINE_ERR("MCP_Open failed");
return false;
}
auto res = MCP_TitleListByDeviceType(handle, MCP_DEVICE_TYPE_ODD, &count, titles, sizeof(titles));
MCP_Close(handle);
if (res >= 0 && count > 0) {
if (discPresent) {
*discPresent = true;
}
for (uint32_t i = 0; i < count; i++) {
if ((titles[i].titleId & 0xFFFFFFFF00000000L) == (0x0005000000000000)) {
if (titleId) {
*titleId = titles[i].titleId;
}
return true;
}
}
}
return false;
}

View File

@ -18,3 +18,5 @@ template<class T, class... Args>
std::shared_ptr<T> make_shared_nothrow(Args &&...args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
return std::shared_ptr<T>(new (std::nothrow) T(std::forward<Args>(args)...));
}
bool GetTitleIdOfDisc(uint64_t *titleId, bool *discPresent);