diff --git a/config.def.keybinds.h b/config.def.keybinds.h index 7d1900b76b..5271b3a068 100644 --- a/config.def.keybinds.h +++ b/config.def.keybinds.h @@ -88,6 +88,7 @@ static const struct retro_keybind retro_keybinds_1[] = { { true, RARCH_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_FPS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, + { true, RARCH_SEND_DEBUG_INFO, MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_NETPLAY_HOST_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, @@ -169,6 +170,7 @@ static const struct retro_keybind retro_keybinds_1[] = { { true, RARCH_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_FPS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, + { true, RARCH_SEND_DEBUG_INFO, MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_NETPLAY_HOST_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, @@ -250,6 +252,7 @@ static const struct retro_keybind retro_keybinds_1[] = { { true, RARCH_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, RETROK_F9, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, RETROK_F12, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_FPS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, RETROK_F3, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, + { true, RARCH_SEND_DEBUG_INFO, MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, RETROK_F10, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_NETPLAY_HOST_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, RETROK_i, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, { true, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE, AXIS_NONE, AXIS_NONE, NULL, NULL }, diff --git a/input/input_defines.h b/input/input_defines.h index 52d47aaa53..edd95037bd 100644 --- a/input/input_defines.h +++ b/input/input_defines.h @@ -98,6 +98,7 @@ enum RARCH_MUTE, RARCH_OSK, RARCH_FPS_TOGGLE, + RARCH_SEND_DEBUG_INFO, RARCH_NETPLAY_HOST_TOGGLE, RARCH_NETPLAY_GAME_WATCH, RARCH_ENABLE_HOTKEY, diff --git a/intl/msg_hash_es.c b/intl/msg_hash_es.c index 7442a1a9f3..722513b7b1 100644 --- a/intl/msg_hash_es.c +++ b/intl/msg_hash_es.c @@ -127,6 +127,13 @@ int menu_hash_get_help_es_enum(enum msg_hash_enums msg, char *s, size_t len) "Muestra o no el contador de fotogramas\n" "por segundo."); break; + case RARCH_SEND_DEBUG_INFO: + snprintf(s, len, + "Envía información de diagnóstico de\n" + "tu dispositivo y la configuración de RetroArch\n" + "a nuestros servidores para su posterior\n" + "análisis."); + break; case RARCH_NETPLAY_HOST_TOGGLE: snprintf(s, len, "Activa o desactiva el servidor de juego en red."); diff --git a/intl/msg_hash_es.h b/intl/msg_hash_es.h index 4eb24a0b38..19b5cb3ef4 100644 --- a/intl/msg_hash_es.h +++ b/intl/msg_hash_es.h @@ -1358,6 +1358,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, "Avanzar fotograma" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, + "Enviar datos de depuración" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, "Mostrar FPS" @@ -9357,6 +9361,38 @@ MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH, "Al buscar entradas asociadas a archivos comprimidos en las listas de reproducción, solo se buscará una coincidencia en el nombre del archivo, en vez de [nombre de archivo]+[contenido]. Activar para evitar duplicados en el historial al cargar archivos comprimidos." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO, + "Enviar información de depuración" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_DEBUG_INFO, + "Error al guardar la información de depuración." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_DEBUG_INFO, + "Error al enviar la información de depuración al servidor." + ) +MSG_HASH( + MSG_SENDING_DEBUG_INFO, + "Enviando información de depuración..." + ) +MSG_HASH( + MSG_SENT_DEBUG_INFO, + "Información enviada al servidor. Tu identificador es %u." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO, + "Envía información de diagnóstico sobre tu dispositivo y tu configuración de RetroArch a nuestros servidores para su posterior análisis." + ) +MSG_HASH( + MSG_PRESS_TWO_MORE_TIMES_TO_SEND_DEBUG_INFO, + "Vuelve a pulsar el botón dos veces para enviar la información de diagnóstico al equipo de RetroArch." + ) +MSG_HASH( + MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO, + "Vuelve a pulsar el botón una última vez para enviar la información de diagnóstico al equipo de RetroArch." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIBRATE_ON_KEYPRESS, "Vibrar al pulsar un botón" diff --git a/intl/msg_hash_fr.c b/intl/msg_hash_fr.c index 425d41bb38..8331f34291 100644 --- a/intl/msg_hash_fr.c +++ b/intl/msg_hash_fr.c @@ -118,6 +118,10 @@ int menu_hash_get_help_fr_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Afficher/masquer le compteur d'images/s."); break; + case RARCH_SEND_DEBUG_INFO: + snprintf(s, len, + "Envoie des informations de diagnostic sur votre appareil et la configuration de RetroArch à nos serveurs pour analyse."); + break; case RARCH_NETPLAY_HOST_TOGGLE: snprintf(s, len, "Activer/désactiver l'hébergement du jeu en réseau."); diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index c261885636..d43cc41437 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1358,6 +1358,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, "Avance image par image" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, + "Envoyer les informations de diagnostic" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, "Afficher/masquer les images/s" @@ -9338,6 +9342,38 @@ MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH, "Lors de la recherche de fichiers compressés dans les listes de lecture, faire correspondre le nom de l'archive uniquement et non [nom]+[contenu]. Activez cette option pour éviter les doublons dans l'historique lors du chargement d'archives." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO, + "Envoyer des informations de diagnostic" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_DEBUG_INFO, + "Échec d'enregistrement des informations de diagnostic." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_DEBUG_INFO, + "Échec d'envoi des informations de diagnostic au serveur." + ) +MSG_HASH( + MSG_SENDING_DEBUG_INFO, + "Envoi des informations de diagnostic..." + ) +MSG_HASH( + MSG_SENT_DEBUG_INFO, + "Les informations de diagnostic ont été envoyées au serveur avec succès. Votre numéro d'identification est %u." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO, + "Envoyer les informations de diagnostic pour votre appareil et la configuration de RetroArch à nos serveurs pour analyse." + ) +MSG_HASH( + MSG_PRESS_TWO_MORE_TIMES_TO_SEND_DEBUG_INFO, + "Appuyez deux fois de plus pour soumettre les informations de diagnostic à l'équipe de RetroArch." + ) +MSG_HASH( + MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO, + "Appuyez une fois de plus pour soumettre les informations de diagnostic à l'équipe de RetroArch." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIBRATE_ON_KEYPRESS, "Vibrer à chaque touche pressée" diff --git a/intl/msg_hash_ja.c b/intl/msg_hash_ja.c index d3bd7333c8..4e8d964758 100644 --- a/intl/msg_hash_ja.c +++ b/intl/msg_hash_ja.c @@ -115,6 +115,10 @@ int menu_hash_get_help_jp_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Toggles frames per second counter."); break; + case RARCH_SEND_DEBUG_INFO: + snprintf(s, len, + "Sends diagnostic info about your device and RetroArch configuration to our servers for analysis."); + break; case RARCH_NETPLAY_HOST_TOGGLE: snprintf(s, len, "Toggles netplay hosting on/off."); diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 3fbe560087..c741366bd1 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -1292,6 +1292,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, "コマ送り" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, + "デバッグ情報の送信" +) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, "FPS表示の切り替え" @@ -8575,6 +8579,30 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_AGGREGATE, "総計" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO, + "デバッグ情報の送信" +) +MSG_HASH( + MSG_FAILED_TO_SAVE_DEBUG_INFO, + "デバッグ情報の保存に失敗しました。" +) +MSG_HASH( + MSG_FAILED_TO_SEND_DEBUG_INFO, + "デバッグ情報のサーバへの送信に失敗しました。" +) +MSG_HASH( + MSG_SENDING_DEBUG_INFO, + "デバッグ情報の送信中..." +) +MSG_HASH( + MSG_SENT_DEBUG_INFO, + "デバッグ情報のサーバへの送信に成功しました。ID番号は %u です。" +) +MSG_HASH( + MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO, + "解析のため, デバイスとRetroArch設定に関する情報をサーバーに送信します。" +) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIBRATE_ON_KEYPRESS, "キー入力で振動" diff --git a/intl/msg_hash_ko.c b/intl/msg_hash_ko.c index 1cf1cd778f..e6a1f1b8fe 100644 --- a/intl/msg_hash_ko.c +++ b/intl/msg_hash_ko.c @@ -109,6 +109,10 @@ int menu_hash_get_help_ko_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "FPS 표시를 전환합니다."); break; + case RARCH_SEND_DEBUG_INFO: + snprintf(s, len, + "기기 및 RetroArch 설정의 분적 정보를 분석을 위해 서버에 보냅니다."); + break; case RARCH_NETPLAY_HOST_TOGGLE: snprintf(s, len, "넷플레 호스트 켜기/끄기."); diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 3bf2c431d4..774ec24d34 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -1283,6 +1283,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, "다음 프레임" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, + "디버그 정보 보내기" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, "FPS 켜기/끄기" @@ -8975,6 +8979,38 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_AGGREGATE, "종합" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO, + "디버그 정보 전송" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_DEBUG_INFO, + "디버그 정보 저장 실패." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_DEBUG_INFO, + "디버그 정보를 서버에 전송하는데 실패했습니다." + ) +MSG_HASH( + MSG_SENDING_DEBUG_INFO, + "디버그 정보 전송 중..." + ) +MSG_HASH( + MSG_SENT_DEBUG_INFO, + "디버그 정보를 성공적으로 서버에 보냈습니다. ID 번호는 %u 입니다." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO, + "장치 및 RetroArch 설정 분석 정보를 분석을 위해 서버로 전송합니다." + ) +MSG_HASH( + MSG_PRESS_TWO_MORE_TIMES_TO_SEND_DEBUG_INFO, + "분석 정보를 RetroArch 팀에게 보내려면 두 번 더 눌러주십시오." + ) +MSG_HASH( + MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO, + "분석 정보를 RetroArch 팀에게 보내려면 한 번 더 눌러주십시오." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIBRATE_ON_KEYPRESS, "키 누를 때 진동" diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 1f06eeb122..766ba2ebd1 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -2066,6 +2066,8 @@ MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_RUNTIME_TYPE, "playlist_sublabel_runtime_type") MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE, "playlist_sublabel_last_played_style") +MSG_HASH(MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO, + "help_send_debug_info") MSG_HASH(MENU_ENUM_LABEL_VIBRATE_ON_KEYPRESS, "vibrate_on_keypress") MSG_HASH(MENU_ENUM_LABEL_ENABLE_DEVICE_VIBRATION, diff --git a/intl/msg_hash_pl.h b/intl/msg_hash_pl.h index 2a4787d4c2..902ee65e8e 100644 --- a/intl/msg_hash_pl.h +++ b/intl/msg_hash_pl.h @@ -4031,6 +4031,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_REWIND_BUFFER_SIZE_STEP, "Krok zmiany rozmiaru bufora (MB)" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO, + "Wyślij informacje o debugowaniu" + ) #ifdef HAVE_LAKKA MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_SHOW_QUIT_RETROARCH, @@ -4547,6 +4551,9 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_SHOW_WIMP, MSG_HASH(MENU_ENUM_SUBLABEL_SHOW_WIMP, "Otwiera menu pulpitu, jeśli jest zamknięte." ) +MSG_HASH(MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO, + "Wysyła informacje diagnostyczne o twoim urządzeniu i konfiguracji RetroArch na nasze serwery w celu analizy." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_SOUNDS, "Dźwięki menu" diff --git a/intl/msg_hash_pt_br.c b/intl/msg_hash_pt_br.c index b098cf32fa..7fa271c066 100644 --- a/intl/msg_hash_pt_br.c +++ b/intl/msg_hash_pt_br.c @@ -116,6 +116,10 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Alternar contador de quadros por segundo."); break; + case RARCH_SEND_DEBUG_INFO: + snprintf(s, len, + "Envia informações de diagnóstico sobre o seu dispositivo e a configuração do RetroArch aos nossos servidores para análise."); + break; case RARCH_NETPLAY_HOST_TOGGLE: snprintf(s, len, "Ativar ou desativar a hospedagem de jogo em rede."); diff --git a/intl/msg_hash_pt_br.h b/intl/msg_hash_pt_br.h index 227b8643b5..f23b669678 100644 --- a/intl/msg_hash_pt_br.h +++ b/intl/msg_hash_pt_br.h @@ -1302,6 +1302,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, "Avanço de Quadro" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, + "Enviar informações de depuração" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, "Alternar FPS" @@ -9218,6 +9222,38 @@ MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH, "Ao pesquisar as listas de reprodução de entradas associadas a arquivos compactados, corresponde apenas ao nome do arquivo morto em vez de [nome do arquivo]+[conteúdo]. Habilite isso para evitar entradas de histórico de conteúdo duplicadas ao carregar arquivos compactados." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO, + "Enviar Informação de Depuração" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_DEBUG_INFO, + "Falha ao salvar informações de depuração." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_DEBUG_INFO, + "Falha ao enviar informações de depuração para o servidor." + ) +MSG_HASH( + MSG_SENDING_DEBUG_INFO, + "Enviando informações de depuração..." + ) +MSG_HASH( + MSG_SENT_DEBUG_INFO, + "Enviado informações de depuração para o servidor com sucesso. Seu ID é o número %u." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO, + "Envia informações de diagnóstico sobre o seu dispositivo e a configuração do RetroArch aos nossos servidores para análise." + ) +MSG_HASH( + MSG_PRESS_TWO_MORE_TIMES_TO_SEND_DEBUG_INFO, + "Pressione mais duas vezes para enviar informações de diagnóstico para a equipe do RetroArch." + ) +MSG_HASH( + MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO, + "Pressione mais uma vez para enviar informações de diagnóstico para a equipe do RetroArch." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIBRATE_ON_KEYPRESS, "Vibrar ao Pressionar a Tecla" diff --git a/intl/msg_hash_tr.c b/intl/msg_hash_tr.c index ac4c37f5b1..1b51dd7b1f 100644 --- a/intl/msg_hash_tr.c +++ b/intl/msg_hash_tr.c @@ -116,6 +116,10 @@ int menu_hash_get_help_tr_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Saniye sayacındaki kareleri değiştirir."); break; + case RARCH_SEND_DEBUG_INFO: + snprintf(s, len, + "Analiz için cihazınızın ve RetroArch yapılandırmasına ilişkin tanılama bilgilerini sunucularımıza gönderin."); + break; case RARCH_NETPLAY_HOST_TOGGLE: snprintf(s, len, "Netplay barındırma özelliğini açar/kapatır."); diff --git a/intl/msg_hash_tr.h b/intl/msg_hash_tr.h index e91e05e357..47a6755e05 100644 --- a/intl/msg_hash_tr.h +++ b/intl/msg_hash_tr.h @@ -1279,6 +1279,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, "Frameadvance" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, + "Hata Ayıklama Bilgisi Gönder" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, "FPS açma-kapama" @@ -8752,6 +8756,38 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_RUNTIME_AGGREGATE, "Toplam" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO, + "Hata Ayıklama Bilgisi Gönder" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_DEBUG_INFO, + "Hata ayıklama bilgisi kaydedilemedi." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_DEBUG_INFO, + "Sunucuya hata ayıklama bilgisi gönderilemedi." + ) +MSG_HASH( + MSG_SENDING_DEBUG_INFO, + "Hata ayıklama bilgisi gönderiliyor..." + ) +MSG_HASH( + MSG_SENT_DEBUG_INFO, + "Sunucuya hata ayıklama bilgisi başarıyla gönderildi. Kimlik numaranız %u." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO, + "Analiz için cihazların ve RetroArch yapılandırmasına ilişkin teşhis bilgilerini gönderir." + ) +MSG_HASH( + MSG_PRESS_TWO_MORE_TIMES_TO_SEND_DEBUG_INFO, + "RetroArch ekibine tanılama bilgileri göndermek için iki kez daha basın." + ) +MSG_HASH( + MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO, + "RetroArch ekibine tanılama bilgileri göndermek için bir kez daha basın." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIBRATE_ON_KEYPRESS, "Tuşa Basınca titret" diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index d5abf3a67f..e74180ace1 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -108,6 +108,10 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Toggles frames per second counter."); break; + case RARCH_SEND_DEBUG_INFO: + snprintf(s, len, + "Sends diagnostic info about your device and RetroArch configuration to our servers for analysis."); + break; case RARCH_NETPLAY_HOST_TOGGLE: snprintf(s, len, "Toggles netplay hosting on/off."); diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 78bdce1abf..5aaddcd2d9 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1386,6 +1386,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FRAMEADVANCE, "Frameadvance" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, + "Send Debug Info" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, "FPS toggle" @@ -9434,6 +9438,38 @@ MSG_HASH( MENU_ENUM_SUBLABEL_PLAYLIST_FUZZY_ARCHIVE_MATCH, "When searching playlists for entries associated with compressed files, match only the archive file name instead of [file name]+[content]. Enable this to avoid duplicate content history entries when loading compressed files." ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO, + "Send Debug Info" + ) +MSG_HASH( + MSG_FAILED_TO_SAVE_DEBUG_INFO, + "Failed to save debug info." + ) +MSG_HASH( + MSG_FAILED_TO_SEND_DEBUG_INFO, + "Failed to send debug info to server." + ) +MSG_HASH( + MSG_SENDING_DEBUG_INFO, + "Sending debug info..." + ) +MSG_HASH( + MSG_SENT_DEBUG_INFO, + "Sent debug info to server successfully. Your ID number is %u." + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO, + "Sends diagnostic info about your device and RetroArch configuration to our servers for analysis." + ) +MSG_HASH( + MSG_PRESS_TWO_MORE_TIMES_TO_SEND_DEBUG_INFO, + "Press two more times to submit diagnostic info to the RetroArch team." + ) +MSG_HASH( + MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO, + "Press one more time to submit diagnostic info to the RetroArch team." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_VIBRATE_ON_KEYPRESS, "Vibrate on key press" diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index 7edca8c465..4881271f60 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -5960,6 +5960,12 @@ static int (funcname)(const char *path, const char *label, unsigned type, size_t return generic_action_ok_help(path, label, type, idx, entry_idx, _id, _id2); \ } +static int action_ok_help_send_debug_info(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + command_event(CMD_EVENT_SEND_DEBUG_INFO, NULL); + return 0; +} + default_action_ok_help(action_ok_help_audio_video_troubleshooting, MENU_ENUM_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING, MENU_DIALOG_HELP_AUDIO_VIDEO_TROUBLESHOOTING) default_action_ok_help(action_ok_help, MENU_ENUM_LABEL_HELP, MENU_DIALOG_WELCOME) default_action_ok_help(action_ok_help_controls, MENU_ENUM_LABEL_HELP_CONTROLS, MENU_DIALOG_HELP_CONTROLS) @@ -6640,6 +6646,9 @@ static int menu_cbs_init_bind_ok_compare_label(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING: BIND_ACTION_OK(cbs, action_ok_help_audio_video_troubleshooting); break; + case MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO: + BIND_ACTION_OK(cbs, action_ok_help_send_debug_info); + break; case MENU_ENUM_LABEL_HELP_SCANNING_CONTENT: BIND_ACTION_OK(cbs, action_ok_help_scanning_content); break; diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index ae5345063f..015bef33a5 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -733,6 +733,7 @@ default_sublabel_macro(action_bind_sublabel_menu_rgui_full_width_layout, default_sublabel_macro(action_bind_sublabel_menu_rgui_extended_ascii, MENU_ENUM_SUBLABEL_MENU_RGUI_EXTENDED_ASCII) default_sublabel_macro(action_bind_sublabel_thumbnails_updater_list, MENU_ENUM_SUBLABEL_THUMBNAILS_UPDATER_LIST) default_sublabel_macro(action_bind_sublabel_pl_thumbnails_updater_list, MENU_ENUM_SUBLABEL_PL_THUMBNAILS_UPDATER_LIST) +default_sublabel_macro(action_bind_sublabel_help_send_debug_info, MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO) default_sublabel_macro(action_bind_sublabel_rdb_entry_detail, MENU_ENUM_SUBLABEL_RDB_ENTRY_DETAIL) default_sublabel_macro(action_bind_sublabel_manual_content_scan_list, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_LIST) default_sublabel_macro(action_bind_sublabel_manual_content_scan_dir, MENU_ENUM_SUBLABEL_MANUAL_CONTENT_SCAN_DIR) @@ -3134,6 +3135,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_PL_THUMBNAILS_UPDATER_LIST: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_pl_thumbnails_updater_list); break; + case MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_help_send_debug_info); + break; case MENU_ENUM_LABEL_RDB_ENTRY_DETAIL: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_rdb_entry_detail); break; diff --git a/menu/drivers/ozone/ozone_texture.c b/menu/drivers/ozone/ozone_texture.c index e69e33c19d..7bb6d281cf 100644 --- a/menu/drivers/ozone/ozone_texture.c +++ b/menu/drivers/ozone/ozone_texture.c @@ -163,6 +163,7 @@ menu_texture_item ozone_entries_icon_get_texture(ozone_handle_t *ozone, case MENU_ENUM_LABEL_HELP_WHAT_IS_A_CORE: case MENU_ENUM_LABEL_HELP_CHANGE_VIRTUAL_GAMEPAD: case MENU_ENUM_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING: + case MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO: return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_HELP]; case MENU_ENUM_LABEL_QUIT_RETROARCH: case MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE: diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 3f4659f17d..15da4b7e7e 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2452,6 +2452,7 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, case MENU_ENUM_LABEL_HELP_WHAT_IS_A_CORE: case MENU_ENUM_LABEL_HELP_CHANGE_VIRTUAL_GAMEPAD: case MENU_ENUM_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING: + case MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO: return xmb->textures.list[XMB_TEXTURE_HELP]; case MENU_ENUM_LABEL_QUIT_RETROARCH: case MENU_ENUM_LABEL_BLOCK_SRAM_OVERWRITE: diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index bd9b27c23c..8a233614e0 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4414,6 +4414,12 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct MENU_ENUM_LABEL_HELP_CONTROLS, 0, 0, 0)) count++; + if (menu_entries_append_enum(list, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO), + msg_hash_to_str(MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO), + MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO, + 0, 0, 0)) + count++; break; case DISPLAYLIST_AUDIO_RESAMPLER_SETTINGS_LIST: if (menu_displaylist_parse_settings_enum(list, diff --git a/menu/widgets/menu_dialog.c b/menu/widgets/menu_dialog.c index c5657cb3f4..636caa970d 100644 --- a/menu/widgets/menu_dialog.c +++ b/menu/widgets/menu_dialog.c @@ -197,6 +197,11 @@ int menu_dialog_iterate(char *s, size_t len, const char *label) MENU_ENUM_LABEL_VALUE_HELP_AUDIO_VIDEO_TROUBLESHOOTING_DESC, s, len); break; + case MENU_DIALOG_HELP_SEND_DEBUG_INFO: + menu_hash_get_help_enum( + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO_DESC, + s, len); + break; case MENU_DIALOG_HELP_SCANNING_CONTENT: menu_hash_get_help_enum(MENU_ENUM_LABEL_VALUE_HELP_SCANNING_CONTENT_DESC, s, len); diff --git a/msg_hash.h b/msg_hash.h index 17a37d11f6..4f0be461a4 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -806,6 +806,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE, + MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, @@ -2707,6 +2708,16 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_DM_HM_AM_PM, MENU_ENUM_LABEL_VALUE_PLAYLIST_SUBLABEL_LAST_PLAYED_STYLE_MD_HM_AM_PM, + MENU_LABEL(HELP_SEND_DEBUG_INFO), + MENU_ENUM_LABEL_VALUE_HELP_SEND_DEBUG_INFO_DESC, + + MSG_FAILED_TO_SAVE_DEBUG_INFO, + MSG_FAILED_TO_SEND_DEBUG_INFO, + MSG_SENDING_DEBUG_INFO, + MSG_SENT_DEBUG_INFO, + MSG_PRESS_TWO_MORE_TIMES_TO_SEND_DEBUG_INFO, + MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO, + MENU_LABEL(VIBRATE_ON_KEYPRESS), MENU_LABEL(ENABLE_DEVICE_VIBRATION), MENU_LABEL(VIDEO_GPU_INDEX), diff --git a/retroarch.c b/retroarch.c index 17536d3c88..426772a3d7 100644 --- a/retroarch.c +++ b/retroarch.c @@ -974,6 +974,8 @@ static const camera_driver_t *camera_drivers[] = { #define QUIT_DELAY_USEC 3 * 1000000 /* 3 seconds */ +#define DEBUG_INFO_FILENAME "debug_info.txt" + /* Descriptive names for options without short variant. * * Please keep the name in sync with the option name. @@ -3412,6 +3414,7 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = { DECLARE_META_BIND(2, audio_mute, RARCH_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE), DECLARE_META_BIND(2, osk_toggle, RARCH_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK), DECLARE_META_BIND(2, fps_toggle, RARCH_FPS_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_FPS_TOGGLE), + DECLARE_META_BIND(2, send_debug_info, RARCH_SEND_DEBUG_INFO, MENU_ENUM_LABEL_VALUE_INPUT_META_SEND_DEBUG_INFO), DECLARE_META_BIND(2, netplay_host_toggle, RARCH_NETPLAY_HOST_TOGGLE, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_HOST_TOGGLE), DECLARE_META_BIND(2, netplay_game_watch, RARCH_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH), DECLARE_META_BIND(2, enable_hotkey, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY), @@ -3569,6 +3572,9 @@ static void core_free_retro_game_info(struct retro_game_info *dest); static bool core_load(unsigned poll_type_behavior); static bool core_unload_game(void); +#ifdef HAVE_NETWORKING +static void rarch_send_debug_info(void); +#endif static bool rarch_environment_cb(unsigned cmd, void *data); static bool driver_location_get_position(double *lat, double *lon, @@ -3781,6 +3787,7 @@ static const struct cmd_map map[] = { { "MUTE", RARCH_MUTE }, { "OSK", RARCH_OSK }, { "FPS_TOGGLE", RARCH_FPS_TOGGLE }, + { "SEND_DEBUG_INFO", RARCH_SEND_DEBUG_INFO }, { "NETPLAY_HOST_TOGGLE", RARCH_NETPLAY_HOST_TOGGLE }, { "NETPLAY_GAME_WATCH", RARCH_NETPLAY_GAME_WATCH }, { "VOLUME_UP", RARCH_VOLUME_UP }, @@ -6742,6 +6749,11 @@ TODO: Add a setting for these tweaks */ runloop_msg_queue_push(msg, 1, 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); } break; + case CMD_EVENT_SEND_DEBUG_INFO: +#ifdef HAVE_NETWORKING + rarch_send_debug_info(); +#endif + break; case CMD_EVENT_FPS_TOGGLE: { settings_t *settings = configuration_settings; @@ -14993,6 +15005,7 @@ static void menu_input_pointer_close_messagebox(void) string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HELP_SCANNING_CONTENT)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HELP_CHANGE_VIRTUAL_GAMEPAD)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HELP_AUDIO_VIDEO_TROUBLESHOOTING)) || + string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HELP_SEND_DEBUG_INFO)) || string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_CHEEVOS_DESCRIPTION))) { /* Have to set this to false, apparently... @@ -15755,6 +15768,7 @@ static void input_menu_keys_pressed(input_bits_t *p_new_state, {RETROK_DELETE, RETRO_DEVICE_ID_JOYPAD_Y }, {0, RARCH_UI_COMPANION_TOGGLE }, {0, RARCH_FPS_TOGGLE }, + {0, RARCH_SEND_DEBUG_INFO }, {0, RARCH_NETPLAY_HOST_TOGGLE }, {0, RARCH_MENU_TOGGLE }, }; @@ -15763,6 +15777,7 @@ static void input_menu_keys_pressed(input_bits_t *p_new_state, ids[10][0] = input_config_binds[0][RARCH_FULLSCREEN_TOGGLE_KEY].key; ids[14][0] = input_config_binds[0][RARCH_UI_COMPANION_TOGGLE].key; ids[15][0] = input_config_binds[0][RARCH_FPS_TOGGLE].key; + ids[16][0] = input_config_binds[0][RARCH_SEND_DEBUG_INFO].key; ids[17][0] = input_config_binds[0][RARCH_NETPLAY_HOST_TOGGLE].key; ids[18][0] = input_config_binds[0][RARCH_MENU_TOGGLE].key; @@ -27194,6 +27209,61 @@ static enum runloop_state runloop_check_state(void) old_pressed = pressed; } + /* Check if we have pressed the "send debug info" button. + * Must press 3 times in a row to activate, but it will + * alert the user of this with each press of the hotkey. */ + { + int any_i; + static uint32_t debug_seq = 0; + static bool old_pressed = false; + static bool old_any_pressed = false; + bool any_pressed = false; + bool pressed = BIT256_GET(current_bits, RARCH_SEND_DEBUG_INFO); + + for (any_i = 0; any_i < ARRAY_SIZE(current_bits.data); any_i++) + { + if (current_bits.data[any_i]) + { + any_pressed = true; + break; + } + } + + if (pressed && !old_pressed) + debug_seq |= pressed ? 1 : 0; + + switch (debug_seq) + { + case 1: /* pressed hotkey one time */ + runloop_msg_queue_push( + msg_hash_to_str(MSG_PRESS_TWO_MORE_TIMES_TO_SEND_DEBUG_INFO), + 2, 180, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + break; + case 3: /* pressed hotkey two times */ + runloop_msg_queue_push( + msg_hash_to_str(MSG_PRESS_ONE_MORE_TIME_TO_SEND_DEBUG_INFO), + 2, 180, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + break; + case 7: /* pressed hotkey third and final time */ + debug_seq = 0; + command_event(CMD_EVENT_SEND_DEBUG_INFO, NULL); + break; + } + + if (any_pressed && !old_any_pressed) + { + debug_seq <<= 1; + + if (debug_seq > 7) + debug_seq = 0; + } + + old_pressed = pressed; + old_any_pressed = any_pressed; + } + /* Check if we have pressed the FPS toggle button */ HOTKEY_CHECK(RARCH_FPS_TOGGLE, CMD_EVENT_FPS_TOGGLE, true, NULL); @@ -27881,6 +27951,625 @@ void rarch_get_cpu_architecture_string(char *cpu_arch_str, size_t len) } } +#ifdef HAVE_NETWORKING +static bool rarch_write_debug_info(void) +{ + int i; + char str[PATH_MAX_LENGTH]; + char debug_filepath[PATH_MAX_LENGTH]; + gfx_ctx_mode_t mode_info = {0}; + settings_t *settings = configuration_settings; + RFILE *file = NULL; + const frontend_ctx_driver_t *frontend = frontend_get_ptr(); + const char *cpu_model = NULL; + const char *path_config = path_get(RARCH_PATH_CONFIG); + unsigned lang = + *msg_hash_get_uint(MSG_HASH_USER_LANGUAGE); + + str[0] = + debug_filepath[0] = '\0'; + + /* Only print our debug info in English */ + if (lang != RETRO_LANGUAGE_ENGLISH) + msg_hash_set_uint(MSG_HASH_USER_LANGUAGE, RETRO_LANGUAGE_ENGLISH); + + fill_pathname_resolve_relative( + debug_filepath, + path_config, + DEBUG_INFO_FILENAME, + sizeof(debug_filepath)); + + file = filestream_open(debug_filepath, + RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE); + + if (!file) + { + RARCH_ERR("Could not open debug info file for writing: %s\n", debug_filepath); + goto error; + } + +#ifdef HAVE_MENU + { + time_t time_; + char timedate[255]; + + timedate[0] = '\0'; + + time(&time_); + + setlocale(LC_TIME, ""); + + strftime(timedate, sizeof(timedate), + "%Y-%m-%d %H:%M:%S", localtime(&time_)); + + filestream_printf(file, "Log Date/Time: %s\n", timedate); + } +#endif + filestream_printf(file, "RetroArch Version: %s\n", PACKAGE_VERSION); + +#ifdef HAVE_LAKKA + if (frontend->get_lakka_version) + { + frontend->get_lakka_version(str, sizeof(str)); + filestream_printf(file, "Lakka Version: %s\n", str); + str[0] = '\0'; + } +#endif + + filestream_printf(file, "RetroArch Build Date: %s\n", __DATE__); +#ifdef HAVE_GIT_VERSION + filestream_printf(file, "RetroArch Git Commit: %s\n", retroarch_git_version); +#endif + + filestream_printf(file, "\n"); + + cpu_model = frontend_driver_get_cpu_model_name(); + + if (!string_is_empty(cpu_model)) + filestream_printf(file, "CPU Model Name: %s\n", cpu_model); + + retroarch_get_capabilities(RARCH_CAPABILITIES_CPU, str, sizeof(str)); + filestream_printf(file, "CPU Capabilities: %s\n", str); + + str[0] = '\0'; + + rarch_get_cpu_architecture_string(str, sizeof(str)); + + filestream_printf(file, "CPU Architecture: %s\n", str); + filestream_printf(file, "CPU Cores: %u\n", cpu_features_get_core_amount()); + + { + uint64_t memory_free = frontend_driver_get_free_memory(); + uint64_t memory_total = frontend_driver_get_total_memory(); + + filestream_printf(file, "Memory: %" PRIu64 "/%" PRIu64 " MB\n", memory_free / 1024 / 1024, memory_total / 1024 / 1024); + } + + filestream_printf(file, "GPU Device: %s\n", !string_is_empty(video_driver_get_gpu_device_string()) ? + video_driver_get_gpu_device_string() : "n/a"); + filestream_printf(file, "GPU API/Driver Version: %s\n", !string_is_empty(video_driver_get_gpu_api_version_string()) ? + video_driver_get_gpu_api_version_string() : "n/a"); + + filestream_printf(file, "\n"); + + video_context_driver_get_video_size(&mode_info); + + filestream_printf(file, "Window Resolution: %u x %u\n", mode_info.width, mode_info.height); + + { + float width = 0, height = 0, refresh = 0.0f; + gfx_ctx_metrics_t metrics; + + metrics.type = DISPLAY_METRIC_PIXEL_WIDTH; + metrics.value = &width; + + video_context_driver_get_metrics(&metrics); + + metrics.type = DISPLAY_METRIC_PIXEL_HEIGHT; + metrics.value = &height; + video_context_driver_get_metrics(&metrics); + + video_context_driver_get_refresh_rate(&refresh); + + filestream_printf(file, "Monitor Resolution: %d x %d @ %.2f Hz (configured for %.2f Hz)\n", (int)width, (int)height, refresh, settings->floats.video_refresh_rate); + } + + filestream_printf(file, "\n"); + + str[0] = '\0'; + + retroarch_get_capabilities(RARCH_CAPABILITIES_COMPILER, str, sizeof(str)); + filestream_printf(file, "%s\n", str); + + str[0] = '\0'; + + filestream_printf(file, "Frontend Identifier: %s\n", frontend->ident); + + if (frontend->get_name) + { + frontend->get_name(str, sizeof(str)); + filestream_printf(file, "Frontend Name: %s\n", str); + str[0] = '\0'; + } + + if (frontend->get_os) + { + int major = 0, minor = 0; + const char *warning = ""; + + frontend->get_os(str, sizeof(str), &major, &minor); + + if (strstr(str, "Build 16299")) + warning = " (WARNING: Fall Creator's Update detected... OpenGL performance may be low)"; + + filestream_printf(file, "Frontend OS: %s (v%d.%d)%s\n", str, major, minor, warning); + + str[0] = '\0'; + } + + filestream_printf(file, "\n"); + filestream_printf(file, "Input Devices (autoconfig is %s):\n", settings->bools.input_autodetect_enable ? "enabled" : "disabled"); + + for (i = 0; i < 4; i++) + { + if (input_is_autoconfigured(i)) + { + unsigned retro_id; + unsigned rebind = 0; + unsigned device = settings->uints.input_libretro_device[i]; + + device &= RETRO_DEVICE_MASK; + + if (device == RETRO_DEVICE_JOYPAD || device == RETRO_DEVICE_ANALOG) + { + for (retro_id = 0; retro_id < RARCH_ANALOG_BIND_LIST_END; retro_id++) + { + char descriptor[300]; + const struct retro_keybind *keybind = &input_config_binds[i][retro_id]; + const struct retro_keybind *auto_bind = (const struct retro_keybind*) + input_config_get_bind_auto(i, retro_id); + + input_config_get_bind_string(descriptor, + keybind, auto_bind, sizeof(descriptor)); + + if (!strstr(descriptor, "Auto") + && auto_bind + && !auto_bind->valid + && (auto_bind->joykey != 0xFFFF) + && !string_is_empty(auto_bind->joykey_label)) + rebind++; + } + } + + if (rebind) + filestream_printf(file, " - Port #%d autoconfigured (WARNING: %u keys rebinded):\n", i, rebind); + else + filestream_printf(file, " - Port #%d autoconfigured:\n", i); + + filestream_printf(file, " - Device name: %s (#%d)\n", + input_config_get_device_name(i), + input_autoconfigure_get_device_name_index(i)); + filestream_printf(file, " - Display name: %s\n", + input_config_get_device_display_name(i) ? + input_config_get_device_display_name(i) : "N/A"); + filestream_printf(file, " - Config path: %s\n", + input_config_get_device_display_name(i) ? + input_config_get_device_config_path(i) : "N/A"); + filestream_printf(file, " - VID/PID: %d/%d (0x%04X/0x%04X)\n", + input_config_get_vid(i), input_config_get_pid(i), + input_config_get_vid(i), input_config_get_pid(i)); + } + else + filestream_printf(file, " - Port #%d not autoconfigured\n", i); + } + + filestream_printf(file, "\n"); + + filestream_printf(file, "Drivers:\n"); + + { + gfx_ctx_ident_t ident_info = {0}; + input_driver_t *input_driver = NULL; + const input_device_driver_t *joypad_driver = NULL; + const char *driver = NULL; +#ifdef HAVE_MENU + driver = menu_driver_ident(); + + if (string_is_equal(driver, settings->arrays.menu_driver)) + filestream_printf(file, " - Menu: %s\n", + !string_is_empty(driver) ? driver : "n/a"); + else + filestream_printf(file, " - Menu: %s (configured for %s)\n", + !string_is_empty(driver) + ? driver + : "n/a", + !string_is_empty(settings->arrays.menu_driver) + ? settings->arrays.menu_driver + : "n/a"); +#endif + driver = video_driver_get_ident(); + + if (string_is_equal(driver, settings->arrays.video_driver)) + filestream_printf(file, " - Video: %s\n", + !string_is_empty(driver) + ? driver + : "n/a"); + else + filestream_printf(file, " - Video: %s (configured for %s)\n", + !string_is_empty(driver) + ? driver + : "n/a", + !string_is_empty(settings->arrays.video_driver) + ? settings->arrays.video_driver + : "n/a"); + + video_context_driver_get_ident(&ident_info); + filestream_printf(file, " - Video Context: %s\n", + ident_info.ident ? ident_info.ident : "n/a"); + + driver = NULL; + if (current_audio) + driver = current_audio->ident; + + if (string_is_equal(driver, settings->arrays.audio_driver)) + filestream_printf(file, " - Audio: %s\n", + !string_is_empty(driver) ? driver : "n/a"); + else + filestream_printf(file, " - Audio: %s (configured for %s)\n", + !string_is_empty(driver) ? driver : "n/a", + !string_is_empty(settings->arrays.audio_driver) ? settings->arrays.audio_driver : "n/a"); + + input_driver = current_input; + + if (input_driver && string_is_equal(input_driver->ident, settings->arrays.input_driver)) + filestream_printf(file, " - Input: %s\n", !string_is_empty(input_driver->ident) ? input_driver->ident : "n/a"); + else + filestream_printf(file, " - Input: %s (configured for %s)\n", !string_is_empty(input_driver->ident) ? input_driver->ident : "n/a", !string_is_empty(settings->arrays.input_driver) ? settings->arrays.input_driver : "n/a"); + + joypad_driver = (input_driver->get_joypad_driver ? input_driver->get_joypad_driver(current_input_data) : NULL); + + if (joypad_driver && string_is_equal(joypad_driver->ident, settings->arrays.input_joypad_driver)) + filestream_printf(file, " - Joypad: %s\n", !string_is_empty(joypad_driver->ident) ? joypad_driver->ident : "n/a"); + else + filestream_printf(file, " - Joypad: %s (configured for %s)\n", !string_is_empty(joypad_driver->ident) ? joypad_driver->ident : "n/a", !string_is_empty(settings->arrays.input_joypad_driver) ? settings->arrays.input_joypad_driver : "n/a"); + } + + filestream_printf(file, "\n"); + + filestream_printf(file, "Configuration related settings:\n"); + filestream_printf(file, " - Save on exit: %s\n", settings->bools.config_save_on_exit ? "yes" : "no"); + filestream_printf(file, " - Load content-specific core options automatically: %s\n", settings->bools.game_specific_options ? "yes" : "no"); + filestream_printf(file, " - Load override files automatically: %s\n", settings->bools.auto_overrides_enable ? "yes" : "no"); + filestream_printf(file, " - Load remap files automatically: %s\n", settings->bools.auto_remaps_enable ? "yes" : "no"); + filestream_printf(file, " - Sort saves in folders: %s\n", settings->bools.sort_savefiles_enable ? "yes" : "no"); + filestream_printf(file, " - Sort states in folders: %s\n", settings->bools.sort_savestates_enable ? "yes" : "no"); + filestream_printf(file, " - Write saves in content dir: %s\n", settings->bools.savefiles_in_content_dir ? "yes" : "no"); + filestream_printf(file, " - Write savestates in content dir: %s\n", settings->bools.savestates_in_content_dir ? "yes" : "no"); + + filestream_printf(file, "\n"); + + filestream_printf(file, "Auto load state: %s\n", settings->bools.savestate_auto_load ? "yes (WARNING: not compatible with all cores)" : "no"); + filestream_printf(file, "Auto save state: %s\n", settings->bools.savestate_auto_save ? "yes" : "no"); + + filestream_printf(file, "\n"); + + filestream_printf(file, "Buildbot cores URL: %s\n", settings->paths.network_buildbot_url); + filestream_printf(file, "Auto-extract downloaded archives: %s\n", settings->bools.network_buildbot_auto_extract_archive ? "yes" : "no"); + + { + size_t count = 0; + core_info_list_t *core_info_list = NULL; + struct string_list *list = NULL; + const char *ext = ".rdb"; + + /* remove dot */ + if (!string_is_empty(ext) && ext[0] == '.' && strlen(ext) > 1) + ext++; + + core_info_get_list(&core_info_list); + + if (core_info_list) + count = core_info_list->count; + + filestream_printf(file, "Core info: %u entries\n", count); + + count = 0; + + list = dir_list_new(settings->paths.path_content_database, ext, false, true, false, true); + + if (list) + { + count = list->size; + string_list_free(list); + } + + filestream_printf(file, "Databases: %u entries\n", count); + } + + filestream_printf(file, "\n"); + + filestream_printf(file, "Performance and latency-sensitive features (may have a large impact depending on the core):\n"); + filestream_printf(file, " - Video:\n"); + filestream_printf(file, " - Runahead: %s\n", settings->bools.run_ahead_enabled ? "yes (WARNING: not compatible with all cores)" : "no"); + filestream_printf(file, " - Rewind: %s\n", settings->bools.rewind_enable ? "yes (WARNING: not compatible with all cores)" : "no"); + filestream_printf(file, " - Hard GPU Sync: %s\n", settings->bools.video_hard_sync ? "yes" : "no"); + filestream_printf(file, " - Frame Delay: %u frames\n", settings->uints.video_frame_delay); + filestream_printf(file, " - Max Swapchain Images: %u\n", settings->uints.video_max_swapchain_images); + filestream_printf(file, " - Max Run Speed: %.1f x\n", settings->floats.fastforward_ratio); + filestream_printf(file, " - Sync to exact content framerate: %s\n", settings->bools.vrr_runloop_enable ? "yes (note: designed for G-Sync/FreeSync displays only)" : "no"); + filestream_printf(file, " - Fullscreen: %s\n", settings->bools.video_fullscreen ? "yes" : "no"); + filestream_printf(file, " - Windowed Fullscreen: %s\n", settings->bools.video_windowed_fullscreen ? "yes" : "no"); + filestream_printf(file, " - Threaded Video: %s\n", settings->bools.video_threaded ? "yes" : "no"); + filestream_printf(file, " - Vsync: %s\n", settings->bools.video_vsync ? "yes" : "no"); + filestream_printf(file, " - Vsync Swap Interval: %u frames\n", settings->uints.video_swap_interval); + filestream_printf(file, " - Black Frame Insertion: %s\n", settings->bools.video_black_frame_insertion ? "yes" : "no"); + filestream_printf(file, " - Bilinear Filtering: %s\n", settings->bools.video_smooth ? "yes" : "no"); + filestream_printf(file, " - Video CPU Filter: %s\n", !string_is_empty(settings->paths.path_softfilter_plugin) ? settings->paths.path_softfilter_plugin : "n/a"); + filestream_printf(file, " - CRT SwitchRes: %s\n", (settings->uints.crt_switch_resolution > CRT_SWITCH_NONE) ? "yes" : "no"); + filestream_printf(file, " - Video Shared Context: %s\n", settings->bools.video_shared_context ? "yes" : "no"); + +#if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_SLANG) || defined(HAVE_HLSL) + { + video_shader_ctx_t shader_info = {0}; + + video_shader_driver_get_current_shader(&shader_info); + + if (shader_info.data) + { + if (string_is_equal(shader_info.data->path, runtime_shader_preset)) + filestream_printf(file, " - Video Shader: %s\n", !string_is_empty(runtime_shader_preset) ? runtime_shader_preset : "n/a"); + else + filestream_printf(file, " - Video Shader: %s (configured for %s)\n", !string_is_empty(shader_info.data->path) ? shader_info.data->path : "n/a", !string_is_empty(runtime_shader_preset) ? runtime_shader_preset : "n/a"); + } + else + filestream_printf(file, " - Video Shader: n/a\n"); + } +#endif + + filestream_printf(file, " - Audio:\n"); + filestream_printf(file, " - Audio Enabled: %s\n", settings->bools.audio_enable ? "yes" : "no (WARNING: content framerate will be incorrect)"); + filestream_printf(file, " - Audio Sync: %s\n", settings->bools.audio_sync ? "yes" : "no (WARNING: content framerate will be incorrect)"); + + { + const char *s = NULL; + + switch (settings->uints.audio_resampler_quality) + { + case RESAMPLER_QUALITY_DONTCARE: + s = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DONT_CARE); + break; + case RESAMPLER_QUALITY_LOWEST: + s = msg_hash_to_str(MSG_RESAMPLER_QUALITY_LOWEST); + break; + case RESAMPLER_QUALITY_LOWER: + s = msg_hash_to_str(MSG_RESAMPLER_QUALITY_LOWER); + break; + case RESAMPLER_QUALITY_HIGHER: + s = msg_hash_to_str(MSG_RESAMPLER_QUALITY_HIGHER); + break; + case RESAMPLER_QUALITY_HIGHEST: + s = msg_hash_to_str(MSG_RESAMPLER_QUALITY_HIGHEST); + break; + case RESAMPLER_QUALITY_NORMAL: + s = msg_hash_to_str(MSG_RESAMPLER_QUALITY_NORMAL); + break; + } + + filestream_printf(file, " - Resampler Quality: %s\n", !string_is_empty(s) ? s : "n/a"); + } + + filestream_printf(file, " - Audio Latency: %u ms\n", settings->uints.audio_latency); + filestream_printf(file, " - Dynamic Rate Control (DRC): %.3f\n", *audio_get_float_ptr(AUDIO_ACTION_RATE_CONTROL_DELTA)); + filestream_printf(file, " - Max Timing Skew: %.2f\n", settings->floats.audio_max_timing_skew); + filestream_printf(file, " - Output Rate: %u Hz\n", settings->uints.audio_out_rate); + filestream_printf(file, " - DSP Plugin: %s\n", !string_is_empty(settings->paths.path_audio_dsp_plugin) ? settings->paths.path_audio_dsp_plugin : "n/a"); + + { + core_info_list_t *core_info_list = NULL; + bool found = false; + + filestream_printf(file, "\n"); + filestream_printf(file, "Firmware files found:\n"); + + core_info_get_list(&core_info_list); + + if (core_info_list) + { + unsigned i; + + for (i = 0; i < core_info_list->count; i++) + { + core_info_t *info = &core_info_list->list[i]; + + if (!info) + continue; + + if (info->firmware_count) + { + unsigned j; + bool core_found = false; + + for (j = 0; j < info->firmware_count; j++) + { + core_info_firmware_t *firmware = &info->firmware[j]; + char path[PATH_MAX_LENGTH]; + + if (!firmware) + continue; + + path[0] = '\0'; + + fill_pathname_join( + path, + settings->paths.directory_system, + firmware->path, + sizeof(path)); + + if (filestream_exists(path)) + { + found = true; + + if (!core_found) + { + core_found = true; + filestream_printf(file, " - %s:\n", !string_is_empty(info->core_name) ? info->core_name : path_basename(info->path)); + } + + filestream_printf(file, " - %s (%s)\n", firmware->path, firmware->optional ? "optional" : "required"); + } + } + } + } + } + + if (!found) + filestream_printf(file, " - n/a\n"); + } + + filestream_close(file); + + RARCH_LOG("Wrote debug info to %s\n", debug_filepath); + + msg_hash_set_uint(MSG_HASH_USER_LANGUAGE, lang); + + return true; + +error: + return false; +} + +static void send_debug_info_cb(retro_task_t *task, + void *task_data, void *user_data, const char *error) +{ + if (task_data) + { + http_transfer_data_t *data = (http_transfer_data_t*)task_data; + + if (!data || data->len == 0) + { + RARCH_LOG("%s\n", msg_hash_to_str(MSG_FAILED_TO_SEND_DEBUG_INFO)); + + runloop_msg_queue_push( + msg_hash_to_str(MSG_FAILED_TO_SEND_DEBUG_INFO), + 2, 180, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR); + free(task_data); + return; + } + + /* don't use string_is_equal() here instead of the memcmp() because the data isn't NULL-terminated */ + if (!string_is_empty(data->data) && data->len >= 2 && !memcmp(data->data, "OK", 2)) + { + char buf[32] = {0}; + struct string_list *list; + + memcpy(buf, data->data, data->len); + + list = string_split(buf, " "); + + if (list && list->size > 1) + { + unsigned id = 0; + char msg[PATH_MAX_LENGTH]; + + msg[0] = '\0'; + + sscanf(list->elems[1].data, "%u", &id); + + snprintf(msg, sizeof(msg), msg_hash_to_str(MSG_SENT_DEBUG_INFO), id); + + RARCH_LOG("%s\n", msg); + + runloop_msg_queue_push( + msg, + 2, 600, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + } + + if (list) + string_list_free(list); + } + else + { + RARCH_LOG("%s\n", msg_hash_to_str(MSG_FAILED_TO_SEND_DEBUG_INFO)); + + runloop_msg_queue_push( + msg_hash_to_str(MSG_FAILED_TO_SEND_DEBUG_INFO), + 2, 180, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR); + } + + free(task_data); + } + else + { + RARCH_LOG("%s\n", msg_hash_to_str(MSG_FAILED_TO_SEND_DEBUG_INFO)); + + runloop_msg_queue_push( + msg_hash_to_str(MSG_FAILED_TO_SEND_DEBUG_INFO), + 2, 180, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR); + } +} + +static void rarch_send_debug_info(void) +{ + char debug_filepath[PATH_MAX_LENGTH]; + const char *url = "http://lobby.libretro.com/debuginfo/add/"; + char *info_buf = NULL; + const size_t param_buf_size = 65535; + char *param_buf = (char*)malloc(param_buf_size); + char *param_buf_tmp = NULL; + int param_buf_pos = 0; + int64_t len = 0; + const char *path_config = path_get(RARCH_PATH_CONFIG); + bool info_written = rarch_write_debug_info(); + + debug_filepath[0] = + param_buf[0] = '\0'; + + fill_pathname_resolve_relative( + debug_filepath, + path_config, + DEBUG_INFO_FILENAME, + sizeof(debug_filepath)); + + if (info_written) + filestream_read_file(debug_filepath, (void**)&info_buf, &len); + + if (string_is_empty(info_buf) || len == 0 || !info_written) + { + runloop_msg_queue_push( + msg_hash_to_str(MSG_FAILED_TO_SAVE_DEBUG_INFO), + 2, 180, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_ERROR); + goto finish; + } + + RARCH_LOG("%s\n", msg_hash_to_str(MSG_SENDING_DEBUG_INFO)); + + runloop_msg_queue_push( + msg_hash_to_str(MSG_SENDING_DEBUG_INFO), + 2, 180, true, + NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); + + param_buf_pos = (int)strlcpy(param_buf, "info=", param_buf_size); + param_buf_tmp = param_buf + param_buf_pos; + + net_http_urlencode(¶m_buf_tmp, info_buf); + + strlcat(param_buf, param_buf_tmp, param_buf_size - param_buf_pos); + + task_push_http_post_transfer(url, param_buf, true, NULL, send_debug_info_cb, NULL); + +finish: + if (param_buf) + free(param_buf); + if (info_buf) + free(info_buf); +} +#endif + void rarch_log_file_init(void) { char log_directory[PATH_MAX_LENGTH];