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:
yellows8 2018-10-18 19:05:53 -04:00
parent 11dccb4fd0
commit 59e2d7a306
11 changed files with 163 additions and 52 deletions

View File

@ -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"),

View File

@ -15,6 +15,7 @@ typedef enum
StrId_NoAppsFound_Msg,
StrId_LastLoadResult,
StrId_AppLaunchError,
StrId_AppInfo_Author,
StrId_AppInfo_Version,

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -1,6 +1,6 @@
#pragma once
#include "common.h"
void workerInit(void);
bool workerInit(void);
void workerExit(void);
void workerSchedule(workerThreadFunc func, void* data);

View File

@ -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 =

View File

@ -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;
}

View File

@ -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);
}

View File

@ -2,8 +2,8 @@
static const loaderFuncs_s* s_loader;
void launchInit(void) {
bool launchInit(void) {
return 1;
}
void launchExit(void) {