Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize nn::spm #26

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM wiiuenv/devkitppc:20211229
FROM ghcr.io/wiiu-env/devkitppc:20240704

COPY --from=wiiuenv/libgui:20220109 /artifacts $DEVKITPRO
COPY --from=wiiuenv/libgui:2022020513505562e265 /artifacts $DEVKITPRO

WORKDIR project
WORKDIR project
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ CFLAGS := -g -Wall -O2 -ffunction-sections \

CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__

CXXFLAGS := $(CFLAGS)
CXXFLAGS := $(CFLAGS) -std=c++20

ASFLAGS := -g $(ARCH)
LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ A simple Wii U Menu replacement, still in early development and not ready for a
## Known Issues
- Random crashes
- The Keyboard input is implemented, but result is ignored.
- nn::spm is not initalized and no quick start menu support. For the it's relying on the [AutobootModule](https://github.com/wiiu-env/AutobootModule) doing this.
- `nn::spm` is not initalized and no quick start menu support. For the it's relying on the [AutobootModule](https://github.com/wiiu-env/AutobootModule) doing this.
- No sound on splash screen.
- Probably a lot more

Expand All @@ -23,7 +23,7 @@ A simple Wii U Menu replacement, still in early development and not ready for a
- Display applets like the original Wii U Menu
- Implement Account selection when no default account is set.
- Implement update check/no way to update games
- Properly implement nn::spm and nn:sl (external storage and quick start menu)
- Properly implement `nn::spm` and `nn::sl` (external storage and quick start menu)
- Fix search
- Implement all the other stuff the Wii U Menu offers (Account creationg, switching between Accounts, set default account etc.)
- Implement ways to launch the original Wii U Menu.
Expand Down
167 changes: 145 additions & 22 deletions src/Application.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,3 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "Application.h"
#include "common/common.h"
#include "resources/Resources.h"
Expand All @@ -22,15 +6,154 @@
#include <coreinit/core.h>
#include <coreinit/foreground.h>
#include <coreinit/title.h>
#include <gui/FreeTypeGX.h>
#include <gui/VPadController.h>
#include <gui/WPadController.h>
#include <gui/memory.h>
#include <gui/sounds/SoundHandler.hpp>
#include <coreinit/thread.h>
#include "gui/FreeTypeGX.h"
#include "gui/VPadController.h"
#include "gui/WPadController.h"
#include "gui/memory.h"
#include "gui/sounds/SoundHandler.hpp"
#include <glm/mat4x4.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <proc_ui/procui.h>
#include <sysapp/switch.h>
#include <sysapp/launch.h>
#include <sysapp/title.h>
#include <nsysuhs/uhs.h>
#include <thread>
#include <malloc.h>
#include <nn/spm.h>
#include <nn/acp/save.h>

static void InitEmptyExternalStorage() {
DEBUG_FUNCTION_LINE("Fallback to empty ExtendedStorage");
nn::spm::VolumeId empty{};
nn::spm::SetDefaultExtendedStorageVolumeId(empty);

nn::spm::StorageIndex storageIndex = 0;
nn::spm::SetExtendedStorage(&storageIndex);
}

static int numberUSBStorageDevicesConnected() {
DEBUG_FUNCTION_LINE("Check if USB Storage is connected");
auto *handle = (UhsHandle *) memalign(0x40, sizeof(UhsHandle));
if (!handle) {
return -1;
}
memset(handle, 0, sizeof(UhsHandle));
auto *config = (UhsConfig *) memalign(0x40, sizeof(UhsConfig));
if (!config) {
free(handle);
return -2;
}
memset(config, 0, sizeof(UhsConfig));

config->controller_num = 0;
uint32_t size = 5120;
void *buffer = memalign(0x40, size);
if (!buffer) {
free(handle);
free(config);
return -3;
}
memset(buffer, 0, size);

config->buffer = buffer;
config->buffer_size = size;

if (UhsClientOpen(handle, config) != UHS_STATUS_OK) {
DEBUG_FUNCTION_LINE("UhsClient failed");
free(handle);
free(config);
free(buffer);
return -4;
}

UhsInterfaceProfile profiles[10];
UhsInterfaceFilter filter = {
.match_params = MATCH_ANY};

UHSStatus result;
if ((result = UhsQueryInterfaces(handle, &filter, profiles, 10)) <= UHS_STATUS_OK) {
DEBUG_FUNCTION_LINE("UhsQueryInterfaces failed");
UhsClientClose(handle);
free(handle);
free(config);
free(buffer);
return -5;
}

auto found = 0;
for (int i = 0; i < (int) result; i++) {
if (profiles[i].if_desc.bInterfaceClass == USBCLASS_STORAGE) {
DEBUG_FUNCTION_LINE("Found USBCLASS_STORAGE");
found++;
}
}

UhsClientClose(handle);
free(handle);
free(config);
free(buffer);
return found;
}

void initExternalStorage() {
if (OSGetTitleID() == _SYSGetSystemApplicationTitleId(SYSTEM_APP_ID_MII_MAKER)) {
// nn::spm functions always call OSFatal when they fail, so we make sure have permission to use
// the lib before actually using it.
return;
}
int numConnectedStorage;
int maxTries = 1200; // Wait up to 20 seconds, like the Wii U Menu
if ((numConnectedStorage = numberUSBStorageDevicesConnected()) <= 0) {
maxTries = 1; // Only try once if no USBStorageDrive is connected
} else {
DEBUG_FUNCTION_LINE("Connected StorageDevices = %d", numConnectedStorage);
}

nn::spm::Initialize();

nn::spm::StorageListItem items[0x20];
int tries = 0;
bool found = false;

while (tries < maxTries) {
int32_t numItems = nn::spm::GetStorageList(items, 0x20);

DEBUG_FUNCTION_LINE("Number of items: %d", numItems);

for (int32_t i = 0; i < numItems; i++) {
if (items[i].type == nn::spm::STORAGE_TYPE_WFS) {
nn::spm::StorageInfo info{};
if (nn::spm::GetStorageInfo(&info, &items[i].index) == 0) {
DEBUG_FUNCTION_LINE("Using %s for extended storage", info.path);

nn::spm::SetExtendedStorage(&items[i].index);
ACPMountExternalStorage();

nn::spm::SetDefaultExtendedStorageVolumeId(info.volumeId);

found = true;
break;
}
}
}
if (found || (numConnectedStorage == numItems)) {
DEBUG_FUNCTION_LINE("Found all expected items, breaking.");
break;
}
OSSleepTicks(OSMillisecondsToTicks(16));
tries++;
}
if (!found) {
if (numConnectedStorage > 0) {
DEBUG_FUNCTION_LINE("USB Storage is connected but either it doesn't have a WFS partition or we ran into a timeout.");
}
InitEmptyExternalStorage();
}

nn::spm::Finalize();
}
Application *Application::applicationInstance = nullptr;
bool Application::exitApplication = false;
bool Application::quitRequest = false;
Expand Down Expand Up @@ -258,4 +381,4 @@ void Application::executeThread() {

DEBUG_FUNCTION_LINE("deinitialize memory");
libgui_memoryRelease();
}
}
35 changes: 10 additions & 25 deletions src/Application.h
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#ifndef _APPLICATION_H
#define _APPLICATION_H

#include "menu/MainWindow.h"
#include "system/CThread.h"
#include <gui/video/CVideo.h>
#include "gui/video/CVideo.h"

// forward declaration
class FreeTypeGX;

class Application : public CThread {
public:
Application();

virtual ~Application();

static Application *applicationInstance;
static bool exitApplication;
static bool quitRequest;

static Application *instance() {
if (!applicationInstance)
applicationInstance = new Application();
Expand Down Expand Up @@ -58,16 +50,9 @@ class Application : public CThread {
void quit(int code);

private:
Application();

virtual ~Application();

bool procUI(void);

static Application *applicationInstance;
static bool exitApplication;
static bool quitRequest;

void executeThread(void);

GuiSound *bgMusic;
Expand All @@ -79,4 +64,4 @@ class Application : public CThread {
BOOL sFromHBL = FALSE;
};

#endif //_APPLICATION_H
#endif //_APPLICATION_H
30 changes: 6 additions & 24 deletions src/menu/MainWindow.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
/****************************************************************************
* Copyright (C) 2015 Dimok
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include "MainWindow.h"
#include "Application.h"
#include "utils/StringTools.h"
#include "utils/logger.h"

#include "GameSplashScreen.h"
#include "gui/GuiIconGrid.h"
#include "gui/GuiTitleBrowser.h"
Expand All @@ -27,7 +10,9 @@
#include <coreinit/title.h>
#include <future>
#include <nn/acp/title.h>
#include <sysapp/args.h>
#include <sysapp/launch.h>
#include <sysapp/switch.h>

MainWindow::MainWindow(int32_t w, int32_t h)
: width(w), height(h), gameClickSound(Resources::GetSound("game_click.mp3")), mainSwitchButtonFrame(nullptr), currentTvFrame(nullptr), currentDrcFrame(nullptr) {
Expand Down Expand Up @@ -401,9 +386,6 @@ void MainWindow::OnGameLaunchSplashScreenFinished(GuiElement *element, gameInfo
}
}

extern "C" int32_t SYSSwitchToBrowser(void *);
extern "C" int32_t SYSSwitchToEShop(void *);
extern "C" int32_t _SYSSwitchTo(uint32_t pfid);

void MainWindow::OnGameLaunch(uint64_t titleId) {
DEBUG_FUNCTION_LINE("Launch GAME!!");
Expand Down Expand Up @@ -434,28 +416,28 @@ void MainWindow::OnGameLaunch(uint64_t titleId) {
titleId == 0x000500301001810AL ||
titleId == 0x000500301001820AL) {
DEBUG_FUNCTION_LINE("Launching the Download Management");
_SYSSwitchTo(12);
_SYSSwitchTo(SYSAPP_PFID_DOWNLOAD_MANAGEMENT);
return;
}
if (titleId == 0x000500301001600AL ||
titleId == 0x000500301001610AL ||
titleId == 0x000500301001620AL) {
DEBUG_FUNCTION_LINE("Launching Miiverse");
_SYSSwitchTo(9);
_SYSSwitchTo(SYSAPP_PFID_MIIVERSE);
return;
}
if (titleId == 0x000500301001500AL ||
titleId == 0x000500301001510AL ||
titleId == 0x000500301001520AL) {
DEBUG_FUNCTION_LINE("Launching Friendlist");
_SYSSwitchTo(11);
_SYSSwitchTo(SYSAPP_PFID_FRIENDLIST);
return;
}
if (titleId == 0x000500301001300AL ||
titleId == 0x000500301001310AL ||
titleId == 0x000500301001320AL) {
DEBUG_FUNCTION_LINE("Launching TVii");
_SYSSwitchTo(3);
_SYSSwitchTo(SYSAPP_PFID_TVII);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion src/menu/MainWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#include "MainDrcButtonsFrame.h"
#include "game/GameList.h"
#include "gui/GuiTitleBrowser.h"
#include <gui/Gui.h>
#include "gui/Gui.h"
#include <queue>
#include <vector>

Expand Down