/* * This software is licensed under the terms of the MIT License. * See COPYING for further information. * --- * Copyright (c) 2019, p-sam . */ #include "arch_switch.h" #include "renderer/glcommon/debug.h" #include "util/env.h" #include "util/io.h" #include #include #include #include #include #include #include #define NX_LOG_FMT(fmt, ...) tsfprintf(stdout, "[NX] " fmt "\n", ##__VA_ARGS__) #define NX_LOG(str) NX_LOG_FMT("%s", str) #define NX_SETENV(name, val) NX_LOG_FMT("Setting env var %s to %s", name, val);env_set_string(name, val, true) static nxAtExitFn g_nxAtExitFn = NULL; static char g_programDir[FS_MAX_PATH] = {0}; static AppletHookCookie g_hookCookie; static s32 g_initialScreenWidth = 1920; static s32 g_initialScreenHeight = 1080; static void onAppletHook(AppletHookType hook, void *param) { switch (hook) { case AppletHookType_OnExitRequest: NX_LOG("Got AppletHook OnExitRequest, exiting.\n"); taisei_quit(); break; default: break; } } attr_used void userAppInit(void) { socketInitializeDefault(); appletLockExit(); appletHook(&g_hookCookie, onAppletHook, NULL); #ifdef DEBUG dup2(1, 2); NX_LOG("stderr -> stdout"); nxlinkStdio(); NX_LOG("nxlink enabled"); #endif appletGetDefaultDisplayResolution(&g_initialScreenWidth, &g_initialScreenHeight); appletInitializeGamePlayRecording(); appletSetGamePlayRecordingState(1); getcwd(g_programDir, FS_MAX_PATH); if(glcommon_debug_requested()) { // enable Mesa logging: NX_SETENV("EGL_LOG_LEVEL", "debug"); NX_SETENV("MESA_VERBOSE", "all"); NX_SETENV("MESA_DEBUG", "1"); NX_SETENV("MESA_INFO", "1"); NX_SETENV("MESA_GLSL", "errors"); NX_SETENV("NOUVEAU_MESA_DEBUG", "1"); NX_SETENV("LIBGL_DEBUG", "verbose"); // enable shader debugging in Nouveau: NX_SETENV("NV50_PROG_OPTIMIZE", "0"); NX_SETENV("NV50_PROG_DEBUG", "1"); NX_SETENV("NV50_PROG_CHIPSET", "0x120"); } else { // disable error checking and save CPU time NX_SETENV("MESA_NO_ERROR", "1"); } } attr_used void userAppExit(void) { socketExit(); appletUnlockExit(); } int nxAtExit(nxAtExitFn fn) { if(g_nxAtExitFn == NULL) { NX_LOG("got exit callback"); g_nxAtExitFn = fn; return 0; } return -1; } void __attribute__((weak)) noreturn __libnx_exit(int rc); void noreturn nxExit(int rc) { if(g_nxAtExitFn != NULL) { NX_LOG("calling exit callback"); g_nxAtExitFn(); g_nxAtExitFn = NULL; } __libnx_exit(rc); } void noreturn nxAbort(void) { /* Using abort would not give us correct offsets in crash reports, * nor code region name, so we use __builtin_trap instead */ __builtin_trap(); } const char* nxGetProgramDir(void) { return g_programDir; } int nxGetInitialScreenWidth(void) { return g_initialScreenWidth; } int nxGetInitialScreenHeight(void) { return g_initialScreenHeight; }