From b8e71dab88ad4b40dc6b7890f96f8199cd3509da Mon Sep 17 00:00:00 2001 From: Pit64 Date: Wed, 29 Nov 2023 19:10:41 +0100 Subject: [PATCH 01/12] feat(webmanager): add webm mime type for videos --- projects/frontend/es-app/src/web/server/handlers/Mime.cpp | 1 + projects/frontend/es-app/src/web/server/handlers/Mime.h | 2 ++ .../frontend/es-app/src/web/server/handlers/RequestHandler.cpp | 2 ++ .../es-app/src/web/server/handlers/RequestHandlerTools.cpp | 3 ++- projects/frontend/external/pistache/include/pistache/mime.h | 3 ++- 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/projects/frontend/es-app/src/web/server/handlers/Mime.cpp b/projects/frontend/es-app/src/web/server/handlers/Mime.cpp index c45e296c14..8de64c7029 100644 --- a/projects/frontend/es-app/src/web/server/handlers/Mime.cpp +++ b/projects/frontend/es-app/src/web/server/handlers/Mime.cpp @@ -19,6 +19,7 @@ Pistache::Http::Mime::MediaType Mime::ImageSvg(Pistache::Http::Mime::Type::Image Pistache::Http::Mime::MediaType Mime::VideoMkv(Pistache::Http::Mime::Type::Video, Pistache::Http::Mime::Subtype::Mkv); Pistache::Http::Mime::MediaType Mime::VideoMp4(Pistache::Http::Mime::Type::Video, Pistache::Http::Mime::Subtype::Mp4); Pistache::Http::Mime::MediaType Mime::VideoAvi(Pistache::Http::Mime::Type::Video, Pistache::Http::Mime::Subtype::Avi); +Pistache::Http::Mime::MediaType Mime::VideoWebm(Pistache::Http::Mime::Type::Video, Pistache::Http::Mime::Subtype::Webm); Pistache::Http::Mime::MediaType Mime::Zip(Pistache::Http::Mime::Type::Application, Pistache::Http::Mime::Subtype::OctetStream, Pistache::Http::Mime::Suffix::Zip); Pistache::Http::Mime::MediaType Mime::FontTtf(Pistache::Http::Mime::Type::Font, Pistache::Http::Mime::Subtype::Ttf); Pistache::Http::Mime::MediaType Mime::FontWoff(Pistache::Http::Mime::Type::Font, Pistache::Http::Mime::Subtype::Woff); diff --git a/projects/frontend/es-app/src/web/server/handlers/Mime.h b/projects/frontend/es-app/src/web/server/handlers/Mime.h index 5e88d76128..a5f56ae8d6 100644 --- a/projects/frontend/es-app/src/web/server/handlers/Mime.h +++ b/projects/frontend/es-app/src/web/server/handlers/Mime.h @@ -38,6 +38,8 @@ class Mime static Pistache::Http::Mime::MediaType VideoMp4; //! AVI MIME Type static Pistache::Http::Mime::MediaType VideoAvi; + //! WEBM MIME Type + static Pistache::Http::Mime::MediaType VideoWebm; //! PDF MIME Type static Pistache::Http::Mime::MediaType FilePdf; //! ttf MIME Type diff --git a/projects/frontend/es-app/src/web/server/handlers/RequestHandler.cpp b/projects/frontend/es-app/src/web/server/handlers/RequestHandler.cpp index 0f099f4619..0e8d9a2f10 100644 --- a/projects/frontend/es-app/src/web/server/handlers/RequestHandler.cpp +++ b/projects/frontend/es-app/src/web/server/handlers/RequestHandler.cpp @@ -503,6 +503,7 @@ void RequestHandler::MediaGet(const Rest::Request& request, Http::ResponseWriter else if (ext == ".mkv") RequestHandlerTools::SendResource(path, response, Mime::VideoMkv); else if (ext == ".mp4") RequestHandlerTools::SendResource(path, response, Mime::VideoMp4); else if (ext == ".avi") RequestHandlerTools::SendResource(path, response, Mime::VideoAvi); + else if (ext == ".webm") RequestHandlerTools::SendResource(path, response, Mime::VideoWebm); // Unknown else RequestHandlerTools::Send(response, Http::Code::Bad_Request, "Invalid media extension!", Mime::PlainText); } @@ -534,6 +535,7 @@ void RequestHandler::MediaGetScreenshot(const Rest::Request& request, Http::Resp else if (ext == ".mkv") RequestHandlerTools::SendResource(path, response, Mime::VideoMkv); else if (ext == ".mp4") RequestHandlerTools::SendResource(path, response, Mime::VideoMp4); else if (ext == ".avi") RequestHandlerTools::SendResource(path, response, Mime::VideoAvi); + else if (ext == ".webm") RequestHandlerTools::SendResource(path, response, Mime::VideoWebm); // Unknown else RequestHandlerTools::Send(response, Http::Code::Bad_Request, "Invalid media extension!", Mime::PlainText); } diff --git a/projects/frontend/es-app/src/web/server/handlers/RequestHandlerTools.cpp b/projects/frontend/es-app/src/web/server/handlers/RequestHandlerTools.cpp index e90277f2da..5f59e08cf1 100644 --- a/projects/frontend/es-app/src/web/server/handlers/RequestHandlerTools.cpp +++ b/projects/frontend/es-app/src/web/server/handlers/RequestHandlerTools.cpp @@ -451,6 +451,7 @@ const HashMap& RequestHandlerTools::SelectConfigurationKeySet { "debuglogs" , Validator(true) }, { "pads.osd" , Validator(true) }, { "pads.osd.type" , Validator(GetAvailableOsdTypes(), false) }, + { "tateonly" , Validator(true) }, }); return sList; @@ -705,7 +706,7 @@ const HashMap& RequestHandlerTools::SelectConfigurationKeySet { static HashMap sList ({ - { "gamerotation", Validator(0, 3) }, // Date: Wed, 29 Nov 2023 19:14:38 +0100 Subject: [PATCH 02/12] feat(webmanager): add some missing new keys It also adds the missing fetchOptions in corresponding pages --- .../emulation/EmulationGlobalTabContent.vue | 28 ++++++++ .../settings/SettingsEmuStationTabContent.vue | 24 +++++++ projects/manager3/src/i18n/en-US/index.json | 65 ++++++++++++------ projects/manager3/src/i18n/fr/index.json | 67 ++++++++++++------- projects/manager3/src/pages/EmulationPage.vue | 10 +-- projects/manager3/src/router/api.routes.ts | 1 + .../manager3/src/stores/configuration/tate.ts | 28 ++++++++ .../stores/plugins/fetchOptionsStorePlugin.ts | 13 ++-- .../src/stores/plugins/fetchStorePlugin.ts | 1 + .../src/stores/types/emulationstation.ts | 8 +++ projects/manager3/src/stores/types/global.ts | 18 +++-- projects/manager3/src/stores/types/system.ts | 14 ++-- projects/manager3/src/stores/types/tate.ts | 16 +++++ 13 files changed, 227 insertions(+), 66 deletions(-) create mode 100644 projects/manager3/src/stores/configuration/tate.ts create mode 100644 projects/manager3/src/stores/types/tate.ts diff --git a/projects/manager3/src/components/emulation/EmulationGlobalTabContent.vue b/projects/manager3/src/components/emulation/EmulationGlobalTabContent.vue index 6eda8db1a8..f61e123bf1 100755 --- a/projects/manager3/src/components/emulation/EmulationGlobalTabContent.vue +++ b/projects/manager3/src/components/emulation/EmulationGlobalTabContent.vue @@ -190,6 +190,29 @@ + + +
@@ -429,6 +452,7 @@ import { useEmulationstationStore } from 'stores/configuration/emulationstation' import { storeToRefs } from 'pinia'; import FormFragmentContainer from 'components/ui-kit/FormFragmentContainer.vue'; import { useAutorunStore } from 'stores/configuration/autorun'; +import { useTateStore } from 'stores/configuration/tate'; const globalStore = useGlobalStore(); globalStore.fetch(); @@ -453,4 +477,8 @@ const { const autorunStore = useAutorunStore(); autorunStore.fetch(); const { autorun } = storeToRefs(autorunStore); + +const tateStore = useTateStore(); +tateStore.fetch(); +const { tate, gameRotationOptions } = storeToRefs(tateStore); diff --git a/projects/manager3/src/components/settings/SettingsEmuStationTabContent.vue b/projects/manager3/src/components/settings/SettingsEmuStationTabContent.vue index dc810668a5..040fbbb75e 100755 --- a/projects/manager3/src/components/settings/SettingsEmuStationTabContent.vue +++ b/projects/manager3/src/components/settings/SettingsEmuStationTabContent.vue @@ -19,6 +19,18 @@ {{ $t('settings.emustation.display.videomode.help') }} + + + @@ -339,6 +351,18 @@ {{ $t('settings.emustation.virtualsystems.tate.help') }} + + + diff --git a/projects/manager3/src/i18n/en-US/index.json b/projects/manager3/src/i18n/en-US/index.json index effdcfb42d..9bc12da513 100755 --- a/projects/manager3/src/i18n/en-US/index.json +++ b/projects/manager3/src/i18n/en-US/index.json @@ -474,6 +474,10 @@ "videomode": { "label": "Video mode", "help": "This option allows you to choose a resolution screen for your Recalbox. There are two groups of video modes: CEA and DMT. Make sure the mode is compatible with your native screen resolution." + }, + "force43": { + "label": "Force 4/3 format", + "help": "This option allows you to choose if you like to force the frontend to display in 4/3 format." } }, "menus": { @@ -596,26 +600,9 @@ "help": "This option allows you to enable or disable Tate virtual system." } }, - "popups": { - "title": "Popups", - "showhelp": { - "label": "Display help", - "help": "This option allows you to enable or disable help popups." - }, - "popup": { - "help": { - "label": "Durée d'affichage de la popup d'aide", - "help": "This option allows you to change the help popup display time period." - }, - "music": { - "label": "Durée d'affichage de la popup de musique", - "help": "This option allows you to change the music popup display time period." - }, - "netplay": { - "label": "Durée d'affichage de la popup de netplay", - "help": "This option allows you to change the netplay popup display time period." - } - } + "tate": { + "label": "Display only tate games in gamelists", + "help": "This option allows you to enable or disable to display only tate games in gamelists." }, "theme": { "title": "Themes", @@ -640,6 +627,27 @@ "1": "If disabled, transition between systems will be instant." } } + }, + "popups": { + "title": "Popups", + "showhelp": { + "label": "Display help", + "help": "This option allows you to enable or disable help popups." + }, + "popup": { + "help": { + "label": "Durée d'affichage de la popup d'aide", + "help": "This option allows you to change the help popup display time period." + }, + "music": { + "label": "Durée d'affichage de la popup de musique", + "help": "This option allows you to change the music popup display time period." + }, + "netplay": { + "label": "Durée d'affichage de la popup de netplay", + "help": "This option allows you to change the netplay popup display time period." + } + } } }, "scraper": { @@ -853,8 +861,21 @@ "autorun": { "title": "Autorun", "enabled": { - "label": "Enable game autorun", - "help": "This option allows you to enable or disable the possibility to launch automatically a specific game. Note: If Kodi is also defined to autorun, Kodi have the priority." + "label": "Enable boot on game", + "help": "This option allows you to enable or disable the possibility to launch automatically a specific game on boot. Note: If Kodi is also defined to boot, Kodi have the priority." + } + }, + "tate": { + "title": "Tate", + "gamerotation": { + "label": "Game rotation", + "help": { + "availableOptions": "This option allows you to define the rotation of the game screen of tate games. Available options:", + "0": "0 will left you games as is.", + "1": "1 will turn game screen 90° to the left.", + "2": "2 will turn upside down game screen.", + "3": "3 will turn game screen 90° to the right." + } } }, "virtualarcade": { diff --git a/projects/manager3/src/i18n/fr/index.json b/projects/manager3/src/i18n/fr/index.json index 690862c6a2..3cee9a0fd9 100755 --- a/projects/manager3/src/i18n/fr/index.json +++ b/projects/manager3/src/i18n/fr/index.json @@ -474,6 +474,10 @@ "videomode": { "label": "Mode vidéo", "help": "Cette option vous permet de choisir une résolution pour tout Recalbox. Il existe deux groupes de modes vidéo : CEA et DMT. Assurez-vous que le mode est compatible avec votre résolution d'écran native" + }, + "force43": { + "label": "Forcer l'affichage en 4/3", + "help": "Cette option vous permet de choisir si vous souhaitez forcer le frontend à s'afficher au format 4/3." } }, "menus": { @@ -596,26 +600,9 @@ "help": "Cette option vous permet d'activer ou de désactiver le système virtuel Tate." } }, - "popups": { - "title": "Popups", - "showhelp": { - "label": "Afficher l'aide", - "help": "Cette option vous permet d'activer ou de désactiver les popups aides." - }, - "popup": { - "help": { - "label": "Durée d'affichage de la popup d'aide", - "help": "Cette option vous permet de choisir en secondes le temps d'affichage de la popup d'aide." - }, - "music": { - "label": "Durée d'affichage de la popup de musique", - "help": "Cette option vous permet de choisir en secondes le temps d'affichage de la popup de musique." - }, - "netplay": { - "label": "Durée d'affichage de la popup de netplay", - "help": "Cette option vous permet de choisir en secondes le temps d'affichage de la popup de netplay." - } - } + "tate": { + "label": "Afficher uniquement les jeux tate dans les listes de jeux", + "help": "Cette option vous permet d'activer ou de désactiver d'afficher uniquement les jeux tate dans les listes de jeux." }, "theme": { "title": "Thèmes", @@ -640,6 +627,27 @@ "1": "Si ceci est désactivé, la transition entre les systèmes sera instantanée." } } + }, + "popups": { + "title": "Popups", + "showhelp": { + "label": "Afficher l'aide", + "help": "Cette option vous permet d'activer ou de désactiver les popups aides." + }, + "popup": { + "help": { + "label": "Durée d'affichage de la popup d'aide", + "help": "Cette option vous permet de choisir en secondes le temps d'affichage de la popup d'aide." + }, + "music": { + "label": "Durée d'affichage de la popup de musique", + "help": "Cette option vous permet de choisir en secondes le temps d'affichage de la popup de musique." + }, + "netplay": { + "label": "Durée d'affichage de la popup de netplay", + "help": "Cette option vous permet de choisir en secondes le temps d'affichage de la popup de netplay." + } + } } }, "scraper": { @@ -851,10 +859,23 @@ } }, "autorun": { - "title": "Auto-démarrage", + "title": "Démarrage sur un jeu", "enabled": { - "label": "Activer l'auto-démarrage sur un jeu", - "help": "Cette option vous permet d'activer ou de désactiver la possibilité d'auto-démarrer sur un jeu spécifique. Remarque : si Kodi est aussi défini en auto-démarrage, Kodi a la priorité." + "label": "Activer le démarrage sur un jeu", + "help": "Cette option vous permet d'activer ou de désactiver la possibilité de lancer automatiquement un jeu spécifique au démarrage. Remarque : si Kodi est aussi défini pour démarrer, Kodi a la priorité." + } + }, + "tate": { + "title": "Tate", + "gamerotation": { + "label": "Rotation des jeux", + "help": { + "availableOptions": "Cette option vous permet de définir la rotation de l'écran dans les jeux tate. Options disponibles :", + "0": "0 laissera vos jeux dans le sens normal.", + "1": "1 tournera les jeux à 90° sur la gauche.", + "2": "2 retournera complètement l'écran de jeu.", + "3": "3 tournera les jeux à 90° sur la droite." + } } }, "virtualarcade": { diff --git a/projects/manager3/src/pages/EmulationPage.vue b/projects/manager3/src/pages/EmulationPage.vue index a9f7c3d3b6..7429eab968 100755 --- a/projects/manager3/src/pages/EmulationPage.vue +++ b/projects/manager3/src/pages/EmulationPage.vue @@ -76,10 +76,6 @@ - - - - @@ -88,9 +84,15 @@ import { useGlobalStore } from 'stores/configuration/global'; import { ref } from 'vue'; import { useControllersStore } from 'stores/configuration/controllers'; +import { useEmulationstationStore } from 'stores/configuration/emulationstation'; +import { useSystemStore } from 'stores/configuration/system'; +import { useTateStore } from 'stores/configuration/tate'; useGlobalStore().fetchOptions(); useControllersStore().fetchOptions(); +useEmulationstationStore().fetchOptions(); +useSystemStore().fetchOptions(); +useTateStore().fetchOptions(); const tab = ref('global'); diff --git a/projects/manager3/src/router/api.routes.ts b/projects/manager3/src/router/api.routes.ts index 826cba0637..192394ee7f 100755 --- a/projects/manager3/src/router/api.routes.ts +++ b/projects/manager3/src/router/api.routes.ts @@ -24,6 +24,7 @@ export const CONFIGURATION = { scraper: '/configuration/scraper', screenshots: '/configuration/screenshots', system: '/configuration/system', + tate: '/configuration/tate', updates: '/configuration/updates', wifi: '/configuration/wifi', wifi2: '/configuration/wifi2', diff --git a/projects/manager3/src/stores/configuration/tate.ts b/projects/manager3/src/stores/configuration/tate.ts new file mode 100644 index 0000000000..f4ddd50890 --- /dev/null +++ b/projects/manager3/src/stores/configuration/tate.ts @@ -0,0 +1,28 @@ +/** + * @author Pit64 + */ +import { defineStore } from 'pinia'; +import { CONFIGURATION } from 'src/router/api.routes'; +import { TateConfigOptionsResponse, TateConfigResponse } from 'stores/types/tate'; + +export type TateStoreState = { + _baseUrl: string, + _tateOptions: TateConfigOptionsResponse, + tate: TateConfigResponse, +}; + +export const useTateStore = defineStore('tate', { + state: () => ({ + _baseUrl: CONFIGURATION.tate, + _tateOptions: { + gamerotation: { + allowedStringList: [''], + }, + }, + tate: {}, + } as TateStoreState), + + getters: { + gameRotationOptions: (state) => state._tateOptions.gamerotation.allowedStringList, + }, +}); diff --git a/projects/manager3/src/stores/plugins/fetchOptionsStorePlugin.ts b/projects/manager3/src/stores/plugins/fetchOptionsStorePlugin.ts index f99876ffb4..800112282f 100644 --- a/projects/manager3/src/stores/plugins/fetchOptionsStorePlugin.ts +++ b/projects/manager3/src/stores/plugins/fetchOptionsStorePlugin.ts @@ -7,16 +7,17 @@ import { PiniaPluginContext } from 'pinia'; const FetchOptionsStorePlugin = (context: PiniaPluginContext) => { const allowedStores = [ 'audio', + 'autorun', + 'controllers', + 'emulationstation', + 'global', + 'hat', 'kodi', 'scraper', - 'emulationstation', - 'wifi', 'system', 'updates', - 'controllers', - 'global', - 'hat', - 'autorun', + 'wifi', + 'tate', ]; if (allowedStores.includes(context.store.$id)) { diff --git a/projects/manager3/src/stores/plugins/fetchStorePlugin.ts b/projects/manager3/src/stores/plugins/fetchStorePlugin.ts index 196ec26014..d56acff1c6 100644 --- a/projects/manager3/src/stores/plugins/fetchStorePlugin.ts +++ b/projects/manager3/src/stores/plugins/fetchStorePlugin.ts @@ -28,6 +28,7 @@ const FetchStorePlugin = (context: PiniaPluginContext) => { 'hat', 'architecture', 'autorun', + 'tate', ]; if (allowedStores.includes(context.store.$id)) { diff --git a/projects/manager3/src/stores/types/emulationstation.ts b/projects/manager3/src/stores/types/emulationstation.ts index b8d910d7b4..ac012d10cb 100644 --- a/projects/manager3/src/stores/types/emulationstation.ts +++ b/projects/manager3/src/stores/types/emulationstation.ts @@ -187,6 +187,10 @@ export interface EmulationStationConfigResponse { exist: boolean; value: string; }; + tateonly: { + exist: boolean; + value: boolean; + }; } export interface EmulationStationConfigOptionsResponse { @@ -382,4 +386,8 @@ export interface EmulationStationConfigOptionsResponse { allowedStringList: string[]; displayableStringList: string[]; }; + tateonly: { + type: string; + value: boolean; + }; } diff --git a/projects/manager3/src/stores/types/global.ts b/projects/manager3/src/stores/types/global.ts index 2cf3a114f6..a4068b0a6a 100644 --- a/projects/manager3/src/stores/types/global.ts +++ b/projects/manager3/src/stores/types/global.ts @@ -119,10 +119,6 @@ export interface GlobalConfigResponse { exist: boolean; value: string[]; }; - configfile: { - exist: boolean; - value: string; - }; 'netplay.active': { exist: boolean; value: boolean; @@ -151,6 +147,14 @@ export interface GlobalConfigResponse { exist: boolean; value: boolean; }; + reducelatency: { + exist: boolean; + value: boolean; + }; + runahead: { + exist: boolean; + value: boolean; + }; } export interface GlobalConfigOptionsResponse { @@ -283,4 +287,10 @@ export interface GlobalConfigOptionsResponse { widescreenmode: { type: string; }; + reducelatency: { + type: string + }; + runahead: { + type: string; + }; } diff --git a/projects/manager3/src/stores/types/system.ts b/projects/manager3/src/stores/types/system.ts index 39af7225b2..ae3127dbfd 100644 --- a/projects/manager3/src/stores/types/system.ts +++ b/projects/manager3/src/stores/types/system.ts @@ -59,10 +59,6 @@ export interface SystemConfigResponse { exist: boolean; value: boolean; }; - 'api.enabled': { - exist: boolean; - value: boolean; - }; overscan: { exist: boolean; value: boolean; @@ -123,6 +119,10 @@ export interface SystemConfigResponse { exist: boolean; value: string; }; + 'es.force43': { + exist: boolean; + value: boolean; + }; } export interface SystemConfigOptionsResponse { @@ -181,9 +181,6 @@ export interface SystemConfigOptionsResponse { 'fbcp.enabled': { type: string; }; - 'api.enabled': { - type: string; - }; overscan: { type: string; }; @@ -236,4 +233,7 @@ export interface SystemConfigOptionsResponse { type: string; allowedChars: string; }; + 'es.force43': { + type: string; + }; } diff --git a/projects/manager3/src/stores/types/tate.ts b/projects/manager3/src/stores/types/tate.ts new file mode 100644 index 0000000000..bf09807a5d --- /dev/null +++ b/projects/manager3/src/stores/types/tate.ts @@ -0,0 +1,16 @@ +/** + * @author Pit64 + */ +export interface TateConfigResponse { + gamerotation: { + exist: boolean; + value: string; + }; +} + +export interface TateConfigOptionsResponse { + gamerotation: { + type: string; + allowedStringList: string[]; + }; +} -- GitLab From 364ea7796c991702a42c283fbfe0839c3adc3ae6 Mon Sep 17 00:00:00 2001 From: Pit64 Date: Wed, 29 Nov 2023 23:49:27 +0100 Subject: [PATCH 03/12] feat(webmanager): fix second mini tft option Also added condition to use those options only if enabled --- .../components/settings/SettingsSystemTabContent.vue | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/projects/manager3/src/components/settings/SettingsSystemTabContent.vue b/projects/manager3/src/components/settings/SettingsSystemTabContent.vue index c245ec8765..c0bc787cf3 100755 --- a/projects/manager3/src/components/settings/SettingsSystemTabContent.vue +++ b/projects/manager3/src/components/settings/SettingsSystemTabContent.vue @@ -482,6 +482,7 @@ :setter="systemStore.post" apiKey="secondminitft.type" v-if="system['secondminitft.type']" + :disable="!system['secondminitft.enabled'].value" help >