diff --git a/.vscode/settings.json b/.vscode/settings.json index c08df32eb9..d445ffca01 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,6 +7,7 @@ "terminal.integrated.cursorBlinking": true, "editor.tabSize": 3, + "editor.detectIndentation": false, "editor.renderWhitespace": "all", "editor.insertSpaces": true, "files.associations": { @@ -26,7 +27,13 @@ "menu_driver.h": "c", "file_path.h": "c", "unordered_map": "c", - "unordered_set": "c" + "unordered_set": "c", + "sstream": "cpp", + "hash_map": "c", + "hash_set": "c", + "initializer_list": "c", + "string_view": "c", + "utility": "c" }, "C_Cpp.dimInactiveRegions": false, } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index b271c66e8f..a90e515b1b 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,12 +4,49 @@ "version": "2.0.0", "tasks": [ { - "taskName": "msys2-mingw64 build", + "label": "linux clean build", + "type": "shell", + "group": "build", + "command": "make clean && ./configure && make -j12" + }, + { + "label": "linux clean", + "type": "shell", + "group": "build", + "command": "make clean" + }, + { + "label": "linux build with debug symbols", + "type": "shell", + "group": "build", + "command": "DEBUG=1 make -j12" + }, + { + "label": "linux build", + "type": "shell", + "group": "build", + "command": "make -j12" + }, + { + "label": "linux build and run", + "type": "shell", + "group": "build", + "command": "make -j12 && ./retroarch -v" + }, + { + "label": "linux build and run with debug symbols", + "type": "shell", + "group": "build", + "command": "DEBUG=1 make -j12 && ./retroarch -v" + }, + { + "label": "msys2-mingw64 build", "type": "shell", "group": { "kind": "build", - "isDefault": true }, + "isDefault": true + }, "command": "./configure; make -j2", "options": { @@ -20,9 +57,9 @@ ] } } - } + }, { - "taskName": "msys2-mingw64 build with debug symbols", + "label": "msys2-mingw64 build with debug symbols", "type": "shell", "group": "build", @@ -36,9 +73,9 @@ ] } } - } + }, { - "taskName": "msys2-mingw64 rebuild", + "label": "msys2-mingw64 rebuild", "type": "shell", "group": "build", @@ -52,9 +89,9 @@ ] } } - } + }, { - "taskName": "msys2-mingw64 clean", + "label": "msys2-mingw64 clean", "type": "shell", "group": "build", @@ -68,9 +105,9 @@ ] } } - } + }, { - "taskName": "msys2-mingw64 run", + "label": "msys2-mingw64 run", "type": "shell", "group": { diff --git a/config.def.h b/config.def.h index 2791384be9..f0ee60d58b 100644 --- a/config.def.h +++ b/config.def.h @@ -478,6 +478,11 @@ static const float crt_refresh_rate = 60/1.001; * Used for setups where one manually rotates the monitor. */ static const bool allow_rotate = true; +#ifdef _3DS +/* Enable bottom LCD screen */ +static const bool video_3ds_lcd_bottom = true; +#endif + /* AUDIO */ /* Will enable audio or not. */ diff --git a/configuration.c b/configuration.c index 65f6a70b7c..2fb5313535 100644 --- a/configuration.c +++ b/configuration.c @@ -1517,6 +1517,10 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("sustained_performance_mode", &settings->bools.sustained_performance_mode, true, sustained_performance_mode, false); +#ifdef _3DS + SETTING_BOOL("video_3ds_lcd_bottom", &settings->bools.video_3ds_lcd_bottom, true, video_3ds_lcd_bottom, false); +#endif + *size = count; return tmp; diff --git a/configuration.h b/configuration.h index eae90fc0b8..5ca67844fb 100644 --- a/configuration.h +++ b/configuration.h @@ -104,6 +104,7 @@ typedef struct settings bool video_statistics_show; bool video_framecount_show; bool video_msg_bgcolor_enable; + bool video_3ds_lcd_bottom; /* Audio */ bool audio_enable; diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index 74a5c074d2..4857e09dd7 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -47,6 +47,12 @@ #include "../../tasks/tasks_internal.h" #endif +/* An annoyance... + * Have to keep track of bottom screen enable state + * externally, otherwise cannot detect current state + * when reinitialising... */ +static bool ctr_bottom_screen_enabled = true; + static INLINE void ctr_check_3D_slider(ctr_video_t* ctr) { float slider_val = *(float*)0x1FF81080; @@ -263,7 +269,7 @@ static void ctr_lcd_aptHook(APT_HookType hook, void* param) if(not_2DS && srvGetServiceHandle(&lcd_handle, "gsp::Lcd") >= 0) { u32 *cmdbuf = getThreadCommandBuffer(); - cmdbuf[0] = ((hook == APTHOOK_ONSUSPEND) || ctr->lcd_buttom_on)? 0x00110040: 0x00120040; + cmdbuf[0] = ((hook == APTHOOK_ONSUSPEND) || ctr_bottom_screen_enabled)? 0x00110040: 0x00120040; cmdbuf[1] = 2; svcSendSyncRequest(lcd_handle); svcCloseHandle(lcd_handle); @@ -283,11 +289,38 @@ static bool ctr_tasks_finder(retro_task_t *task,void *userdata) task_finder_data_t ctr_tasks_finder_data = {ctr_tasks_finder, NULL}; #endif +static void ctr_set_bottom_screen_enable(void* data, bool enabled) +{ + Handle lcd_handle; + u8 not_2DS; + extern PrintConsole* currentConsole; + ctr_video_t *ctr = (ctr_video_t*)data; + + if (!ctr) + return; + + gfxBottomFramebuffers[0] = enabled ? (u8*)currentConsole->frameBuffer: + (u8*)ctr->empty_framebuffer; + + CFGU_GetModelNintendo2DS(¬_2DS); + if(not_2DS && srvGetServiceHandle(&lcd_handle, "gsp::Lcd") >= 0) + { + u32 *cmdbuf = getThreadCommandBuffer(); + cmdbuf[0] = enabled? 0x00110040: 0x00120040; + cmdbuf[1] = 2; + svcSendSyncRequest(lcd_handle); + svcCloseHandle(lcd_handle); + } + + ctr_bottom_screen_enabled = enabled; +} + static void* ctr_init(const video_info_t* video, const input_driver_t** input, void** input_data) { float refresh_rate; void* ctrinput = NULL; + settings_t *settings = config_get_ptr(); ctr_video_t* ctr = (ctr_video_t*)linearAlloc(sizeof(ctr_video_t)); if (!ctr) @@ -415,7 +448,6 @@ static void* ctr_init(const video_info_t* video, if (input && input_data) { - settings_t *settings = config_get_ptr(); ctrinput = input_ctr.init(settings->arrays.input_joypad_driver); *input = ctrinput ? &input_ctr : NULL; *input_data = ctrinput; @@ -425,7 +457,7 @@ static void* ctr_init(const video_info_t* video, ctr->should_resize = true; ctr->smooth = video->smooth; ctr->vsync = video->vsync; - ctr->lcd_buttom_on = true; + ctr->lcd_buttom_on = true; /* Unused */ ctr->current_buffer_top = 0; ctr->empty_framebuffer = linearAlloc(320 * 240 * 2); @@ -444,6 +476,11 @@ static void* ctr_init(const video_info_t* video, ctr->menu_texture_frame_enable = false; ctr->menu_texture_enable = false; + /* Set bottom screen enable state, if required */ + if (settings->bools.video_3ds_lcd_bottom != ctr_bottom_screen_enabled) { + ctr_set_bottom_screen_enable(ctr, settings->bools.video_3ds_lcd_bottom); + } + gspSetEventCallback(GSPGPU_EVENT_VBlank0, (ThreadFunc)ctr_vsync_hook, ctr, false); return ctr; @@ -494,24 +531,7 @@ static bool ctr_frame(void* data, const void* frame, hidTouchRead(&state_tmp_touch); if((state_tmp & KEY_TOUCH) && (state_tmp_touch.py < 120)) { - Handle lcd_handle; - u8 not_2DS; - extern PrintConsole* currentConsole; - - gfxBottomFramebuffers[0] = ctr->lcd_buttom_on ? (u8*)ctr->empty_framebuffer: - (u8*)currentConsole->frameBuffer; - - CFGU_GetModelNintendo2DS(¬_2DS); - if(not_2DS && srvGetServiceHandle(&lcd_handle, "gsp::Lcd") >= 0) - { - u32 *cmdbuf = getThreadCommandBuffer(); - cmdbuf[0] = ctr->lcd_buttom_on? 0x00120040: 0x00110040; - cmdbuf[1] = 2; - svcSendSyncRequest(lcd_handle); - svcCloseHandle(lcd_handle); - } - - ctr->lcd_buttom_on = !ctr->lcd_buttom_on; + ctr_set_bottom_screen_enable(ctr, !ctr_bottom_screen_enabled); } diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index bc76244dbb..813689be7c 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -1772,6 +1772,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "裁剪过扫描部分(需重启)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "禁用桌面元素") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "3DS底部屏幕") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "视频驱动") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_cht.h b/intl/msg_hash_cht.h index 0b526f8321..c025ffed0a 100644 --- a/intl/msg_hash_cht.h +++ b/intl/msg_hash_cht.h @@ -1590,6 +1590,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Crop Overscan (Reload)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "禁用桌面元素") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "3DS底部屏幕") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "視訊驅動") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 18f288c08d..f87411aa60 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -1663,6 +1663,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Bildränder (Overscan) zuschneiden (Neustart erforderlich)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Deaktiviere Desktop-Gestaltung") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "3DS-Bildschirm unten") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Videotreiber") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_el.h b/intl/msg_hash_el.h index 3bf6e07e19..e3bc73e9e9 100644 --- a/intl/msg_hash_el.h +++ b/intl/msg_hash_el.h @@ -3066,6 +3066,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Disable Desktop Composition" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "Κάτω οθόνη 3DS" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Οδηγός Βίντεο" diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index 642b47b408..c28eff54ef 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -1492,6 +1492,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Crop Overscan (Reload)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Disable Desktop Composition") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "3DS Fundo Ekrano") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Video Driver") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index 63d48b5c1c..acbef69d97 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -3028,6 +3028,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Desactivar composición de escritorio" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "Pantalla inferior 3DS" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Controlador de video" diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index cdd7e695b5..2d9a560a34 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1607,6 +1607,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Tronquer l'overscan (Reload)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Désactiver le compositeur de bureau") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "Écran inférieur 3DS") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Pilote vidéo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index 70e5c77a9a..fe7be6d34a 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -1637,6 +1637,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Crop Overscan (Ricarica)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Disattiva composizione del Desktop") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "3DS Bottom Screen") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Driver Video") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index a662fff365..813efe054a 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -1811,6 +1811,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "オーバースキャンをクロップ(再起動が必要)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "デスクトップコンポジションを無効") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "3DSボトム画面") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "ビデオのドライバ") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 8be4801cab..60b669cbfb 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -1587,6 +1587,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "오버스캔 잘라내기(재시작)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "데스크탑 구성요소 사용안함") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "3DS 하단 화면") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "비디오 드라이버") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 82a15774ce..9ac9cf2db7 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1737,3 +1737,5 @@ MSG_HASH(MENU_ENUM_LABEL_NO_IMAGES_AVAILABLE, "no_images") MSG_HASH(MENU_ENUM_LABEL_NO_FAVORITES_AVAILABLE, "no_favorites") +MSG_HASH(MENU_ENUM_LABEL_VIDEO_3DS_LCD_BOTTOM, + "video_3ds_lcd_bottom") diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index ed434c82f4..b32f6d954e 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -1502,6 +1502,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Overscan Afsnijden (Herladen Vereist)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Desktop Compositie Deactiveren") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "3DS onderste scherm") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Video Driver") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index 593f16d711..882a39f1bc 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -1741,6 +1741,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Przytnij Overscan (Przeładuj)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Wyłącz kompozycję pulpitu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "Dolny ekran 3DS") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Sterownik wideo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index a10c59afc5..f576b77216 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -3098,6 +3098,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Desativar Composição da Área de Trabalho" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "Tela Inferior 3DS" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Driver de Vídeo" diff --git a/intl/msg_hash_pt_pt.h b/intl/msg_hash_pt_pt.h index da038fa1d6..056b071dca 100644 --- a/intl/msg_hash_pt_pt.h +++ b/intl/msg_hash_pt_pt.h @@ -1579,6 +1579,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Cortar sobreexploração (recarregar)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Desativar composição do ambiente de trabalho") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "Tela Inferior 3DS") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Controlador de vídeo") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index cc54746ee2..51bb95d1de 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -1616,6 +1616,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Обрезка обрезки (перезагрузка)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Отключить компоновку рабочего стола") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "Нижний экран 3DS") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Видеодрайвер") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 905d18752e..7a0e276106 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3098,6 +3098,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Disable Desktop Composition" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "3DS Bottom Screen" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Video Driver" diff --git a/intl/msg_hash_vn.h b/intl/msg_hash_vn.h index 5d2b3b1a21..56937789be 100644 --- a/intl/msg_hash_vn.h +++ b/intl/msg_hash_vn.h @@ -1605,6 +1605,8 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_CROP_OVERSCAN, "Crop Overscan (Reload)") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DISABLE_COMPOSITION, "Disable Desktop Composition") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + "Màn hình dưới 3DS") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER, "Video Driver") MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_FILTER, diff --git a/menu/drivers/materialui.c b/menu/drivers/materialui.c index 92e4457f4a..cc6b7deede 100644 --- a/menu/drivers/materialui.c +++ b/menu/drivers/materialui.c @@ -559,7 +559,7 @@ static void materialui_render_messagebox(materialui_handle_t *mui, mui->font, msg, x - longest_width/2.0, y + i * line_height + mui->font->size / 3, - width, height, font_color, TEXT_ALIGN_LEFT, 1.0f, false, 0); + width, height, font_color, TEXT_ALIGN_LEFT, 1.0f, false, 0, false); } @@ -864,7 +864,7 @@ static void materialui_render_label_value( mui->margin + icon_margin, y + (scale_factor / 4) + mui->font->size, width, height, sublabel_color, TEXT_ALIGN_LEFT, - 1.0f, false, 0); + 1.0f, false, 0, false); } free(sublabel_str); } @@ -872,13 +872,13 @@ static void materialui_render_label_value( menu_display_draw_text(mui->font, label_str, mui->margin + icon_margin, y + (scale_factor / 5), - width, height, color, TEXT_ALIGN_LEFT, 1.0f, false, 0); + width, height, color, TEXT_ALIGN_LEFT, 1.0f, false, 0, false); if (do_draw_text) menu_display_draw_text(mui->font, value_str, width - mui->margin, y + (scale_factor / 5), - width, height, color, TEXT_ALIGN_RIGHT, 1.0f, false, 0); + width, height, color, TEXT_ALIGN_RIGHT, 1.0f, false, 0, false); if (texture_switch2) materialui_draw_icon(video_info, @@ -1562,7 +1562,7 @@ static void materialui_frame(void *data, video_frame_info_t *video_info) menu_display_draw_text(mui->font, title_buf, title_margin, header_height / 2 + mui->font->size / 3, - width, height, font_header_color, TEXT_ALIGN_LEFT, 1.0f, false, 0); + width, height, font_header_color, TEXT_ALIGN_LEFT, 1.0f, false, 0, false); materialui_draw_scrollbar(mui, video_info, width, height, &grey_bg[0]); diff --git a/menu/drivers/ozone.c b/menu/drivers/ozone.c index 6f8ae1719c..73c52cd396 100644 --- a/menu/drivers/ozone.c +++ b/menu/drivers/ozone.c @@ -54,7 +54,8 @@ #define ENTRIES_START_Y 127 -#define BATTERY_LEVEL_CHECK_INTERVAL (30 * 1000000) +#define INTERVAL_BATTERY_LEVEL_CHECK (30 * 1000000) +#define INTERVAL_OSK_CURSOR (0.5f * 1000000) static float ozone_pure_white[16] = { 1.00, 1.00, 1.00, 1.00, @@ -70,6 +71,13 @@ static float ozone_backdrop[16] = { 0.00, 0.00, 0.00, 0.75, }; +static float ozone_osk_backdrop[16] = { + 0.00, 0.00, 0.00, 0.15, + 0.00, 0.00, 0.00, 0.15, + 0.00, 0.00, 0.00, 0.15, + 0.00, 0.00, 0.00, 0.15, +}; + enum OZONE_TEXTURE { OZONE_TEXTURE_RETROARCH = 0, OZONE_TEXTURE_CURSOR_BORDER, @@ -205,6 +213,24 @@ static enum msg_hash_enums ozone_system_tabs_idx[OZONE_SYSTEM_TAB_LAST] = { MENU_ENUM_LABEL_ADD_TAB }; +static unsigned ozone_system_tabs_icons[OZONE_SYSTEM_TAB_LAST] = { + OZONE_TAB_TEXTURE_MAIN_MENU, + OZONE_TAB_TEXTURE_SETTINGS, + OZONE_TAB_TEXTURE_HISTORY, + OZONE_TAB_TEXTURE_FAVORITES, + OZONE_TAB_TEXTURE_MUSIC, +#if defined(HAVE_FFMPEG) || defined(HAVE_MPV) + OZONE_TAB_TEXTURE_VIDEO, +#endif +#ifdef HAVE_IMAGEVIEWER + OZONE_TAB_TEXTURE_IMAGE, +#endif +#ifdef HAVE_NETWORKING + OZONE_TAB_TEXTURE_NETWORK, +#endif + OZONE_TAB_TEXTURE_SCAN_CONTENT +}; + enum { OZONE_ENTRIES_ICONS_TEXTURE_MAIN_MENU = 0, @@ -317,24 +343,6 @@ enum OZONE_ENTRIES_ICONS_TEXTURE_LAST }; -static unsigned ozone_system_tabs_icons[OZONE_SYSTEM_TAB_LAST] = { - OZONE_TAB_TEXTURE_MAIN_MENU, - OZONE_TAB_TEXTURE_SETTINGS, - OZONE_TAB_TEXTURE_HISTORY, - OZONE_TAB_TEXTURE_FAVORITES, - OZONE_TAB_TEXTURE_MUSIC, -#if defined(HAVE_FFMPEG) || defined(HAVE_MPV) - OZONE_TAB_TEXTURE_VIDEO, -#endif -#ifdef HAVE_IMAGEVIEWER - OZONE_TAB_TEXTURE_IMAGE, -#endif -#ifdef HAVE_NETWORKING - OZONE_TAB_TEXTURE_NETWORK, -#endif - OZONE_TAB_TEXTURE_SCAN_CONTENT -}; - #define HEX_R(hex) ((hex >> 16) & 0xFF) * (1.0f / 255.0f) #define HEX_G(hex) ((hex >> 8 ) & 0xFF) * (1.0f / 255.0f) #define HEX_B(hex) ((hex >> 0 ) & 0xFF) * (1.0f / 255.0f) @@ -346,6 +354,8 @@ static unsigned ozone_system_tabs_icons[OZONE_SYSTEM_TAB_LAST] = { HEX_R(hex), HEX_G(hex), HEX_B(hex), alpha \ } +#define COLOR_TEXT_ALPHA(color, alpha) (color & 0xFFFFFF00) | alpha + static float ozone_sidebar_background_light[16] = { 0.94, 0.94, 0.94, 1.00, 0.94, 0.94, 0.94, 1.00, @@ -546,6 +556,8 @@ typedef struct ozone_handle float scroll_y; float list_alpha; + + float messagebox_alpha; } animations; bool fade_direction; /* false = left to right, true = right to left */ @@ -577,6 +589,7 @@ typedef struct ozone_handle unsigned cursor_state; /* 0 -> 1 -> 0 -> 1 [...] */ float cursor_border[16]; + float message_background[16]; } theme_dynamic; bool need_compute; @@ -590,6 +603,18 @@ typedef struct ozone_handle char *pending_message; bool has_all_assets; + + bool is_playlist; + bool is_playlist_old; + + bool empty_playlist; + + bool osk_cursor; /* true = display it, false = don't */ + bool messagebox_state; + bool messagebox_state_old; + bool should_draw_messagebox; + + unsigned old_list_offset_y; } ozone_handle_t; /* If you change this struct, also @@ -1360,7 +1385,8 @@ static void ozone_draw_text( float y, enum text_alignment text_align, unsigned width, unsigned height, font_data_t* font, - uint32_t color) + uint32_t color, + bool draw_outside) { if ((color & 0x000000FF) == 0) return; @@ -1368,7 +1394,7 @@ static void ozone_draw_text( menu_display_draw_text(font, str, x, y, width, height, color, text_align, 1.0f, false, - 1.0); + 1.0, draw_outside); } static void ozone_unload_theme_textures(ozone_handle_t *ozone) @@ -1505,6 +1531,7 @@ static void ozone_set_color_theme(ozone_handle_t *ozone, unsigned color_theme) memcpy(ozone->theme_dynamic.entries_icon, ozone->theme->entries_icon, sizeof(ozone->theme_dynamic.entries_icon)); memcpy(ozone->theme_dynamic.entries_checkmark, ozone_pure_white, sizeof(ozone->theme_dynamic.entries_checkmark)); memcpy(ozone->theme_dynamic.cursor_alpha, ozone_pure_white, sizeof(ozone->theme_dynamic.cursor_alpha)); + memcpy(ozone->theme_dynamic.message_background, ozone->theme->message_background, sizeof(ozone->theme_dynamic.message_background)); ozone_restart_cursor_animation(ozone); @@ -1540,6 +1567,9 @@ static void *ozone_init(void **userdata, bool video_is_threaded) ozone->draw_sidebar = true; ozone->sidebar_offset = 0; ozone->pending_message = NULL; + ozone->is_playlist = false; + ozone->categories_selection_ptr = 0; + ozone->pending_message = NULL; ozone->system_tab_end = 0; ozone->tabs[ozone->system_tab_end] = OZONE_SYSTEM_TAB_MAIN; @@ -1783,16 +1813,18 @@ static void ozone_context_reset(void *data, bool is_threaded) menu_display_allocate_white_texture(); /* State reset */ - ozone->frame_count = 0; - ozone->fade_direction = false; - ozone->cursor_in_sidebar = false; - ozone->cursor_in_sidebar_old = false; - ozone->draw_old_list = false; + ozone->frame_count = 0; + ozone->fade_direction = false; + ozone->cursor_in_sidebar = false; + ozone->cursor_in_sidebar_old = false; + ozone->draw_old_list = false; + ozone->messagebox_state = false; + ozone->messagebox_state_old = false; /* Animations */ - ozone->animations.cursor_alpha = 1.0f; - ozone->animations.scroll_y = 0.0f; - ozone->animations.list_alpha = 1.0f; + ozone->animations.cursor_alpha = 1.0f; + ozone->animations.scroll_y = 0.0f; + ozone->animations.list_alpha = 1.0f; /* Missing assets message */ /* TODO Localize */ @@ -2250,6 +2282,37 @@ static unsigned ozone_count_lines(const char *str) return lines; } +static bool ozone_is_playlist(ozone_handle_t *ozone) +{ + bool is_playlist; + + switch (ozone->categories_selection_ptr) + { + case OZONE_SYSTEM_TAB_MAIN: + case OZONE_SYSTEM_TAB_SETTINGS: + case OZONE_SYSTEM_TAB_ADD: + is_playlist = false; + break; + case OZONE_SYSTEM_TAB_HISTORY: + case OZONE_SYSTEM_TAB_FAVORITES: + case OZONE_SYSTEM_TAB_MUSIC: +#if defined(HAVE_FFMPEG) || defined(HAVE_MPV) + case OZONE_SYSTEM_TAB_VIDEO: +#endif +#ifdef HAVE_IMAGEVIEWER + case OZONE_SYSTEM_TAB_IMAGES: +#endif +#ifdef HAVE_NETWORKING + case OZONE_SYSTEM_TAB_NETPLAY: +#endif + default: + is_playlist = true; + break; + } + + return is_playlist && ozone->depth == 1; +} + static void ozone_compute_entries_position(ozone_handle_t *ozone) { /* Compute entries height and adjust scrolling if needed */ @@ -2276,6 +2339,19 @@ static void ozone_compute_entries_position(ozone_handle_t *ozone) menu_entry_init(&entry); menu_entry_get(&entry, 0, (unsigned)i, NULL, true); + /* Empty playlist detection: + only one item which icon is + OZONE_ENTRIES_ICONS_TEXTURE_CORE_INFO */ + if (ozone->is_playlist && entries_end == 1) + { + unsigned icon = ozone_entries_icon_get_id(ozone, entry.enum_idx, entry.type, false); + ozone->empty_playlist = icon == OZONE_ENTRIES_ICONS_TEXTURE_CORE_INFO; + } + else + { + ozone->empty_playlist = false; + } + /* Cache node */ node = (ozone_node_t*)file_list_get_userdata_at_offset(selection_buf, i); @@ -2413,7 +2489,7 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i menu_animation_ticker(&ticker); - ozone_draw_text(video_info, ozone, title, 128, 20 + FONT_SIZE_TITLE, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.title, ozone->theme->text_rgba); + ozone_draw_text(video_info, ozone, title, 128, 20 + FONT_SIZE_TITLE, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.title, ozone->theme->text_rgba, false); /* Icon */ menu_display_blend_begin(video_info); @@ -2433,7 +2509,7 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i if (state == FRONTEND_POWERSTATE_CHARGING) charging = true; - if (current_time - last_time >= BATTERY_LEVEL_CHECK_INTERVAL) + if (current_time - last_time >= INTERVAL_BATTERY_LEVEL_CHECK) { last_time = current_time; task_push_get_powerstate(); @@ -2447,7 +2523,7 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i snprintf(msg, sizeof(msg), "%d%%", percent); - ozone_draw_text(video_info, ozone, msg, video_info->width - 85, 30 + FONT_SIZE_TIME, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.time, ozone->theme->text_rgba); + ozone_draw_text(video_info, ozone, msg, video_info->width - 85, 30 + FONT_SIZE_TIME, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.time, ozone->theme->text_rgba, false); menu_display_blend_begin(video_info); ozone_draw_icon(video_info, 92, 92, ozone->icons_textures[charging ? OZONE_ENTRIES_ICONS_TEXTURE_BATTERY_CHARGING : OZONE_ENTRIES_ICONS_TEXTURE_BATTERY_FULL], video_info->width - 60 - 56, 30 - 28, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon); @@ -2469,7 +2545,7 @@ static void ozone_draw_header(ozone_handle_t *ozone, video_frame_info_t *video_i menu_display_timedate(&datetime); - ozone_draw_text(video_info, ozone, timedate, video_info->width - 87 - timedate_offset, 30 + FONT_SIZE_TIME, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.time, ozone->theme->text_rgba); + ozone_draw_text(video_info, ozone, timedate, video_info->width - 87 - timedate_offset, 30 + FONT_SIZE_TIME, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.time, ozone->theme->text_rgba, false); menu_display_blend_begin(video_info); ozone_draw_icon(video_info, 92, 92, ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_CLOCK], video_info->width - 60 - 56 - timedate_offset, 30 - 28, video_info->width, video_info->height, 0, 1, ozone->theme->entries_icon); @@ -2490,7 +2566,7 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i /* Core title or Switch icon */ if (settings->bools.menu_core_enable && menu_entries_get_core_title(core_title, sizeof(core_title)) == 0) - ozone_draw_text(video_info, ozone, core_title, 59, video_info->height - 49 + FONT_SIZE_FOOTER, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba); + ozone_draw_text(video_info, ozone, core_title, 59, video_info->height - 49 + FONT_SIZE_FOOTER, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba, false); else ozone_draw_icon(video_info, 69, 30, ozone->theme->textures[OZONE_THEME_TEXTURE_SWITCH], 59, video_info->height - 52, video_info->width,video_info->height, 0, 1, NULL); @@ -2530,12 +2606,12 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i do_swap ? msg_hash_to_str(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_OK) : msg_hash_to_str(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK), - video_info->width - back_width, video_info->height - back_height + FONT_SIZE_FOOTER, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba); + video_info->width - back_width, video_info->height - back_height + FONT_SIZE_FOOTER, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba, false); ozone_draw_text(video_info, ozone, do_swap ? msg_hash_to_str(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_BACK) : msg_hash_to_str(MENU_ENUM_LABEL_VALUE_BASIC_MENU_CONTROLS_OK), - video_info->width - ok_width, video_info->height - ok_height + FONT_SIZE_FOOTER, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba); + video_info->width - ok_width, video_info->height - ok_height + FONT_SIZE_FOOTER, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.footer, ozone->theme->text_rgba, false); } menu_display_blend_end(video_info); @@ -2546,7 +2622,7 @@ static void ozone_draw_footer(ozone_handle_t *ozone, video_frame_info_t *video_i static void ozone_draw_cursor_slice(ozone_handle_t *ozone, video_frame_info_t *video_info, int x_offset, - unsigned entry_width, + unsigned width, unsigned height, size_t y, float alpha) { ozone_color_alpha(ozone->theme_dynamic.cursor_alpha, alpha); @@ -2560,8 +2636,8 @@ static void ozone_draw_cursor_slice(ozone_handle_t *ozone, x_offset - 14, y + 8, 80, 80, - entry_width + 3 + 28 - 4, - 72, + width + 3 + 28 - 4, + height + 20, video_info->width, video_info->height, ozone->theme_dynamic.cursor_alpha, 20, 1.0, @@ -2574,8 +2650,8 @@ static void ozone_draw_cursor_slice(ozone_handle_t *ozone, x_offset - 14, y + 8, 80, 80, - entry_width + 3 + 28 - 4, - 72, + width + 3 + 28 - 4, + height + 20, video_info->width, video_info->height, ozone->theme_dynamic.cursor_border, 20, 1.0, @@ -2588,32 +2664,40 @@ static void ozone_draw_cursor_slice(ozone_handle_t *ozone, static void ozone_draw_cursor_fallback(ozone_handle_t *ozone, video_frame_info_t *video_info, int x_offset, - unsigned entry_width, + unsigned width, unsigned height, size_t y, float alpha) { ozone_color_alpha(ozone->theme_dynamic.selection_border, alpha); ozone_color_alpha(ozone->theme_dynamic.selection, alpha); /* Fill */ - menu_display_draw_quad(video_info, x_offset, y, entry_width, 70 - 10 - 10 - 3, video_info->width, video_info->height, ozone->theme_dynamic.selection); + menu_display_draw_quad(video_info, x_offset, y, width, height - 5, video_info->width, video_info->height, ozone->theme_dynamic.selection); /* Borders (can't do one single quad because of alpha) */ - menu_display_draw_quad(video_info, x_offset -3, y - 3, entry_width + 6, 3, video_info->width, video_info->height, ozone->theme_dynamic.selection_border); - menu_display_draw_quad(video_info, x_offset -3, y + 70 - 10 - 10 - 3, entry_width + 6, 3, video_info->width, video_info->height, ozone->theme_dynamic.selection_border); - menu_display_draw_quad(video_info, x_offset -3, y, 3, 70 - 10 - 3 - 6 - 4, video_info->width, video_info->height, ozone->theme_dynamic.selection_border); - menu_display_draw_quad(video_info, x_offset + entry_width, y, 3, 70 - 10 - 3 - 6 - 4, video_info->width, video_info->height, ozone->theme_dynamic.selection_border); + + /* Top */ + menu_display_draw_quad(video_info, x_offset - 3, y - 3, width + 6, 3, video_info->width, video_info->height, ozone->theme_dynamic.selection_border); + + /* Bottom */ + menu_display_draw_quad(video_info, x_offset - 3, y + height - 5, width + 6, 3, video_info->width, video_info->height, ozone->theme_dynamic.selection_border); + + /* Left */ + menu_display_draw_quad(video_info, x_offset - 3, y, 3, height - 5, video_info->width, video_info->height, ozone->theme_dynamic.selection_border); + + /* Right */ + menu_display_draw_quad(video_info, x_offset + width, y, 3, height - 5, video_info->width, video_info->height, ozone->theme_dynamic.selection_border); } static void ozone_draw_cursor(ozone_handle_t *ozone, video_frame_info_t *video_info, int x_offset, - unsigned entry_width, + unsigned width, unsigned height, size_t y, float alpha) { if (ozone->has_all_assets) - ozone_draw_cursor_slice(ozone, video_info, x_offset, entry_width, y, alpha); + ozone_draw_cursor_slice(ozone, video_info, x_offset, width, height, y, alpha); else - ozone_draw_cursor_fallback(ozone, video_info, x_offset, entry_width, y, alpha); + ozone_draw_cursor_fallback(ozone, video_info, x_offset, width, height, y, alpha); } static void ozone_draw_sidebar(ozone_handle_t *ozone, video_frame_info_t *video_info) @@ -2631,9 +2715,12 @@ static void ozone_draw_sidebar(ozone_handle_t *ozone, video_frame_info_t *video_ /* Background */ sidebar_height = video_info->height - 87 - 55 - 78; - menu_display_draw_quad(video_info, ozone->sidebar_offset, 88, 408, 55/2, video_info->width, video_info->height, ozone->theme->sidebar_top_gradient); - menu_display_draw_quad(video_info, ozone->sidebar_offset, 88 + 55/2, 408, sidebar_height, video_info->width, video_info->height, ozone->theme->sidebar_background); - menu_display_draw_quad(video_info, ozone->sidebar_offset, 55*2 + sidebar_height, 408, 55/2 + 1, video_info->width, video_info->height, ozone->theme->sidebar_bottom_gradient); + if (!video_info->libretro_running) + { + menu_display_draw_quad(video_info, ozone->sidebar_offset, 88, 408, 55/2, video_info->width, video_info->height, ozone->theme->sidebar_top_gradient); + menu_display_draw_quad(video_info, ozone->sidebar_offset, 88 + 55/2, 408, sidebar_height, video_info->width, video_info->height, ozone->theme->sidebar_background); + menu_display_draw_quad(video_info, ozone->sidebar_offset, 55*2 + sidebar_height, 408, 55/2 + 1, video_info->width, video_info->height, ozone->theme->sidebar_bottom_gradient); + } /* Tabs */ /* TODO Scroll */ @@ -2651,37 +2738,38 @@ static void ozone_draw_sidebar(ozone_handle_t *ozone, video_frame_info_t *video_ /* Cursor */ if (ozone->cursor_in_sidebar) - ozone_draw_cursor(ozone, video_info, ozone->sidebar_offset + 41, 408-81, selection_y-8, ozone->animations.cursor_alpha); + ozone_draw_cursor(ozone, video_info, ozone->sidebar_offset + 41, 408 - 81, 52, selection_y-8, ozone->animations.cursor_alpha); if (ozone->cursor_in_sidebar_old) - ozone_draw_cursor(ozone, video_info, ozone->sidebar_offset + 41, 408-81, selection_old_y-8, 1-ozone->animations.cursor_alpha); + ozone_draw_cursor(ozone, video_info, ozone->sidebar_offset + 41, 408 - 81, 52, selection_old_y-8, 1-ozone->animations.cursor_alpha); /* Icons */ y = ENTRIES_START_Y - 10; menu_display_blend_begin(video_info); /* TODO Cache all the tabs data */ - for (i = 0; i < OZONE_SYSTEM_TAB_LAST; i++) + for (i = 0; i < ozone->system_tab_end; i++) { enum msg_hash_enums value_idx; const char *title = NULL; bool selected = (ozone->categories_selection_ptr == i); - unsigned icon = ozone_system_tabs_icons[i]; + unsigned icon = ozone_system_tabs_icons[ozone->tabs[i]]; /* Icon */ ozone_draw_icon(video_info, 40, 40, ozone->tab_textures[icon], ozone->sidebar_offset + 41 + 10, y - 5, video_info->width, video_info->height, 0, 1, (selected ? ozone->theme->text_selected : ozone->theme->entries_icon)); - value_idx = ozone_system_tabs_value[i]; + value_idx = ozone_system_tabs_value[ozone->tabs[i]]; title = msg_hash_to_str(value_idx); /* Text */ - ozone_draw_text(video_info, ozone, title, ozone->sidebar_offset + 115 - 10, y + FONT_SIZE_SIDEBAR, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.sidebar, (selected ? ozone->theme->text_selected_rgba : ozone->theme->text_rgba)); + ozone_draw_text(video_info, ozone, title, ozone->sidebar_offset + 115 - 10, y + FONT_SIZE_SIDEBAR, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.sidebar, (selected ? ozone->theme->text_selected_rgba : ozone->theme->text_rgba), true); y += 65; } menu_display_blend_end(video_info); font_driver_flush(video_info->width, video_info->height, ozone->fonts.sidebar, video_info); + ozone->raster_blocks.sidebar.carr.coords.vertices = 0; menu_display_scissor_end(video_info); } @@ -2691,19 +2779,16 @@ static void ozone_draw_entry_value(ozone_handle_t *ozone, char *value, unsigned x, unsigned y, uint32_t alpha_uint32, - bool checked) + menu_entry_t *entry) { - enum msg_file_type hash_type; bool switch_is_on = true; bool do_draw_text = false; - if (!checked && string_is_empty(value)) + if (!entry->checked && string_is_empty(value)) return; - hash_type = msg_hash_to_file_type(msg_hash_calculate(value)); - /* check icon */ - if (checked) + if (entry->checked) { menu_display_blend_begin(video_info); ozone_draw_icon(video_info, 30, 30, ozone->theme->textures[OZONE_THEME_TEXTURE_CHECK], x - 20, y - 22, video_info->width, video_info->height, 0, 1, ozone->theme_dynamic.entries_checkmark); @@ -2726,51 +2811,59 @@ static void ozone_draw_entry_value(ozone_handle_t *ozone, } else { - switch (hash_type) + if (!string_is_empty(entry->value)) { - case FILE_TYPE_IN_CARCHIVE: - case FILE_TYPE_COMPRESSED: - case FILE_TYPE_MORE: - case FILE_TYPE_CORE: - case FILE_TYPE_DIRECT_LOAD: - case FILE_TYPE_RDB: - case FILE_TYPE_CURSOR: - case FILE_TYPE_PLAIN: - case FILE_TYPE_DIRECTORY: - case FILE_TYPE_MUSIC: - case FILE_TYPE_IMAGE: - case FILE_TYPE_MOVIE: + if ( + string_is_equal(entry->value, "...") || + string_is_equal(entry->value, "(PRESET)") || + string_is_equal(entry->value, "(SHADER)") || + string_is_equal(entry->value, "(COMP)") || + string_is_equal(entry->value, "(CORE)") || + string_is_equal(entry->value, "(MOVIE)") || + string_is_equal(entry->value, "(MUSIC)") || + string_is_equal(entry->value, "(DIR)") || + string_is_equal(entry->value, "(RDB)") || + string_is_equal(entry->value, "(CURSOR)")|| + string_is_equal(entry->value, "(CFILE)") || + string_is_equal(entry->value, "(FILE)") || + string_is_equal(entry->value, "(IMAGE)") + ) + { return; - default: + } + else do_draw_text = true; - break; } + else + do_draw_text = true; } if (do_draw_text) { - ozone_draw_text(video_info, ozone, value, x, y, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.entries_label, (ozone->theme->text_selected_rgba & 0xFFFFFF00) | alpha_uint32); + ozone_draw_text(video_info, ozone, value, x, y, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.entries_label, COLOR_TEXT_ALPHA(ozone->theme->text_selected_rgba, alpha_uint32), false); } else { ozone_draw_text(video_info, ozone, (switch_is_on ? msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON) : msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)), x, y, TEXT_ALIGN_RIGHT, video_info->width, video_info->height, ozone->fonts.entries_label, - ((switch_is_on ? ozone->theme->text_selected_rgba : ozone->theme->text_sublabel_rgba) & 0xFFFFFF00) | alpha_uint32); + COLOR_TEXT_ALPHA(switch_is_on ? ozone->theme->text_selected_rgba : ozone->theme->text_sublabel_rgba, alpha_uint32), false); } } static void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_info, unsigned selection, unsigned selection_old, - file_list_t *selection_buf, float alpha, float scroll_y) + file_list_t *selection_buf, float alpha, float scroll_y, + bool is_playlist) { bool old_list; uint32_t alpha_uint32; size_t i, y, entries_end; float sidebar_offset, bottom_boundary, invert, alpha_anim; - unsigned video_info_height, entry_width; - int x_offset = 22; - size_t selection_y = 0; - size_t old_selection_y = 0; + unsigned video_info_height, video_info_width, entry_width, button_height; + menu_entry_t entry; + int x_offset = 22; + size_t selection_y = 0; + size_t old_selection_y = 0; menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &i); @@ -2779,8 +2872,9 @@ static void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_ y = ENTRIES_START_Y; sidebar_offset = ozone->sidebar_offset / 2.0f; entry_width = video_info->width - 548; + button_height = 52; /* height of the button (entry minus sublabel) */ - video_driver_get_size(NULL, &video_info_height); + video_driver_get_size(&video_info_width, &video_info_height); bottom_boundary = video_info_height - 87 - 78; invert = (ozone->fade_direction) ? -1 : 1; @@ -2802,7 +2896,7 @@ static void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_ /* Borders layer */ for (i = 0; i < entries_end; i++) - { + { bool entry_selected = selection == i; bool entry_old_selected = selection_old == i; ozone_node_t *node = NULL; @@ -2814,35 +2908,39 @@ static void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_ node = (ozone_node_t*) file_list_get_userdata_at_offset(selection_buf, i); - if (!node) - continue; + if (!node || ozone->empty_playlist) + goto border_iterate; if (y + scroll_y + node->height + 20 < ENTRIES_START_Y) - goto text_iterate; + goto border_iterate; else if (y + scroll_y - node->height - 20 > bottom_boundary) - goto text_iterate; + goto border_iterate; ozone_color_alpha(ozone->theme_dynamic.entries_border, alpha); ozone_color_alpha(ozone->theme_dynamic.entries_checkmark, alpha); /* Borders */ menu_display_draw_quad(video_info, x_offset + 456-3, y - 3 + scroll_y, entry_width + 10 - 3 -1, 1, video_info->width, video_info->height, ozone->theme_dynamic.entries_border); - menu_display_draw_quad(video_info, x_offset + 456-3, y - 5 + 70 + 10 - 10 - 10 - 3 - 3 + scroll_y, entry_width + 10 - 3-1, 1, video_info->width, video_info->height, ozone->theme_dynamic.entries_border); + menu_display_draw_quad(video_info, x_offset + 456-3, y - 3 + button_height + scroll_y, entry_width + 10 - 3-1, 1, video_info->width, video_info->height, ozone->theme_dynamic.entries_border); -text_iterate: +border_iterate: y += node->height; } /* Cursor(s) layer - current */ if (!ozone->cursor_in_sidebar) - ozone_draw_cursor(ozone, video_info, x_offset + 456, entry_width, selection_y + scroll_y, ozone->animations.cursor_alpha * alpha); + ozone_draw_cursor(ozone, video_info, x_offset + 456, entry_width, button_height, selection_y + scroll_y, ozone->animations.cursor_alpha * alpha); /* Old*/ if (!ozone->cursor_in_sidebar_old) - ozone_draw_cursor(ozone, video_info, x_offset + 456, entry_width, old_selection_y + scroll_y, (1-ozone->animations.cursor_alpha) * alpha); + ozone_draw_cursor(ozone, video_info, x_offset + 456, entry_width, button_height, old_selection_y + scroll_y, (1-ozone->animations.cursor_alpha) * alpha); /* Icons + text */ y = ENTRIES_START_Y; + + if (old_list) + y += ozone->old_list_offset_y; + for (i = 0; i < entries_end; i++) { unsigned icon; @@ -2852,10 +2950,10 @@ text_iterate: char rich_label[255]; char entry_value_ticker[255]; char *sublabel_str; - ozone_node_t *node = NULL; - char *entry_rich_label = NULL; - bool entry_selected = false; - int text_offset = -40; + ozone_node_t *node = NULL; + char *entry_rich_label = NULL; + bool entry_selected = false; + int text_offset = -40; entry_value[0] = '\0'; entry_selected = selection == i; @@ -2873,6 +2971,29 @@ text_iterate: else if (y + scroll_y - node->height - 20 > bottom_boundary) goto icons_iterate; + /* Prepare text */ + entry_rich_label = menu_entry_get_rich_label(&entry); + + ticker.idx = ozone->frame_count / 20; + ticker.s = rich_label; + ticker.str = entry_rich_label; + ticker.selected = entry_selected && !ozone->cursor_in_sidebar; + ticker.len = (entry_width - 60 - text_offset) / ozone->entry_font_glyph_width; + + menu_animation_ticker(&ticker); + + if (ozone->empty_playlist) + { + unsigned text_width = font_driver_get_message_width(ozone->fonts.entries_label, rich_label, (unsigned)strlen(rich_label), 1); + x_offset = (video_info_width - 408 - 162)/2 - text_width/2; + y = video_info_height/2 - 60; + } + + sublabel_str = menu_entry_get_sublabel(&entry); + + if (node->wrap) + word_wrap(sublabel_str, sublabel_str, (video_info->width - 548) / ozone->sublabel_font_glyph_width, false); + /* Icon */ icon = ozone_entries_icon_get_id(ozone, entry.enum_idx, entry.type, entry_selected); if (icon != OZONE_ENTRIES_ICONS_TEXTURE_SUBSETTING) @@ -2886,27 +3007,11 @@ text_iterate: text_offset = 0; } - entry_rich_label = menu_entry_get_rich_label(&entry); - - ticker.idx = ozone->frame_count / 20; - ticker.s = rich_label; - ticker.str = entry_rich_label; - ticker.selected = entry_selected && !ozone->cursor_in_sidebar; - ticker.len = (entry_width - 60) / ozone->entry_font_glyph_width; - - menu_animation_ticker(&ticker); - - /* Text */ - sublabel_str = menu_entry_get_sublabel(&entry); - - if (node->wrap) - word_wrap(sublabel_str, sublabel_str, (video_info->width - 548) / ozone->sublabel_font_glyph_width, false); - - ozone_draw_text(video_info, ozone, rich_label, text_offset + x_offset + 521, y + FONT_SIZE_ENTRIES_LABEL + 8 - 1 + scroll_y, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.entries_label, (ozone->theme->text_rgba & 0xFFFFFF00) | alpha_uint32); - ozone_draw_text(video_info, ozone, sublabel_str, x_offset + 470, y + FONT_SIZE_ENTRIES_SUBLABEL + 80 - 20 - 3 + scroll_y, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.entries_sublabel, (ozone->theme->text_sublabel_rgba & 0xFFFFFF00) | alpha_uint32); + /* Draw text */ + ozone_draw_text(video_info, ozone, rich_label, text_offset + x_offset + 521, y + FONT_SIZE_ENTRIES_LABEL + 8 - 1 + scroll_y, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.entries_label, COLOR_TEXT_ALPHA(ozone->theme->text_rgba, alpha_uint32), false); + ozone_draw_text(video_info, ozone, sublabel_str, x_offset + 470, y + FONT_SIZE_ENTRIES_SUBLABEL + 80 - 20 - 3 + scroll_y, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.entries_sublabel, COLOR_TEXT_ALPHA(ozone->theme->text_sublabel_rgba, alpha_uint32), false); /* Value */ - ticker.idx = ozone->frame_count / 20; ticker.s = entry_value_ticker; ticker.str = entry_value; @@ -2914,7 +3019,7 @@ text_iterate: ticker.len = (entry_width - 60 - ((int)utf8len(entry_rich_label) * ozone->entry_font_glyph_width)) / ozone->entry_font_glyph_width; menu_animation_ticker(&ticker); - ozone_draw_entry_value(ozone, video_info, entry_value_ticker, x_offset + 426 + entry_width, y + FONT_SIZE_ENTRIES_LABEL + 8 - 1 + scroll_y,alpha_uint32, entry.checked); + ozone_draw_entry_value(ozone, video_info, entry_value_ticker, x_offset + 426 + entry_width, y + FONT_SIZE_ENTRIES_LABEL + 8 - 1 + scroll_y,alpha_uint32, &entry); free(entry_rich_label); free(sublabel_str); @@ -2995,11 +3100,106 @@ static unsigned ozone_get_system_theme() return 0; } -static void ozone_draw_backdrop(video_frame_info_t *video_info) +static void ozone_draw_backdrop(video_frame_info_t *video_info, float alpha) { + /* TODO Replace this backdrop by a blur shader on the whole screen if available */ + if (alpha == -1) + alpha = 0.75f; + ozone_color_alpha(ozone_backdrop, alpha); menu_display_draw_quad(video_info, 0, 0, video_info->width, video_info->height, video_info->width, video_info->height, ozone_backdrop); } +static void ozone_draw_osk(ozone_handle_t *ozone, + video_frame_info_t *video_info, + const char *label, const char *str) +{ + int i; + const char *text; + char message[2048]; + unsigned text_color; + struct string_list *list; + + unsigned margin = 75; + unsigned padding = 10; + unsigned bottom_end = video_info->height/2; + unsigned y_offset = 0; + bool draw_placeholder = string_is_empty(str); + + retro_time_t current_time = cpu_features_get_time_usec(); + static retro_time_t last_time = 0; + + if (current_time - last_time >= INTERVAL_OSK_CURSOR) + { + ozone->osk_cursor = !ozone->osk_cursor; + last_time = current_time; + } + + /* Border */ + /* Top */ + menu_display_draw_quad(video_info, margin, margin, video_info->width - margin*2, 1, video_info->width, video_info->height, ozone->theme->entries_border); + + /* Bottom */ + menu_display_draw_quad(video_info, margin, bottom_end - margin, video_info->width - margin*2, 1, video_info->width, video_info->height, ozone->theme->entries_border); + + /* Left */ + menu_display_draw_quad(video_info, margin, margin, 1, bottom_end - margin*2, video_info->width, video_info->height, ozone->theme->entries_border); + + /* Right */ + menu_display_draw_quad(video_info, video_info->width - margin, margin, 1, bottom_end - margin*2, video_info->width, video_info->height, ozone->theme->entries_border); + + /* Backdrop */ + /* TODO Remove the backdrop if blur shader is available */ + menu_display_draw_quad(video_info, margin + 1, margin + 1, video_info->width - margin*2 - 2, bottom_end - margin*2 - 2, video_info->width, video_info->height, ozone_osk_backdrop); + + /* Placeholder & text*/ + if (!draw_placeholder) + { + text = str; + text_color = 0xffffffff; + } + else + { + text = label; + text_color = ozone_theme_light.text_sublabel_rgba; + } + + word_wrap(message, text, (video_info->width - margin*2 - padding*2) / ozone->entry_font_glyph_width, true); + + list = string_split(message, "\n"); + + for (i = 0; i < list->size; i++) + { + const char *msg = list->elems[i].data; + + ozone_draw_text(video_info, ozone, msg, margin + padding * 2, margin + padding + FONT_SIZE_ENTRIES_LABEL + y_offset, TEXT_ALIGN_LEFT, video_info->width, video_info->height, ozone->fonts.entries_label, text_color, false); + + /* Cursor */ + if (i == list->size - 1) + { + if (ozone->osk_cursor) + { + unsigned cursor_x = draw_placeholder ? 0 : font_driver_get_message_width(ozone->fonts.entries_label, msg, (unsigned)strlen(msg), 1); + menu_display_draw_quad(video_info, margin + padding*2 + cursor_x, margin + padding + y_offset + 3, 1, 25, video_info->width, video_info->height, ozone_pure_white); + } + } + else + { + y_offset += 25; + } + } + + /* Keyboard */ + menu_display_draw_keyboard( + ozone->theme->textures[OZONE_THEME_TEXTURE_CURSOR_STATIC], + ozone->fonts.entries_label, + video_info, + menu_event_get_osk_grid(), + menu_event_get_osk_ptr(), + ozone->theme->text_rgba); + + string_list_free(list); +} + static void ozone_draw_messagebox(ozone_handle_t *ozone, video_frame_info_t *video_info, const char *message) @@ -3045,6 +3245,8 @@ static void ozone_draw_messagebox(ozone_handle_t *ozone, } } + ozone_color_alpha(ozone->theme_dynamic.message_background, ozone->animations.messagebox_alpha); + menu_display_blend_begin(video_info); if (ozone->has_all_assets) /* avoid drawing a black box if there's no assets */ @@ -3056,7 +3258,7 @@ static void ozone_draw_messagebox(ozone_handle_t *ozone, longest_width + 48 * 2, line_height * list->size + 48 * 2, width, height, - ozone->theme->message_background, + ozone->theme_dynamic.message_background, 16, 1.0, ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_DIALOG_SLICE] ); @@ -3073,30 +3275,33 @@ static void ozone_draw_messagebox(ozone_handle_t *ozone, TEXT_ALIGN_LEFT, width, height, ozone->fonts.footer, - ozone->theme->text_rgba + COLOR_TEXT_ALPHA(ozone->theme->text_rgba, (uint32_t)(ozone->animations.messagebox_alpha*255.0f)), + false ); } - if (menu_input_dialog_get_display_kb()) - menu_display_draw_keyboard( - ozone->theme->textures[OZONE_THEME_TEXTURE_CURSOR_STATIC], - ozone->fonts.footer, - video_info, - menu_event_get_osk_grid(), - menu_event_get_osk_ptr(), - ozone->theme->text_rgba); - end: string_list_free(list); } +static void ozone_messagebox_fadeout_cb(void *userdata) +{ + ozone_handle_t *ozone = (ozone_handle_t*) userdata; + + free(ozone->pending_message); + ozone->pending_message = NULL; + + ozone->should_draw_messagebox = false; +} + static void ozone_frame(void *data, video_frame_info_t *video_info) { - ozone_handle_t* ozone = (ozone_handle_t*) data; - settings_t *settings = config_get_ptr(); - unsigned color_theme = video_info->ozone_color_theme; - bool draw_message_box = false; - char msg[2014]; + ozone_handle_t* ozone = (ozone_handle_t*) data; + settings_t *settings = config_get_ptr(); + unsigned color_theme = video_info->ozone_color_theme; + menu_animation_ctx_tag messagebox_tag = (uintptr_t)ozone->pending_message; + + menu_animation_ctx_entry_t entry; if (!ozone) return; @@ -3134,6 +3339,9 @@ static void ozone_frame(void *data, video_frame_info_t *video_info) ozone->raster_blocks.entries_sublabel.carr.coords.vertices = 0; ozone->raster_blocks.sidebar.carr.coords.vertices = 0; + /* TODO Replace this by blur backdrop if available */ + ozone_color_alpha(ozone->theme->background, video_info->libretro_running ? 0.75f : 1.0f); + /* Background */ menu_display_draw_quad(video_info, 0, 0, video_info->width, video_info->height, @@ -3158,7 +3366,8 @@ static void ozone_frame(void *data, video_frame_info_t *video_info) ozone->selection_old, menu_entries_get_selection_buf_ptr(0), ozone->animations.list_alpha, - ozone->animations.scroll_y + ozone->animations.scroll_y, + ozone->is_playlist ); /* Old list */ @@ -3169,7 +3378,8 @@ static void ozone_frame(void *data, video_frame_info_t *video_info) ozone->selection_old_list, ozone->selection_buf_old, ozone->animations.list_alpha, - ozone->scroll_old + ozone->scroll_old, + ozone->is_playlist_old ); menu_display_scissor_end(video_info); @@ -3184,32 +3394,69 @@ static void ozone_frame(void *data, video_frame_info_t *video_info) font_driver_bind_block(ozone->fonts.time, NULL); font_driver_bind_block(ozone->fonts.entries_label, NULL); + /* Message box & OSK - second layer of text */ + ozone->raster_blocks.footer.carr.coords.vertices = 0; + ozone->raster_blocks.entries_label.carr.coords.vertices = 0; + + if (ozone->should_draw_messagebox || menu_input_dialog_get_display_kb()) + { + /* Fade in animation */ + if (ozone->messagebox_state_old != ozone->messagebox_state && ozone->messagebox_state) + { + ozone->messagebox_state_old = ozone->messagebox_state; + + menu_animation_kill_by_tag(&messagebox_tag); + ozone->animations.messagebox_alpha = 0.0f; + + entry.cb = NULL; + entry.duration = ANIMATION_PUSH_ENTRY_DURATION; + entry.easing_enum = EASING_OUT_QUAD; + entry.subject = &ozone->animations.messagebox_alpha; + entry.tag = messagebox_tag; + entry.target_value = 1.0f; + entry.userdata = NULL; + + menu_animation_push(&entry); + } + /* Fade out animation */ + else if (ozone->messagebox_state_old != ozone->messagebox_state && !ozone->messagebox_state) + { + ozone->messagebox_state_old = ozone->messagebox_state; + ozone->messagebox_state = false; + + menu_animation_kill_by_tag(&messagebox_tag); + ozone->animations.messagebox_alpha = 1.0f; + + entry.cb = ozone_messagebox_fadeout_cb; + entry.duration = ANIMATION_PUSH_ENTRY_DURATION; + entry.easing_enum = EASING_OUT_QUAD; + entry.subject = &ozone->animations.messagebox_alpha; + entry.tag = messagebox_tag; + entry.target_value = 0.0f; + entry.userdata = ozone; + + menu_animation_push(&entry); + } + + ozone_draw_backdrop(video_info, fmin(ozone->animations.messagebox_alpha, 0.75f)); + + if (menu_input_dialog_get_display_kb()) + { + const char *label = menu_input_dialog_get_label_buffer(); + const char *str = menu_input_dialog_get_buffer(); + + ozone_draw_osk(ozone, video_info, label, str); + } + else + { + ozone_draw_messagebox(ozone, video_info, ozone->pending_message); + } + } + + font_driver_flush(video_info->width, video_info->height, ozone->fonts.footer, video_info); + font_driver_flush(video_info->width, video_info->height, ozone->fonts.entries_label, video_info); + menu_display_unset_viewport(video_info->width, video_info->height); - - /* Message box & OSK */ - if (!string_is_empty(ozone->pending_message)) - { - strlcpy(msg, ozone->pending_message, - sizeof(msg)); - free(ozone->pending_message); - ozone->pending_message = NULL; - draw_message_box = true; - } - - if (menu_input_dialog_get_display_kb()) - { - const char *str = menu_input_dialog_get_buffer(); - const char *label = menu_input_dialog_get_label_buffer(); - - snprintf(msg, sizeof(msg), "%s\n%s", label, str); - draw_message_box = true; - } - - if (draw_message_box) - { - ozone_draw_backdrop(video_info); - ozone_draw_messagebox(ozone, video_info, msg); - } } static void ozone_set_header(ozone_handle_t *ozone) @@ -3303,8 +3550,9 @@ static void ozone_populate_entries(void *data, const char *path, const char *lab int new_depth = (int)ozone_list_get_size(ozone, MENU_LIST_PLAIN); - ozone->fade_direction = new_depth <= ozone->depth; - ozone->depth = new_depth; + ozone->fade_direction = new_depth <= ozone->depth; + ozone->depth = new_depth; + ozone->is_playlist = ozone_is_playlist(ozone); if (ozone->categories_selection_ptr == ozone->categories_active_idx_old) { @@ -3369,6 +3617,9 @@ static void ozone_leave_sidebar(ozone_handle_t *ozone, uintptr_t tag) { struct menu_animation_ctx_entry entry; + if (ozone->empty_playlist) + return; + ozone->categories_active_idx_old = ozone->categories_selection_ptr; ozone->cursor_in_sidebar_old = ozone->cursor_in_sidebar; ozone->cursor_in_sidebar = false; @@ -3387,6 +3638,38 @@ static void ozone_leave_sidebar(ozone_handle_t *ozone, uintptr_t tag) menu_animation_push(&entry); } +static void ozone_sidebar_goto(ozone_handle_t *ozone, unsigned new_selection) +{ + struct menu_animation_ctx_entry entry; + + menu_animation_ctx_tag tag = (uintptr_t)ozone; + + if (ozone->categories_selection_ptr != new_selection) + { + ozone->categories_active_idx_old = ozone->categories_selection_ptr; + ozone->categories_selection_ptr = new_selection; + + ozone->cursor_in_sidebar_old = ozone->cursor_in_sidebar; + + menu_animation_kill_by_tag(&tag); + } + + /* Cursor animation */ + ozone->animations.cursor_alpha = 0.0f; + + entry.cb = NULL; + entry.duration = ANIMATION_CURSOR_DURATION; + entry.easing_enum = EASING_OUT_QUAD; + entry.subject = &ozone->animations.cursor_alpha; + entry.tag = tag; + entry.target_value = 1.0f; + entry.userdata = NULL; + + menu_animation_push(&entry); + + ozone_change_tab(ozone, ozone_system_tabs_idx[ozone->tabs[new_selection]], ozone_system_tabs_type[ozone->tabs[new_selection]]); +} + static int ozone_menu_iterate(menu_handle_t *menu, void *userdata, enum menu_action action) { int new_selection; @@ -3396,6 +3679,8 @@ static int ozone_menu_iterate(menu_handle_t *menu, void *userdata, enum menu_act file_list_t *selection_buf = NULL; ozone_handle_t *ozone = (ozone_handle_t*) userdata; + ozone->messagebox_state = false || menu_input_dialog_get_display_kb(); + if (!ozone) return generic_menu_iterate(menu, userdata, action); @@ -3414,33 +3699,10 @@ static int ozone_menu_iterate(menu_handle_t *menu, void *userdata, enum menu_act new_selection = (ozone->categories_selection_ptr + 1); - if (new_selection >= OZONE_SYSTEM_TAB_LAST) /* TODO Check against actual tabs count and not just system tabs */ + if (new_selection >= ozone->system_tab_end) new_selection = 0; - if (ozone->categories_selection_ptr != new_selection) - { - ozone->categories_active_idx_old = ozone->categories_selection_ptr; - ozone->categories_selection_ptr = new_selection; - - ozone->cursor_in_sidebar_old = ozone->cursor_in_sidebar; - - menu_animation_kill_by_tag(&tag); - } - - /* Cursor animation */ - ozone->animations.cursor_alpha = 0.0f; - - entry.cb = NULL; - entry.duration = ANIMATION_CURSOR_DURATION; - entry.easing_enum = EASING_OUT_QUAD; - entry.subject = &ozone->animations.cursor_alpha; - entry.tag = tag; - entry.target_value = 1.0f; - entry.userdata = NULL; - - menu_animation_push(&entry); - - ozone_change_tab(ozone, ozone_system_tabs_idx[new_selection], ozone_system_tabs_type[new_selection]); + ozone_sidebar_goto(ozone, new_selection); new_action = MENU_ACTION_NOOP; break; @@ -3453,32 +3715,9 @@ static int ozone_menu_iterate(menu_handle_t *menu, void *userdata, enum menu_act new_selection = ozone->categories_selection_ptr - 1; if (new_selection < 0) - new_selection = OZONE_SYSTEM_TAB_LAST-1; /* TODO Set this to actual tabs count and not just system tabs */ + new_selection = ozone->system_tab_end-1; - if (ozone->categories_selection_ptr != new_selection) - { - ozone->categories_active_idx_old = ozone->categories_selection_ptr; - ozone->categories_selection_ptr = new_selection; - - ozone->cursor_in_sidebar_old = ozone->cursor_in_sidebar; - - menu_animation_kill_by_tag(&tag); - } - - /* Cursor animation */ - ozone->animations.cursor_alpha = 0.0f; - - entry.cb = NULL; - entry.duration = ANIMATION_CURSOR_DURATION; - entry.easing_enum = EASING_OUT_QUAD; - entry.subject = &ozone->animations.cursor_alpha; - entry.tag = tag; - entry.target_value = 1.0f; - entry.userdata = NULL; - - menu_animation_push(&entry); - - ozone_change_tab(ozone, ozone_system_tabs_idx[new_selection], ozone_system_tabs_type[new_selection]); + ozone_sidebar_goto(ozone, new_selection); new_action = MENU_ACTION_NOOP; break; @@ -3519,6 +3758,10 @@ static int ozone_menu_iterate(menu_handle_t *menu, void *userdata, enum menu_act case MENU_ACTION_CANCEL: if (ozone->cursor_in_sidebar) { + /* Go back to main menu tab */ + if (ozone->categories_selection_ptr != 0) + ozone_sidebar_goto(ozone, 0); + new_action = MENU_ACTION_NOOP; break; } @@ -3698,6 +3941,7 @@ static void ozone_list_cache(void *data, unsigned i; unsigned video_info_height; float bottom_boundary; + ozone_node_t *first_node; unsigned first = 0; unsigned last = 0; file_list_t *selection_buf = NULL; @@ -3709,6 +3953,7 @@ static void ozone_list_cache(void *data, ozone->need_compute = true; ozone->selection_old_list = ozone->selection; ozone->scroll_old = ozone->animations.scroll_y; + ozone->is_playlist_old = ozone->is_playlist; /* Deep copy visible elements */ video_driver_get_size(NULL, &video_info_height); @@ -3738,6 +3983,10 @@ text_iterate: } last -= 1; + last += first; + + first_node = (ozone_node_t*) file_list_get_userdata_at_offset(selection_buf, first); + ozone->old_list_offset_y = first_node->position_y; ozone_list_deep_copy(selection_buf, ozone->selection_buf_old, first, last); } @@ -3774,7 +4023,51 @@ static void ozone_messagebox(void *data, const char *message) if (!ozone || string_is_empty(message)) return; + if (ozone->pending_message) + { + free(ozone->pending_message); + ozone->pending_message = NULL; + } + ozone->pending_message = strdup(message); + ozone->messagebox_state = true || menu_input_dialog_get_display_kb(); + ozone->should_draw_messagebox = true; +} + +static int ozone_deferred_push_content_actions(menu_displaylist_info_t *info) +{ + if (!menu_displaylist_ctl( + DISPLAYLIST_HORIZONTAL_CONTENT_ACTIONS, info)) + return -1; + menu_displaylist_process(info); + menu_displaylist_info_free(info); + return 0; +} + +static int ozone_list_bind_init_compare_label(menu_file_list_cbs_t *cbs) +{ + if (cbs && cbs->enum_idx != MSG_UNKNOWN) + { + switch (cbs->enum_idx) + { + case MENU_ENUM_LABEL_CONTENT_ACTIONS: + cbs->action_deferred_push = ozone_deferred_push_content_actions; + break; + default: + return -1; + } + } + + return 0; +} + +static int ozone_list_bind_init(menu_file_list_cbs_t *cbs, + const char *path, const char *label, unsigned type, size_t idx) +{ + if (ozone_list_bind_init_compare_label(cbs) == 0) + return 0; + + return -1; } menu_ctx_driver_t menu_ctx_ozone = { @@ -3807,7 +4100,7 @@ menu_ctx_driver_t menu_ctx_ozone = { ozone_list_get_size, ozone_list_get_entry, NULL, /* list_set_selection */ - NULL, /* bind_init */ + ozone_list_bind_init, /* bind_init */ NULL, /* load_image */ "ozone", ozone_environ_cb, diff --git a/menu/drivers/stripes.c b/menu/drivers/stripes.c index 87cc84c000..be2abdd1e5 100755 --- a/menu/drivers/stripes.c +++ b/menu/drivers/stripes.c @@ -668,7 +668,7 @@ static void stripes_draw_text( menu_display_draw_text(font, str, x, y, width, height, color, text_align, scale_factor, video_info->xmb_shadows_enable, - stripes->shadow_offset); + stripes->shadow_offset, false); } static void stripes_messagebox(void *data, const char *message) @@ -742,7 +742,7 @@ static void stripes_render_keyboard( width/2.0 - (11*ptr_width)/2.0 + (i % 11) * ptr_width + ptr_width/2.0, height/2.0 + ptr_height + line_y + stripes->font->size / 3, width, height, 0xffffffff, TEXT_ALIGN_CENTER, 1.0f, - false, 0); + false, 0, false); } } @@ -843,7 +843,7 @@ static void stripes_render_messagebox_internal( menu_display_draw_text(stripes->font, msg, x - longest_width/2.0, y + (i+0.75) * line_height, - width, height, 0x444444ff, TEXT_ALIGN_LEFT, 1.0f, false, 0); + width, height, 0x444444ff, TEXT_ALIGN_LEFT, 1.0f, false, 0, false); } if (menu_input_dialog_get_display_kb()) diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 5426cc69ee..66e02c18d2 100755 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -833,7 +833,7 @@ static void xmb_draw_text( menu_display_draw_text(font, str, x, y, width, height, color, text_align, scale_factor, video_info->xmb_shadows_enable, - xmb->shadow_offset); + xmb->shadow_offset, false); } static void xmb_messagebox(void *data, const char *message) @@ -913,7 +913,7 @@ static void xmb_render_messagebox_internal( menu_display_draw_text(xmb->font, msg, x - longest_width/2.0, y + (i+0.75) * line_height, - width, height, 0x444444ff, TEXT_ALIGN_LEFT, 1.0f, false, 0); + width, height, 0x444444ff, TEXT_ALIGN_LEFT, 1.0f, false, 0, false); } if (menu_input_dialog_get_display_kb()) @@ -5415,7 +5415,7 @@ static void xmb_toggle(void *userdata, bool menu_on) xmb_toggle_horizontal_list(xmb); } -static int deferred_push_content_actions(menu_displaylist_info_t *info) +static int xmb_deferred_push_content_actions(menu_displaylist_info_t *info) { if (!menu_displaylist_ctl( DISPLAYLIST_HORIZONTAL_CONTENT_ACTIONS, info)) @@ -5432,7 +5432,7 @@ static int xmb_list_bind_init_compare_label(menu_file_list_cbs_t *cbs) switch (cbs->enum_idx) { case MENU_ENUM_LABEL_CONTENT_ACTIONS: - cbs->action_deferred_push = deferred_push_content_actions; + cbs->action_deferred_push = xmb_deferred_push_content_actions; break; default: return -1; diff --git a/menu/menu_animation.c b/menu/menu_animation.c index 68c6260fbb..d2b2b0f72f 100644 --- a/menu/menu_animation.c +++ b/menu/menu_animation.c @@ -711,3 +711,30 @@ bool menu_animation_ctl(enum menu_animation_ctl_state state, void *data) return true; } + +void menu_timer_start(menu_timer_t *timer, menu_timer_ctx_entry_t *timer_entry) +{ + menu_animation_ctx_tag tag = (uintptr_t) timer; + + menu_timer_kill(timer); + + *timer = 0.0f; + + menu_animation_ctx_entry_t entry; + + entry.easing_enum = EASING_LINEAR; + entry.tag = tag; + entry.duration = timer_entry->duration; + entry.target_value = 1.0f; + entry.subject = timer; + entry.cb = timer_entry->cb; + entry.userdata = timer_entry->userdata; + + menu_animation_push(&entry); +} + +void menu_timer_kill(menu_timer_t *timer) +{ + menu_animation_ctx_tag tag = (uintptr_t) timer; + menu_animation_kill_by_tag(&tag); +} diff --git a/menu/menu_animation.h b/menu/menu_animation.h index 6983237719..d1bc513489 100644 --- a/menu/menu_animation.h +++ b/menu/menu_animation.h @@ -118,6 +118,19 @@ typedef struct menu_animation_ctx_ticker const char *str; } menu_animation_ctx_ticker_t; +typedef float menu_timer_t; + +typedef struct menu_timer_ctx_entry +{ + float duration; + tween_cb cb; + void *userdata; +} menu_timer_ctx_entry_t; + +void menu_timer_start(menu_timer_t *timer, menu_timer_ctx_entry_t *timer_entry); + +void menu_timer_kill(menu_timer_t *timer); + bool menu_animation_update(float delta_time); bool menu_animation_get_ideal_delta_time(menu_animation_ctx_delta_t *delta); diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 2b78c5037e..ac59ae52a7 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6098,6 +6098,11 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_UI_COMPANION_TOGGLE, PARSE_ONLY_BOOL, false); +#endif +#ifdef _3DS + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_VIDEO_3DS_LCD_BOTTOM, + PARSE_ONLY_BOOL, false); #endif info->need_refresh = true; info->need_push = true; diff --git a/menu/menu_driver.c b/menu/menu_driver.c index 503bfaee8c..8ca72c132e 100644 --- a/menu/menu_driver.c +++ b/menu/menu_driver.c @@ -76,6 +76,13 @@ typedef struct menu_ctx_load_image enum menu_image_type type; } menu_ctx_load_image_t; +float osk_dark[16] = { + 0.00, 0.00, 0.00, 0.85, + 0.00, 0.00, 0.00, 0.85, + 0.00, 0.00, 0.00, 0.85, + 0.00, 0.00, 0.00, 0.85, +}; + /* Menu drivers */ static const menu_ctx_driver_t *menu_ctx_drivers[] = { #if defined(HAVE_OZONE) @@ -1160,18 +1167,18 @@ void menu_display_draw_texture_slice( vert_coord[2] = V_BR[0] + vert_scaled_mid_width; vert_coord[3] = V_BR[1] - vert_hoff - vert_scaled_mid_height; vert_coord[4] = V_TL[0] + vert_woff; - vert_coord[5] = V_TL[1] - vert_scaled_mid_height; + vert_coord[5] = V_TL[1] - vert_hoff - vert_scaled_mid_height; vert_coord[6] = V_TR[0] + vert_scaled_mid_width; - vert_coord[7] = V_TR[1] - vert_scaled_mid_height; + vert_coord[7] = V_TR[1] - vert_hoff - vert_scaled_mid_height; tex_coord[0] = T_BL[0] + tex_woff; tex_coord[1] = T_BL[1] + tex_hoff + tex_mid_height; tex_coord[2] = T_BR[0] + tex_mid_width; tex_coord[3] = T_BR[1] + tex_hoff + tex_mid_height; tex_coord[4] = T_TL[0] + tex_woff; - tex_coord[5] = T_TL[1] + tex_mid_height; + tex_coord[5] = T_TL[1] + tex_hoff + tex_mid_height; tex_coord[6] = T_TR[0] + tex_mid_width; - tex_coord[7] = T_TR[1] + tex_mid_height; + tex_coord[7] = T_TR[1] + tex_hoff + tex_mid_height; menu_display_draw(&draw, video_info); @@ -1510,12 +1517,6 @@ void menu_display_draw_keyboard( int ptr_width, ptr_height; unsigned width = video_info->width; unsigned height = video_info->height; - float dark[16] = { - 0.00, 0.00, 0.00, 0.85, - 0.00, 0.00, 0.00, 0.85, - 0.00, 0.00, 0.00, 0.85, - 0.00, 0.00, 0.00, 0.85, - }; float white[16]= { 1.00, 1.00, 1.00, 1.00, @@ -1528,7 +1529,7 @@ void menu_display_draw_keyboard( video_info, 0, height/2.0, width, height/2.0, width, height, - &dark[0]); + &osk_dark[0]); ptr_width = width / 11; ptr_height = height / 10; @@ -1564,7 +1565,7 @@ void menu_display_draw_keyboard( * ptr_width + ptr_width/2.0, height/2.0 + ptr_height + line_y + font->size / 3, width, height, color, TEXT_ALIGN_CENTER, 1.0f, - false, 0); + false, 0, false); } } @@ -1574,13 +1575,15 @@ void menu_display_draw_text( const font_data_t *font, const char *text, float x, float y, int width, int height, uint32_t color, enum text_alignment text_align, - float scale, bool shadows_enable, float shadow_offset) + float scale, bool shadows_enable, float shadow_offset, + bool draw_outside) { struct font_params params; /* Don't draw outside of the screen */ - if ( (x < -64 || x > width + 64) - || (y < -64 || y > height + 64) + if ( ((x < -64 || x > width + 64) + || (y < -64 || y > height + 64)) + && !draw_outside ) return; diff --git a/menu/menu_driver.h b/menu/menu_driver.h index 225125503b..25fc929b50 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -57,6 +57,8 @@ RETRO_BEGIN_DECLS #define MENU_SETTINGS_CHEEVOS_START 0x40000 #define MENU_SETTINGS_NETPLAY_ROOMS_START 0x80000 +extern float osk_dark[16]; + enum menu_image_type { MENU_IMAGE_NONE = 0, @@ -811,7 +813,8 @@ void menu_display_draw_text( const font_data_t *font, const char *text, float x, float y, int width, int height, uint32_t color, enum text_alignment text_align, - float scale_factor, bool shadows_enable, float shadow_offset); + float scale_factor, bool shadows_enable, float shadow_offset, + bool draw_outside); #define menu_display_set_alpha(color, alpha_value) (color[3] = color[7] = color[11] = color[15] = (alpha_value)) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 5a7c9cef89..b7af68fac5 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -4081,7 +4081,6 @@ static bool setting_append_list( &group_info, &subgroup_info, parent_group); - settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); CONFIG_ACTION( list, list_info, @@ -8685,6 +8684,24 @@ static bool setting_append_list( settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); #endif +#ifdef _3DS + CONFIG_BOOL( + list, list_info, + &settings->bools.video_3ds_lcd_bottom, + MENU_ENUM_LABEL_VIDEO_3DS_LCD_BOTTOM, + MENU_ENUM_LABEL_VALUE_VIDEO_3DS_LCD_BOTTOM, + video_3ds_lcd_bottom, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_CMD_APPLY_AUTO); + menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT_FROM_TOGGLE); +#endif + #ifdef HAVE_NETWORKING CONFIG_BOOL( list, list_info, diff --git a/msg_hash.h b/msg_hash.h index d5255e0979..c343242314 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -874,6 +874,7 @@ enum msg_hash_enums MENU_LABEL(UI_COMPANION_TOGGLE), MENU_LABEL(DESKTOP_MENU_ENABLE), MENU_LABEL(UI_MENUBAR_ENABLE), + MENU_LABEL(VIDEO_3DS_LCD_BOTTOM), MENU_ENUM_LABEL_FILE_CONFIG, MENU_ENUM_LABEL_FILE_BROWSER_COMPRESSED_ARCHIVE,