diff --git a/src/input/n3ds_input.cpp b/src/input/n3ds_input.cpp index 2079b548..f65a6151 100644 --- a/src/input/n3ds_input.cpp +++ b/src/input/n3ds_input.cpp @@ -22,9 +22,9 @@ #include <3ds.h> #include #include +#include #include #include -#include #define QUIT_BUTTONS (PLAY_FLAG | BACK_FLAG | LB_FLAG | RB_FLAG) #define TOUCH_GAMEPAD_BUTTONS (SPECIAL_FLAG | LS_CLK_FLAG | RS_CLK_FLAG) @@ -69,7 +69,8 @@ static void remove_gamepad() { LiSendMultiControllerEvent(0, ~activeGamepadMask, 0, 0, 0, 0, 0, 0, 0); } -void n3dsinput_init(N3dsTouchType touch_type, bool swap_face_buttons, bool swap_triggers_and_shoulders) { +void n3dsinput_init(N3dsTouchType touch_type, bool swap_face_buttons, + bool swap_triggers_and_shoulders) { hidInit(); HIDUSER_GetGyroscopeRawToDpsCoefficient(&gyro_coeff); add_gamepad(); @@ -85,10 +86,16 @@ void n3dsinput_init(N3dsTouchType touch_type, bool swap_face_buttons, bool swap_ SWAP_ZL = KEY_L; SWAP_ZR = KEY_R; } - touch_handler = std::make_unique(&gamepad_state, touch_type); + touch_handler = + std::make_unique(&gamepad_state, touch_type); } -void n3dsinput_cleanup() { remove_gamepad(); } +void n3dsinput_cleanup() { + remove_gamepad(); + gamepad_state = GAMEPAD_STATE(); + previous_state = GAMEPAD_STATE(); + touch_handler = nullptr; +} static inline int n3ds_to_li_button(u32 key_in, u32 key_n3ds, int key_li) { return ((key_in & key_n3ds) / key_n3ds) * key_li; diff --git a/src/n3ds_main.cpp b/src/n3ds_main.cpp index 39bc4fdc..4d5ba9c7 100644 --- a/src/n3ds_main.cpp +++ b/src/n3ds_main.cpp @@ -364,7 +364,7 @@ static void init_3ds() { static int prompt_for_app_id(PSERVER_DATA server) { PAPP_LIST list = NULL; if (gs_applist(server, &list) != GS_OK) { - fprintf(stderr, "Can't get app list\n"); + printf("Can't get app list\n"); return -1; } @@ -401,24 +401,23 @@ static void stream(PSERVER_DATA server, PCONFIGURATION config, int appId) { config->localaudio, gamepad_mask); if (ret < 0) { if (ret == GS_NOT_SUPPORTED_4K) - fprintf(stderr, "Server doesn't support 4K\n"); + printf("Server doesn't support 4K\n"); else if (ret == GS_NOT_SUPPORTED_MODE) - fprintf(stderr, - "Server doesn't support %dx%d (%d fps) or remove " - "--nounsupported option\n", - config->stream.width, config->stream.height, - config->stream.fps); + printf("Server doesn't support %dx%d (%d fps) or remove " + "--nounsupported option\n", + config->stream.width, config->stream.height, + config->stream.fps); else if (ret == GS_NOT_SUPPORTED_SOPS_RESOLUTION) - fprintf( - stderr, + printf( "Optimal Playable Settings isn't supported for the resolution " "%dx%d, use supported resolution or add --nosops option\n", config->stream.width, config->stream.height); else if (ret == GS_ERROR) - fprintf(stderr, "Gamestream error: %s\n", gs_error); + printf("Gamestream error: %s\n", gs_error); else - fprintf(stderr, "Errorcode starting app: %d\n", ret); - exit(-1); + printf("Errorcode starting app: %d\n", ret); + wait_for_button(); + return; } n3ds_audio_disabled = config->localaudio; @@ -445,6 +444,7 @@ static void stream(PSERVER_DATA server, PCONFIGURATION config, int appId) { printf("Ignoring invalid rotation value: %d\n", config->rotate); } + n3ds_connection_closed = false; n3ds_enable_motion = config->motion_controls; PDECODER_RENDERER_CALLBACKS video_callbacks = config->hwdecode ? &decoder_callbacks_n3ds_mvd @@ -468,7 +468,9 @@ static void stream(PSERVER_DATA server, PCONFIGURATION config, int appId) { if (status != 0) { n3ds_connection_callbacks.connectionTerminated(status); - exit(status); + printf("Connection failed with error: %d\n", status); + wait_for_button(); + return; } printf("Connected!\n"); @@ -502,20 +504,19 @@ int main_loop(int argc, char *argv[]) { if ((ret = gs_init(&server, config.address, config.port, config.key_dir, config.debug_level, config.unsupported)) == GS_OUT_OF_MEMORY) { - fprintf(stderr, "Not enough memory\n"); + printf("Not enough memory\n"); exit(-1); } else if (ret == GS_ERROR) { - fprintf(stderr, "Gamestream error: %s\n", gs_error); + printf("Gamestream error: %s\n", gs_error); exit(-1); } else if (ret == GS_INVALID) { - fprintf(stderr, "Invalid data received from server: %s\n", - gs_error); + printf("Invalid data received from server: %s\n", gs_error); exit(-1); } else if (ret == GS_UNSUPPORTED_VERSION) { - fprintf(stderr, "Unsupported version: %s\n", gs_error); + printf("Unsupported version: %s\n", gs_error); exit(-1); } else if (ret != GS_OK) { - fprintf(stderr, "Can't connect to server %s\n", config.address); + printf("Can't connect to server %s\n", config.address); wait_for_button(); continue; } @@ -579,8 +580,6 @@ int main_loop(int argc, char *argv[]) { if (!config.viewonly) { n3dsinput_cleanup(); } - // Exit app after streaming has closed - exit(0); } else if (strcmp("pair", config.action) == 0) { char pin[5]; if (config.pin > 0 && config.pin <= 9999) { @@ -594,7 +593,7 @@ int main_loop(int argc, char *argv[]) { pin); fflush(stdout); if (gs_pair(&server, &pin[0]) != GS_OK) { - fprintf(stderr, "Failed to pair to server: %s\n", gs_error); + printf("Failed to pair to server: %s\n", gs_error); } else { printf("Succesfully paired\n"); add_pair_address(config.address); @@ -605,8 +604,7 @@ int main_loop(int argc, char *argv[]) { continue; } else if (strcmp("unpair", config.action) == 0) { if (gs_unpair(&server) != GS_OK) { - fprintf(stderr, "Failed to unpair to server: %s\n", - gs_error); + printf("Failed to unpair to server: %s\n", gs_error); } else { printf("Succesfully unpaired\n"); remove_pair_address(config.address); @@ -616,7 +614,7 @@ int main_loop(int argc, char *argv[]) { printf("Sending app quit request ...\n"); gs_quit_app(&server); } else - fprintf(stderr, "%s is not a valid action\n", config.action); + printf("%s is not a valid action\n", config.action); wait_for_button(); } @@ -628,16 +626,14 @@ int main(int argc, char *argv[]) { try { main_loop(argc, argv); } catch (const std::exception &ex) { - fprintf(stderr, "Moonlight crashed with the following error: %s\n", - ex.what()); + printf("Moonlight crashed with the following error: %s\n", ex.what()); return 1; } catch (const std::string &ex) { - fprintf(stderr, - "Moonlight crashed with the following error message: %s\n", - ex.c_str()); + printf("Moonlight crashed with the following error message: %s\n", + ex.c_str()); return 1; } catch (...) { - fprintf(stderr, "Moonlight crashed with an unknown error\n"); + printf("Moonlight crashed with an unknown error\n"); return 1; } return 0; diff --git a/src/video/n3ds/N3dsRendererBase.cpp b/src/video/n3ds/N3dsRendererBase.cpp index 3a7e2d30..d4b1a400 100644 --- a/src/video/n3ds/N3dsRendererBase.cpp +++ b/src/video/n3ds/N3dsRendererBase.cpp @@ -44,6 +44,22 @@ N3dsRendererBase::~N3dsRendererBase() { linearFree(cmdlist); vramFree(vramFb); vramFree(vramTex); + // Return to the default display width before exiting + if (surface_width == GSP_SCREEN_HEIGHT_TOP_2X) { + gfxSetWide(false); + } + // Clear both screens + u8 *top = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); + memset(top, 0, GSP_SCREEN_HEIGHT_TOP * GSP_SCREEN_WIDTH * px_size); + gfxScreenSwapBuffers(GFX_TOP, true); + + GSPGPU_FramebufferFormat px_fmt_btm = gfxGetScreenFormat(GFX_BOTTOM); + int px_size_btm = gspGetBytesPerPixel(px_fmt_btm); + u8 *btm = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); + memset(btm, 0, GSP_SCREEN_HEIGHT_BOTTOM * GSP_SCREEN_WIDTH * px_size_btm); + gfxScreenSwapBuffers(GFX_BOTTOM, true); + + printf("Closing stream..."); } void N3dsRendererBase::ensure_3d_enabled() { diff --git a/src/video/n3ds_video_mvd.cpp b/src/video/n3ds_video_mvd.cpp index e87812d1..de29fbf4 100644 --- a/src/video/n3ds_video_mvd.cpp +++ b/src/video/n3ds_video_mvd.cpp @@ -54,6 +54,7 @@ static int n3ds_init(int videoFormat, int width, int height, int redrawRate, return -1; } + first_frame = true; int status = mvdstdInit(MVDMODE_VIDEOPROCESSING, MVD_INPUT_H264, MVD_OUTPUT_BGR565, width * height * N3DS_DEC_BUFF_SIZE, NULL);