Display an error screen with print-console instead of using fatalSimple. Display a msgbox in launchFile() when an error occurs instead of using fatalSimple. Better error handling etc in worker/launch.
This commit is contained in:
parent
11dccb4fd0
commit
59e2d7a306
@ -221,6 +221,11 @@ const char* const g_strings[StrId_Max][16] =
|
||||
STR_TW("程式執行時發生錯誤:"),
|
||||
},
|
||||
|
||||
[StrId_AppLaunchError] =
|
||||
{
|
||||
STR_EN("Failed to launch the application:"),
|
||||
},
|
||||
|
||||
[StrId_AppInfo_Author] =
|
||||
{
|
||||
STR_EN("Author"),
|
||||
|
@ -15,6 +15,7 @@ typedef enum
|
||||
StrId_NoAppsFound_Msg,
|
||||
|
||||
StrId_LastLoadResult,
|
||||
StrId_AppLaunchError,
|
||||
|
||||
StrId_AppInfo_Author,
|
||||
StrId_AppInfo_Version,
|
||||
|
@ -16,7 +16,7 @@ typedef struct
|
||||
//void (* useTitle)(u64 tid, u8 mediatype);
|
||||
} loaderFuncs_s;
|
||||
|
||||
void launchInit(void);
|
||||
bool launchInit(void);
|
||||
void launchExit(void);
|
||||
const loaderFuncs_s* launchGetLoader(void);
|
||||
size_t launchAddArg(argData_s* ad, const char* arg);
|
||||
|
@ -8,7 +8,7 @@ static int s_textLang = SetLanguage_ENUS;
|
||||
static int s_textLang = 1;
|
||||
#endif
|
||||
|
||||
void textInit(void) {
|
||||
Result textInit(void) {
|
||||
#ifdef __SWITCH__
|
||||
s32 Language=0;
|
||||
|
||||
@ -19,11 +19,13 @@ void textInit(void) {
|
||||
if (R_SUCCEEDED(rc)) rc = setMakeLanguage(s_textLanguageCode, &Language);
|
||||
//if (R_SUCCEEDED(rc) && Language < 16) s_textLang = Language;//TODO: Re-enable this once language.c supports all used languages.
|
||||
setExit();
|
||||
if (R_FAILED(rc)) fatalSimple(-8);
|
||||
if (R_FAILED(rc)) return rc;
|
||||
#else
|
||||
s_textLang = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int textGetLang(void) {
|
||||
return s_textLang;
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include "common.h"
|
||||
#include "language.h"
|
||||
|
||||
void textInit(void);
|
||||
Result textInit(void);
|
||||
int textGetLang(void);
|
||||
const char* textGetString(StrId id);
|
||||
u64 textGetLanguageCode(void);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "worker.h"
|
||||
|
||||
static bool s_workerInitialized = 0;
|
||||
static thrd_t s_workerThread;
|
||||
static cnd_t s_workerCdn;
|
||||
static mtx_t s_workerMtx;
|
||||
@ -31,18 +32,33 @@ static int workerThreadProc(void* unused)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void workerInit(void)
|
||||
bool workerInit(void)
|
||||
{
|
||||
cnd_init(&s_workerCdn);
|
||||
mtx_init(&s_workerMtx, mtx_plain);
|
||||
if (s_workerInitialized) return 1;
|
||||
|
||||
thrd_create(&s_workerThread, workerThreadProc, 0);
|
||||
if (cnd_init(&s_workerCdn) != thrd_success) return 0;
|
||||
if (mtx_init(&s_workerMtx, mtx_plain) != thrd_success) {
|
||||
cnd_destroy(&s_workerCdn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (thrd_create(&s_workerThread, workerThreadProc, 0) != thrd_success) {
|
||||
mtx_destroy(&s_workerMtx);
|
||||
cnd_destroy(&s_workerCdn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s_workerInitialized = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void workerExit(void)
|
||||
{
|
||||
int res=0;
|
||||
|
||||
if (!s_workerInitialized) return;
|
||||
s_workerInitialized = 0;
|
||||
|
||||
mtx_lock(&s_workerMtx);
|
||||
s_workerParam.exit = true;
|
||||
cnd_signal(&s_workerCdn);
|
||||
@ -55,6 +71,8 @@ void workerExit(void)
|
||||
|
||||
void workerSchedule(workerThreadFunc func, void* data)
|
||||
{
|
||||
if (!s_workerInitialized) return;
|
||||
|
||||
mtx_lock(&s_workerMtx);
|
||||
s_workerParam.func = func;
|
||||
s_workerParam.data = data;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include "common.h"
|
||||
|
||||
void workerInit(void);
|
||||
bool workerInit(void);
|
||||
void workerExit(void);
|
||||
void workerSchedule(workerThreadFunc func, void* data);
|
||||
|
@ -53,6 +53,7 @@ static void deinit(void)
|
||||
|
||||
static void launchFile(const char* path, argData_s* args)
|
||||
{
|
||||
char msg[256];
|
||||
/*if (strncmp(path, "sdmc:/",6) == 0)
|
||||
path += 5;*/
|
||||
memset(argBuf, 0, sizeof(argBuf));
|
||||
@ -68,9 +69,15 @@ static void launchFile(const char* path, argData_s* args)
|
||||
init_args(argBuf, sizeof(argBuf)-1, args->buf, sizeof(args->buf));
|
||||
|
||||
Result rc = envSetNextLoad(path, argBuf);
|
||||
if(R_FAILED(rc)) {
|
||||
memset(msg, 0, sizeof(msg));
|
||||
snprintf(msg, sizeof(msg)-1, "%s\n0x%x", textGetString(StrId_AppLaunchError), rc);
|
||||
|
||||
if(R_FAILED(rc)) fatalSimple(rc);//TODO: How should failing be handled?
|
||||
uiExitLoop();
|
||||
menuCreateMsgBox(780, 300, msg);
|
||||
}
|
||||
else {
|
||||
uiExitLoop();
|
||||
}
|
||||
}
|
||||
|
||||
const loaderFuncs_s loader_builtin =
|
||||
|
143
nx_main/main.c
143
nx_main/main.c
@ -8,6 +8,8 @@
|
||||
uint8_t* g_framebuf;
|
||||
u32 g_framebuf_width;
|
||||
|
||||
bool menuUpdateErrorScreen(void);
|
||||
|
||||
#ifdef PERF_LOG
|
||||
u64 g_tickdiff_vsync=0;
|
||||
u64 g_tickdiff_frame=0;
|
||||
@ -18,82 +20,144 @@ void audio_initialize(void);
|
||||
void audio_exit(void);
|
||||
#endif
|
||||
|
||||
extern u32 __nx_applet_exit_mode;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
bool error_screen=0;
|
||||
Result lastret=0;
|
||||
Result rc=0;
|
||||
char msg[256];
|
||||
char errormsg[256];//Can't use StrId for these error messages since it would be unavailable if textInit fails.
|
||||
|
||||
#ifdef PERF_LOG
|
||||
u64 start_tick=0;
|
||||
#endif
|
||||
|
||||
gfxInitDefault();
|
||||
memset(errormsg, 0, sizeof(errormsg));
|
||||
|
||||
appletSetScreenShotPermission(1);
|
||||
|
||||
ColorSetId theme;
|
||||
rc = setsysInitialize();
|
||||
if (R_FAILED(rc)) fatalSimple(-5);
|
||||
if (R_FAILED(rc)) snprintf(errormsg, sizeof(errormsg)-1, "Error: setsysInitialize() failed: 0x%x.", rc);
|
||||
|
||||
setsysGetColorSetId(&theme);
|
||||
if (R_SUCCEEDED(rc)) setsysGetColorSetId(&theme);
|
||||
|
||||
rc = plInitialize();
|
||||
if (R_FAILED(rc)) fatalSimple(-6);
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
rc = plInitialize();
|
||||
if (R_FAILED(rc)) snprintf(errormsg, sizeof(errormsg)-1, "Error: plInitialize() failed: 0x%x.", rc);
|
||||
}
|
||||
|
||||
menuStartupPath();
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
rc = textInit();
|
||||
if (R_FAILED(rc)) {
|
||||
snprintf(errormsg, sizeof(errormsg)-1, "Error: textInit() failed: 0x%x.", rc);
|
||||
}
|
||||
}
|
||||
|
||||
themeStartup((ThemePreset)theme);
|
||||
textInit();
|
||||
powerInit();
|
||||
workerInit();
|
||||
menuStartup();
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
menuStartupPath();
|
||||
|
||||
launchInit();
|
||||
if (!fontInitialize()) fatalSimple(-7);
|
||||
themeStartup((ThemePreset)theme);
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc)) powerInit();
|
||||
|
||||
if (R_SUCCEEDED(rc) && !workerInit()) {
|
||||
rc = 1;
|
||||
snprintf(errormsg, sizeof(errormsg)-1, "Error: workerInit() failed.");
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc)) menuStartup();
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
if (!launchInit()) {
|
||||
rc = 2;
|
||||
snprintf(errormsg, sizeof(errormsg)-1, "Error: launchInit() failed.");
|
||||
}
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc) && !fontInitialize()) {
|
||||
rc = 3;
|
||||
snprintf(errormsg, sizeof(errormsg)-1, "Error: fontInitialize() failed.");
|
||||
}
|
||||
|
||||
#ifdef ENABLE_AUDIO
|
||||
audio_initialize();
|
||||
if (R_SUCCEEDED(rc)) audio_initialize();
|
||||
#endif
|
||||
|
||||
lastret = envGetLastLoadResult();
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
lastret = envGetLastLoadResult();
|
||||
|
||||
if (R_FAILED(lastret)) {
|
||||
memset(msg, 0, sizeof(msg));
|
||||
snprintf(msg, sizeof(msg)-1, "%s\n0x%x", textGetString(StrId_LastLoadResult), lastret);
|
||||
if (R_FAILED(lastret)) {
|
||||
memset(msg, 0, sizeof(msg));
|
||||
snprintf(msg, sizeof(msg)-1, "%s\n0x%x", textGetString(StrId_LastLoadResult), lastret);
|
||||
|
||||
menuCreateMsgBox(780, 300, msg);
|
||||
menuCreateMsgBox(780, 300, msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (errormsg[0]) error_screen = 1;
|
||||
|
||||
if (!error_screen) {
|
||||
gfxInitDefault();
|
||||
}
|
||||
else {
|
||||
consoleInit(NULL);
|
||||
printf("%s\n", errormsg);
|
||||
printf("Press the + button to exit.\n");
|
||||
}
|
||||
|
||||
#ifdef PERF_LOG
|
||||
gfxWaitForVsync();
|
||||
if (!error_screen) {
|
||||
gfxWaitForVsync();
|
||||
|
||||
start_tick = svcGetSystemTick();
|
||||
gfxWaitForVsync();
|
||||
g_tickdiff_vsync = svcGetSystemTick() - start_tick;
|
||||
start_tick = svcGetSystemTick();
|
||||
gfxWaitForVsync();
|
||||
g_tickdiff_vsync = svcGetSystemTick() - start_tick;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (appletMainLoop())
|
||||
{
|
||||
#ifdef PERF_LOG
|
||||
start_tick = svcGetSystemTick();
|
||||
if (!error_screen) start_tick = svcGetSystemTick();
|
||||
#endif
|
||||
|
||||
//Scan all the inputs. This should be done once for each frame
|
||||
hidScanInput();
|
||||
|
||||
g_framebuf = gfxGetFramebuffer(&g_framebuf_width, NULL);
|
||||
memset(g_framebuf, 237, gfxGetFramebufferSize());
|
||||
if (!uiUpdate()) break;
|
||||
menuLoop();
|
||||
if (!error_screen) {
|
||||
g_framebuf = gfxGetFramebuffer(&g_framebuf_width, NULL);
|
||||
memset(g_framebuf, 237, gfxGetFramebufferSize());
|
||||
if (!uiUpdate()) break;
|
||||
menuLoop();
|
||||
}
|
||||
else {
|
||||
if (menuUpdateErrorScreen()) break;
|
||||
}
|
||||
|
||||
gfxFlushBuffers();
|
||||
if (!error_screen) {
|
||||
gfxFlushBuffers();
|
||||
|
||||
#ifdef PERF_LOG
|
||||
g_tickdiff_frame = svcGetSystemTick() - start_tick;
|
||||
#endif
|
||||
#ifdef PERF_LOG
|
||||
g_tickdiff_frame = svcGetSystemTick() - start_tick;
|
||||
#endif
|
||||
|
||||
gfxSwapBuffers();
|
||||
gfxSwapBuffers();
|
||||
}
|
||||
else {
|
||||
consoleUpdate(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!error_screen) {
|
||||
gfxExit();
|
||||
}
|
||||
else {
|
||||
consoleExit(NULL);
|
||||
__nx_applet_exit_mode = 1;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_AUDIO
|
||||
@ -107,7 +171,6 @@ int main(int argc, char **argv)
|
||||
plExit();
|
||||
setsysExit();
|
||||
|
||||
gfxExit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -154,3 +217,15 @@ bool menuUpdate(void) {
|
||||
|
||||
return exitflag;
|
||||
}
|
||||
|
||||
bool menuUpdateErrorScreen(void) {
|
||||
bool exitflag = 0;
|
||||
u32 down = hidKeysDown(CONTROLLER_P1_AUTO);
|
||||
|
||||
if (down & KEY_PLUS)
|
||||
{
|
||||
exitflag = 1;
|
||||
}
|
||||
|
||||
return exitflag;
|
||||
}
|
||||
|
@ -2,25 +2,27 @@
|
||||
|
||||
static const loaderFuncs_s* s_loader;
|
||||
|
||||
void launchInit(void) {
|
||||
bool launchInit(void) {
|
||||
#define ADD_LOADER(_name) do \
|
||||
{ \
|
||||
extern const loaderFuncs_s _name; \
|
||||
if (_name.init()) \
|
||||
{ \
|
||||
s_loader = &_name; \
|
||||
return; \
|
||||
return 1; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
ADD_LOADER(loader_builtin);
|
||||
|
||||
// Shouldn't happen
|
||||
fatalSimple(-1);//TODO: What value should be used for this?
|
||||
s_loader = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void launchExit(void) {
|
||||
s_loader->deinit();
|
||||
if (s_loader) s_loader->deinit();
|
||||
s_loader = NULL;
|
||||
}
|
||||
|
||||
const loaderFuncs_s* launchGetLoader(void) {
|
||||
@ -71,5 +73,6 @@ void launchMenuEntry(menuEntry_s* me) {
|
||||
descriptorScanFile(&me->descriptor, me->path);*/
|
||||
|
||||
// Launch it
|
||||
if (s_loader == NULL) return;
|
||||
s_loader->launchFile(me->path, &me->args);
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
static const loaderFuncs_s* s_loader;
|
||||
|
||||
void launchInit(void) {
|
||||
|
||||
bool launchInit(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void launchExit(void) {
|
||||
|
Loading…
Reference in New Issue
Block a user