From 07600392df4d52e975c71ca28c12fc8ee793e03d Mon Sep 17 00:00:00 2001 From: MrHuu Date: Mon, 6 Sep 2021 01:16:16 +0200 Subject: [PATCH] (3DS) Add bottom screen idle state (#12942) --- gfx/common/ctr_common.h | 4 ++ gfx/drivers/ctr_gfx.c | 150 ++++++++++++++++++++++++++++++++++------ 2 files changed, 133 insertions(+), 21 deletions(-) diff --git a/gfx/common/ctr_common.h b/gfx/common/ctr_common.h index 658a08f638..5a741cdc6d 100644 --- a/gfx/common/ctr_common.h +++ b/gfx/common/ctr_common.h @@ -153,6 +153,10 @@ typedef struct ctr_video bool state_data_exist; char state_date[CTR_STATE_DATE_SIZE]; int state_slot; + bool bottom_check_idle; + bool bottom_is_idle; + bool bottom_is_fading; + u64 idle_timestamp; ctr_bottom_menu bottom_menu; ctr_bottom_menu prev_bottom_menu; struct ctr_bottom_texture_data *bottom_textures; diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index 778008952b..b7902abbdb 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -65,6 +65,9 @@ extern uint64_t lifecycle_state; * externally, otherwise cannot detect current state * when reinitialising... */ bool ctr_bottom_screen_enabled = true; +int fadeCount = 256; + +static void ctr_set_bottom_screen_enable(bool enabled, bool idle); static INLINE void ctr_check_3D_slider(ctr_video_t* ctr, ctr_video_mode_enum video_mode) { @@ -466,17 +469,32 @@ static void bottom_menu_control(void* data, bool lcd_bottom) BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE); + if (!rarch_ctl(RARCH_CTL_CORE_IS_RUNNING, NULL)) + { + if (!ctr->bottom_is_idle) + { + ctr->bottom_is_idle = true; + ctr_set_bottom_screen_enable(false, ctr->bottom_is_idle); + } + return; + } + state_tmp = hidKeysDown(); hidTouchRead(&state_tmp_touch); - + if (!state_tmp) + { + if (!ctr->bottom_check_idle && !ctr->bottom_is_idle) + { + ctr->idle_timestamp = svcGetSystemTick(); + ctr->bottom_check_idle = true; + } + } if (state_tmp & KEY_TOUCH) { #ifdef CONSOLE_LOG BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE); return; #endif - if (!rarch_ctl(RARCH_CTL_CORE_IS_RUNNING, NULL)) - return; if (!lcd_bottom || ctr->bottom_menu == CTR_BOTTOM_MENU_NOT_AVAILABLE) @@ -485,6 +503,20 @@ static void bottom_menu_control(void* data, bool lcd_bottom) return; } + if (ctr->bottom_is_idle) + { + ctr->bottom_is_idle = false; + ctr->bottom_is_fading = false; + fadeCount = 256; + ctr_set_bottom_screen_enable(true,true); + } + else if (ctr->bottom_check_idle) + { + ctr->bottom_check_idle = false; + ctr->bottom_is_fading = false; + fadeCount = 256; + } + switch (ctr->bottom_menu) { case CTR_BOTTOM_MENU_DEFAULT: @@ -568,7 +600,7 @@ static void bottom_menu_control(void* data, bool lcd_bottom) } break; } - + ctr->bottom_check_idle = false; ctr->refresh_bottom_menu = true; } @@ -781,7 +813,58 @@ static void ctr_render_bottom_screen(void *data) } } -static void ctr_set_bottom_screen_enable(bool enabled) +// graphic function originates from here: +// https://github.com/smealum/3ds_hb_menu/blob/master/source/gfx.c +void ctr_fade_bottom_screen(gfxScreen_t screen, gfx3dSide_t side, u32 f) +{ + u16 fbWidth, fbHeight; + u8* fbAdr=gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); + + int i; for(i=0; i>8;fbAdr++; + *fbAdr=(*fbAdr*f)>>8;fbAdr++; + *fbAdr=(*fbAdr*f)>>8;fbAdr++; + *fbAdr=(*fbAdr*f)>>8;fbAdr++; + *fbAdr=(*fbAdr*f)>>8;fbAdr++; + *fbAdr=(*fbAdr*f)>>8;fbAdr++; + } +} + +static void ctr_set_bottom_screen_idle(ctr_video_t * ctr) +{ + if (ctr->bottom_menu == CTR_BOTTOM_MENU_SELECT) + return; + + u64 elapsed_tick = ( svcGetSystemTick() - ctr->idle_timestamp ); + if ( elapsed_tick > 2000000000 ) + { + if (!ctr->bottom_is_fading) + { + ctr->bottom_is_fading = true; + ctr->refresh_bottom_menu = true; + return; + } + + if ( fadeCount > 0 ) + { + fadeCount--; + ctr_fade_bottom_screen(GFX_BOTTOM, GFX_LEFT, fadeCount); + + if ( fadeCount <= 128 ) + { + ctr->bottom_is_idle = true; + ctr->bottom_is_fading = false; + ctr->bottom_check_idle = false; + fadeCount = 256; + ctr_set_bottom_screen_enable(false,true); + return; + } + } + } +} + +static void ctr_set_bottom_screen_enable(bool enabled, bool idle) { Handle lcd_handle; u8 not_2DS; @@ -796,7 +879,8 @@ static void ctr_set_bottom_screen_enable(bool enabled) svcCloseHandle(lcd_handle); } - ctr_bottom_screen_enabled = enabled; + if (!idle) + ctr_bottom_screen_enabled = enabled; } static void ctr_lcd_aptHook(APT_HookType hook, void* param) @@ -858,7 +942,7 @@ static void ctr_lcd_aptHook(APT_HookType hook, void* param) if ((hook == APTHOOK_ONSUSPEND) || (hook == APTHOOK_ONRESTORE) || (hook == APTHOOK_ONWAKEUP)) { - ctr_set_bottom_screen_enable(hook == APTHOOK_ONSUSPEND); + ctr_set_bottom_screen_enable(hook == APTHOOK_ONSUSPEND, ctr->bottom_is_idle); if (ctr->state_data_on_ram) { @@ -941,6 +1025,10 @@ static void* ctr_init(const video_info_t* video, ctr->render_state_from_png_file = false; ctr->bottom_menu = CTR_BOTTOM_MENU_NOT_AVAILABLE; ctr->prev_bottom_menu = CTR_BOTTOM_MENU_NOT_AVAILABLE; + ctr->bottom_check_idle = false; + ctr->bottom_is_idle = false; + ctr->bottom_is_fading = false; + ctr->idle_timestamp = 0; ctr->state_slot = settings->ints.state_slot; snprintf(ctr->state_date, sizeof(ctr->state_date), "%s", "00/00/0000"); @@ -1082,7 +1170,7 @@ static void* ctr_init(const video_info_t* video, /* Set bottom screen enable state, if required */ if (lcd_bottom != ctr_bottom_screen_enabled) - ctr_set_bottom_screen_enable(lcd_bottom); + ctr_set_bottom_screen_enable(lcd_bottom, false); gspSetEventCallback(GSPGPU_EVENT_VBlank0, (ThreadFunc)ctr_vsync_hook, ctr, false); @@ -1135,7 +1223,16 @@ static bool ctr_frame(void* data, const void* frame, lcd_bottom = settings->bools.video_3ds_lcd_bottom; if (lcd_bottom != ctr_bottom_screen_enabled) - ctr_set_bottom_screen_enable(lcd_bottom); + { + if (rarch_ctl(RARCH_CTL_CORE_IS_RUNNING, NULL)) + { + ctr_set_bottom_screen_enable(lcd_bottom, false); + if (lcd_bottom) + ctr->refresh_bottom_menu = true; + } + else + ctr_bottom_screen_enabled = lcd_bottom; + } bottom_menu_control(data, lcd_bottom); if (ctr->p3d_event_pending) @@ -1478,7 +1575,15 @@ static bool ctr_frame(void* data, const void* frame, #ifndef CONSOLE_LOG if (ctr_bottom_screen_enabled && rarch_ctl(RARCH_CTL_CORE_IS_RUNNING, NULL)) - ctr_render_bottom_screen(ctr); + { + if ( !ctr->bottom_is_idle ) + { + ctr_render_bottom_screen(ctr); + + if ( ctr->bottom_check_idle ) + ctr_set_bottom_screen_idle(ctr); + } + } #endif if (msg) @@ -1502,15 +1607,13 @@ static bool ctr_frame(void* data, const void* frame, gfxTopRightFramebuffers[ctr->current_buffer_top], 240, CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); #ifndef CONSOLE_LOG - ctrGuDisplayTransfer(true, - ctr->drawbuffers.bottom, - 240, - 320, - CTRGU_RGBA8, - gfxBottomFramebuffers[ctr->current_buffer_bottom], - 240, - CTRGU_RGB8, - CTRGU_MULTISAMPLE_NONE); + if (ctr->refresh_bottom_menu) + ctrGuDisplayTransfer(true, + ctr->drawbuffers.bottom, + 240, + 320, + CTRGU_RGBA8, + gfxBottomFramebuffers[ctr->current_buffer_bottom], 240, CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); #endif /* Swap buffers : */ @@ -1548,6 +1651,10 @@ static bool ctr_frame(void* data, const void* frame, gspPresentBuffer(GFX_BOTTOM, ctr->current_buffer_bottom, bottom, bottom, stride, GSP_BGR8_OES); } + else if (ctr->bottom_is_fading) + { + gfxScreenSwapBuffers(GFX_BOTTOM,false); + } #endif #else topFramebufferInfo. @@ -1618,9 +1725,10 @@ static bool ctr_frame(void* data, const void* frame, } #endif #endif - ctr->current_buffer_top ^= 1; - ctr->current_buffer_bottom ^= 1; + if (ctr->refresh_bottom_menu || ctr->bottom_is_fading) + ctr->current_buffer_bottom ^= 1; + ctr->p3d_event_pending = true; ctr->ppf_event_pending = true; ctr->refresh_bottom_menu = false;