mirror of
https://github.com/wiiu-env/launchiine.git
synced 2025-02-21 10:12:03 +01:00
Init nn::spm
This commit is contained in:
parent
5498bda9a9
commit
f0daf88b39
@ -1,42 +1,165 @@
|
|||||||
/****************************************************************************
|
|
||||||
* 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 "Application.h"
|
||||||
#include "common/common.h"
|
#include "common/common.h"
|
||||||
#include "resources/Resources.h"
|
#include "resources/Resources.h"
|
||||||
#include "utils/AsyncExecutor.h"
|
#include "utils/AsyncExecutor.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
|
#include "utils/SplashSoundPlayer.h"
|
||||||
#include <coreinit/core.h>
|
#include <coreinit/core.h>
|
||||||
#include <coreinit/foreground.h>
|
#include <coreinit/foreground.h>
|
||||||
#include <coreinit/title.h>
|
#include <coreinit/title.h>
|
||||||
#include <gui/FreeTypeGX.h>
|
#include <coreinit/thread.h>
|
||||||
#include <gui/VPadController.h>
|
#include "gui/FreeTypeGX.h"
|
||||||
#include <gui/WPadController.h>
|
#include "gui/VPadController.h"
|
||||||
#include <gui/memory.h>
|
#include "gui/WPadController.h"
|
||||||
#include <gui/sounds/SoundHandler.hpp>
|
#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 <proc_ui/procui.h>
|
||||||
|
#include <sysapp/switch.h>
|
||||||
#include <sysapp/launch.h>
|
#include <sysapp/launch.h>
|
||||||
|
#include <sysapp/title.h>
|
||||||
|
#include <nsysuhs/uhs.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <nn/spm.h>
|
||||||
|
#include <nn/acp/save.h>
|
||||||
|
|
||||||
Application *Application::applicationInstance = nullptr;
|
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::exitApplication = false;
|
||||||
bool Application::quitRequest = false;
|
bool Application::quitRequest = false;
|
||||||
|
|
||||||
Application::Application()
|
Application::Application(): CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x800000), bgMusic(nullptr), video(nullptr), mainWindow(nullptr), fontSystem(nullptr), exitCode(0) {
|
||||||
: CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x800000), bgMusic(nullptr), video(nullptr), mainWindow(nullptr), fontSystem(nullptr), exitCode(0) {
|
|
||||||
controller[0] = new VPadController(GuiTrigger::CHANNEL_1);
|
controller[0] = new VPadController(GuiTrigger::CHANNEL_1);
|
||||||
controller[1] = new WPadController(GuiTrigger::CHANNEL_2);
|
controller[1] = new WPadController(GuiTrigger::CHANNEL_2);
|
||||||
controller[2] = new WPadController(GuiTrigger::CHANNEL_3);
|
controller[2] = new WPadController(GuiTrigger::CHANNEL_3);
|
||||||
@ -45,11 +168,13 @@ Application::Application()
|
|||||||
|
|
||||||
//! create bgMusic
|
//! create bgMusic
|
||||||
bgMusic = new GuiSound(Resources::GetFile("bgMusic.ogg"), Resources::GetFileSize("bgMusic.ogg"));
|
bgMusic = new GuiSound(Resources::GetFile("bgMusic.ogg"), Resources::GetFileSize("bgMusic.ogg"));
|
||||||
bgMusic->SetLoop(true);
|
bgMusic -> SetLoop(true);
|
||||||
bgMusic->Play();
|
bgMusic -> Play();
|
||||||
bgMusic->SetVolume(50);
|
bgMusic -> SetVolume(50);
|
||||||
|
|
||||||
AsyncExecutor::execute([] { DEBUG_FUNCTION_LINE("Hello"); });
|
AsyncExecutor::execute([] {
|
||||||
|
DEBUG_FUNCTION_LINE("Hello");
|
||||||
|
});
|
||||||
|
|
||||||
exitApplication = false;
|
exitApplication = false;
|
||||||
|
|
||||||
@ -62,7 +187,7 @@ Application::~Application() {
|
|||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Destroy controller");
|
DEBUG_FUNCTION_LINE("Destroy controller");
|
||||||
|
|
||||||
for (auto &i : controller) {
|
for (auto & i: controller) {
|
||||||
delete i;
|
delete i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +219,14 @@ void Application::quit(int32_t code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Application::fadeOut() {
|
void Application::fadeOut() {
|
||||||
GuiImage fadeOut(video->getTvWidth(), video->getTvHeight(), (GX2Color){0, 0, 0, 255});
|
GuiImage fadeOut(video->getTvWidth(), video->getTvHeight(), (GX2Color) {
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
255
|
||||||
|
});
|
||||||
|
|
||||||
|
glm::mat4 identityMatrix(1.0f);
|
||||||
|
|
||||||
for (int32_t i = 0; i < 255; i += 10) {
|
for (int32_t i = 0; i < 255; i += 10) {
|
||||||
if (i > 255)
|
if (i > 255)
|
||||||
@ -103,30 +235,30 @@ void Application::fadeOut() {
|
|||||||
fadeOut.setAlpha(i / 255.0f);
|
fadeOut.setAlpha(i / 255.0f);
|
||||||
|
|
||||||
//! start rendering DRC
|
//! start rendering DRC
|
||||||
video->prepareDrcRendering();
|
video -> prepareDrcRendering();
|
||||||
mainWindow->drawDrc(video);
|
mainWindow -> drawDrc(video);
|
||||||
|
|
||||||
GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS);
|
GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS);
|
||||||
fadeOut.draw(video);
|
fadeOut.draw(video, identityMatrix);
|
||||||
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_LEQUAL);
|
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_LEQUAL);
|
||||||
|
|
||||||
video->drcDrawDone();
|
video -> drcDrawDone();
|
||||||
|
|
||||||
//! start rendering TV
|
//! start rendering TV
|
||||||
video->prepareTvRendering();
|
video -> prepareTvRendering();
|
||||||
|
|
||||||
mainWindow->drawTv(video);
|
mainWindow -> drawTv(video);
|
||||||
|
|
||||||
GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS);
|
GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS);
|
||||||
fadeOut.draw(video);
|
fadeOut.draw(video, identityMatrix);
|
||||||
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_LEQUAL);
|
GX2SetDepthOnlyControl(GX2_ENABLE, GX2_ENABLE, GX2_COMPARE_FUNC_LEQUAL);
|
||||||
|
|
||||||
video->tvDrawDone();
|
video -> tvDrawDone();
|
||||||
|
|
||||||
//! as last point update the effects as it can drop elements
|
//! as last point update the effects as it can drop elements
|
||||||
mainWindow->updateEffects();
|
mainWindow -> updateEffects();
|
||||||
|
|
||||||
video->waitForVSync();
|
video -> waitForVSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,8 +276,8 @@ bool Application::procUI() {
|
|||||||
DEBUG_FUNCTION_LINE("PROCUI_STATUS_RELEASE_FOREGROUND");
|
DEBUG_FUNCTION_LINE("PROCUI_STATUS_RELEASE_FOREGROUND");
|
||||||
if (video != nullptr) {
|
if (video != nullptr) {
|
||||||
// we can turn ofF 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(true);
|
video -> tvEnable(true);
|
||||||
video->drcEnable(true);
|
video -> drcEnable(true);
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("delete fontSystem");
|
DEBUG_FUNCTION_LINE("delete fontSystem");
|
||||||
delete fontSystem;
|
delete fontSystem;
|
||||||
@ -172,16 +304,16 @@ bool Application::procUI() {
|
|||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Initialize video");
|
DEBUG_FUNCTION_LINE("Initialize video");
|
||||||
video = new CVideo(GX2_TV_SCAN_MODE_720P, GX2_DRC_RENDER_MODE_SINGLE);
|
video = new CVideo(GX2_TV_SCAN_MODE_720P, GX2_DRC_RENDER_MODE_SINGLE);
|
||||||
DEBUG_FUNCTION_LINE("Video size %i x %i", video->getTvWidth(), video->getTvHeight());
|
DEBUG_FUNCTION_LINE("Video size %i x %i", video -> getTvWidth(), video -> getTvHeight());
|
||||||
|
|
||||||
//! setup default Font
|
//! setup default Font
|
||||||
DEBUG_FUNCTION_LINE("Initialize main font system");
|
DEBUG_FUNCTION_LINE("Initialize main font system");
|
||||||
auto *fontSystem = new FreeTypeGX(Resources::GetFile("font.ttf"), Resources::GetFileSize("font.ttf"), true);
|
auto * fontSystem = new FreeTypeGX(Resources::GetFile("font.ttf"), Resources::GetFileSize("font.ttf"), true);
|
||||||
GuiText::setPresetFont(fontSystem);
|
GuiText::setPresetFont(fontSystem);
|
||||||
|
|
||||||
if (mainWindow == nullptr) {
|
if (mainWindow == nullptr) {
|
||||||
DEBUG_FUNCTION_LINE("Initialize main window");
|
DEBUG_FUNCTION_LINE("Initialize main window");
|
||||||
mainWindow = new MainWindow(video->getTvWidth(), video->getTvHeight());
|
mainWindow = new MainWindow(video -> getTvWidth(), video -> getTvHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
executeProcess = true;
|
executeProcess = true;
|
||||||
@ -205,43 +337,43 @@ void Application::executeThread() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mainWindow->lockGUI();
|
mainWindow -> lockGUI();
|
||||||
mainWindow->process();
|
mainWindow -> process();
|
||||||
|
|
||||||
//! Read out inputs
|
//! Read out inputs
|
||||||
for (auto &i : controller) {
|
for (auto & i: controller) {
|
||||||
if (!i->update(video->getTvWidth(), video->getTvHeight()))
|
if (!i -> update(video -> getTvWidth(), video -> getTvHeight()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//! update controller states
|
//! update controller states
|
||||||
mainWindow->update(i);
|
mainWindow -> update(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! start rendering DRC
|
//! start rendering DRC
|
||||||
video->prepareDrcRendering();
|
video -> prepareDrcRendering();
|
||||||
mainWindow->drawDrc(video);
|
mainWindow -> drawDrc(video);
|
||||||
video->drcDrawDone();
|
video -> drcDrawDone();
|
||||||
|
|
||||||
//! start rendering TV
|
//! start rendering TV
|
||||||
video->prepareTvRendering();
|
video -> prepareTvRendering();
|
||||||
mainWindow->drawTv(video);
|
mainWindow -> drawTv(video);
|
||||||
video->tvDrawDone();
|
video -> tvDrawDone();
|
||||||
|
|
||||||
//! enable screen after first frame render
|
//! enable screen after first frame render
|
||||||
if (video->getFrameCount() == 0) {
|
if (video -> getFrameCount() == 0) {
|
||||||
video->tvEnable(true);
|
video -> tvEnable(true);
|
||||||
video->drcEnable(true);
|
video -> drcEnable(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! as last point update the effects as it can drop elements
|
//! as last point update the effects as it can drop elements
|
||||||
mainWindow->updateEffects();
|
mainWindow -> updateEffects();
|
||||||
mainWindow->unlockGUI();
|
mainWindow -> unlockGUI();
|
||||||
|
|
||||||
video->waitForVSync();
|
video -> waitForVSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bgMusic) {
|
if (bgMusic) {
|
||||||
bgMusic->SetVolume(0);
|
bgMusic -> SetVolume(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("delete mainWindow");
|
DEBUG_FUNCTION_LINE("delete mainWindow");
|
||||||
@ -258,4 +390,5 @@ void Application::executeThread() {
|
|||||||
|
|
||||||
DEBUG_FUNCTION_LINE("deinitialize memory");
|
DEBUG_FUNCTION_LINE("deinitialize memory");
|
||||||
libgui_memoryRelease();
|
libgui_memoryRelease();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user