From be64bf08e4218a7cc2835e818a30c3730e5b1c43 Mon Sep 17 00:00:00 2001 From: Lubosz Sarnecki Date: Wed, 24 Jan 2018 07:55:00 +0100 Subject: [PATCH 1/4] config.def.h: Toggle menu with start & select (- & +) on Switch. --- config.def.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.def.h b/config.def.h index df031402a9..8bf11e774a 100644 --- a/config.def.h +++ b/config.def.h @@ -352,6 +352,8 @@ static bool default_screenshots_in_content_dir = false; static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_L3_R3; #elif defined(VITA) static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_L1_R1_START_SELECT; +#elif defined(SWITCH) +static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_START_SELECT; #else static unsigned menu_toggle_gamepad_combo = INPUT_TOGGLE_NONE; #endif From 7487d938b39d87f09ae009bc9ee44eb582767977 Mon Sep 17 00:00:00 2001 From: misson20000 Date: Mon, 5 Mar 2018 20:14:52 -0800 Subject: [PATCH 2/4] NSW: remove global state in graphics driver, as it is no longer necessary --- gfx/drivers/switch_gfx.c | 80 +++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/gfx/drivers/switch_gfx.c b/gfx/drivers/switch_gfx.c index 6b5a1ad1e3..f84be48535 100644 --- a/gfx/drivers/switch_gfx.c +++ b/gfx/drivers/switch_gfx.c @@ -51,14 +51,12 @@ typedef struct struct scaler_ctx scaler; } menu_texture; + + surface_t surface; + revent_h vsync_h; + uint32_t image[1280*720]; } switch_video_t; -static uint32_t image[1280*720]; - -static bool has_initialized = false; -static surface_t surface; -static revent_h vsync_h; - static void *switch_init(const video_info_t *video, const input_driver_t **input, void **input_data) { @@ -69,35 +67,28 @@ static void *switch_init(const video_info_t *video, RARCH_LOG("loading switch gfx driver, width: %d, height: %d\n", video->width, video->height); - if (has_initialized) - RARCH_LOG("global graphics were already initialized; skipping...\n"); - else + result_t r = display_init(); + if (r != RESULT_OK) { - result_t r = display_init(); - if (r != RESULT_OK) - { - free(sw); - return NULL; - } - r = display_open_layer(&surface); + free(sw); + return NULL; + } + r = display_open_layer(&sw->surface); - if (r != RESULT_OK) - { - display_finalize(); - free(sw); - return NULL; - } - r = display_get_vsync_event(&vsync_h); + if (r != RESULT_OK) + { + display_finalize(); + free(sw); + return NULL; + } + r = display_get_vsync_event(&sw->vsync_h); - if (r != RESULT_OK) - { - display_finalize(); - free(sw); - return NULL; - } - - atexit(display_finalize); - has_initialized = true; + if (r != RESULT_OK) + { + display_close_layer(&sw->surface); + display_finalize(); + free(sw); + return NULL; } sw->vp.x = 0; @@ -118,7 +109,7 @@ static void *switch_init(const video_info_t *video, for(x = 0; x < 1280; x++) { for(y = 0; y < 720; y++) - image[(y*1280)+x] = 0xFF000000; + sw->image[(y*1280)+x] = 0xFF000000; } return sw; @@ -127,8 +118,8 @@ static void *switch_init(const video_info_t *video, static void switch_wait_vsync(switch_video_t *sw) { uint32_t handle_idx; - svcWaitSynchronization(&handle_idx, &vsync_h, 1, 33333333); - svcResetSignal(vsync_h); + svcWaitSynchronization(&handle_idx, &sw->vsync_h, 1, 33333333); + svcResetSignal(sw->vsync_h); } static bool switch_frame(void *data, const void *frame, @@ -163,7 +154,7 @@ static bool switch_frame(void *data, const void *frame, { for(y = 0; y < height; y++) { - unsigned subx, suby; + unsigned subx, suby; uint32_t pixel = 0; if (sw->rgb32) @@ -171,8 +162,8 @@ static bool switch_frame(void *data, const void *frame, const uint32_t *frame_pixels = frame; pixel = frame_pixels[(y*pitch/sizeof(uint32_t)) + x]; } - else - { + else + { const uint16_t *frame_pixels = frame; uint32_t spixel = frame_pixels[(y*pitch/sizeof(uint16_t)) + x]; uint8_t r = (spixel >> 11) & 31; @@ -186,7 +177,7 @@ static bool switch_frame(void *data, const void *frame, for (subx = 0; subx < xsf; subx++) for (suby = 0; suby < ysf; suby++) - image[(((y*sf)+suby+centery)*1280) + sw->image[(((y*sf)+suby+centery)*1280) + ((x*sf)+subx+centerx)] = pixel; } } @@ -202,7 +193,7 @@ static bool switch_frame(void *data, const void *frame, if (sw->menu_texture.fullscreen) { #endif - scaler_ctx_scale(&sw->menu_texture.scaler, image, sw->menu_texture.pixels); + scaler_ctx_scale(&sw->menu_texture.scaler, sw->image, sw->menu_texture.pixels); #if 0 } else @@ -232,14 +223,14 @@ static bool switch_frame(void *data, const void *frame, post_vsync = svcGetSystemTick(); - r = surface_dequeue_buffer(&surface, &out_buffer); + r = surface_dequeue_buffer(&sw->surface, &out_buffer); } while(r != RESULT_OK); pre_swizzle = svcGetSystemTick(); - gfx_slow_swizzling_blit(out_buffer, image, 1280, 720, 0, 0); + gfx_slow_swizzling_blit(out_buffer, sw->image, 1280, 720, 0, 0); post_swizzle = svcGetSystemTick(); - r = surface_queue_buffer(&surface); + r = surface_queue_buffer(&sw->surface); if (r != RESULT_OK) return false; @@ -288,6 +279,9 @@ static bool switch_has_windowed(void *data) static void switch_free(void *data) { switch_video_t *sw = data; + svcCloseHandle(sw->vsync_h); + display_close_layer(&sw->surface); + display_finalize(); free(sw); } From 22c95b31eaeff44623599440ef20c130af50223a Mon Sep 17 00:00:00 2001 From: misson20000 Date: Mon, 5 Mar 2018 20:23:49 -0800 Subject: [PATCH 3/4] NSW: cpu_features_get_time_usec: put SWITCH block before POSIX_MONOTONIC_CLOCK block --- libretro-common/features/features_cpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretro-common/features/features_cpu.c b/libretro-common/features/features_cpu.c index efccf93070..dc3872043f 100644 --- a/libretro-common/features/features_cpu.c +++ b/libretro-common/features/features_cpu.c @@ -219,6 +219,8 @@ retro_time_t cpu_features_get_time_usec(void) return sys_time_get_system_time(); #elif defined(GEKKO) return ticks_to_microsecs(gettime()); +#elif defined(SWITCH) + return (svcGetSystemTick() * 10) / 192; #elif defined(_POSIX_MONOTONIC_CLOCK) || defined(__QNX__) || defined(ANDROID) || defined(__MACH__) struct timespec tv = {0}; if (ra_clock_gettime(CLOCK_MONOTONIC, &tv) < 0) @@ -236,8 +238,6 @@ retro_time_t cpu_features_get_time_usec(void) return sceKernelGetProcessTimeWide(); #elif defined(WIIU) return ticks_to_us(OSGetSystemTime()); -#elif defined(SWITCH) - return (svcGetSystemTick() * 10) / 192; #else #error "Your platform does not have a timer function implemented in cpu_features_get_time_usec(). Cannot continue." #endif From 90c36c52ced5b68b81948e62443354d65412de36 Mon Sep 17 00:00:00 2001 From: misson20000 Date: Mon, 5 Mar 2018 23:45:28 -0800 Subject: [PATCH 4/4] NSW: fix graphics driver colors for rgb32 and don't break aspect ratio when scaling menu texture --- gfx/drivers/switch_gfx.c | 109 +++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 38 deletions(-) diff --git a/gfx/drivers/switch_gfx.c b/gfx/drivers/switch_gfx.c index f84be48535..ac3682dfa4 100644 --- a/gfx/drivers/switch_gfx.c +++ b/gfx/drivers/switch_gfx.c @@ -49,12 +49,19 @@ typedef struct unsigned width; unsigned height; + unsigned tgtw; + unsigned tgth; + struct scaler_ctx scaler; } menu_texture; surface_t surface; revent_h vsync_h; uint32_t image[1280*720]; + + struct scaler_ctx scaler; + uint32_t last_width; + uint32_t last_height; } switch_video_t; static void *switch_init(const video_info_t *video, @@ -100,18 +107,11 @@ static void *switch_init(const video_info_t *video, video_driver_set_size(&sw->vp.width, &sw->vp.height); sw->vsync = video->vsync; - sw->rgb32 = video->rgb32; - + *input = NULL; *input_data = NULL; - for(x = 0; x < 1280; x++) - { - for(y = 0; y < 720; y++) - sw->image[(y*1280)+x] = 0xFF000000; - } - return sw; } @@ -150,38 +150,45 @@ static bool switch_frame(void *data, const void *frame, begin = svcGetSystemTick(); - for(x = 0; x < width; x++) + // clear image to black + for(x = 0; x < 1280; x++) { - for(y = 0; y < height; y++) + for(y = 0; y < 720; y++) { - unsigned subx, suby; - uint32_t pixel = 0; - - if (sw->rgb32) - { - const uint32_t *frame_pixels = frame; - pixel = frame_pixels[(y*pitch/sizeof(uint32_t)) + x]; - } - else - { - const uint16_t *frame_pixels = frame; - uint32_t spixel = frame_pixels[(y*pitch/sizeof(uint16_t)) + x]; - uint8_t r = (spixel >> 11) & 31; - uint8_t g = (spixel >> 5) & 63; - uint8_t b = (spixel >> 0) & 31; - r = (r * 256) / 32; - g = (g * 256) / 64; - b = (b * 256) / 32; - pixel = (r << 0) | (g << 8) | (b << 16) | (0xFF << 24); - } - - for (subx = 0; subx < xsf; subx++) - for (suby = 0; suby < ysf; suby++) - sw->image[(((y*sf)+suby+centery)*1280) - + ((x*sf)+subx+centerx)] = pixel; + sw->image[y*1280+x] = 0xFF000000; } } + if(width > 0 && height > 0) { + if(sw->last_width != width || + sw->last_height != height) + { + scaler_ctx_gen_reset(&sw->scaler); + + sw->scaler.in_width = width; + sw->scaler.in_height = height; + sw->scaler.in_stride = pitch; + sw->scaler.in_fmt = sw->rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGB565; + + sw->scaler.out_width = tgtw; + sw->scaler.out_height = tgth; + sw->scaler.out_stride = 1280 * sizeof(uint32_t); + sw->scaler.out_fmt = SCALER_FMT_ARGB8888; + + sw->scaler.scaler_type = SCALER_TYPE_POINT; + + if(!scaler_ctx_gen_filter(&sw->scaler)) { + RARCH_ERR("failed to generate scaler for main image\n"); + return false; + } + + sw->last_width = width; + sw->last_height = height; + } + + scaler_ctx_scale(&sw->scaler, sw->image + (centery * 1280) + centerx, frame); + } + #if defined(HAVE_MENU) if (sw->menu_texture.enable) { @@ -193,7 +200,9 @@ static bool switch_frame(void *data, const void *frame, if (sw->menu_texture.fullscreen) { #endif - scaler_ctx_scale(&sw->menu_texture.scaler, sw->image, sw->menu_texture.pixels); + scaler_ctx_scale(&sw->menu_texture.scaler, sw->image + + ((720-sw->menu_texture.tgth)/2)*1280 + + ((1280-sw->menu_texture.tgtw)/2), sw->menu_texture.pixels); #if 0 } else @@ -203,6 +212,21 @@ static bool switch_frame(void *data, const void *frame, } } #endif + + for(x = 0; x < 1280; x++) + { + for(y = 0; y < 720; y++) + { + // swizzle components + uint32_t *pixel = &sw->image[(y*1280) + x]; + uint32_t src = *pixel; + uint8_t a = (src & 0xFF000000) >> 24; + uint8_t r = (src & 0x00FF0000) >> 16; + uint8_t g = (src & 0x0000FF00) >> 8; + uint8_t b = (src & 0x000000FF) >> 0; + *pixel = (a << 24) | (b << 16) | (g << 8) | (r << 0); + } + } done_copying = svcGetSystemTick(); @@ -337,8 +361,17 @@ static void switch_set_texture_frame( return; } + int xsf = 1280 / width; + int ysf = 720 / height; + int sf = xsf; + + if (ysf < sf) + sf = ysf; + sw->menu_texture.width = width; sw->menu_texture.height = height; + sw->menu_texture.tgtw = width * sf; + sw->menu_texture.tgth = height * sf; struct scaler_ctx *sctx = &sw->menu_texture.scaler; scaler_ctx_gen_reset(sctx); @@ -348,8 +381,8 @@ static void switch_set_texture_frame( sctx->in_stride = width * 4; sctx->in_fmt = SCALER_FMT_ARGB8888; - sctx->out_width = 1280; - sctx->out_height = 720; + sctx->out_width = sw->menu_texture.tgtw; + sctx->out_height = sw->menu_texture.tgth; sctx->out_stride = 1280 * 4; sctx->out_fmt = SCALER_FMT_ARGB8888;