FS#7704 - Talk support for plugins

Original patch by Mario Lang
Heavily updated by Igor Poretsky
Further updated by myself

  This patch breaks binary API compatibility by placing the new
  functions where they make the most logical sense. IMO this is
  the better approach to take given the scope of the changes needed
  for talk support.

  Since binary API is changing, the patch also moves some other
  functions around to more logical locations.

  As well as voice support in plugins, this patch voice-enables several
  simple plugins.  There will be follow-up patches for many plugins that
  build on this one.

Change-Id: I18070c06e77e8a3c016c2eb6b6c5dbe6633b9b54
This commit is contained in:
Solomon Peachy 2019-02-03 20:12:50 -05:00 committed by William Wilgus
parent 9c17734394
commit 55eb1c54eb
12 changed files with 583 additions and 133 deletions

View file

@ -1255,19 +1255,22 @@
</phrase>
<phrase>
id: LANG_DITHERING
desc: in the sound settings menu
desc: in the sound settings and some other menus
user: core
<source>
*: none
swcodec: "Dithering"
lcd_bitmap: "Dithering"
</source>
<dest>
*: none
swcodec: "Dithering"
lcd_bitmap: "Dithering"
</dest>
<voice>
*: none
swcodec: "Dithering"
lcd_bitmap: "Dithering"
</voice>
</phrase>
<phrase>
@ -8259,7 +8262,7 @@
*: "Incompatible model"
</dest>
<voice>
*: ""
*: "Incompatible model"
</voice>
</phrase>
<phrase>
@ -8273,7 +8276,7 @@
*: "Incompatible version"
</dest>
<voice>
*: ""
*: "Incompatible version"
</voice>
</phrase>
<phrase>
@ -8287,7 +8290,7 @@
*: "Plugin returned error"
</dest>
<voice>
*: ""
*: "Plugin returned error"
</voice>
</phrase>
<phrase>
@ -14051,3 +14054,374 @@
pitchscreen: "Time stretch"
</voice>
</phrase>
<phrase>
id: LANG_REMOTE_CONTROL
desc: Item for menus
user: core
<source>
*: "Remote Control"
</source>
<dest>
*: "Remote Control"
</dest>
<voice>
*: "Remote Control"
</voice>
</phrase>
<phrase>
id: LANG_NO_REM_CONTROL
desc: Item for menus
user: core
<source>
*: "No Rem. Control"
</source>
<dest>
*: "No Rem. Control"
</dest>
<voice>
*: "No Remote Control"
</voice>
</phrase>
<phrase>
id: LANG_OUT_OF_CONTROL
desc: Item for menus
user: core
<source>
*: "Out of Control"
</source>
<dest>
*: "Out of Control"
</dest>
<voice>
*: "Out of Control"
</voice>
</phrase>
<phrase>
id: LANG_2_KEY_CONTROL
desc: Item for menus
user: core
<source>
*: "2 Key Control"
</source>
<dest>
*: "2 Key Control"
</dest>
<voice>
*: "2 Key Control"
</voice>
</phrase>
<phrase>
id: LANG_4_KEY_CONTROL
desc: Item for menus
user: core
<source>
*: "4 Key Control"
</source>
<dest>
*: "4 Key Control"
</dest>
<voice>
*: "4 Key Control"
</voice>
</phrase>
<phrase>
id: LANG_PLAY_WORMLET
desc: For wormlet menu
user: core
<source>
*: none
lcd_bitmap: "Play Wormlet!"
</source>
<dest>
*: none
lcd_bitmap: "Play Wormlet!"
</dest>
<voice>
*: none
lcd_bitmap: "Play Wormlet!"
</voice>
</phrase>
<phrase>
id: LANG_NUMBER_OF_WORMS
desc: For wormlet menu
user: core
<source>
*: none
lcd_bitmap: "Number of Worms"
</source>
<dest>
*: none
lcd_bitmap: "Number of Worms"
</dest>
<voice>
*: none
lcd_bitmap: "Number of Worms"
</voice>
</phrase>
<phrase>
id: LANG_WORM_GROWTH_PER_FOOD
desc: For wormlet menu
user: core
<source>
*: none
lcd_bitmap: "Worm Growth Per Food"
</source>
<dest>
*: none
lcd_bitmap: "Worm Growth Per Food"
</dest>
<voice>
*: none
lcd_bitmap: "Worm Growth Per Food"
</voice>
</phrase>
<phrase>
id: LANG_WORM_SPEED
desc: For wormlet menu
user: core
<source>
*: none
lcd_bitmap: "Worm Speed"
</source>
<dest>
*: none
lcd_bitmap: "Worm Speed"
</dest>
<voice>
*: none
lcd_bitmap: "Worm Speed"
</voice>
</phrase>
<phrase>
id: LANG_ARGHS_PER_FOOD
desc: For wormlet menu
user: core
<source>
*: none
lcd_bitmap: "Arghs Per Food"
</source>
<dest>
*: none
lcd_bitmap: "Arghs Per Food"
</dest>
<voice>
*: none
lcd_bitmap: "Arghs Per Food"
</voice>
</phrase>
<phrase>
id: LANG_ARGH_SIZE
desc: For wormlet menu
user: core
<source>
*: none
lcd_bitmap: "Argh Size"
</source>
<dest>
*: none
lcd_bitmap: "Argh Size"
</dest>
<voice>
*: none
lcd_bitmap: "Argh Size"
</voice>
</phrase>
<phrase>
id: LANG_FOOD_SIZE
desc: For wormlet menu
user: core
<source>
*: none
lcd_bitmap: "Food Size"
</source>
<dest>
*: none
lcd_bitmap: "Food Size"
</dest>
<voice>
*: none
lcd_bitmap: "Food Size"
</voice>
</phrase>
<phrase>
id: LANG_NUMBER_OF_PLAYERS
desc: For game menus
user: core
<source>
*: "Number of Players"
</source>
<dest>
*: "Number of Players"
</dest>
<voice>
*: "Number of Players"
</voice>
</phrase>
<phrase>
id: LANG_CONTROL_STYLE
desc: In various menus
user: core
<source>
*: "Control Style"
</source>
<dest>
*: "Control Style"
</dest>
<voice>
*: "Control Style"
</voice>
</phrase>
<phrase>
id: LANG_REVERT_TO_DEFAULT_SETTINGS
desc: In various menus
user: core
<source>
*: "Revert to Default Settings"
</source>
<dest>
*: "Revert to Default Settings"
</dest>
<voice>
*: "Revert to Default Settings"
</voice>
</phrase>
<phrase>
id: LANG_MENU_QUIT
desc: in various menus
user: core
<source>
*: "Quit"
</source>
<dest>
*: "Quit"
</dest>
<voice>
*: "Quit"
</voice>
</phrase>
<phrase>
id: LANG_MENU_DISPLAY_OPTIONS
desc: in various menus
user: core
<source>
*: "Display Options"
</source>
<dest>
*: "Display Options"
</dest>
<voice>
*: "Display Options"
</voice>
</phrase>
<phrase>
id: LANG_PREVTRACK
desc: in playback control menu
user: core
<source>
*: "Previous Track"
</source>
<dest>
*: "Previous Track"
</dest>
<voice>
*: "Previous Track"
</voice>
</phrase>
<phrase>
id: LANG_PLAYPAUSE
desc: in playback control menu
user: core
<source>
*: "Pause / Play"
</source>
<dest>
*: "Pause / Play"
</dest>
<voice>
*: "Pause / Play"
</voice>
</phrase>
<phrase>
id: LANG_STOP_PLAYBACK
desc: in playback control menu
user: core
<source>
*: "Stop Playback"
</source>
<dest>
*: "Stop Playback"
</dest>
<voice>
*: "Stop Playback"
</voice>
</phrase>
<phrase>
id: LANG_NEXTTRACK
desc: in playback control menu
user: core
<source>
*: "Next Track"
</source>
<dest>
*: "Next Track"
</dest>
<voice>
*: "Next Track"
</voice>
</phrase>
<phrase>
id: LANG_CHANGE_VOLUME
desc: in playback control menu
user: core
<source>
*: "Change Volume"
</source>
<dest>
*: "Change Volume"
</dest>
<voice>
*: "Change Volume"
</voice>
</phrase>
<phrase>
id: LANG_CHANGE_SHUFFLE_MODE
desc: in playback control menu
user: core
<source>
*: "Shuffle Mode"
</source>
<dest>
*: "Shuffle Mode"
</dest>
<voice>
*: "Shuffle Mode"
</voice>
</phrase>
<phrase>
id: LANG_CHANGE_REPEAT_MODE
desc: in playback control menu
user: core
<source>
*: "Change Repeat Mode"
</source>
<dest>
*: "Change Repeat Mode"
</dest>
<voice>
*: "Change Repeat Mode"
</voice>
</phrase>
<phrase>
id: LANG_PLAYBACK_CONTROL
desc: in playback control menu
user: core
<source>
*: "Playback Control"
</source>
<dest>
*: "Playback Control"
</dest>
<voice>
*: "Playback Control"
</voice>
</phrase>

View file

@ -42,6 +42,8 @@ $(BUILDDIR)/lang/lang.h: $(APPSDIR)/lang/$(LANGUAGE).lang $(BUILDDIR)/apps/featu
perl -s $(TOOLSDIR)/genlang -p=$(BUILDDIR)/lang -t=$(MODELNAME)$$feat $<
$(BUILDDIR)/lang/lang_core.c: $(BUILDDIR)/lang/lang.h
$(BUILDDIR)/lang_enum.h: $(BUILDDIR)/lang/lang.h
# NOTE: for some weird reasons in GNU make, multi targets rules WITH patterns actually express
# the fact that the two files are created as the result of one invocation of the rule
$(BUILDDIR)/%.lng $(BUILDDIR)/%.vstrings: $(ROOTDIR)/%.lang $(BUILDDIR)/apps/genlang-features

View file

@ -176,6 +176,10 @@ static void plugin_check_open_close__exit(void)
#endif /* HAVE_PLUGIN_CHECK_OPEN_CLOSE */
static const struct plugin_api rockbox_api = {
rbversion,
&global_settings,
&global_status,
language_strings,
/* lcd */
#ifdef HAVE_LCD_CONTRAST
@ -258,6 +262,7 @@ static const struct plugin_api rockbox_api = {
bidi_l2v,
#ifdef HAVE_LCD_BITMAP
is_diacritic,
get_codepage_name,
#endif
font_get_bits,
font_load,
@ -268,7 +273,6 @@ static const struct plugin_api rockbox_api = {
screen_clear_area,
gui_scrollbar_draw,
#endif /* HAVE_LCD_BITMAP */
get_codepage_name,
backlight_on,
backlight_off,
@ -334,14 +338,16 @@ static const struct plugin_api rockbox_api = {
viewportmanager_theme_undo,
viewport_set_fullscreen,
#endif
/* list */
gui_synclist_init,
gui_synclist_set_nb_items,
gui_synclist_set_voice_callback,
gui_synclist_set_icon_callback,
gui_synclist_get_nb_items,
gui_synclist_get_sel_pos,
gui_synclist_draw,
gui_synclist_speak_item,
gui_synclist_select_item,
gui_synclist_add_item,
gui_synclist_del_item,
@ -369,7 +375,7 @@ static const struct plugin_api rockbox_api = {
touchscreen_set_mode,
touchscreen_get_mode,
#endif
#ifdef HAVE_BUTTON_LIGHT
buttonlight_set_timeout,
buttonlight_off,
@ -421,6 +427,21 @@ static const struct plugin_api rockbox_api = {
browse_context_init,
rockbox_browse,
/* talking */
talk_id,
talk_file,
talk_file_or_spell,
talk_dir_or_spell,
talk_number,
talk_value,
talk_spell,
talk_time,
talk_date,
talk_disable,
talk_shutup,
talk_force_shutup,
talk_force_enqueue_next,
/* kernel/ system */
#if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE
__div0,
@ -541,7 +562,7 @@ static const struct plugin_api rockbox_api = {
utf8encode,
utf8length,
utf8seek,
/* the buflib memory management library */
buflib_init,
buflib_available,
@ -625,6 +646,7 @@ static const struct plugin_api rockbox_api = {
mixer_set_frequency,
mixer_get_frequency,
pcmbuf_fade,
system_sound_play,
keyclick_click,
#endif /* CONFIG_CODEC == SWCODEC */
@ -676,7 +698,12 @@ static const struct plugin_api rockbox_api = {
#endif /* !SIMULATOR && CONFIG_CODEC != SWCODEC */
/* menu */
root_menu_get_options,
do_menu,
root_menu_set_default,
root_menu_write_to_cfg,
root_menu_load_from_cfg,
/* statusbars */
&statusbars,
gui_syncstatusbar_draw,
@ -684,10 +711,12 @@ static const struct plugin_api rockbox_api = {
/* options */
get_settings_list,
find_setting,
settings_save,
option_screen,
set_option,
set_bool_options,
set_int,
set_int_ex,
set_bool,
#ifdef HAVE_LCD_COLOR
set_color,
@ -731,17 +760,17 @@ static const struct plugin_api rockbox_api = {
plugin_get_buffer,
plugin_get_audio_buffer, /* defined in plugin.c */
plugin_release_audio_buffer, /* defined in plugin.c */
plugin_tsr, /* defined in plugin.c */
plugin_tsr, /* defined in plugin.c */
plugin_get_current_filename,
#ifdef PLUGIN_USE_IRAM
audio_hard_stop,
#endif
#if defined(DEBUG) || defined(SIMULATOR)
debugf,
#endif
#ifdef ROCKBOX_HAS_LOGF
_logf,
#endif
&global_settings,
&global_status,
talk_disable,
#if CONFIG_CODEC == SWCODEC
codec_thread_do_callback,
codec_load_file,
@ -813,13 +842,6 @@ static const struct plugin_api rockbox_api = {
semaphore_release,
#endif
rbversion,
root_menu_get_options,
root_menu_set_default,
root_menu_write_to_cfg,
root_menu_load_from_cfg,
settings_save,
/* new stuff at the end, sort into place next time
the API gets incompatible */
};
@ -857,7 +879,7 @@ int plugin_load(const char* plugin, const void* parameter)
p_hdr = lc_get_header(current_plugin_handle);
hdr = p_hdr ? &p_hdr->lc_hdr : NULL;
if (hdr == NULL
|| hdr->magic != PLUGIN_MAGIC
@ -869,14 +891,14 @@ int plugin_load(const char* plugin, const void* parameter)
)
{
lc_close(current_plugin_handle);
splash(HZ*2, str(LANG_PLUGIN_WRONG_MODEL));
splash(HZ*2, ID2P(LANG_PLUGIN_WRONG_MODEL));
return -1;
}
if (hdr->api_version > PLUGIN_API_VERSION
|| hdr->api_version < PLUGIN_MIN_API_VERSION)
{
lc_close(current_plugin_handle);
splash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION));
splash(HZ*2, ID2P(LANG_PLUGIN_WRONG_VERSION));
return -1;
}
#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
@ -901,18 +923,19 @@ int plugin_load(const char* plugin, const void* parameter)
FOR_NB_SCREENS(i)
viewportmanager_theme_enable(i, false, NULL);
#ifdef HAVE_TOUCHSCREEN
touchscreen_set_mode(TOUCHSCREEN_BUTTON);
#endif
/* allow voice to back off if the plugin needs lots of memory */
talk_buffer_set_policy(TALK_BUFFER_LOOSE);
if (!global_settings.talk_menu)
talk_buffer_set_policy(TALK_BUFFER_LOOSE);
plugin_check_open_close__enter();
int rc = p_hdr->entry_point(parameter);
tree_unlock_cache(tree_get_context());
pop_current_activity();

View file

@ -71,6 +71,9 @@ void* plugin_get_buffer(size_t *buffer_size);
#include "mp3_playback.h"
#include "root_menu.h"
#include "talk.h"
#ifdef PLUGIN
#include "lang_enum.h"
#endif
#ifdef RB_PROFILE
#include "profile.h"
#endif
@ -160,12 +163,12 @@ void* plugin_get_buffer(size_t *buffer_size);
#define PLUGIN_MAGIC 0x526F634B /* RocK */
/* increase this every time the api struct changes */
#define PLUGIN_API_VERSION 235
#define PLUGIN_API_VERSION 236
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */
#define PLUGIN_MIN_API_VERSION 235
#define PLUGIN_MIN_API_VERSION 236
/* plugin return codes */
/* internal returns start at 0x100 to make exit(1..255) work */
@ -186,9 +189,13 @@ enum plugin_status {
version
*/
struct plugin_api {
/* let's put these at the top */
const char *rbversion;
struct user_settings* global_settings;
struct system_status *global_status;
unsigned char **language_strings;
/* lcd */
#ifdef HAVE_LCD_CONTRAST
void (*lcd_set_contrast)(int x);
#endif
@ -284,6 +291,7 @@ struct plugin_api {
unsigned short *(*bidi_l2v)( const unsigned char *str, int orientation );
#ifdef HAVE_LCD_BITMAP
bool (*is_diacritic)(const unsigned short char_code, bool *is_rtl);
const char* (*get_codepage_name)(int cp);
#endif
const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code );
int (*font_load)(const char *path);
@ -299,8 +307,6 @@ struct plugin_api {
int min_shown, int max_shown,
unsigned flags);
#endif /* HAVE_LCD_BITMAP */
const char* (*get_codepage_name)(int cp);
/* backlight */
/* The backlight_* functions must be present in the API regardless whether
* HAVE_BACKLIGHT is defined or not. The reason is that the stock Ondio has
@ -370,7 +376,7 @@ struct plugin_api {
int width, int height);
#endif
void (*viewport_set_defaults)(struct viewport *vp,
const enum screen_type screen);
const enum screen_type screen);
#ifdef HAVE_LCD_BITMAP
void (*viewportmanager_theme_enable)(enum screen_type screen, bool enable,
struct viewport *viewport);
@ -384,11 +390,13 @@ struct plugin_api {
bool scroll_all,int selected_size,
struct viewport parent[NB_SCREENS]);
void (*gui_synclist_set_nb_items)(struct gui_synclist * lists, int nb_items);
void (*gui_synclist_set_voice_callback)(struct gui_synclist * lists, list_speak_item voice_callback);
void (*gui_synclist_set_icon_callback)(struct gui_synclist * lists,
list_get_icon icon_callback);
int (*gui_synclist_get_nb_items)(struct gui_synclist * lists);
int (*gui_synclist_get_sel_pos)(struct gui_synclist * lists);
void (*gui_synclist_draw)(struct gui_synclist * lists);
void (*gui_synclist_speak_item)(struct gui_synclist * lists);
void (*gui_synclist_select_item)(struct gui_synclist * lists,
int item_number);
void (*gui_synclist_add_item)(struct gui_synclist * lists);
@ -463,8 +471,6 @@ struct plugin_api {
int (*filetype_get_attr)(const char* file);
/* dir */
DIR * (*opendir)(const char *dirname);
int (*closedir)(DIR *dirp);
@ -481,6 +487,24 @@ struct plugin_api {
const char *root, const char *selected);
int (*rockbox_browse)(struct browse_context *browse);
/* talking */
int (*talk_id)(int32_t id, bool enqueue);
int (*talk_file)(const char *root, const char *dir, const char *file,
const char *ext, const long *prefix_ids, bool enqueue);
int (*talk_file_or_spell)(const char *dirname, const char* filename,
const long *prefix_ids, bool enqueue);
int (*talk_dir_or_spell)(const char* filename,
const long *prefix_ids, bool enqueue);
int (*talk_number)(long n, bool enqueue);
int (*talk_value)(long n, int unit, bool enqueue);
int (*talk_spell)(const char* spell, bool enqueue);
void (*talk_time)(const struct tm *tm, bool enqueue);
void (*talk_date)(const struct tm *tm, bool enqueue);
void (*talk_disable)(bool disable);
void (*talk_shutup)(void);
void (*talk_force_shutup)(void);
void (*talk_force_enqueue_next)(void);
/* kernel/ system */
#if defined(CPU_ARM) && CONFIG_PLATFORM & PLATFORM_NATIVE
void (*__div0)(void);
@ -716,6 +740,7 @@ struct plugin_api {
chan_buffer_hook_fn_type fn);
void (*mixer_set_frequency)(unsigned int samplerate);
unsigned int (*mixer_get_frequency)(void);
void (*pcmbuf_fade)(bool fade, bool in);
void (*system_sound_play)(enum system_sound sound);
void (*keyclick_click)(bool rawbutton, int action);
#endif /* CONFIG_CODEC == SWCODC */
@ -773,8 +798,12 @@ struct plugin_api {
#endif
/* menu */
struct menu_table *(*root_menu_get_options)(int *nb_options);
int (*do_menu)(const struct menu_item_ex *menu, int *start_selected,
struct viewport parent[NB_SCREENS], bool hide_theme);
void (*root_menu_set_default)(void* setting, void* defaultval);
char* (*root_menu_write_to_cfg)(void* setting, char*buf, int buf_len);
void (*root_menu_load_from_cfg)(void* setting, char *value);
/* scroll bar */
struct gui_syncstatusbar *statusbars;
@ -783,6 +812,7 @@ struct plugin_api {
/* options */
const struct settings_list* (*get_settings_list)(int*count);
const struct settings_list* (*find_setting)(const void* variable, int *id);
int (*settings_save)(void);
bool (*option_screen)(const struct settings_list *setting,
struct viewport parent[NB_SCREENS],
bool use_temp_var, unsigned char* option_title);
@ -797,6 +827,11 @@ struct plugin_api {
const int* variable, void (*function)(int), int step,
int min, int max,
const char* (*formatter)(char*, size_t, int, const char*) );
bool (*set_int_ex)(const unsigned char* string, const char* unit, int voice_unit,
const int* variable, void (*function)(int), int step,
int min, int max,
const char* (*formatter)(char*, size_t, int, const char*) ,
int32_t (*get_talk_id)(int, int));
bool (*set_bool)(const char* string, const bool* variable );
#ifdef HAVE_LCD_COLOR
@ -846,15 +881,15 @@ struct plugin_api {
void (*plugin_release_audio_buffer)(void);
void (*plugin_tsr)(bool (*exit_callback)(bool reenter));
char* (*plugin_get_current_filename)(void);
#ifdef PLUGIN_USE_IRAM
void (*audio_hard_stop)(void);
#endif
#if defined(DEBUG) || defined(SIMULATOR)
void (*debugf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
#endif
#ifdef ROCKBOX_HAS_LOGF
void (*logf)(const char *fmt, ...) ATTRIBUTE_PRINTF(1, 2);
#endif
struct user_settings* global_settings;
struct system_status *global_status;
void (*talk_disable)(bool disable);
#if CONFIG_CODEC == SWCODEC
void (*codec_thread_do_callback)(void (*fn)(void),
unsigned int *audio_thread_id);
@ -950,13 +985,6 @@ struct plugin_api {
void (*semaphore_release)(struct semaphore *s);
#endif
const char *rbversion;
struct menu_table *(*root_menu_get_options)(int *nb_options);
void (*root_menu_set_default)(void* setting, void* defaultval);
char* (*root_menu_write_to_cfg)(void* setting, char*buf, int buf_len);
void (*root_menu_load_from_cfg)(void* setting, char *value);
int (*settings_save)(void);
/* new stuff at the end, sort into place next time
the API gets incompatible */
};
@ -988,6 +1016,13 @@ extern unsigned char plugin_end_addr[];
#endif /* CONFIG_PLATFORM */
#endif /* PLUGIN */
/*
* The str() macro/functions is how to access strings that might be
* translated. Use it like str(MACRO) and expect a string to be
* returned!
*/
#define str(x) language_strings[x]
int plugin_load(const char* plugin, const void* parameter);
/* defined by the plugin */

View file

@ -51,14 +51,14 @@ static struct dices dice;
static int sides_index;
static struct opt_items nb_sides_option[8] = {
{ "3", -1 },
{ "4", -1 },
{ "6", -1 },
{ "8", -1 },
{ "10", -1 },
{ "12", -1 },
{ "20", -1 },
{ "100", -1 }
{ "3", TALK_ID(3, UNIT_INT) },
{ "4", TALK_ID(4, UNIT_INT) },
{ "6", TALK_ID(6, UNIT_INT) },
{ "8", TALK_ID(8, UNIT_INT) },
{ "10", TALK_ID(10, UNIT_INT) },
{ "12", TALK_ID(12, UNIT_INT) },
{ "20", TALK_ID(20, UNIT_INT) },
{ "100", TALK_ID(100, UNIT_INT) }
};
static int nb_sides_values[] = { 3, 4, 6, 8, 10, 12, 20, 100 };
static char *sides_conf[] = {"3", "4", "6", "8", "10", "12", "20", "100" };

View file

@ -113,35 +113,35 @@ LCD_RGBPACK(19,10,26) };
#endif
static const struct opt_items autofire_delay_settings[15] = {
{ "Off", -1 },
{ "50ms", -1 },
{ "100ms", -1 },
{ "200ms", -1 },
{ "300ms", -1 },
{ "400ms", -1 },
{ "500ms", -1 },
{ "600ms", -1 },
{ "700ms", -1 },
{ "800ms", -1 },
{ "900ms", -1 },
{ "1s", -1 },
{ "2s", -1 },
{ "3s", -1 },
{ "4s", -1 }
{ STR(LANG_OFF) },
{ "50ms", TALK_ID(50, UNIT_MS) },
{ "100ms", TALK_ID(100, UNIT_MS) },
{ "200ms", TALK_ID(200, UNIT_MS) },
{ "300ms", TALK_ID(300, UNIT_MS) },
{ "400ms", TALK_ID(400, UNIT_MS) },
{ "500ms", TALK_ID(500, UNIT_MS) },
{ "600ms", TALK_ID(600, UNIT_MS) },
{ "700ms", TALK_ID(700, UNIT_MS) },
{ "800ms", TALK_ID(800, UNIT_MS) },
{ "900ms", TALK_ID(900, UNIT_MS) },
{ "1s", TALK_ID(1, UNIT_SEC) },
{ "2s", TALK_ID(2, UNIT_SEC) },
{ "3s", TALK_ID(3, UNIT_SEC) },
{ "4s", TALK_ID(4, UNIT_SEC) }
};
int autofire_delay_values[15] = {
0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400 };
static const struct opt_items particle_settings[8] = {
{ "5", -1 },
{ "10", -1 },
{ "15", -1 },
{ "20", -1 },
{ "25", -1 },
{ "30", -1 },
{ "35", -1 },
{ "40", -1 },
{ "5", TALK_ID(5, UNIT_INT) },
{ "10", TALK_ID(10, UNIT_INT) },
{ "15", TALK_ID(15, UNIT_INT) },
{ "20", TALK_ID(20, UNIT_INT) },
{ "25", TALK_ID(25, UNIT_INT) },
{ "30", TALK_ID(30, UNIT_INT) },
{ "35", TALK_ID(35, UNIT_INT) },
{ "40", TALK_ID(40, UNIT_INT) },
};
int particle_values[8] = {
@ -163,7 +163,7 @@ int particle_life_values[9] = {
20, 30, 40, 50, 60, 70, 80, 90, 100 };
static const struct opt_items gravity_settings[4] = {
{ "Off", -1 },
{ STR(LANG_OFF) },
{ "Weak", -1 },
{ "Moderate", -1 },
{ "Strong", -1 },
@ -185,8 +185,8 @@ int rocket_values[4] = {
#else
static const struct opt_items rocket_settings[2] = {
{ "No", -1 },
{ "Yes", -1 },
{ STR(LANG_SET_BOOL_NO) },
{ STR(LANG_SET_BOOL_YES) },
};
int rocket_values[4] = {
1, 0 };

View file

@ -90,21 +90,21 @@ static bool repeat_mode(void)
return false;
}
MENUITEM_FUNCTION(prevtrack_item, 0, "Previous Track",
MENUITEM_FUNCTION(prevtrack_item, 0, ID2P(LANG_PREVTRACK),
prevtrack, NULL, NULL, Icon_NOICON);
MENUITEM_FUNCTION(playpause_item, 0, "Pause / Play",
MENUITEM_FUNCTION(playpause_item, 0, ID2P(LANG_PLAYPAUSE),
play, NULL, NULL, Icon_NOICON);
MENUITEM_FUNCTION(stop_item, 0, "Stop Playback",
MENUITEM_FUNCTION(stop_item, 0, ID2P(LANG_STOP_PLAYBACK),
stop, NULL, NULL, Icon_NOICON);
MENUITEM_FUNCTION(nexttrack_item, 0, "Next Track",
MENUITEM_FUNCTION(nexttrack_item, 0, ID2P(LANG_NEXTTRACK),
nexttrack, NULL, NULL, Icon_NOICON);
MENUITEM_FUNCTION(volume_item, 0, "Change Volume",
MENUITEM_FUNCTION(volume_item, 0, ID2P(LANG_CHANGE_VOLUME),
volume, NULL, NULL, Icon_NOICON);
MENUITEM_FUNCTION(shuffle_item, 0, "Enable/Disable Shuffle",
MENUITEM_FUNCTION(shuffle_item, 0, ID2P(LANG_CHANGE_SHUFFLE_MODE),
shuffle, NULL, NULL, Icon_NOICON);
MENUITEM_FUNCTION(repeat_mode_item, 0, "Change Repeat Mode",
MENUITEM_FUNCTION(repeat_mode_item, 0, ID2P(LANG_CHANGE_REPEAT_MODE),
repeat_mode, NULL, NULL, Icon_NOICON);
MAKE_MENU(playback_control_menu, "Playback Control", NULL, Icon_NOICON,
MAKE_MENU(playback_control_menu, ID2P(LANG_PLAYBACK_CONTROL), NULL, Icon_NOICON,
&prevtrack_item, &playpause_item, &stop_item, &nexttrack_item,
&volume_item, &shuffle_item, &repeat_mode_item);

View file

@ -3685,19 +3685,19 @@ static int recording_menu(void)
bool done = false;
static const struct opt_items freqs[9] = {
{ "8000Hz", -1 },
{ "11025Hz", -1 },
{ "12000Hz", -1 },
{ "16000Hz", -1 },
{ "22050Hz", -1 },
{ "24000Hz", -1 },
{ "32000Hz", -1 },
{ "44100Hz", -1 },
{ "48000Hz", -1 },
{ "8000Hz", TALK_ID(8, UNIT_KHZ) },
{ "11025Hz", TALK_ID(11, UNIT_KHZ) },
{ "12000Hz", TALK_ID(12, UNIT_KHZ) },
{ "16000Hz", TALK_ID(16, UNIT_KHZ) },
{ "22050Hz", TALK_ID(22, UNIT_KHZ) },
{ "24000Hz", TALK_ID(24, UNIT_KHZ) },
{ "32000Hz", TALK_ID(32, UNIT_KHZ) },
{ "44100Hz", TALK_ID(44, UNIT_KHZ) },
{ "48000Hz", TALK_ID(48, UNIT_KHZ) },
};
static const struct opt_items chans[2] = {
{ "Mono", -1 },
{ "Stereo", -1 },
{ STR(LANG_CHANNEL_MONO) },
{ STR(LANG_CHANNEL_STEREO) },
};
static const struct opt_items srcs[WAV_NUM_SRC] = {
{ "Line In", -1 },

View file

@ -2499,39 +2499,41 @@ enum plugin_status plugin_start(const void* parameter)
/* Setup screen */
static const struct opt_items noyes[2] = {
{ "No", -1 },
{ "Yes", -1 },
{ STR(LANG_SET_BOOL_NO) },
{ STR(LANG_SET_BOOL_YES) },
};
static const struct opt_items remoteonly_option[1] = {
{ "Remote Control", -1 }
{ STR(LANG_REMOTE_CONTROL) }
};
static const struct opt_items key24_option[2] = {
{ "4 Key Control", -1 },
{ "2 Key Control", -1 }
{ STR(LANG_4_KEY_CONTROL) },
{ STR(LANG_2_KEY_CONTROL) }
};
#ifdef REMOTE
static const struct opt_items remote_option[2] = {
{ "Remote Control", -1 },
{ "No Rem. Control", -1 }
{ STR(LANG_REMOTE_CONTROL) },
{ STR(LANG_NO_REM_CONTROL) }
};
#else
static const struct opt_items key2_option[1] = {
{ "2 Key Control", -1 }
{ STR(LANG_2_KEY_CONTROL) }
};
#endif
static const struct opt_items nokey_option[1] = {
{ "Out of Control", -1 }
{ STR(LANG_OUT_OF_CONTROL) }
};
MENUITEM_STRINGLIST(menu, "Wormlet Menu", NULL, "Play Wormlet!",
"Number of Worms", "Number of Players", "Control Style",
"Worm Growth Per Food","Worm Speed","Arghs Per Food",
"Argh Size","Food Size","Revert to Default Settings",
"Playback Control", "Quit");
MENUITEM_STRINGLIST(menu, "Wormlet Menu", NULL,
ID2P(LANG_PLAY_WORMLET), ID2P(LANG_NUMBER_OF_WORMS),
ID2P(LANG_NUMBER_OF_PLAYERS), ID2P(LANG_CONTROL_STYLE),
ID2P(LANG_WORM_GROWTH_PER_FOOD), ID2P(LANG_WORM_SPEED),
ID2P(LANG_ARGHS_PER_FOOD), ID2P(LANG_ARGH_SIZE),
ID2P(LANG_FOOD_SIZE), ID2P(LANG_REVERT_TO_DEFAULT_SETTINGS),
ID2P(LANG_PLAYBACK_CONTROL), ID2P(LANG_MENU_QUIT));
rb->button_clear_queue();
@ -2543,7 +2545,7 @@ enum plugin_status plugin_start(const void* parameter)
launch_wormlet();
break;
case 1:
rb->set_int("Number of Worms", "", UNIT_INT, &worm_count, NULL,
rb->set_int(rb->str(LANG_NUMBER_OF_WORMS), "", UNIT_INT, &worm_count, NULL,
1, 1, 3, NULL);
if (worm_count < players) {
worm_count = players;
@ -2551,10 +2553,10 @@ enum plugin_status plugin_start(const void* parameter)
break;
case 2:
#ifdef MULTIPLAYER
rb->set_int("Number of Players", "", UNIT_INT, &players, NULL,
rb->set_int(rb->str(LANG_NUMBER_OF_PLAYERS), "", UNIT_INT, &players, NULL,
1, 0, 4, NULL);
#else
rb->set_int("Number of Players", "", UNIT_INT, &players, NULL,
rb->set_int(rb->str(LANG_NUMBER_OF_PLAYERS), "", UNIT_INT, &players, NULL,
1, 0, 2, NULL);
#endif
if (players > worm_count) {
@ -2567,53 +2569,53 @@ enum plugin_status plugin_start(const void* parameter)
case 3:
switch(players) {
case 0:
rb->set_option("Control Style",&use_remote,INT,
rb->set_option(rb->str(LANG_CONTROL_STYLE),&use_remote,INT,
nokey_option, 1, NULL);
break;
case 1:
rb->set_option("Control Style",&use_remote,INT,
rb->set_option(rb->str(LANG_CONTROL_STYLE),&use_remote,INT,
key24_option, 2, NULL);
break;
case 2:
#ifdef REMOTE
rb->set_option("Control Style",&use_remote,INT,
rb->set_option(rb->str(LANG_CONTROL_STYLE),&use_remote,INT,
remote_option, 2, NULL);
#else
rb->set_option("Control Style",&use_remote,INT,
rb->set_option(rb->str(LANG_CONTROL_STYLE),&use_remote,INT,
key2_option, 1, NULL);
#endif
break;
case 3:
rb->set_option("Control Style",&use_remote,INT,
rb->set_option(rb->str(LANG_CONTROL_STYLE),&use_remote,INT,
remoteonly_option, 1, NULL);
break;
}
break;
case 4:
rb->set_int("Worm Growth Per Food", "", UNIT_INT, &worm_food,
rb->set_int(rb->str(LANG_WORM_GROWTH_PER_FOOD), "", UNIT_INT, &worm_food,
NULL, 1, 0, 15, NULL);
break;
case 5:
new_setting = 20 - speed;
rb->set_int("Worm Speed", "", UNIT_INT, &new_setting,
rb->set_int(rb->str(LANG_WORM_SPEED), "", UNIT_INT, &new_setting,
NULL, 1, 0, 20, NULL);
speed = 20 - new_setting;
break;
case 6:
rb->set_int("Arghs Per Food", "", UNIT_INT, &arghs_per_food,
rb->set_int(rb->str(LANG_ARGHS_PER_FOOD), "", UNIT_INT, &arghs_per_food,
NULL, 1, 0, 8, NULL);
break;
case 7:
rb->set_int("Argh Size", "", UNIT_INT, &argh_size,
rb->set_int(rb->str(LANG_ARGH_SIZE), "", UNIT_INT, &argh_size,
NULL, 1, 2, 10, NULL);
break;
case 8:
rb->set_int("Food Size", "", UNIT_INT, &food_size,
rb->set_int(rb->str(LANG_FOOD_SIZE), "", UNIT_INT, &food_size,
NULL, 1, 2, 10, NULL);
break;
case 9:
new_setting = 0;
rb->set_option("Reset Settings?", &new_setting, INT, noyes , 2, NULL);
rb->set_option(rb->str(LANG_RESET), &new_setting, INT, noyes , 2, NULL);
if (new_setting == 1)
default_settings();
break;

View file

@ -1540,7 +1540,6 @@ void talk_setting(const void *global_settings_variable)
}
#if CONFIG_RTC
void talk_date(const struct tm *tm, bool enqueue)
{
talk_id(LANG_MONTH_JANUARY + tm->tm_mon, enqueue);
@ -1595,8 +1594,6 @@ void talk_time(const struct tm *tm, bool enqueue)
}
}
#endif /* CONFIG_RTC */
bool talk_get_debug_data(struct talk_debug_data *data)
{
char* p_lang = DEFAULT_VOICE_LANG; /* default */

View file

@ -107,11 +107,11 @@ int talk_file(const char *root, const char *dir, const char *file,
/* play file's thumbnail or spell name */
int talk_file_or_spell(const char *dirname, const char* filename,
const long *prefix_ids, bool enqueue);
#if CONFIG_CODEC == SWCODEC
/* play dir's thumbnail or spell name */
int talk_dir_or_spell(const char* filename,
const long *prefix_ids, bool enqueue);
#endif
/* play thumbnails for each components of full path, or spell */
int talk_fullpath(const char* path, bool enqueue);
int talk_number(long n, bool enqueue); /* say a number */
@ -126,10 +126,8 @@ void talk_shutup(void); /* Interrupt voice, as when enqueue is false */
/* helper function for speaking fractional numbers */
void talk_fractional(char *tbuf, int value, int unit);
#if CONFIG_RTC
void talk_time(const struct tm *tm, bool enqueue);
void talk_date(const struct tm *tm, bool enqueue);
#endif /* CONFIG_RTC */
/* speaks hr, min, sec, ms; unit_idx is lowest or base unit of the time value */
int talk_time_intervals(long time, int unit_idx, bool enqueue);

View file

@ -658,6 +658,20 @@ extern unsigned char *language_strings[];
/* this contains the concatenation of all strings, separated by \\0 chars */
extern const unsigned char core_language_builtin[];
#include "${prefix}_enum.h"
MOO
;
close(HFILE_CORE);
open(HFILE_CORE, ">${prefix}_enum.h") ||
die "couldn't create file ${prefix}_enum.h\n";
print HFILE_CORE <<MOO
/* This file was automatically generated using genlang */
#ifndef _LANG_ENUM_H_
#define _LANG_ENUM_H_
/* The enum below contains all available strings */
enum \{
MOO
@ -702,8 +716,13 @@ MOO
printf HFILE_CORE (" %s, /* 0x%x */\n", $name, $i);
}
# Output end of enum
print HFILE_CORE "\n};\n/* end of generated enum list */\n";
# Output end of lang_enum.h
print HFILE_CORE <<MOO
};
/* end of generated enum list */
#endif /* _LANG_ENUM_H_ */
MOO
;
# Output the target phrases for the source file
for $i (0 .. $idcount[$users{"core"}]-1) {