summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/keymaps/keymap-h1x0_h3x0.c11
-rw-r--r--apps/lang/english.lang80
-rw-r--r--apps/recorder/icons.c6
-rw-r--r--apps/recorder/icons.h7
-rw-r--r--apps/recorder/recording.c173
-rw-r--r--apps/settings.c168
-rw-r--r--apps/settings.h12
-rw-r--r--apps/sound_menu.c23
8 files changed, 470 insertions, 10 deletions
diff --git a/apps/keymaps/keymap-h1x0_h3x0.c b/apps/keymaps/keymap-h1x0_h3x0.c
index 0c0b61d201..4ac671ff3c 100644
--- a/apps/keymaps/keymap-h1x0_h3x0.c
+++ b/apps/keymaps/keymap-h1x0_h3x0.c
@@ -415,6 +415,10 @@ const struct button_mapping button_context_settings_h100remote[] = {
415 { ACTION_SETTINGS_INCREPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE }, 415 { ACTION_SETTINGS_INCREPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE },
416 { ACTION_SETTINGS_DEC, BUTTON_RC_FF, BUTTON_NONE }, 416 { ACTION_SETTINGS_DEC, BUTTON_RC_FF, BUTTON_NONE },
417 { ACTION_SETTINGS_DECREPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE }, 417 { ACTION_SETTINGS_DECREPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE },
418 { ACTION_STD_PREV, BUTTON_RC_SOURCE, BUTTON_NONE },
419 { ACTION_STD_PREVREPEAT, BUTTON_RC_SOURCE|BUTTON_REPEAT, BUTTON_NONE },
420 { ACTION_STD_NEXT, BUTTON_RC_BITRATE, BUTTON_NONE },
421 { ACTION_STD_NEXTREPEAT, BUTTON_RC_BITRATE|BUTTON_REPEAT, BUTTON_NONE },
418/* { ACTION_NONE, BUTTON_RC_ON, BUTTON_NONE }, 422/* { ACTION_NONE, BUTTON_RC_ON, BUTTON_NONE },
419 { ACTION_NONE, BUTTON_RC_STOP, BUTTON_NONE }, 423 { ACTION_NONE, BUTTON_RC_STOP, BUTTON_NONE },
420 { ACTION_NONE, BUTTON_RC_MENU|BUTTON_REL, BUTTON_NONE }, 424 { ACTION_NONE, BUTTON_RC_MENU|BUTTON_REL, BUTTON_NONE },
@@ -427,8 +431,11 @@ const struct button_mapping button_context_settings_h300lcdremote[] = {
427 { ACTION_SETTINGS_INCREPEAT, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, 431 { ACTION_SETTINGS_INCREPEAT, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE },
428 { ACTION_SETTINGS_DEC, BUTTON_RC_VOL_DOWN, BUTTON_NONE }, 432 { ACTION_SETTINGS_DEC, BUTTON_RC_VOL_DOWN, BUTTON_NONE },
429 { ACTION_SETTINGS_DECREPEAT, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, 433 { ACTION_SETTINGS_DECREPEAT, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
430 { ACTION_NONE, BUTTON_RC_REW, BUTTON_NONE }, 434 { ACTION_STD_PREV, BUTTON_RC_REW, BUTTON_NONE },
431 { ACTION_NONE, BUTTON_RC_FF, BUTTON_NONE }, 435 { ACTION_STD_PREVREPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE },
436 { ACTION_STD_NEXT, BUTTON_RC_FF, BUTTON_NONE },
437 { ACTION_STD_NEXTREPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE },
438 { ACTION_SETTINGS_RESET, BUTTON_RC_ON, BUTTON_NONE },
432 439
433 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) 440 LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
434}; /* button_context_settings */ 441}; /* button_context_settings */
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 320d4d0f2b..8dee255c8a 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -9806,3 +9806,83 @@
9806 *: "" 9806 *: ""
9807 </voice> 9807 </voice>
9808</phrase> 9808</phrase>
9809<phrase>
9810 id: LANG_TIMER_CONFIRM
9811 desc: Confirm string for recording countdown timer settings
9812 user:
9813 <source>
9814 *: "Press PLAY to confirm"
9815 </source>
9816 <dest>
9817 *: "Press PLAY to confirm"
9818 h100,h120,h300: "Press NAVI to confirm"
9819 </dest>
9820 <voice>
9821 *: ""
9822 </voice>
9823</phrase>
9824<phrase>
9825 id: LANG_TIMER_SET
9826 desc: Recording timer menu
9827 <source>
9828 *: "Set countdown timer"
9829 </source>
9830 <dest>
9831 *: "Set countdown timer"
9832 </dest>
9833 <voice>
9834 *: "Set countdown timer"
9835 </voice>
9836</phrase>
9837<phrase>
9838 id: LANG_TIMER_DAYS
9839 desc: recording timer settings string
9840 <source>
9841 *: "Days"
9842 </source>
9843 <dest>
9844 *: "Days"
9845 </dest>
9846 <voice>
9847 *: "Days"
9848 </voice>
9849</phrase>
9850<phrase>
9851 id: LANG_TIMER_HRS
9852 desc: recording timer settings string
9853 <source>
9854 *: "Hrs"
9855 </source>
9856 <dest>
9857 *: "Hrs"
9858 </dest>
9859 <voice>
9860 *: "Hrs"
9861 </voice>
9862</phrase>
9863<phrase>
9864 id: LANG_TIMER_MINS
9865 desc: recording timer settings string
9866 <source>
9867 *: "Mins"
9868 </source>
9869 <dest>
9870 *: "Mins"
9871 </dest>
9872 <voice>
9873 *: "Mins"
9874 </voice>
9875</phrase>
9876<phrase>
9877 id: LANG_REC_TIMER
9878 desc: recording screen timer string
9879 <source>
9880 *: "Timer"
9881 </source>
9882 <dest>
9883 *: "Timer"
9884 </dest>
9885 <voice>
9886 *: "Timer"
9887 </voice>
9888</phrase>
diff --git a/apps/recorder/icons.c b/apps/recorder/icons.c
index 711df633f4..20a681fc81 100644
--- a/apps/recorder/icons.c
+++ b/apps/recorder/icons.c
@@ -36,6 +36,12 @@ const unsigned char bitmap_icons_5x8[][5] =
36 [Icon_Mono]={0x00, 0x1c, 0x22, 0x1c, 0x00} /* Mono recording */ 36 [Icon_Mono]={0x00, 0x1c, 0x22, 0x1c, 0x00} /* Mono recording */
37}; 37};
38 38
39const unsigned char bitmap_icons_7x7[][7] =
40{
41 [Icon_Timer]={0x1c, 0x22, 0x41, 0x4f, 0x49, 0x22, 0x1d}, /* Recording timer icon */
42 [Icon_Blank]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* Blank for flashing */
43};
44
39const unsigned char bitmap_icons_6x8[][6] = 45const unsigned char bitmap_icons_6x8[][6] =
40{ 46{
41 { 0x60, 0x7f, 0x03, 0x33, 0x3f, 0x00 }, /* Musical note */ 47 { 0x60, 0x7f, 0x03, 0x33, 0x3f, 0x00 }, /* Musical note */
diff --git a/apps/recorder/icons.h b/apps/recorder/icons.h
index b4310aa90a..c68b281852 100644
--- a/apps/recorder/icons.h
+++ b/apps/recorder/icons.h
@@ -44,6 +44,12 @@ enum icons_5x8 {
44 Icon5x8Last 44 Icon5x8Last
45}; 45};
46 46
47enum icons_7x7 {
48 Icon_Timer,
49 Icon_Blank,
50 Icon7x7Last
51};
52
47enum icons_6x8 { 53enum icons_6x8 {
48 Icon_Audio, 54 Icon_Audio,
49 Icon_Folder, 55 Icon_Folder,
@@ -117,6 +123,7 @@ enum icons_18x8 {
117#endif 123#endif
118 124
119extern const unsigned char bitmap_icons_5x8[Icon5x8Last][5]; 125extern const unsigned char bitmap_icons_5x8[Icon5x8Last][5];
126extern const unsigned char bitmap_icons_7x7[Icon7x7Last][7];
120extern const unsigned char bitmap_icons_6x8[Icon6x8Last][6]; 127extern const unsigned char bitmap_icons_6x8[Icon6x8Last][6];
121extern const unsigned char bitmap_icons_7x8[Icon7x8Last][7]; 128extern const unsigned char bitmap_icons_7x8[Icon7x8Last][7];
122#if CONFIG_CODEC == SWCODEC 129#if CONFIG_CODEC == SWCODEC
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index 6ee71d2eee..4d0e226254 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -69,8 +69,18 @@
69#include "screen_access.h" 69#include "screen_access.h"
70#include "action.h" 70#include "action.h"
71#include "radio.h" 71#include "radio.h"
72#include "timer.h"
72#ifdef HAVE_RECORDING 73#ifdef HAVE_RECORDING
73 74
75#ifdef SIMULATOR
76bool timer_register(int reg_prio, void (*unregister_callback)(void),
77 long cycles, int int_prio, void (*timer_callback)(void));
78void timer_unregister(void);
79#define TIMER_FREQ 0
80#endif
81#define TIMER_ICON_WIDTH 7
82#define TIMER_ICON_HEIGHT 7
83
74#define PM_HEIGHT ((LCD_HEIGHT >= 72) ? 2 : 1) 84#define PM_HEIGHT ((LCD_HEIGHT >= 72) ? 2 : 1)
75 85
76bool f2_rec_screen(void); 86bool f2_rec_screen(void);
@@ -78,6 +88,9 @@ bool f3_rec_screen(void);
78 88
79#define MAX_FILE_SIZE 0x7F800000 /* 2 GB - 4 MB */ 89#define MAX_FILE_SIZE 0x7F800000 /* 2 GB - 4 MB */
80 90
91int days, hrs, mins, secs;
92bool timer_icon; /* timer icon displayed? */
93
81int screen_update = NB_SCREENS; 94int screen_update = NB_SCREENS;
82bool remote_display_on = true; 95bool remote_display_on = true;
83const char* const freq_str[6] = 96const char* const freq_str[6] =
@@ -779,6 +792,52 @@ static void trigger_listener(int trigger_status)
779 } 792 }
780} 793}
781 794
795/* countdown timer callback function */
796void timer_callback(void)
797{
798 static int mini_tick = 0;
799 /* print icon at bottom right of main screen */
800 if (timer_icon)
801 screens[0].mono_bitmap(bitmap_icons_7x7[Icon_Timer],
802 screens[0].width - TIMER_ICON_WIDTH,
803 screens[0].height - TIMER_ICON_HEIGHT,
804 TIMER_ICON_WIDTH, TIMER_ICON_HEIGHT);
805 else
806 screens[0].mono_bitmap(bitmap_icons_7x7[Icon_Blank],
807 screens[0].width - TIMER_ICON_WIDTH,
808 screens[0].height - TIMER_ICON_HEIGHT,
809 TIMER_ICON_WIDTH, TIMER_ICON_HEIGHT);
810
811 screens[0].update_rect(screens[0].width - TIMER_ICON_WIDTH,
812 screens[0].height - TIMER_ICON_HEIGHT,
813 TIMER_ICON_WIDTH, TIMER_ICON_HEIGHT);
814
815 mini_tick ++;
816 /* the countdown */
817 if (mini_tick > 10)
818 {
819 secs -= 1;
820 if (secs < 0){
821 mins -= 1;
822 secs = 59;
823 if (mins < 0){
824 hrs -= 1;
825 mins = 59;
826 if (hrs < 0){
827 days -= 1;
828 hrs = 23;
829 if (days < 0)
830 {
831 days = hrs = mins = secs = 0;
832 timer_icon = !timer_icon; /* flash icon when */
833 } /* countdown finished */
834 }
835 }
836 }
837 mini_tick = 0;
838 }
839}
840
782bool recording_screen(bool no_source) 841bool recording_screen(bool no_source)
783{ 842{
784 long button; 843 long button;
@@ -818,6 +877,8 @@ bool recording_screen(bool no_source)
818 int i; 877 int i;
819 int filename_offset[NB_SCREENS]; 878 int filename_offset[NB_SCREENS];
820 int pm_y[NB_SCREENS]; 879 int pm_y[NB_SCREENS];
880 static bool countdown; /* countdown in progress indicator */
881 int countdown_offset = 0;
821 882
822 static const unsigned char *byte_units[] = { 883 static const unsigned char *byte_units[] = {
823 ID2P(LANG_BYTE), 884 ID2P(LANG_BYTE),
@@ -827,6 +888,20 @@ bool recording_screen(bool no_source)
827 }; 888 };
828 889
829 global_settings.recscreen_on = true; 890 global_settings.recscreen_on = true;
891
892 /* Stop countdown if countdown settings changed */
893 if ((mins != global_settings.ctdn_mins)||
894 (hrs != global_settings.ctdn_hrs) ||
895 (days != global_settings.ctdn_days))
896 {
897 mins = global_settings.ctdn_mins;
898 hrs = global_settings.ctdn_hrs;
899 days = global_settings.ctdn_days;
900 secs = global_settings.ctdn_secs;
901 countdown = false;
902 timer_unregister();
903 }
904
830 cursor = 0; 905 cursor = 0;
831#if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR) 906#if (CONFIG_LED == LED_REAL) && !defined(SIMULATOR)
832 ata_set_led_enabled(false); 907 ata_set_led_enabled(false);
@@ -969,6 +1044,17 @@ bool recording_screen(bool no_source)
969 last_audio_stat = audio_stat; 1044 last_audio_stat = audio_stat;
970 } 1045 }
971 1046
1047 /* When countdown timer reaches zero fake a new file button press */
1048 if (countdown && !days && !hrs && !mins && !secs)
1049 {
1050 timer_unregister();
1051 button = ACTION_REC_NEWFILE;
1052 countdown = false;
1053 global_settings.ctdn_days = days;
1054 global_settings.ctdn_hrs = hrs;
1055 global_settings.ctdn_mins = mins;
1056 }
1057
972 switch(button) 1058 switch(button)
973 { 1059 {
974 case ACTION_REC_LCD: 1060 case ACTION_REC_LCD:
@@ -1004,7 +1090,12 @@ bool recording_screen(bool no_source)
1004#if CONFIG_CODEC != SWCODEC 1090#if CONFIG_CODEC != SWCODEC
1005 peak_meter_playback(true); 1091 peak_meter_playback(true);
1006 peak_meter_enabled = false; 1092 peak_meter_enabled = false;
1007#endif 1093#endif
1094 /* keeps settings the same as the countdown values */
1095 global_settings.ctdn_days = days;
1096 global_settings.ctdn_hrs = hrs;
1097 global_settings.ctdn_mins = mins;
1098 global_settings.ctdn_secs = secs;
1008 done = true; 1099 done = true;
1009 } 1100 }
1010 update_countdown = 1; /* Update immediately */ 1101 update_countdown = 1; /* Update immediately */
@@ -1014,7 +1105,27 @@ bool recording_screen(bool no_source)
1014 case ACTION_REC_NEWFILE: 1105 case ACTION_REC_NEWFILE:
1015 /* Only act if the mpeg is stopped */ 1106 /* Only act if the mpeg is stopped */
1016 if(!(audio_stat & AUDIO_STATUS_RECORD)) 1107 if(!(audio_stat & AUDIO_STATUS_RECORD))
1017 { 1108 { /* if countdown timer is set, start countdown */
1109 if (days || hrs || mins || secs)
1110 {
1111 if (button == ACTION_REC_PAUSE)
1112 {
1113 countdown = !countdown;
1114 if (countdown)
1115 timer_register(1, NULL, TIMER_FREQ/10, 1, timer_callback);
1116 else
1117 timer_unregister();
1118 break;
1119 }
1120 else
1121 {
1122 /* if newfile button pressed and countdown timer is on,
1123 start new file and reset timer */
1124 timer_unregister();
1125 days = hrs = mins = secs = 0;
1126 countdown = false;
1127 }
1128 }
1018 /* is this manual or triggered recording? */ 1129 /* is this manual or triggered recording? */
1019 if ((global_settings.rec_trigger_mode == TRIG_MODE_OFF) || 1130 if ((global_settings.rec_trigger_mode == TRIG_MODE_OFF) ||
1020 (peak_meter_trigger_status() != TRIG_OFF)) 1131 (peak_meter_trigger_status() != TRIG_OFF))
@@ -1221,7 +1332,11 @@ bool recording_screen(bool no_source)
1221#ifdef HAVE_FMRADIO_IN 1332#ifdef HAVE_FMRADIO_IN
1222 const int prev_rec_source = global_settings.rec_source; 1333 const int prev_rec_source = global_settings.rec_source;
1223#endif 1334#endif
1224 1335 /* maintain countdown values when entering menu */
1336 global_settings.ctdn_days = days;
1337 global_settings.ctdn_hrs = hrs;
1338 global_settings.ctdn_mins = mins;
1339 global_settings.ctdn_secs = secs;
1225#if CONFIG_LED == LED_REAL 1340#if CONFIG_LED == LED_REAL
1226 /* led is restored at begin of loop / end of function */ 1341 /* led is restored at begin of loop / end of function */
1227 led(false); 1342 led(false);
@@ -1245,6 +1360,19 @@ bool recording_screen(bool no_source)
1245 && prev_rec_source == AUDIO_SRC_FMRADIO) 1360 && prev_rec_source == AUDIO_SRC_FMRADIO)
1246 radio_status = FMRADIO_OFF; 1361 radio_status = FMRADIO_OFF;
1247#endif 1362#endif
1363 /* if countdown timer settings changed in menu,
1364 stop counting and reset */
1365 if ((hrs != global_settings.ctdn_hrs) ||
1366 (mins != global_settings.ctdn_mins) ||
1367 (days != global_settings.ctdn_days))
1368 {
1369 days = global_settings.ctdn_days;
1370 hrs = global_settings.ctdn_hrs;
1371 mins = global_settings.ctdn_mins;
1372 secs = global_settings.ctdn_secs;
1373 countdown = false;
1374 timer_unregister();
1375 }
1248 1376
1249#if CONFIG_CODEC == SWCODEC 1377#if CONFIG_CODEC == SWCODEC
1250 /* reinit after submenu exit */ 1378 /* reinit after submenu exit */
@@ -1347,6 +1475,8 @@ bool recording_screen(bool no_source)
1347 break; 1475 break;
1348 } 1476 }
1349 1477
1478 timer_icon = countdown; /* display timer icon if countdown enabled */
1479
1350#ifdef HAVE_AGC 1480#ifdef HAVE_AGC
1351 peak_read = !peak_read; 1481 peak_read = !peak_read;
1352 if (peak_read) { /* every 2nd run of loop */ 1482 if (peak_read) { /* every 2nd run of loop */
@@ -1383,11 +1513,13 @@ bool recording_screen(bool no_source)
1383 1513
1384 if ((global_settings.rec_sizesplit) && (global_settings.rec_split_method)) 1514 if ((global_settings.rec_sizesplit) && (global_settings.rec_split_method))
1385 { 1515 {
1516 countdown_offset = 1;
1386 dmb = dsize/1024/1024; 1517 dmb = dsize/1024/1024;
1387 snprintf(buf, sizeof(buf), "%s %dMB", 1518 snprintf(buf, sizeof(buf), "%s %dMB",
1388 str(LANG_SYSFONT_SPLIT_SIZE), dmb); 1519 str(LANG_SYSFONT_SPLIT_SIZE), dmb);
1389 } 1520 }
1390 else 1521 /* only display recording time if countdown timer is off */
1522 else if (!days && !hrs && !mins && !secs)
1391 { 1523 {
1392 hours = seconds / 3600; 1524 hours = seconds / 3600;
1393 minutes = (seconds - (hours * 3600)) / 60; 1525 minutes = (seconds - (hours * 3600)) / 60;
@@ -1395,6 +1527,11 @@ bool recording_screen(bool no_source)
1395 str(LANG_SYSFONT_RECORDING_TIME), 1527 str(LANG_SYSFONT_RECORDING_TIME),
1396 hours, minutes, seconds%60); 1528 hours, minutes, seconds%60);
1397 } 1529 }
1530 else
1531 {
1532 countdown_offset = 0;
1533 snprintf(buf, 32, "");
1534 }
1398 1535
1399 for(i = 0; i < screen_update; i++) 1536 for(i = 0; i < screen_update; i++)
1400 screens[i].puts(0, 0, buf); 1537 screens[i].puts(0, 0, buf);
@@ -1418,7 +1555,8 @@ bool recording_screen(bool no_source)
1418 str(LANG_SYSFONT_RECORD_TIMESPLIT_REC), 1555 str(LANG_SYSFONT_RECORD_TIMESPLIT_REC),
1419 dhours, dminutes); 1556 dhours, dminutes);
1420 } 1557 }
1421 else 1558 /* only display recording size if countdown timer is off */
1559 else if (!days && !hrs && !mins && !secs)
1422 { 1560 {
1423 output_dyn_value(buf2, sizeof buf2, 1561 output_dyn_value(buf2, sizeof buf2,
1424 num_recorded_bytes, 1562 num_recorded_bytes,
@@ -1430,6 +1568,16 @@ bool recording_screen(bool no_source)
1430 for(i = 0; i < screen_update; i++) 1568 for(i = 0; i < screen_update; i++)
1431 screens[i].puts(0, 1, buf); 1569 screens[i].puts(0, 1, buf);
1432 1570
1571 /* display countdown timer if set */
1572 if (days || hrs || mins || secs)
1573 {
1574 snprintf(buf, 32, "%s %d:%02d:%02d:%02d", str(LANG_REC_TIMER),
1575 days, hrs, mins, secs);
1576
1577 for(i = 0; i < screen_update; i++)
1578 screens[i].puts(0, countdown_offset, buf);
1579 }
1580
1433 for(i = 0; i < screen_update; i++) 1581 for(i = 0; i < screen_update; i++)
1434 { 1582 {
1435 if (filename_offset[i] > 0) 1583 if (filename_offset[i] > 0)
@@ -2123,6 +2271,21 @@ unsigned long pcm_rec_status(void)
2123 2271
2124#endif /* #ifdef SIMULATOR */ 2272#endif /* #ifdef SIMULATOR */
2125#endif /* #ifdef CONFIG_CODEC == SWCODEC */ 2273#endif /* #ifdef CONFIG_CODEC == SWCODEC */
2274#ifdef SIMULATOR
2275bool timer_register(int reg_prio, void (*unregister_callback)(void),
2276 long cycles, int int_prio, void (*timer_callback)(void))
2277{
2278 reg_prio = reg_prio;
2279 unregister_callback = unregister_callback;
2280 cycles = cycles;
2281 int_prio = int_prio;
2282 timer_callback = timer_callback;
2283 return false;
2284}
2126 2285
2286void timer_unregister(void)
2287{
2288}
2289#endif
2127 2290
2128#endif /* HAVE_RECORDING */ 2291#endif /* HAVE_RECORDING */
diff --git a/apps/settings.c b/apps/settings.c
index 3dc4ee1530..b2f7888a22 100644
--- a/apps/settings.c
+++ b/apps/settings.c
@@ -96,7 +96,7 @@ const char rec_base_directory[] = REC_BASE_DIR;
96#include "eq_menu.h" 96#include "eq_menu.h"
97#endif 97#endif
98 98
99#define CONFIG_BLOCK_VERSION 52 99#define CONFIG_BLOCK_VERSION 53
100#define CONFIG_BLOCK_SIZE 512 100#define CONFIG_BLOCK_SIZE 512
101#define RTC_BLOCK_SIZE 44 101#define RTC_BLOCK_SIZE 44
102 102
@@ -477,6 +477,11 @@ static const struct bit_entry hd_bits[] =
477 {1, S_O(rec_channels), 0, "rec channels", "stereo,mono" }, 477 {1, S_O(rec_channels), 0, "rec channels", "stereo,mono" },
478 {1, S_O(rec_split_type), 0, "rec split type", "Split, Stop" }, 478 {1, S_O(rec_split_type), 0, "rec split type", "Split, Stop" },
479 {1, S_O(rec_split_method), 0, "rec split method", "Time,Filesize" }, 479 {1, S_O(rec_split_method), 0, "rec split method", "Time,Filesize" },
480 {6, S_O(ctdn_mins), 0, "countdown timer minutes", NULL }, /* 0 - 59 */
481 {5, S_O(ctdn_hrs), 0, "countdown timer hours", NULL }, /* 0 - 23 */
482 {6, S_O(ctdn_secs), 0, "countdown timer seconds", NULL }, /* 0 - 59 */
483 {3, S_O(ctdn_days), 0, "countdown timer days", NULL }, /* 0 - 6 */
484
480 485
481 { 486 {
482#if defined(HAVE_SPDIF_IN) || defined(HAVE_FMRADIO_IN) 487#if defined(HAVE_SPDIF_IN) || defined(HAVE_FMRADIO_IN)
@@ -2032,6 +2037,167 @@ bool set_int(const unsigned char* string,
2032 (max-*variable)/step, &data,function); 2037 (max-*variable)/step, &data,function);
2033} 2038}
2034 2039
2040/* Useful for time and other multi integer settings */
2041bool set_multi_int(const char* string, const struct opt_items * names,
2042 struct opt_settings * variable, int varcount)
2043{
2044 int i, j;
2045 char buf[32];
2046 long button;
2047 int cursor = 0;
2048 bool done = false;
2049 int oldvalue[varcount];
2050 int pos = 0;
2051
2052 for(j = 0; j < varcount; j++)
2053 oldvalue[j] = *(int*)variable[j].setting;
2054
2055 FOR_NB_SCREENS(i)
2056 {
2057 screens[i].clear_display();
2058#ifdef HAVE_LCD_BITMAP
2059 screens[i].setmargins(0, 8);
2060#endif
2061 }
2062
2063 snprintf(buf, sizeof(buf), "%s", string);
2064 FOR_NB_SCREENS(i)
2065 screens[i].puts(0, 0, buf);
2066
2067 /* print variable names */
2068 for(j = 0; j < varcount ; j++)
2069 {
2070 if (j > 0)
2071 {
2072 snprintf(buf, sizeof(buf), ":");
2073 FOR_NB_SCREENS(i)
2074 screens[i].puts(pos - 2, 1, buf);
2075 }
2076
2077 snprintf(buf, sizeof(buf), "%s", P2STR(names[j].string));
2078 FOR_NB_SCREENS(i)
2079 screens[i].puts(pos, 1, buf);
2080
2081 pos += strlen(buf) + 3;
2082 }
2083
2084 snprintf(buf, sizeof(buf), "%s", str(LANG_TIMER_CONFIRM));
2085 FOR_NB_SCREENS(i)
2086 screens[i].puts(0, 5, buf);
2087
2088 gui_syncstatusbar_draw(&statusbars, true);
2089
2090 while(!done)
2091 {
2092 pos = 0;
2093
2094 /* print variables */
2095 for(j = 0; j < varcount; j++)
2096 {
2097 if (j > 0)
2098 {
2099 snprintf(buf, sizeof(buf), " :");
2100 FOR_NB_SCREENS(i)
2101 screens[i].puts(pos - 3, 3, buf);
2102 }
2103
2104 snprintf(buf, sizeof(buf), "%d", *(int*)variable[j].setting);
2105
2106#ifdef HAVE_LCD_BITMAP
2107 if (cursor == j)
2108 {
2109 FOR_NB_SCREENS(i)
2110 screens[i].puts_style_offset(pos, 3, buf, STYLE_INVERT, 0);
2111 }
2112 else
2113#endif
2114 {
2115 FOR_NB_SCREENS(i)
2116 screens[i].puts(pos, 3, buf);
2117 }
2118
2119 snprintf(buf, sizeof(buf), "%d", variable[j].setting_max);
2120 pos += strlen(buf) + 3;
2121 }
2122
2123 /* print empty char to terminate invert style */
2124 snprintf(buf, sizeof(buf), " ");
2125 FOR_NB_SCREENS(i)
2126 screens[i].puts(pos - 3, 3, buf);
2127
2128#ifdef HAVE_LCD_BITMAP
2129 FOR_NB_SCREENS(i)
2130 screens[i].update();
2131#endif
2132
2133 button = get_action(CONTEXT_SETTINGS, TIMEOUT_BLOCK);
2134
2135 switch (button)
2136 {
2137 case ACTION_STD_NEXT:
2138 cursor ++;
2139 if (cursor >= varcount)
2140 cursor = varcount - 1;
2141 if (global_settings.talk_menu)
2142 talk_id(names[cursor].voice_id, false);
2143 break;
2144
2145 case ACTION_STD_PREV:
2146 if (cursor == 0)
2147 {
2148 /* cancel if pressing left when cursor
2149 is already at the far left */
2150 for(j = 0; j < varcount; j++)
2151 *(int*)variable[j].setting = oldvalue[j];
2152 gui_syncsplash(HZ/2, true, str(LANG_MENU_SETTING_CANCEL));
2153 done = true;
2154 }
2155 else
2156 cursor --;
2157 if (cursor < 0)
2158 cursor = 0;
2159 if (global_settings.talk_menu)
2160 talk_id(names[cursor].voice_id, false);
2161 break;
2162
2163 case ACTION_SETTINGS_INC:
2164 case ACTION_SETTINGS_INCREPEAT:
2165 *(int*)variable[cursor].setting += 1;
2166 if (*(int*)variable[cursor].setting >
2167 variable[cursor].setting_max)
2168 *(int*)variable[cursor].setting = 0;
2169 if (global_settings.talk_menu)
2170 talk_unit(INT, *(int*)variable[cursor].setting);
2171 break;
2172
2173 case ACTION_SETTINGS_DEC:
2174 case ACTION_SETTINGS_DECREPEAT:
2175 *(int*)variable[cursor].setting -= 1;
2176 if (*(int*)variable[cursor].setting < 0)
2177 *(int*)variable[cursor].setting =
2178 variable[cursor].setting_max;
2179 if (global_settings.talk_menu)
2180 talk_unit(INT, *(int*)variable[cursor].setting);
2181 break;
2182
2183 case ACTION_STD_OK:
2184 done = true;
2185 break;
2186
2187 case ACTION_STD_CANCEL:
2188 for(j = 0; j < varcount; j++)
2189 *(int*)variable[j].setting = oldvalue[j];
2190 gui_syncsplash(HZ/2, true, str(LANG_MENU_SETTING_CANCEL));
2191 return false;
2192
2193 default:
2194 if (default_event_handler(button) == SYS_USB_CONNECTED)
2195 return true;
2196 }
2197 }
2198 return false;
2199}
2200
2035/* NOTE: the 'type' parameter specifies the actual type of the variable 2201/* NOTE: the 'type' parameter specifies the actual type of the variable
2036 that 'variable' points to. not the value within. Only variables with 2202 that 'variable' points to. not the value within. Only variables with
2037 type 'bool' should use parameter BOOL. 2203 type 'bool' should use parameter BOOL.
diff --git a/apps/settings.h b/apps/settings.h
index 561dc59375..fe00dce023 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -167,7 +167,10 @@ struct user_settings
167 13= 1GB, 14 = 1.5GB 15 = 1.75MB*/ 167 13= 1GB, 14 = 1.5GB 15 = 1.75MB*/
168 int rec_split_type; /* split/stop */ 168 int rec_split_type; /* split/stop */
169 int rec_split_method; /* time/filesize */ 169 int rec_split_method; /* time/filesize */
170 170 int ctdn_mins; /* 0 - 59 */
171 int ctdn_hrs; /* 0 - 23 */
172 int ctdn_secs; /* 0 - 59 */
173 int ctdn_days; /* 0 - 6 */
171 int rec_prerecord_time; /* In seconds, 0-30, 0 means OFF */ 174 int rec_prerecord_time; /* In seconds, 0-30, 0 means OFF */
172 int rec_directory; /* 0=base dir, 1=current dir */ 175 int rec_directory; /* 0=base dir, 1=current dir */
173 bool rec_startup; /* true means start Rockbox in recording screen */ 176 bool rec_startup; /* true means start Rockbox in recording screen */
@@ -495,6 +498,11 @@ struct opt_items {
495 long voice_id; 498 long voice_id;
496}; 499};
497 500
501struct opt_settings {
502 int* setting;
503 int setting_max;
504};
505
498/* prototypes */ 506/* prototypes */
499 507
500void settings_calc_config_sector(void); 508void settings_calc_config_sector(void);
@@ -516,6 +524,8 @@ bool set_bool_options(const char* string, bool* variable,
516bool set_bool(const char* string, bool* variable ); 524bool set_bool(const char* string, bool* variable );
517bool set_option(const char* string, void* variable, enum optiontype type, 525bool set_option(const char* string, void* variable, enum optiontype type,
518 const struct opt_items* options, int numoptions, void (*function)(int)); 526 const struct opt_items* options, int numoptions, void (*function)(int));
527bool set_multi_int(const char* string, const struct opt_items * names,
528 struct opt_settings * variable, int varcount);
519bool set_int(const unsigned char* string, const char* unit, int voice_unit, 529bool set_int(const unsigned char* string, const char* unit, int voice_unit,
520 int* variable, 530 int* variable,
521 void (*function)(int), int step, int min, int max, 531 void (*function)(int), int step, int min, int max,
diff --git a/apps/sound_menu.c b/apps/sound_menu.c
index f220d26f8f..6537b5b171 100644
--- a/apps/sound_menu.c
+++ b/apps/sound_menu.c
@@ -7,7 +7,7 @@
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2002 Björn Stenberg 10 * Copyright (C) 2002 Bj�n Stenberg
11 * 11 *
12 * All files in this archive are subject to the GNU General Public License. 12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement. 13 * See the file COPYING in the source tree root for full license agreement.
@@ -591,6 +591,25 @@ static bool agc_cliptime(void)
591 INT, names, 5, NULL ); 591 INT, names, 5, NULL );
592} 592}
593#endif /* HAVE_AGC */ 593#endif /* HAVE_AGC */
594
595/* Displays a menu for changing the countdown timer settings */
596static bool countdown_timer(void)
597{
598 static const struct opt_items names[] = {
599 { STR(LANG_TIMER_DAYS) },
600 { STR(LANG_TIMER_HRS) },
601 { STR(LANG_TIMER_MINS) }
602 };
603
604 struct opt_settings settings[] = {
605 { &global_settings.ctdn_days, 6 },
606 { &global_settings.ctdn_hrs, 23 },
607 { &global_settings.ctdn_mins, 59 }
608 };
609
610 return set_multi_int(str(LANG_TIMER_SET), names, settings, 3);
611}
612
594#endif /* HAVE_RECORDING */ 613#endif /* HAVE_RECORDING */
595 614
596static bool chanconf(void) 615static bool chanconf(void)
@@ -1089,6 +1108,8 @@ bool recording_menu(bool no_source)
1089 items[i].desc = ID2P(LANG_RECORD_AGC_CLIPTIME); 1108 items[i].desc = ID2P(LANG_RECORD_AGC_CLIPTIME);
1090 items[i++].function = agc_cliptime; 1109 items[i++].function = agc_cliptime;
1091#endif 1110#endif
1111 items[i].desc = ID2P(LANG_TIMER_SET);
1112 items[i++].function = countdown_timer;
1092 1113
1093 m=menu_init( items, i, NULL, NULL, NULL, NULL); 1114 m=menu_init( items, i, NULL, NULL, NULL, NULL);
1094 result = menu_run(m); 1115 result = menu_run(m);