2020-01-12 20:34:31 +00:00
|
|
|
|
/* RetroArch - A frontend for libretro.
|
|
|
|
|
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
|
|
|
|
|
* Copyright (C) 2011-2016 - Daniel De Matteis
|
|
|
|
|
*
|
|
|
|
|
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
|
* of the GNU General Public License as published by the Free Software Found-
|
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License along with RetroArch.
|
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifndef __RETROARCH_ACCESSIBILITY_H
|
|
|
|
|
#define __RETROARCH_ACCESSIBILITY_H
|
|
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
#include <boolean.h>
|
|
|
|
|
#include <retro_inline.h>
|
|
|
|
|
#include <retro_common_api.h>
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2021-11-06 01:18:01 +00:00
|
|
|
|
#include "configuration.h"
|
2023-10-24 07:27:06 +00:00
|
|
|
|
#include "tasks/tasks_internal.h"
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
|
#include "rthreads/rthreads.h"
|
|
|
|
|
#endif
|
2021-11-06 01:18:01 +00:00
|
|
|
|
|
2021-11-06 00:59:03 +00:00
|
|
|
|
typedef struct
|
|
|
|
|
{
|
2023-10-24 07:27:06 +00:00
|
|
|
|
/* The last request task, used to prepare and send the translation */
|
|
|
|
|
retro_task_t *request_task;
|
2024-02-09 05:14:23 +00:00
|
|
|
|
|
2023-10-24 07:27:06 +00:00
|
|
|
|
/* The last response task, used to parse costly translation data */
|
|
|
|
|
retro_task_t *response_task;
|
2024-02-09 05:14:23 +00:00
|
|
|
|
|
2023-10-24 07:27:06 +00:00
|
|
|
|
/* Timestamp of the last translation request */
|
|
|
|
|
retro_time_t last_call;
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_THREADS
|
|
|
|
|
/* Necessary because last_image is manipulated by task handlers */
|
|
|
|
|
slock_t *image_lock;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* Frame captured during the last call to the translation service */
|
|
|
|
|
uint8_t *last_image;
|
2023-11-05 23:33:49 +00:00
|
|
|
|
unsigned last_image_size;
|
2023-10-24 07:27:06 +00:00
|
|
|
|
|
|
|
|
|
/* 1 if the automatic mode has been enabled, 0 otherwise */
|
2021-11-06 00:59:03 +00:00
|
|
|
|
int ai_service_auto;
|
2024-02-09 05:14:23 +00:00
|
|
|
|
|
2023-10-24 07:27:06 +00:00
|
|
|
|
/* Text-to-speech narrator override flag */
|
2021-11-06 00:59:03 +00:00
|
|
|
|
bool enabled;
|
|
|
|
|
} access_state_t;
|
|
|
|
|
|
2021-11-06 01:13:10 +00:00
|
|
|
|
bool is_accessibility_enabled(bool accessibility_enable, bool accessibility_enabled);
|
|
|
|
|
|
2021-11-06 01:18:01 +00:00
|
|
|
|
#ifdef HAVE_TRANSLATE
|
|
|
|
|
bool is_narrator_running(bool accessibility_enable);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
2024-02-09 05:14:23 +00:00
|
|
|
|
Invoke this method to send a request to the AI service.
|
2023-10-24 07:27:06 +00:00
|
|
|
|
It makes the following POST request using URL params:
|
|
|
|
|
– source_lang (optional): language code of the content currently running.
|
|
|
|
|
– target_lang (optional): language of the content to return.
|
|
|
|
|
– output: comma-separated list of formats that must be provided by the
|
|
|
|
|
service. Also lists supported sub-formats.
|
2024-02-09 05:14:23 +00:00
|
|
|
|
|
2023-10-24 07:27:06 +00:00
|
|
|
|
The currently supported formats are:
|
|
|
|
|
– sound: raw audio to playback. (wav)
|
|
|
|
|
– text: text to be read through internal text-to-speech capabilities.
|
|
|
|
|
'subs' can be specified on top of that to explain that we are looking
|
|
|
|
|
for short text response in the manner of subtitles.
|
|
|
|
|
– image: image to display on top of the video feed. Widgets will be used
|
2024-02-09 05:14:23 +00:00
|
|
|
|
first if possible, otherwise we'll try to draw it directly on the
|
2023-10-24 07:27:06 +00:00
|
|
|
|
video buffer. (bmp, png, png-a) [All in 24-bits BGR formats]
|
2024-02-09 05:14:23 +00:00
|
|
|
|
|
2023-10-24 07:27:06 +00:00
|
|
|
|
In addition, the request contains a JSON payload, formatted as such:
|
|
|
|
|
– image: captured frame from the currently running content (in base64).
|
|
|
|
|
– format: format of the captured frame ("png", or "bmp").
|
2024-02-09 05:14:23 +00:00
|
|
|
|
– coords: array describing the coordinates of the image within the
|
2023-10-24 07:27:06 +00:00
|
|
|
|
viewport space (x, y, width, height).
|
|
|
|
|
– viewport: array describing the size of the viewport (width, height).
|
|
|
|
|
– label: a text string describing the content (<system id>__<content id>).
|
|
|
|
|
– state: a JSON object describing the state of the frontend, containing:
|
|
|
|
|
– paused: 1 if the content has been paused, 0 otherwise.
|
|
|
|
|
– <key>: the name of a retropad input, valued 1 if pressed.
|
|
|
|
|
(a, b, x, y, l, r, l2, r2, l3, r3)
|
|
|
|
|
(up, down, left, right, start, select)
|
2024-02-09 05:14:23 +00:00
|
|
|
|
|
2023-10-24 07:27:06 +00:00
|
|
|
|
The translation component then expects a response from the AI service in the
|
|
|
|
|
form of a JSON payload, formatted as such:
|
|
|
|
|
– image: base64 representation of an image in a supported format.
|
|
|
|
|
– sound: base64 representation of a sound byte in a supported format.
|
|
|
|
|
– text: results from the service as a string.
|
|
|
|
|
– text_position: hint for the position of the text when the service is
|
|
|
|
|
running in text mode (ie subtitles). Position is a number,
|
|
|
|
|
1 for Bottom or 2 for Top (defaults to bottom).
|
2024-02-09 05:14:23 +00:00
|
|
|
|
– press: a list of retropad input to forcibly press. On top of the
|
2023-10-24 07:27:06 +00:00
|
|
|
|
expected keys (cf. 'state' above) values 'pause' and 'unpause' can be
|
|
|
|
|
specified to control the flow of the content.
|
|
|
|
|
– error: any error encountered with the request.
|
|
|
|
|
– auto: either 'auto' or 'continue' to control automatic requests.
|
2024-02-09 05:14:23 +00:00
|
|
|
|
|
2023-10-24 07:27:06 +00:00
|
|
|
|
All fields are optional, but at least one of them must be present.
|
|
|
|
|
If 'error' is set, the error is shown to the user and everything else is
|
|
|
|
|
ignored, even 'auto' settings.
|
2024-02-09 05:14:23 +00:00
|
|
|
|
|
2023-10-24 07:27:06 +00:00
|
|
|
|
With 'auto' on 'auto', RetroArch will automatically send a new request
|
|
|
|
|
(with a minimum delay enforced by uints.ai_service_poll_delay), with a value
|
2024-02-09 05:14:23 +00:00
|
|
|
|
of 'continue', RetroArch will ignore the returned content and skip to the
|
2023-10-24 07:27:06 +00:00
|
|
|
|
next automatic request. This allows the service to specify that the returned
|
|
|
|
|
content is the same as the one previously sent, so RetroArch does not need to
|
2024-02-09 05:14:23 +00:00
|
|
|
|
update its display unless necessary. With 'continue' the service *must*
|
|
|
|
|
still send the content, as we may need to display it if the user paused the
|
2023-10-24 07:27:06 +00:00
|
|
|
|
AI service for instance.
|
|
|
|
|
|
2024-02-09 05:14:23 +00:00
|
|
|
|
{paused} boolean is passed in to indicate if the current call was made
|
|
|
|
|
during a paused frame. Due to how the menu widgets work, if the AI service
|
|
|
|
|
is called in 'auto' mode, then this call will be made while the menu widgets
|
2023-10-24 07:27:06 +00:00
|
|
|
|
unpause the core for a frame to update the on-screen widgets. To tell the AI
|
2024-02-09 05:14:23 +00:00
|
|
|
|
service what the pause mode is honestly, we store the runloop_paused
|
2023-10-24 07:27:06 +00:00
|
|
|
|
variable from before the service wipes the widgets, and pass that in here.
|
2021-11-06 01:18:01 +00:00
|
|
|
|
*/
|
|
|
|
|
bool run_translation_service(settings_t *settings, bool paused);
|
|
|
|
|
|
2023-10-24 07:27:06 +00:00
|
|
|
|
void translation_release(bool inform);
|
|
|
|
|
|
2024-02-09 05:14:23 +00:00
|
|
|
|
/* Proxy for calls related to menu navigation */
|
|
|
|
|
bool navigation_say(
|
2021-11-06 01:13:10 +00:00
|
|
|
|
bool accessibility_enable,
|
|
|
|
|
unsigned accessibility_narrator_speech_speed,
|
2024-02-09 05:14:23 +00:00
|
|
|
|
const char* speak_text,
|
|
|
|
|
int priority);
|
|
|
|
|
|
|
|
|
|
/* Local platform-specific TTS */
|
|
|
|
|
bool accessibility_speak_priority(
|
|
|
|
|
unsigned accessibility_narrator_speech_speed,
|
|
|
|
|
const char *speak_text,
|
|
|
|
|
int priority,
|
|
|
|
|
const char* voice);
|
2021-11-06 01:13:10 +00:00
|
|
|
|
|
2021-11-06 00:59:03 +00:00
|
|
|
|
access_state_t *access_state_get_ptr(void);
|
|
|
|
|
|
2020-01-12 20:34:31 +00:00
|
|
|
|
#endif
|