Something went wrong. Try again.
A modern, network-enabled music player platform built on Rockbox technology. rockboxd.tsiry-sandratraina.com
rust deno navidrome airplay libadwaita zig mpris snapcast mpd rockbox audio subsonic
Something went wrong. Try again.
46 kB · 1433 lines
C
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434#include "plugin.h"#include "lib/helper.h"#include "lib/configfile.h"
#include "mpegplayer.h"#include "mpeg_settings.h"
struct mpeg_settings settings;
#define THUMB_DELAY (75*HZ/100)
/* button definitions */#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ (CONFIG_KEYPAD == IRIVER_H300_PAD)#define MPEG_START_TIME_SELECT BUTTON_ON#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_OFF
#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ (CONFIG_KEYPAD == IPOD_3G_PAD) || \ (CONFIG_KEYPAD == IPOD_1G2G_PAD)#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_SCROLL_FWD#define MPEG_START_TIME_DOWN BUTTON_SCROLL_BACK#define MPEG_START_TIME_EXIT BUTTON_MENU
#elif CONFIG_KEYPAD == GIGABEAT_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#define MPEG_START_TIME_RC_SELECT (BUTTON_RC_PLAY | BUTTON_REL)#define MPEG_START_TIME_RC_LEFT BUTTON_RC_REW#define MPEG_START_TIME_RC_RIGHT BUTTON_RC_FF#define MPEG_START_TIME_RC_UP BUTTON_RC_VOL_UP#define MPEG_START_TIME_RC_DOWN BUTTON_RC_VOL_DOWN#define MPEG_START_TIME_RC_EXIT (BUTTON_RC_PLAY | BUTTON_REPEAT)
#elif CONFIG_KEYPAD == GIGABEAT_S_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#define MPEG_START_TIME_RC_SELECT (BUTTON_RC_PLAY | BUTTON_REL)#define MPEG_START_TIME_RC_LEFT BUTTON_RC_REW#define MPEG_START_TIME_RC_RIGHT BUTTON_RC_FF#define MPEG_START_TIME_RC_UP BUTTON_RC_VOL_UP#define MPEG_START_TIME_RC_DOWN BUTTON_RC_VOL_DOWN#define MPEG_START_TIME_RC_EXIT (BUTTON_RC_PLAY | BUTTON_REPEAT)
#elif CONFIG_KEYPAD == IRIVER_H10_PAD#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_SCROLL_UP#define MPEG_START_TIME_DOWN BUTTON_SCROLL_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif (CONFIG_KEYPAD == SANSA_E200_PAD)#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_SCROLL_BACK#define MPEG_START_TIME_RIGHT2 BUTTON_SCROLL_FWD#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_SCROLL_BACK#define MPEG_START_TIME_RIGHT2 BUTTON_SCROLL_FWD#define MPEG_START_TIME_EXIT (BUTTON_HOME|BUTTON_REPEAT)
#elif (CONFIG_KEYPAD == SANSA_C200_PAD) || \(CONFIG_KEYPAD == SANSA_CLIP_PAD) || \(CONFIG_KEYPAD == SANSA_M200_PAD)#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == MROBE500_PAD#define MPEG_START_TIME_SELECT BUTTON_RC_HEART#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_RC_PLAY#define MPEG_START_TIME_DOWN BUTTON_RC_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_RC_VOL_UP#define MPEG_START_TIME_RIGHT2 BUTTON_RC_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == MROBE100_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_PLAY#define MPEG_START_TIME_RIGHT2 BUTTON_MENU#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == IAUDIO_M3_PAD#define MPEG_START_TIME_SELECT BUTTON_RC_PLAY#define MPEG_START_TIME_LEFT BUTTON_RC_REW#define MPEG_START_TIME_RIGHT BUTTON_RC_FF#define MPEG_START_TIME_UP BUTTON_RC_VOL_UP#define MPEG_START_TIME_DOWN BUTTON_RC_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_RC_REC
#elif CONFIG_KEYPAD == COWON_D2_PAD#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif (CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD)#define MPEG_START_TIME_SELECT (BUTTON_PLAY|BUTTON_REL)#define MPEG_START_TIME_LEFT BUTTON_BACK#define MPEG_START_TIME_RIGHT BUTTON_MENU#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT (BUTTON_PLAY|BUTTON_REPEAT)
#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_PREV#define MPEG_START_TIME_RIGHT BUTTON_NEXT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == ONDAVX747_PAD#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == ONDAVX777_PAD#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD) || \ (CONFIG_KEYPAD == SAMSUNG_YH92X_PAD)#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_REW
#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_PREV#define MPEG_START_TIME_RIGHT BUTTON_NEXT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_LEFT2 BUTTON_OK#define MPEG_START_TIME_RIGHT2 BUTTON_CANCEL#define MPEG_START_TIME_EXIT BUTTON_REC
#elif CONFIG_KEYPAD == MPIO_HD200_PAD#define MPEG_START_TIME_SELECT BUTTON_FUNC#define MPEG_START_TIME_LEFT BUTTON_REW#define MPEG_START_TIME_RIGHT BUTTON_FF#define MPEG_START_TIME_UP BUTTON_VOL_UP#define MPEG_START_TIME_DOWN BUTTON_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_REC
#elif CONFIG_KEYPAD == MPIO_HD300_PAD#define MPEG_START_TIME_SELECT BUTTON_ENTER#define MPEG_START_TIME_LEFT BUTTON_REW#define MPEG_START_TIME_RIGHT BUTTON_FF#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_REC
#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_BACK
#elif (CONFIG_KEYPAD == HM60X_PAD) || (CONFIG_KEYPAD == HM801_PAD)#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == SONY_NWZ_PAD#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_BACK
#elif CONFIG_KEYPAD == CREATIVE_ZEN_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_BACK
#elif CONFIG_KEYPAD == DX50_PAD#define MPEG_START_TIME_EXIT BUTTON_POWER#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_VOL_UP#define MPEG_START_TIME_DOWN BUTTON_VOL_DOWN
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == XDUOO_X3_PAD#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_PREV#define MPEG_START_TIME_RIGHT BUTTON_NEXT#define MPEG_START_TIME_UP BUTTON_HOME#define MPEG_START_TIME_DOWN BUTTON_OPTION#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == XDUOO_X3II_PAD || CONFIG_KEYPAD == XDUOO_X20_PAD#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_PREV#define MPEG_START_TIME_RIGHT BUTTON_NEXT#define MPEG_START_TIME_UP BUTTON_HOME#define MPEG_START_TIME_DOWN BUTTON_OPTION#define MPEG_START_TIME_LEFT2 BUTTON_VOL_UP#define MPEG_START_TIME_RIGHT2 BUTTON_VOL_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == IHIFI_770_PAD || CONFIG_KEYPAD == IHIFI_800_PAD#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_HOME#define MPEG_START_TIME_RIGHT BUTTON_VOL_DOWN#define MPEG_START_TIME_UP BUTTON_PREV#define MPEG_START_TIME_DOWN BUTTON_NEXT#define MPEG_START_TIME_LEFT2 (BUTTON_POWER + BUTTON_HOME)#define MPEG_START_TIME_RIGHT2 (BUTTON_POWER + BUTTON_VOL_DOWN)#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == EROSQ_PAD#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_SCROLL_BACK#define MPEG_START_TIME_RIGHT BUTTON_SCROLL_FWD#define MPEG_START_TIME_UP BUTTON_PREV#define MPEG_START_TIME_DOWN BUTTON_NEXT#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == FIIO_M3K_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == MA_PAD#define MPEG_START_TIME_SELECT BUTTON_PLAY#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_BACK
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD || CONFIG_KEYPAD == HIBY_R3PROII_PAD || CONFIG_KEYPAD == HIDIZS_AP80MAX_PAD#define MPEG_START_TIME_EXIT BUTTON_POWER
#elif CONFIG_KEYPAD == RG_NANO_PAD#define MPEG_START_TIME_SELECT BUTTON_A#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_LEFT2 BUTTON_L#define MPEG_START_TIME_RIGHT2 BUTTON_R#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_START
#elif CONFIG_KEYPAD == N3DS_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_BACK
#elif CONFIG_KEYPAD == ECHO_R1_PAD#define MPEG_START_TIME_SELECT BUTTON_A#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_B
#elif CONFIG_KEYPAD == PSP_PAD#define MPEG_START_TIME_SELECT BUTTON_SELECT#define MPEG_START_TIME_LEFT BUTTON_LEFT#define MPEG_START_TIME_RIGHT BUTTON_RIGHT#define MPEG_START_TIME_UP BUTTON_UP#define MPEG_START_TIME_DOWN BUTTON_DOWN#define MPEG_START_TIME_EXIT BUTTON_BACK
#else#error No keymap defined!#endif
#ifdef HAVE_TOUCHSCREEN#ifndef MPEG_START_TIME_SELECT#define MPEG_START_TIME_SELECT BUTTON_CENTER#endif#ifndef MPEG_START_TIME_LEFT#define MPEG_START_TIME_LEFT BUTTON_MIDLEFT#endif#ifndef MPEG_START_TIME_RIGHT#define MPEG_START_TIME_RIGHT BUTTON_MIDRIGHT#endif#ifndef MPEG_START_TIME_UP#define MPEG_START_TIME_UP BUTTON_TOPMIDDLE#endif#ifndef MPEG_START_TIME_DOWN#define MPEG_START_TIME_DOWN BUTTON_BOTTOMMIDDLE#endif#ifndef MPEG_START_TIME_LEFT2#define MPEG_START_TIME_LEFT2 BUTTON_TOPRIGHT#endif#ifndef MPEG_START_TIME_RIGHT2#define MPEG_START_TIME_RIGHT2 BUTTON_TOPLEFT#endif#ifndef MPEG_START_TIME_EXIT#define MPEG_START_TIME_EXIT BUTTON_TOPLEFT#endif#endif
static struct configdata config[] ={ {TYPE_INT, 0, 2, { .int_p = &settings.showfps }, "Show FPS", NULL}, {TYPE_INT, 0, 2, { .int_p = &settings.limitfps }, "Limit FPS", NULL}, {TYPE_INT, 0, 2, { .int_p = &settings.skipframes }, "Skip frames", NULL}, {TYPE_INT, 0, INT_MAX, { .int_p = &settings.resume_count }, "Resume count", NULL}, {TYPE_INT, 0, MPEG_RESUME_NUM_OPTIONS, { .int_p = &settings.resume_options }, "Resume options", NULL},#if MPEG_OPTION_DITHERING_ENABLED {TYPE_INT, 0, INT_MAX, { .int_p = &settings.displayoptions }, "Display options", NULL},#endif {TYPE_INT, 0, 2, { .int_p = &settings.tone_controls }, "Tone controls", NULL}, {TYPE_INT, 0, 2, { .int_p = &settings.channel_modes }, "Channel modes", NULL}, {TYPE_INT, 0, 2, { .int_p = &settings.crossfeed }, "Crossfeed", NULL}, {TYPE_INT, 0, 2, { .int_p = &settings.equalizer }, "Equalizer", NULL}, {TYPE_INT, 0, 2, { .int_p = &settings.dithering }, "Dithering", NULL}, {TYPE_INT, 0, 2, { .int_p = &settings.play_mode }, "Play mode", NULL},#ifdef HAVE_BACKLIGHT_BRIGHTNESS {TYPE_INT, -1, INT_MAX, { .int_p = &settings.backlight_brightness }, "Backlight brightness", NULL},#endif};
static const struct opt_items noyes[2] = { { STR(LANG_SET_BOOL_NO) }, { STR(LANG_SET_BOOL_YES) },};
static const struct opt_items singleall[2] = { { STR(LANG_SINGLE) }, { STR(LANG_ALL) },};
static const struct opt_items globaloff[2] = { { STR(LANG_OFF) }, { STR(LANG_USE_SOUND_SETTING) },};
static void mpeg_settings(void);static bool mpeg_set_option(const char* string, void* variable, enum optiontype type, const struct opt_items* options, int numoptions, void (*function)(int)){ mpeg_sysevent_clear();
/* This eats SYS_POWEROFF - :\ */ bool usb = rb->set_option(string, variable, type, options, numoptions, function);
if (usb) mpeg_sysevent_set();
return usb;}
#ifdef HAVE_BACKLIGHT_BRIGHTNESS /* Only used for this atm */static bool mpeg_set_int(const 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)){ mpeg_sysevent_clear();
bool usb = rb->set_int_ex(string, unit, voice_unit, variable, function, step, min, max, formatter, get_talk_id);
if (usb) mpeg_sysevent_set();
return usb;}
static int32_t backlight_brightness_getlang(int value, int unit){ if (value < 0) return LANG_USE_COMMON_SETTING;
return TALK_ID(value + MIN_BRIGHTNESS_SETTING, unit);}
void mpeg_backlight_update_brightness(int value){ if (value >= 0) { value += MIN_BRIGHTNESS_SETTING; backlight_brightness_set(value); } else { backlight_brightness_use_setting(); }}
static void backlight_brightness_function(int value){ mpeg_backlight_update_brightness(value);}
static const char* backlight_brightness_formatter(char *buf, size_t length, int value, const char *input){ (void)input;
if (value < 0) return rb->str(LANG_USE_COMMON_SETTING); else rb->snprintf(buf, length, "%d", value + MIN_BRIGHTNESS_SETTING); return buf;}#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
/* Sync a particular audio setting to global or mpegplayer forced off */static void sync_audio_setting(int setting, bool global){ switch (setting) { case MPEG_AUDIO_TONE_CONTROLS: #ifdef AUDIOHW_HAVE_BASS rb->sound_set(SOUND_BASS, (global || settings.tone_controls) ? rb->global_settings->bass : rb->sound_default(SOUND_BASS)); #endif #ifdef AUDIOHW_HAVE_TREBLE rb->sound_set(SOUND_TREBLE, (global || settings.tone_controls) ? rb->global_settings->treble : rb->sound_default(SOUND_TREBLE)); #endif
#ifdef AUDIOHW_HAVE_EQ for (int band = 0;; band++) { int setting = rb->sound_enum_hw_eq_band_setting(band, AUDIOHW_EQ_GAIN);
if (setting == -1) break;
rb->sound_set(setting, (global || settings.tone_controls) ? rb->global_settings->hw_eq_bands[band].gain : rb->sound_default(setting)); } #endif /* AUDIOHW_HAVE_EQ */ break;
case MPEG_AUDIO_CHANNEL_MODES: rb->sound_set(SOUND_CHANNELS, (global || settings.channel_modes) ? rb->global_settings->channel_config : SOUND_CHAN_STEREO); break;
case MPEG_AUDIO_CROSSFEED: rb->dsp_set_crossfeed_type((global || settings.crossfeed) ? rb->global_settings->crossfeed : CROSSFEED_TYPE_NONE); break;
case MPEG_AUDIO_EQUALIZER: rb->dsp_eq_enable((global || settings.equalizer) ? rb->global_settings->eq_enabled : false); break;
case MPEG_AUDIO_DITHERING: rb->dsp_dither_enable((global || settings.dithering) ? rb->global_settings->dithering_enabled : false); break; }}
/* Sync all audio settings to global or mpegplayer forced off */static void sync_audio_settings(bool global){ static const int setting_index[] = { MPEG_AUDIO_TONE_CONTROLS, MPEG_AUDIO_CHANNEL_MODES, MPEG_AUDIO_CROSSFEED, MPEG_AUDIO_EQUALIZER, MPEG_AUDIO_DITHERING, }; unsigned i;
for (i = 0; i < ARRAYLEN(setting_index); i++) { sync_audio_setting(setting_index[i], global); }}
#ifndef HAVE_LCD_COLOR/* Cheapo splash implementation for the grey surface */static void grey_splash(int ticks, const unsigned char *fmt, ...){ unsigned char buffer[256]; int x, y, w, h; int oldfg, oldmode;
va_list ap; va_start(ap, fmt);
rb->vsnprintf(buffer, sizeof (buffer), fmt, ap);
va_end(ap);
grey_getstringsize(buffer, &w, &h);
oldfg = grey_get_foreground(); oldmode = grey_get_drawmode();
grey_set_drawmode(DRMODE_FG); grey_set_foreground(GREY_LIGHTGRAY);
x = (LCD_WIDTH - w) / 2; y = (LCD_HEIGHT - h) / 2;
grey_fillrect(x - 1, y - 1, w + 2, h + 2);
grey_set_foreground(GREY_BLACK);
grey_putsxy(x, y, buffer); grey_drawrect(x - 2, y - 2, w + 4, h + 4);
grey_set_foreground(oldfg); grey_set_drawmode(oldmode);
grey_update();
if (ticks > 0) rb->sleep(ticks);}#endif /* !HAVE_LCD_COLOR */
static void show_loading(struct vo_rect *rc){ int oldmode = mylcd_get_drawmode(); mylcd_set_drawmode(DRMODE_SOLID | DRMODE_INVERSEVID); mylcd_fillrect(rc->l-1, rc->t-1, rc->r - rc->l + 2, rc->b - rc->t + 2); mylcd_set_drawmode(oldmode); mylcd_splash(0, "Loading...");}
static void draw_slider(uint32_t range, uint32_t pos, struct vo_rect *rc){ #define SLIDER_WIDTH (LCD_WIDTH-SLIDER_LMARGIN-SLIDER_RMARGIN) #define SLIDER_X SLIDER_LMARGIN #define SLIDER_Y (LCD_HEIGHT-SLIDER_HEIGHT-SLIDER_BMARGIN) #define SLIDER_HEIGHT 8 #define SLIDER_TEXTMARGIN 1 #define SLIDER_LMARGIN 1 #define SLIDER_RMARGIN 1 #define SLIDER_TMARGIN 1 #define SLIDER_BMARGIN 1 #define SCREEN_MARGIN 1
struct hms hms; char str[32]; int text_w, text_h, text_y;
/* Put positition on left */ ts_to_hms(pos, &hms); hms_format(str, sizeof(str), &hms); mylcd_getstringsize(str, NULL, &text_h); text_y = SLIDER_Y - SLIDER_TEXTMARGIN - text_h;
if (rc == NULL) { int oldmode = mylcd_get_drawmode(); mylcd_set_drawmode(DRMODE_BG | DRMODE_INVERSEVID); mylcd_fillrect(SLIDER_X, text_y, SLIDER_WIDTH, LCD_HEIGHT - SLIDER_BMARGIN - text_y - SLIDER_TMARGIN); mylcd_set_drawmode(oldmode);
mylcd_putsxy(SLIDER_X, text_y, str);
/* Put duration on right */ ts_to_hms(range, &hms); hms_format(str, sizeof(str), &hms); mylcd_getstringsize(str, &text_w, NULL);
mylcd_putsxy(SLIDER_X + SLIDER_WIDTH - text_w, text_y, str);
/* Draw slider */ mylcd_drawrect(SLIDER_X, SLIDER_Y, SLIDER_WIDTH, SLIDER_HEIGHT); mylcd_fillrect(SLIDER_X, SLIDER_Y, muldiv_uint32(pos, SLIDER_WIDTH, range), SLIDER_HEIGHT);
/* Update screen */ mylcd_update_rect(SLIDER_X, text_y - SLIDER_TMARGIN, SLIDER_WIDTH, LCD_HEIGHT - SLIDER_BMARGIN - text_y + SLIDER_TEXTMARGIN); } else { /* Just return slider rectangle */ rc->l = SLIDER_X; rc->t = text_y - SLIDER_TMARGIN; rc->r = rc->l + SLIDER_WIDTH; rc->b = rc->t + LCD_HEIGHT - SLIDER_BMARGIN - text_y; }}
static bool display_thumb_image(const struct vo_rect *rc){ bool retval = true; unsigned ltgray = MYLCD_LIGHTGRAY; unsigned dkgray = MYLCD_DARKGRAY;
int oldcolor = mylcd_get_foreground();
if (!stream_display_thumb(rc)) { /* Display "No Frame" and erase any border */ const char * const str = "No Frame"; int x, y, w, h;
mylcd_getstringsize(str, &w, &h); x = (rc->r + rc->l - w) / 2; y = (rc->b + rc->t - h) / 2; mylcd_putsxy(x, y, str);
mylcd_update_rect(x, y, w, h);
ltgray = dkgray = mylcd_get_background(); retval = false; }
/* Draw a raised border around the frame (or erase if no frame) */
mylcd_set_foreground(ltgray);
mylcd_hline(rc->l-1, rc->r-1, rc->t-1); mylcd_vline(rc->l-1, rc->t, rc->b-1);
mylcd_set_foreground(dkgray);
mylcd_hline(rc->l-1, rc->r, rc->b); mylcd_vline(rc->r, rc->t-1, rc->b);
mylcd_set_foreground(oldcolor);
mylcd_update_rect(rc->l-1, rc->t-1, rc->r - rc->l + 2, 1); mylcd_update_rect(rc->l-1, rc->t, 1, rc->b - rc->t); mylcd_update_rect(rc->l-1, rc->b, rc->r - rc->l + 2, 1); mylcd_update_rect(rc->r, rc->t, 1, rc->b - rc->t);
return retval;}
/* Add an amount to the specified time - with saturation */static uint32_t increment_time(uint32_t val, int32_t amount, uint32_t range){ if (amount < 0) { uint32_t off = -amount; if (range > off && val >= off) val -= off; else val = 0; } else if (amount > 0) { uint32_t off = amount; if (range > off && val <= range - off) val += off; else val = range; }
return val;}
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)static void get_start_time_lcd_enable_hook(unsigned short id, void *param){ (void)id; (void)param; rb->button_queue_post(LCD_ENABLE_EVENT_0, 0);}#endif /* HAVE_LCD_ENABLE */
static int get_start_time(uint32_t duration){ int button = 0; int tmo = TIMEOUT_NOBLOCK; uint32_t resume_time = settings.resume_time; struct vo_rect rc_vid, rc_bound; uint32_t aspect_vid, aspect_bound; bool sliding = false;
enum state_enum slider_state = STATE0;
mylcd_clear_display(); mylcd_update();
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) rb->add_event(LCD_EVENT_ACTIVATION, get_start_time_lcd_enable_hook);#endif
draw_slider(0, 100, &rc_bound); rc_bound.b = rc_bound.t - SLIDER_TMARGIN; rc_bound.t = SCREEN_MARGIN;
DEBUGF("rc_bound: %d, %d, %d, %d\n", rc_bound.l, rc_bound.t, rc_bound.r, rc_bound.b);
rc_vid.l = rc_vid.t = 0; if (!stream_vo_get_size((struct vo_ext *)&rc_vid.r)) { /* Can't get size - fill whole thing */ rc_vid.r = rc_bound.r - rc_bound.l; rc_vid.b = rc_bound.b - rc_bound.t; }
/* Get aspect ratio of bounding rectangle and video in u16.16 */ aspect_bound = ((rc_bound.r - rc_bound.l) << 16) / (rc_bound.b - rc_bound.t);
DEBUGF("aspect_bound: %u.%02u\n", (unsigned)(aspect_bound >> 16), (unsigned)(100*(aspect_bound & 0xffff) >> 16));
aspect_vid = (rc_vid.r << 16) / rc_vid.b;
DEBUGF("aspect_vid: %u.%02u\n", (unsigned)(aspect_vid >> 16), (unsigned)(100*(aspect_vid & 0xffff) >> 16));
if (aspect_vid >= aspect_bound) { /* Video proportionally wider than or same as bounding rectangle */ if (rc_vid.r > rc_bound.r - rc_bound.l) { rc_vid.r = rc_bound.r - rc_bound.l; rc_vid.b = (rc_vid.r << 16) / aspect_vid; } /* else already fits */ } else { /* Video proportionally narrower than bounding rectangle */ if (rc_vid.b > rc_bound.b - rc_bound.t) { rc_vid.b = rc_bound.b - rc_bound.t; rc_vid.r = (aspect_vid * rc_vid.b) >> 16; } /* else already fits */ }
/* Even width and height >= 2 */ rc_vid.r = (rc_vid.r < 2) ? 2 : (rc_vid.r & ~1); rc_vid.b = (rc_vid.b < 2) ? 2 : (rc_vid.b & ~1);
/* Center display in bounding rectangle */ rc_vid.l = ((rc_bound.l + rc_bound.r) - rc_vid.r) / 2; rc_vid.r += rc_vid.l;
rc_vid.t = ((rc_bound.t + rc_bound.b) - rc_vid.b) / 2; rc_vid.b += rc_vid.t;
DEBUGF("rc_vid: %d, %d, %d, %d\n", rc_vid.l, rc_vid.t, rc_vid.r, rc_vid.b);
#ifndef HAVE_LCD_COLOR stream_gray_show(true);#endif
while (slider_state < STATE9) { button = mpeg_button_get(tmo);
switch (button) { case BUTTON_NONE: break;
/* Coarse (1 minute) control */ case MPEG_START_TIME_DOWN: case MPEG_START_TIME_DOWN | BUTTON_REPEAT:#ifdef MPEG_START_TIME_RC_DOWN case MPEG_START_TIME_RC_DOWN: case MPEG_START_TIME_RC_DOWN | BUTTON_REPEAT:#endif resume_time = increment_time(resume_time, -60*TS_SECOND, duration); slider_state = STATE0; break;
case MPEG_START_TIME_UP: case MPEG_START_TIME_UP | BUTTON_REPEAT:#ifdef MPEG_START_TIME_RC_UP case MPEG_START_TIME_RC_UP: case MPEG_START_TIME_RC_UP | BUTTON_REPEAT:#endif resume_time = increment_time(resume_time, 60*TS_SECOND, duration); slider_state = STATE0; break;
/* Fine (1 second) control */ case MPEG_START_TIME_LEFT: case MPEG_START_TIME_LEFT | BUTTON_REPEAT:#ifdef MPEG_START_TIME_RC_LEFT case MPEG_START_TIME_RC_LEFT: case MPEG_START_TIME_RC_LEFT | BUTTON_REPEAT:#endif#ifdef MPEG_START_TIME_LEFT2 case MPEG_START_TIME_LEFT2: case MPEG_START_TIME_LEFT2 | BUTTON_REPEAT:#endif resume_time = increment_time(resume_time, -TS_SECOND, duration); slider_state = STATE0; break;
case MPEG_START_TIME_RIGHT: case MPEG_START_TIME_RIGHT | BUTTON_REPEAT:#ifdef MPEG_START_TIME_RC_RIGHT case MPEG_START_TIME_RC_RIGHT: case MPEG_START_TIME_RC_RIGHT | BUTTON_REPEAT:#endif#ifdef MPEG_START_TIME_RIGHT2 case MPEG_START_TIME_RIGHT2: case MPEG_START_TIME_RIGHT2 | BUTTON_REPEAT:#endif resume_time = increment_time(resume_time, TS_SECOND, duration); slider_state = STATE0; break;
case MPEG_START_TIME_SELECT:#ifdef MPEG_START_TIME_RC_SELECT case MPEG_START_TIME_RC_SELECT:#endif settings.resume_time = resume_time; button = MPEG_START_SEEK; slider_state = STATE9; break;
case MPEG_START_TIME_EXIT:#ifdef MPEG_START_TIME_RC_EXIT case MPEG_START_TIME_RC_EXIT:#endif button = MPEG_START_EXIT; slider_state = STATE9; break;
case ACTION_STD_CANCEL: button = MPEG_START_QUIT; slider_state = STATE9; break;
#ifdef HAVE_LCD_ENABLE case LCD_ENABLE_EVENT_0: if (slider_state == STATE2) display_thumb_image(&rc_vid); continue;#endif
default: rb->default_event_handler(button); rb->yield(); continue; }
switch (slider_state) { case STATE0: if (!sliding) { trigger_cpu_boost(); sliding = true; } stream_seek(resume_time, SEEK_SET); show_loading(&rc_bound); draw_slider(duration, resume_time, NULL); slider_state = STATE1; tmo = THUMB_DELAY; break; case STATE1: display_thumb_image(&rc_vid); slider_state = STATE2; tmo = TIMEOUT_BLOCK; if (sliding) { cancel_cpu_boost(); if (rb->global_settings->talk_menu) { talk_val(resume_time / TS_SECOND, UNIT_TIME, false); talk_val(resume_time * 100 / duration, UNIT_PERCENT, true); } sliding = false; } default: break; }
rb->yield(); }
#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) rb->remove_event(LCD_EVENT_ACTIVATION, get_start_time_lcd_enable_hook);#endif#ifndef HAVE_LCD_COLOR stream_gray_show(false); grey_clear_display(); grey_update();#endif
cancel_cpu_boost();
return button;}
static int show_start_menu(uint32_t duration){ int selected = 0; int result = 0; bool menu_quit = false;
MENUITEM_STRINGLIST(menu, "MPEG Player", mpeg_sysevent_callback, ID2P(LANG_RESTART_PLAYBACK), ID2P(LANG_RESUME_PLAYBACK), ID2P(LANG_SET_RESUME_TIME), ID2P(LANG_SETTINGS), ID2P(LANG_MENU_QUIT));
rb->button_clear_queue();
while (!menu_quit) { mpeg_sysevent_clear(); result = rb->do_menu(&menu, &selected, NULL, false);
switch (result) { case MPEG_START_RESTART: settings.resume_time = 0; menu_quit = true; break;
case MPEG_START_RESUME: menu_quit = true; break;
case MPEG_START_SEEK: if (!stream_can_seek()) { rb->splash(HZ, ID2P(LANG_UNAVAILABLE)); break; }
result = get_start_time(duration);
if (result != MPEG_START_EXIT) menu_quit = true; break;
case MPEG_START_SETTINGS: mpeg_settings(); break;
default: result = MPEG_START_QUIT; menu_quit = true; break; }
if (mpeg_sysevent() != 0) { result = MPEG_START_QUIT; menu_quit = true; } }
return result;}
/* Return the desired resume action */int mpeg_start_menu(uint32_t duration){ mpeg_sysevent_clear();
switch (settings.resume_options) { case MPEG_RESUME_MENU_IF_INCOMPLETE: if (!stream_can_seek() || settings.resume_time == 0) { case MPEG_RESUME_RESTART: settings.resume_time = 0; return MPEG_START_RESTART; } default: case MPEG_RESUME_MENU_ALWAYS: return show_start_menu(duration); case MPEG_RESUME_ALWAYS: return MPEG_START_SEEK; }}
int mpeg_menu(void){ int result;
MENUITEM_STRINGLIST(menu, "MPEG Player", mpeg_sysevent_callback, ID2P(LANG_SETTINGS), ID2P(LANG_RESUME_PLAYBACK), ID2P(LANG_MENU_QUIT));
rb->button_clear_queue();
mpeg_sysevent_clear();
result = rb->do_menu(&menu, NULL, NULL, false);
switch (result) { case MPEG_MENU_SETTINGS: mpeg_settings(); break;
case MPEG_MENU_RESUME: break;
case MPEG_MENU_QUIT: break;
default: break; }
if (mpeg_sysevent() != 0) result = MPEG_MENU_QUIT;
return result;}
static void display_options(void){ int selected = 0; int result; bool menu_quit = false;
MENUITEM_STRINGLIST(menu, ID2P(LANG_MENU_DISPLAY_OPTIONS), mpeg_sysevent_callback,#if MPEG_OPTION_DITHERING_ENABLED ID2P(LANG_DITHERING),#endif ID2P(LANG_DISPLAY_FPS), ID2P(LANG_LIMIT_FPS), ID2P(LANG_SKIP_FRAMES),#ifdef HAVE_BACKLIGHT_BRIGHTNESS ID2P(LANG_BACKLIGHT_BRIGHTNESS),#endif );
rb->button_clear_queue();
while (!menu_quit) { mpeg_sysevent_clear(); result = rb->do_menu(&menu, &selected, NULL, false);
switch (result) {#if MPEG_OPTION_DITHERING_ENABLED case MPEG_OPTION_DITHERING: result = (settings.displayoptions & LCD_YUV_DITHER) ? 1 : 0; mpeg_set_option(rb->str(LANG_DITHERING), &result, RB_INT, noyes, 2, NULL); settings.displayoptions = (settings.displayoptions & ~LCD_YUV_DITHER) | ((result != 0) ? LCD_YUV_DITHER : 0); rb->lcd_yuv_set_options(settings.displayoptions); break;#endif /* MPEG_OPTION_DITHERING_ENABLED */
case MPEG_OPTION_DISPLAY_FPS: mpeg_set_option(rb->str(LANG_DISPLAY_FPS), &settings.showfps, RB_INT, noyes, 2, NULL); break;
case MPEG_OPTION_LIMIT_FPS: mpeg_set_option(rb->str(LANG_LIMIT_FPS), &settings.limitfps, RB_INT, noyes, 2, NULL); break;
case MPEG_OPTION_SKIP_FRAMES: mpeg_set_option(rb->str(LANG_SKIP_FRAMES), &settings.skipframes, RB_INT, noyes, 2, NULL); break;
#ifdef HAVE_BACKLIGHT_BRIGHTNESS case MPEG_OPTION_BACKLIGHT_BRIGHTNESS: result = settings.backlight_brightness; mpeg_backlight_update_brightness(result); mpeg_set_int(rb->str(LANG_BACKLIGHT_BRIGHTNESS), NULL, UNIT_INT, &result, backlight_brightness_function, 1, -1, MAX_BRIGHTNESS_SETTING - MIN_BRIGHTNESS_SETTING, backlight_brightness_formatter, backlight_brightness_getlang); settings.backlight_brightness = result; mpeg_backlight_update_brightness(-1); break;#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
default: menu_quit = true; break; }
if (mpeg_sysevent() != 0) menu_quit = true; }}
static void audio_options(void){ int selected = 0; int result; bool menu_quit = false;
MENUITEM_STRINGLIST(menu, ID2P(LANG_MENU_AUDIO_OPTIONS), mpeg_sysevent_callback, ID2P(LANG_TONE_CONTROLS), ID2P(LANG_CHANNEL_CONFIGURATION), ID2P(LANG_CROSSFEED), ID2P(LANG_EQUALIZER), ID2P(LANG_DITHERING));
rb->button_clear_queue();
while (!menu_quit) { mpeg_sysevent_clear(); result = rb->do_menu(&menu, &selected, NULL, false);
switch (result) { case MPEG_AUDIO_TONE_CONTROLS: mpeg_set_option(rb->str(LANG_TONE_CONTROLS), &settings.tone_controls, RB_INT, globaloff, 2, NULL); sync_audio_setting(result, false); break;
case MPEG_AUDIO_CHANNEL_MODES: mpeg_set_option(rb->str(LANG_CHANNEL_CONFIGURATION), &settings.channel_modes, RB_INT, globaloff, 2, NULL); sync_audio_setting(result, false); break;
case MPEG_AUDIO_CROSSFEED: mpeg_set_option(rb->str(LANG_CROSSFEED), &settings.crossfeed, RB_INT, globaloff, 2, NULL); sync_audio_setting(result, false); break;
case MPEG_AUDIO_EQUALIZER: mpeg_set_option(rb->str(LANG_EQUALIZER), &settings.equalizer, RB_INT, globaloff, 2, NULL); sync_audio_setting(result, false); break;
case MPEG_AUDIO_DITHERING: mpeg_set_option(rb->str(LANG_DITHERING), &settings.dithering, RB_INT, globaloff, 2, NULL); sync_audio_setting(result, false); break;
default: menu_quit = true; break; }
if (mpeg_sysevent() != 0) menu_quit = true; }}
static void resume_options(void){ static const struct opt_items items[MPEG_RESUME_NUM_OPTIONS] = { [MPEG_RESUME_MENU_ALWAYS] = { STR(LANG_FORCE_START_MENU) }, [MPEG_RESUME_MENU_IF_INCOMPLETE] = { STR(LANG_CONDITIONAL_START_MENU) }, [MPEG_RESUME_ALWAYS] = { STR(LANG_AUTO_RESUME) }, [MPEG_RESUME_RESTART] = { STR(LANG_RESTART_PLAYBACK) }, };
mpeg_set_option(rb->str(LANG_MENU_RESUME_OPTIONS), &settings.resume_options, RB_INT, items, MPEG_RESUME_NUM_OPTIONS, NULL);}
static void clear_resume_count(void){ settings.resume_count = 0; configfile_save(SETTINGS_FILENAME, config, ARRAYLEN(config), SETTINGS_VERSION);}
static void mpeg_settings(void){ int selected = 0; int result; bool menu_quit = false;
MENUITEM_STRINGLIST(menu, ID2P(LANG_SETTINGS), mpeg_sysevent_callback, ID2P(LANG_MENU_DISPLAY_OPTIONS), ID2P(LANG_MENU_AUDIO_OPTIONS), ID2P(LANG_MENU_RESUME_OPTIONS), ID2P(LANG_MENU_PLAY_MODE), ID2P(LANG_CLEAR_ALL_RESUMES));
rb->button_clear_queue();
while (!menu_quit) { mpeg_sysevent_clear();
result = rb->do_menu(&menu, &selected, NULL, false);
switch (result) { case MPEG_SETTING_DISPLAY_SETTINGS: display_options(); break;
case MPEG_SETTING_AUDIO_SETTINGS: audio_options(); break;
case MPEG_SETTING_ENABLE_START_MENU: resume_options(); break;
case MPEG_SETTING_PLAY_MODE: mpeg_set_option(rb->str(LANG_MENU_PLAY_MODE), &settings.play_mode, RB_INT, singleall, 2, NULL); break;
case MPEG_SETTING_CLEAR_RESUMES: clear_resume_count(); break;
default: menu_quit = true; break; }
if (mpeg_sysevent() != 0) menu_quit = true; }}
void init_settings(const char* filename){ /* Set the default settings */ settings.showfps = 0; /* Do not show FPS */ settings.limitfps = 1; /* Limit FPS */ settings.skipframes = 1; /* Skip frames */ settings.play_mode = 0; /* Play single video */ settings.resume_options = MPEG_RESUME_MENU_ALWAYS; /* Enable start menu */ settings.resume_count = 0;#ifdef HAVE_BACKLIGHT_BRIGHTNESS settings.backlight_brightness = -1; /* Use default setting */#endif#if MPEG_OPTION_DITHERING_ENABLED settings.displayoptions = 0; /* No visual effects */#endif settings.tone_controls = false; settings.channel_modes = false; settings.crossfeed = false; settings.equalizer = false; settings.dithering = false;
if (configfile_load(SETTINGS_FILENAME, config, ARRAYLEN(config), SETTINGS_MIN_VERSION) < 0) { /* Generate a new config file with default values */ configfile_save(SETTINGS_FILENAME, config, ARRAYLEN(config), SETTINGS_VERSION); }
rb->strlcpy(settings.resume_filename, filename, MAX_PATH);
/* get the resume time for the current mpeg if it exists */ if ((settings.resume_time = configfile_get_value (SETTINGS_FILENAME, filename)) < 0) { settings.resume_time = 0; }
#if MPEG_OPTION_DITHERING_ENABLED rb->lcd_yuv_set_options(settings.displayoptions);#endif
/* Set our audio options */ sync_audio_settings(false);}
void save_settings(void){ unsigned i; for (i = 0; i < ARRAYLEN(config); i++) { configfile_update_entry(SETTINGS_FILENAME, config[i].name, *(config[i].int_p)); }
/* If this was a new resume entry then update the total resume count */ if (configfile_update_entry(SETTINGS_FILENAME, settings.resume_filename, settings.resume_time) == 0) { configfile_update_entry(SETTINGS_FILENAME, "Resume count", ++settings.resume_count); }
/* Restore audio options */ sync_audio_settings(true);}