Compare commits

...

7 Commits

Author SHA1 Message Date
Maschell 641c3adaa4
Merge branch 'main' into dependabot/github_actions/actions/checkout-4 2024-04-26 10:33:56 +02:00
Maschell f80e83dff9 Bump version 2024-04-25 17:59:25 +02:00
Maschell b245a71cdb Update github actions 2024-04-25 17:59:25 +02:00
Maschell 688b834d2a Improve LaunchInfoDatabase reading code 2024-04-25 17:59:25 +02:00
Maschell bf8d1a974d Add support for quick starting into homebrew titles 2024-04-25 17:59:25 +02:00
Maschell f313152874 Fix launching the system settings 2024-04-25 17:59:25 +02:00
Maschell f1a240ddbc Update .gitignore to ignore .zip files 2024-04-25 17:59:25 +02:00
7 changed files with 93 additions and 29 deletions

View File

@ -48,7 +48,7 @@ jobs:
- name: zip artifact
run: zip -r ${{ env.REPOSITORY_NAME }}_${{ env.DATETIME }}.zip *.rpx
- name: Create Release
uses: "softprops/action-gh-release@v1"
uses: "softprops/action-gh-release@v2"
with:
tag_name: ${{ env.REPOSITORY_NAME }}-${{ env.DATETIME }}
draft: false

1
.gitignore vendored
View File

@ -5,3 +5,4 @@ build/
.vscode/
cmake-build-debug/
CMakeLists.txt
*.zip

View File

@ -1,5 +1,6 @@
FROM ghcr.io/wiiu-env/devkitppc:20230621
FROM ghcr.io/wiiu-env/devkitppc:20240423
COPY --from=ghcr.io/wiiu-env/libmocha:20230621 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/librpxloader:20240425 /artifacts $DEVKITPRO
WORKDIR project

View File

@ -10,6 +10,8 @@ TOPDIR ?= $(CURDIR)
include $(DEVKITPRO)/wut/share/wut_rules
WUMS_ROOT := $(DEVKITPRO)/wums
#-------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
@ -36,7 +38,7 @@ CXXFLAGS := $(CFLAGS) -std=c++20 -fno-rtti
ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) $(RPXSPECS) --entry=_start -Wl,-Map,$(notdir $*.map)
LIBS := -lpng -lmocha -lwut -lz
LIBS := -lrpxloader -lpng -lmocha -lwut -lz
ifeq ($(DEBUG),1)
CXXFLAGS += -DDEBUG -g
@ -52,7 +54,7 @@ endif
# list of directories containing libraries, this must be the top level
# containing include and lib
#-------------------------------------------------------------------------------
LIBDIRS := $(PORTLIBS) $(WUT_ROOT) $(WUT_ROOT)/usr
LIBDIRS := $(PORTLIBS) $(WUMS_ROOT) $(WUT_ROOT) $(WUT_ROOT)/usr
#-------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional

View File

@ -18,7 +18,7 @@
#include <sysapp/title.h>
#include <vector>
#define AUTOBOOT_MODULE_VERSION "v0.2.0"
#define AUTOBOOT_MODULE_VERSION "v0.2.1"
const char *autoboot_config_strings[] = {
"wiiu_menu",

View File

@ -13,12 +13,17 @@
#include <nn/act/client_cpp.h>
#include <nn/ccr/sys_caffeine.h>
#include <nn/sl.h>
#include <optional>
#include <proc_ui/procui.h>
#include <rpxloader/rpxloader.h>
#include <sysapp/launch.h>
#include <sysapp/title.h>
extern "C" void __fini_wut();
#define UPPER_TITLE_ID_HOMEBREW 0x0005000F
#define TITLE_ID_HOMEBREW_MASK (((uint64_t) UPPER_TITLE_ID_HOMEBREW) << 32)
static void StartAppletAndExit() {
DEBUG_FUNCTION_LINE("Wait for applet");
ProcUIInit(OSSavesDone_ReadyToRelease);
@ -79,28 +84,65 @@ void loadConsoleAccount(const char *data_uuid) {
nn::act::Finalize();
}
class FileStreamWrapper {
public:
static std::unique_ptr<FileStreamWrapper> CreateFromPath(std::string_view path, std::string_view mode = "r") {
return std::unique_ptr<FileStreamWrapper>(new FileStreamWrapper(path, mode));
}
~FileStreamWrapper() {
mFileStream.reset();
FSDelClient(&mFsClient, FS_ERROR_FLAG_NONE);
}
nn::sl::details::IStreamBase &GetStream() {
return *mFileStream;
}
private:
explicit FileStreamWrapper(std::string_view path, std::string_view mode) {
FSAddClient(&mFsClient, FS_ERROR_FLAG_NONE);
FSInitCmdBlock(&mCmdBlock);
mFileStream = std::make_unique<nn::sl::FileStream>();
mFileStream->Initialize(&mFsClient, &mCmdBlock, path.data(), mode.data());
}
std::unique_ptr<nn::sl::FileStream> mFileStream{};
FSClient mFsClient{};
FSCmdBlock mCmdBlock{};
};
bool getQuickBoot() {
// Waits until the quick start menu has been closed. TODO: abort this checks after a given time?
auto bootCheck = CCRSysCaffeineBootCheck();
if (bootCheck == 0) {
nn::sl::Initialize(MEMAllocFromDefaultHeapEx, MEMFreeToDefaultHeap);
char path[0x80];
nn::sl::GetDefaultDatabasePath(path, 0x80, 0x0005001010066000); // ECO process
FSCmdBlock cmdBlock;
FSInitCmdBlock(&cmdBlock);
auto fileStream = new nn::sl::FileStream;
auto *fsClient = (FSClient *) memalign(0x40, sizeof(FSClient));
if (!fsClient) {
DEBUG_FUNCTION_LINE("Couldn't alloc memory for fsClient.");
return false;
nn::sl::LaunchInfoDatabase launchInfoDatabase;
nn::sl::LaunchInfo info;
{
// In theory the region doesn't even matter.
// The region is to load a "system table" into the LaunchInfoDatabase which provides the LaunchInfos for
// the Wii U Menu and System Settings. In the code below we check for all possible System Settings title id and
// have a fallback to the Wii U Menu... This means we could get away a wrong region, but let's use the correct one
// anyway
const auto region = []() {
if (SYSCheckTitleExists(0x0005001010047000L)) { // JPN System Settings
return nn::sl::REGION_JPN;
} else if (SYSCheckTitleExists(0x0005001010047100L)) { // USA System Settings
return nn::sl::REGION_USA;
} else if (SYSCheckTitleExists(0x0005001010047200L)) { // EUR System Settings
return nn::sl::REGION_EUR;
}
return nn::sl::REGION_EUR;
}();
auto fileStream = FileStreamWrapper::CreateFromPath(path);
if (launchInfoDatabase.Load(fileStream->GetStream(), region).IsFailure()) {
DEBUG_FUNCTION_LINE_ERR("Failed to load LaunchInfoDatabase");
return false;
}
}
memset(fsClient, 0, sizeof(*fsClient));
FSAddClient(fsClient, FS_ERROR_FLAG_NONE);
fileStream->Initialize(fsClient, &cmdBlock, path, "r");
auto database = new nn::sl::LaunchInfoDatabase;
database->Load(fileStream, nn::sl::REGION_EUR);
CCRAppLaunchParam data; // load sys caffeine data
// load app launch param
@ -108,15 +150,7 @@ bool getQuickBoot() {
loadConsoleAccount(data.uuid);
// get launch info for id
nn::sl::LaunchInfo info;
auto result = database->GetLaunchInfoById(&info, data.titleId);
delete database;
delete fileStream;
FSDelClient(fsClient, FS_ERROR_FLAG_NONE);
free(fsClient);
auto result = launchInfoDatabase.GetLaunchInfoById(&info, data.titleId);
nn::sl::Finalize();
@ -125,6 +159,17 @@ bool getQuickBoot() {
return false;
}
if ((info.titleId & TITLE_ID_HOMEBREW_MASK) == TITLE_ID_HOMEBREW_MASK) {
std::string homebrewPath = info.parameter;
DEBUG_FUNCTION_LINE("Trying to launch homebrew title: \"%s\"", homebrewPath.c_str());
if (auto err = RPXLoader_LaunchHomebrew(homebrewPath.c_str()); err != RPX_LOADER_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE_WARN("Failed to launch homebrew title: %s (%d)", RPXLoader_GetStatusStr(err), err);
return false;
}
return true;
}
if (info.titleId == 0x0005001010040000L ||
info.titleId == 0x0005001010040100L ||
info.titleId == 0x0005001010040200L) {
@ -132,6 +177,14 @@ bool getQuickBoot() {
return false;
}
if (info.titleId == 0x0005001010047000L ||
info.titleId == 0x0005001010047100L ||
info.titleId == 0x0005001010047200L) {
DEBUG_FUNCTION_LINE("Launch Settings");
_SYSLaunchSettings(nullptr);
return true;
}
if (info.titleId == 0x000500301001220AL ||
info.titleId == 0x000500301001210AL ||
info.titleId == 0x000500301001200AL) {

View File

@ -10,6 +10,7 @@
#include <gx2/state.h>
#include <malloc.h>
#include <mocha/mocha.h>
#include <rpxloader/rpxloader.h>
#include <sndcore2/core.h>
#include <string>
#include <sys/stat.h>
@ -50,6 +51,12 @@ int32_t main(int32_t argc, char **argv) {
OSFatal("AutobootModule: Mocha_InitLibrary failed");
}
// Use librpxloader.
RPXLoaderStatus error3;
if ((error3 = RPXLoader_InitLibrary()) != RPX_LOADER_RESULT_SUCCESS) {
DEBUG_FUNCTION_LINE("AutobootModule: Failed to init RPXLoader. This can be ignored when not running Aroma. Error %s [%d]", RPXLoader_GetStatusStr(error3), error3);
}
InputUtils::InputData buttons = InputUtils::getControllerInput();
FSAInit();