Skip to content

Commit

Permalink
Allow the app to stay open after exiting a stream
Browse files Browse the repository at this point in the history
Replace fprintf calls for the 3DS UI
Fix stream variable reinitialization issues
  • Loading branch information
zoeyjodon committed May 26, 2024
1 parent 9e2d5d2 commit 5598742
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 35 deletions.
15 changes: 11 additions & 4 deletions src/input/n3ds_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
#include <3ds.h>
#include <Limelight.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

#define QUIT_BUTTONS (PLAY_FLAG | BACK_FLAG | LB_FLAG | RB_FLAG)
#define TOUCH_GAMEPAD_BUTTONS (SPECIAL_FLAG | LS_CLK_FLAG | RS_CLK_FLAG)
Expand Down Expand Up @@ -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();
Expand All @@ -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<N3dsTouchscreenInput>(&gamepad_state, touch_type);
touch_handler =
std::make_unique<N3dsTouchscreenInput>(&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;
Expand Down
58 changes: 27 additions & 31 deletions src/n3ds_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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");
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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();
}
Expand All @@ -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;
Expand Down
16 changes: 16 additions & 0 deletions src/video/n3ds/N3dsRendererBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
1 change: 1 addition & 0 deletions src/video/n3ds_video_mvd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 5598742

Please sign in to comment.