summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2006-03-10 00:18:58 +0000
committerJens Arnold <amiconn@rockbox.org>2006-03-10 00:18:58 +0000
commit78e4f4d1b14eea3a78f1af267b6fc100c5297b25 (patch)
treeaf12d0ee6a3e9921272e7f2e7a35779e0678aa85 /apps/plugins
parentff862e19ccd6209cd13b91761fcf944a7e0abd11 (diff)
downloadrockbox-78e4f4d1b14eea3a78f1af267b6fc100c5297b25.zip
rockbox-78e4f4d1b14eea3a78f1af267b6fc100c5297b25.tar.gz
rockbox-78e4f4d1b14eea3a78f1af267b6fc100c5297b25.tar.bz2
rockbox-78e4f4d1b14eea3a78f1af267b6fc100c5297b25.tar.xz
Oscilloscope: Added vertical orientation option. Flipped horizontal mode to show left channel on top. Vertical mode prints speed messages. Set default speed to 50 instead of 100.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8986 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/oscilloscope.c288
1 files changed, 245 insertions, 43 deletions
diff --git a/apps/plugins/oscilloscope.c b/apps/plugins/oscilloscope.c
index e215f78..2d1425b 100644
--- a/apps/plugins/oscilloscope.c
+++ b/apps/plugins/oscilloscope.c
@@ -39,6 +39,7 @@ PLUGIN_HEADER
#define OSCILLOSCOPE_QUIT BUTTON_OFF
#define OSCILLOSCOPE_MODE BUTTON_F1
#define OSCILLOSCOPE_SCROLL BUTTON_F2
+#define OSCILLOSCOPE_ORIENTATION BUTTON_F3
#define OSCILLOSCOPE_PAUSE BUTTON_PLAY
#define OSCILLOSCOPE_SPEED_UP BUTTON_RIGHT
#define OSCILLOSCOPE_SPEED_DOWN BUTTON_LEFT
@@ -50,6 +51,7 @@ PLUGIN_HEADER
#define OSCILLOSCOPE_MODE_PRE BUTTON_MENU
#define OSCILLOSCOPE_MODE (BUTTON_MENU | BUTTON_REL)
#define OSCILLOSCOPE_SCROLL (BUTTON_MENU | BUTTON_RIGHT)
+#define OSCILLOSCOPE_ORIENTATION (BUTTON_MENU | BUTTON_LEFT)
#define OSCILLOSCOPE_PAUSE (BUTTON_MENU | BUTTON_OFF)
#define OSCILLOSCOPE_SPEED_UP BUTTON_RIGHT
#define OSCILLOSCOPE_SPEED_DOWN BUTTON_LEFT
@@ -60,6 +62,7 @@ PLUGIN_HEADER
#define OSCILLOSCOPE_QUIT BUTTON_OFF
#define OSCILLOSCOPE_MODE BUTTON_SELECT
#define OSCILLOSCOPE_SCROLL BUTTON_MODE
+#define OSCILLOSCOPE_ORIENTATION BUTTON_REC
#define OSCILLOSCOPE_PAUSE BUTTON_ON
#define OSCILLOSCOPE_SPEED_UP BUTTON_RIGHT
#define OSCILLOSCOPE_SPEED_DOWN BUTTON_LEFT
@@ -70,6 +73,7 @@ PLUGIN_HEADER
#define OSCILLOSCOPE_QUIT (BUTTON_SELECT | BUTTON_MENU)
#define OSCILLOSCOPE_MODE (BUTTON_SELECT | BUTTON_PLAY)
#define OSCILLOSCOPE_SCROLL (BUTTON_SELECT | BUTTON_RIGHT)
+#define OSCILLOSCOPE_ORIENTATION (BUTTON_SELECT | BUTTON_LEFT)
#define OSCILLOSCOPE_PAUSE BUTTON_PLAY
#define OSCILLOSCOPE_SPEED_UP BUTTON_RIGHT
#define OSCILLOSCOPE_SPEED_DOWN BUTTON_LEFT
@@ -79,7 +83,8 @@ PLUGIN_HEADER
#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
#define OSCILLOSCOPE_QUIT BUTTON_POWER
#define OSCILLOSCOPE_MODE BUTTON_SELECT
-#define OSCILLOSCOPE_SCROLL BUTTON_MENU
+#define OSCILLOSCOPE_SCROLL BUTTON_DOWN
+#define OSCILLOSCOPE_ORIENTATION BUTTON_UP
#define OSCILLOSCOPE_PAUSE BUTTON_A
#define OSCILLOSCOPE_SPEED_UP BUTTON_RIGHT
#define OSCILLOSCOPE_SPEED_DOWN BUTTON_LEFT
@@ -88,8 +93,10 @@ PLUGIN_HEADER
#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
#define OSCILLOSCOPE_QUIT BUTTON_POWER
-#define OSCILLOSCOPE_MODE BUTTON_SELECT
+#define OSCILLOSCOPE_MODE_PRE BUTTON_SELECT
+#define OSCILLOSCOPE_MODE (BUTTON_SELECT | BUTTON_REL)
#define OSCILLOSCOPE_SCROLL BUTTON_REC
+#define OSCILLOSCOPE_ORIENTATION (BUTTON_SELECT | BUTTON_REPEAT)
#define OSCILLOSCOPE_PAUSE BUTTON_PLAY
#define OSCILLOSCOPE_SPEED_UP BUTTON_RIGHT
#define OSCILLOSCOPE_SPEED_DOWN BUTTON_LEFT
@@ -102,22 +109,33 @@ PLUGIN_HEADER
#define mas_codec_readreg(x) rand()%MAX_PEAK
#endif
+/* prototypes */
+
+void anim_horizontal(int, int);
+void anim_vertical(int, int);
+
/* global variables */
-struct plugin_api* rb; /* global api struct pointer */
+struct plugin_api* rb; /* global api struct pointer */
int osc_mode = OSC_MODE_FILLED;
-int osc_delay = 1; /* in ticks */
+int osc_delay = 2; /* in ticks */
bool osc_scroll = true;
-long last_tick = 0;
+void (*anim)(int, int) = anim_horizontal;
+
+long last_tick = 0; /* time of last drawing */
+int last_pos = 0; /* last x or y drawing position. Reset for aspect switch. */
+int last_left; /* last channel values */
+int last_right;
+
+unsigned char message[16]; /* message to display */
+bool displaymsg = false;
+int font_height = 8;
/* implementation */
-void animate(int cur_left, int cur_right)
+void anim_horizontal(int cur_left, int cur_right)
{
- static int last_x = 0;
- static int last_left, last_right;
-
int cur_x, x;
int left, right, dl, dr;
long cur_tick = *rb->current_tick;
@@ -135,7 +153,7 @@ void animate(int cur_left, int cur_right)
last_right = cur_right;
return;
}
- cur_x = last_x + d;
+ cur_x = last_pos + d;
if (cur_x >= LCD_WIDTH)
{
@@ -145,7 +163,7 @@ void animate(int cur_left, int cur_right)
xlcd_scroll_left(shift);
full_update = true;
cur_x -= shift;
- last_x -= shift;
+ last_pos -= shift;
}
else /* wrap */
{
@@ -154,13 +172,13 @@ void animate(int cur_left, int cur_right)
}
rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- if (cur_x > last_x)
+ if (cur_x > last_pos)
{
- rb->lcd_fillrect(last_x + 1, 0, d + 2, LCD_HEIGHT);
+ rb->lcd_fillrect(last_pos + 1, 0, d + 2, LCD_HEIGHT);
}
else
{
- rb->lcd_fillrect(last_x + 1, 0, (LCD_WIDTH-1) - last_x, LCD_HEIGHT);
+ rb->lcd_fillrect(last_pos + 1, 0, (LCD_WIDTH-1) - last_pos, LCD_HEIGHT);
rb->lcd_fillrect(0, 0, cur_x + 2, LCD_HEIGHT);
}
rb->lcd_set_drawmode(DRMODE_SOLID);
@@ -173,7 +191,7 @@ void animate(int cur_left, int cur_right)
dl = (cur_left - left) / d;
dr = (cur_right - right) / d;
- for (x = last_x + 1; d > 0; x++, d--)
+ for (x = last_pos + 1; d > 0; x++, d--)
{
if (x == LCD_WIDTH)
x = 0;
@@ -181,47 +199,47 @@ void animate(int cur_left, int cur_right)
left += dl;
right += dr;
- rb->lcd_vline(x, LCD_HEIGHT/2+1,
- LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * left) >> 16));
rb->lcd_vline(x, LCD_HEIGHT/2-1,
- LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * right) >> 16));
+ LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * left) >> 16));
+ rb->lcd_vline(x, LCD_HEIGHT/2+1,
+ LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * right) >> 16));
}
break;
case OSC_MODE_OUTLINE:
- if (cur_x > last_x)
+ if (cur_x > last_pos)
{
rb->lcd_drawline(
- last_x, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * last_left) >> 16),
- cur_x, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * cur_left) >> 16)
+ last_pos, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * last_left) >> 16),
+ cur_x, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * cur_left) >> 16)
);
rb->lcd_drawline(
- last_x, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * last_right) >> 16),
- cur_x, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * cur_right) >> 16)
+ last_pos, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * last_right) >> 16),
+ cur_x, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * cur_right) >> 16)
);
}
else
{
left = last_left
- + (LCD_WIDTH - last_x) * (last_left - cur_left) / d;
+ + (LCD_WIDTH - last_pos) * (last_left - cur_left) / d;
right = last_right
- + (LCD_WIDTH - last_x) * (last_right - cur_right) / d;
+ + (LCD_WIDTH - last_pos) * (last_right - cur_right) / d;
rb->lcd_drawline(
- last_x, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * last_left) >> 16),
- LCD_WIDTH, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * left) >> 16)
+ last_pos, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * last_left) >> 16),
+ LCD_WIDTH, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * left) >> 16)
);
rb->lcd_drawline(
- last_x, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * last_right) >> 16),
- LCD_WIDTH, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * right) >> 16)
+ 0, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * left) >> 16),
+ cur_x, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * cur_left) >> 16)
);
rb->lcd_drawline(
- 0, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * left) >> 16),
- cur_x, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * cur_left) >> 16)
+ last_pos, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * last_right) >> 16),
+ LCD_WIDTH, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * right) >> 16)
);
rb->lcd_drawline(
- 0, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * right) >> 16),
- cur_x, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * cur_right) >> 16)
+ 0, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * right) >> 16),
+ cur_x, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * cur_right) >> 16)
);
}
break;
@@ -232,7 +250,7 @@ void animate(int cur_left, int cur_right)
dl = (cur_left - left) / d;
dr = (cur_right - right) / d;
- for (x = last_x + 1; d > 0; x++, d--)
+ for (x = last_pos + 1; d > 0; x++, d--)
{
if (x == LCD_WIDTH)
x = 0;
@@ -240,8 +258,8 @@ void animate(int cur_left, int cur_right)
left += dl;
right += dr;
- rb->lcd_drawpixel(x, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * left) >> 16));
- rb->lcd_drawpixel(x, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * right) >> 16));
+ rb->lcd_drawpixel(x, LCD_HEIGHT/2-1 - (((LCD_HEIGHT-2) * left) >> 16));
+ rb->lcd_drawpixel(x, LCD_HEIGHT/2+1 + (((LCD_HEIGHT-2) * right) >> 16));
}
break;
@@ -255,17 +273,179 @@ void animate(int cur_left, int cur_right)
}
else
{
- if (cur_x > last_x)
+ if (cur_x > last_pos)
{
- rb->lcd_update_rect(last_x, 0, cur_x - last_x + 2, LCD_HEIGHT);
+ rb->lcd_update_rect(last_pos, 0, cur_x - last_pos + 2, LCD_HEIGHT);
}
else
{
- rb->lcd_update_rect(last_x, 0, (LCD_WIDTH-1) - last_x, LCD_HEIGHT);
+ rb->lcd_update_rect(last_pos, 0, (LCD_WIDTH-1) - last_pos, LCD_HEIGHT);
rb->lcd_update_rect(0, 0, cur_x + 2, LCD_HEIGHT);
}
}
- last_x = cur_x;
+ last_pos = cur_x;
+}
+
+void anim_vertical(int cur_left, int cur_right)
+{
+ int cur_y, y;
+ int left, right, dl, dr;
+ long cur_tick = *rb->current_tick;
+ long d = (cur_tick - last_tick) / osc_delay;
+ bool full_update = false;
+
+ if (d == 0) /* too early, bail out */
+ return;
+
+ last_tick = cur_tick;
+
+ if (d > HZ) /* first call or too much delay, (re)start */
+ {
+ last_left = cur_left;
+ last_right = cur_right;
+ return;
+ }
+ cur_y = last_pos + d;
+
+ if (cur_y >= LCD_HEIGHT)
+ {
+ if (osc_scroll) /* scroll */
+ {
+ int shift = cur_y - (LCD_HEIGHT-1);
+ xlcd_scroll_up(shift);
+ full_update = true;
+ cur_y -= shift;
+ last_pos -= shift;
+ }
+ else /* wrap */
+ {
+ cur_y -= LCD_HEIGHT;
+ }
+ }
+ rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
+
+ if (cur_y > last_pos)
+ {
+ rb->lcd_fillrect(0, last_pos + 1, LCD_WIDTH, d + 2);
+ }
+ else
+ {
+ rb->lcd_fillrect(0, last_pos + 1, LCD_WIDTH, (LCD_HEIGHT-1) - last_pos);
+ rb->lcd_fillrect(0, 0, LCD_WIDTH, cur_y + 2);
+ }
+ rb->lcd_set_drawmode(DRMODE_SOLID);
+
+ switch (osc_mode)
+ {
+ case OSC_MODE_FILLED:
+ left = last_left;
+ right = last_right;
+ dl = (cur_left - left) / d;
+ dr = (cur_right - right) / d;
+
+ for (y = last_pos + 1; d > 0; y++, d--)
+ {
+ if (y == LCD_HEIGHT)
+ y = 0;
+
+ left += dl;
+ right += dr;
+
+ rb->lcd_hline(LCD_WIDTH/2-1,
+ LCD_WIDTH/2-1 - (((LCD_WIDTH-2) * left) >> 16), y);
+ rb->lcd_hline(LCD_WIDTH/2+1,
+ LCD_WIDTH/2+1 + (((LCD_WIDTH-2) * right) >> 16), y);
+ }
+ break;
+
+ case OSC_MODE_OUTLINE:
+ if (cur_y > last_pos)
+ {
+ rb->lcd_drawline(
+ LCD_WIDTH/2-1 - (((LCD_WIDTH-2) * last_left) >> 16), last_pos,
+ LCD_WIDTH/2-1 - (((LCD_WIDTH-2) * cur_left) >> 16), cur_y
+ );
+ rb->lcd_drawline(
+ LCD_WIDTH/2+1 + (((LCD_WIDTH-2) * last_right) >> 16), last_pos,
+ LCD_WIDTH/2+1 + (((LCD_WIDTH-2) * cur_right) >> 16), cur_y
+ );
+ }
+ else
+ {
+ left = last_left
+ + (LCD_HEIGHT - last_pos) * (last_left - cur_left) / d;
+ right = last_right
+ + (LCD_HEIGHT - last_pos) * (last_right - cur_right) / d;
+
+ rb->lcd_drawline(
+ LCD_WIDTH/2-1 - (((LCD_WIDTH-2) * last_left) >> 16), last_pos,
+ LCD_WIDTH/2-1 - (((LCD_WIDTH-2) * left) >> 16), LCD_HEIGHT
+ );
+ rb->lcd_drawline(
+ LCD_WIDTH/2-1 - (((LCD_WIDTH-2) * left) >> 16), 0,
+ LCD_WIDTH/2-1 - (((LCD_WIDTH-2) * cur_left) >> 16), cur_y
+ );
+ rb->lcd_drawline(
+ LCD_WIDTH/2+1 + (((LCD_WIDTH-2) * last_right) >> 16), last_pos,
+ LCD_WIDTH/2+1 + (((LCD_WIDTH-2) * right) >> 16), LCD_HEIGHT
+ );
+ rb->lcd_drawline(
+ LCD_WIDTH/2+1 + (((LCD_WIDTH-2) * right) >> 16), 0,
+ LCD_WIDTH/2+1 + (((LCD_WIDTH-2) * cur_right) >> 16), cur_y
+ );
+ }
+ break;
+
+ case OSC_MODE_PIXEL:
+ left = last_left;
+ right = last_right;
+ dl = (cur_left - left) / d;
+ dr = (cur_right - right) / d;
+
+ for (y = last_pos + 1; d > 0; y++, d--)
+ {
+ if (y == LCD_HEIGHT)
+ y = 0;
+
+ left += dl;
+ right += dr;
+
+ rb->lcd_drawpixel(LCD_WIDTH/2-1 - (((LCD_WIDTH-2) * left) >> 16), y);
+ rb->lcd_drawpixel(LCD_WIDTH/2+1 + (((LCD_WIDTH-2) * right) >> 16), y);
+ }
+ break;
+
+ }
+ last_left = cur_left;
+ last_right = cur_right;
+
+ if (displaymsg)
+ {
+ last_pos -= font_height - 1;
+ if (last_pos < 0)
+ last_pos = LCD_HEIGHT - font_height;
+
+ rb->lcd_putsxy(0, last_pos, message);
+ displaymsg = false;
+ }
+
+ if (full_update)
+ {
+ rb->lcd_update();
+ }
+ else
+ {
+ if (cur_y > last_pos)
+ {
+ rb->lcd_update_rect(0, last_pos, LCD_WIDTH, cur_y - last_pos + 2);
+ }
+ else
+ {
+ rb->lcd_update_rect(0, last_pos, LCD_WIDTH, (LCD_HEIGHT-1) - last_pos);
+ rb->lcd_update_rect(0, 0, LCD_WIDTH, cur_y + 2);
+ }
+ }
+ last_pos = cur_y;
}
void cleanup(void *parameter)
@@ -284,6 +464,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
int lastbutton = BUTTON_NONE;
bool exit = false;
bool paused = false;
+ bool tell_speed;
(void)parameter;
rb = api;
@@ -297,7 +478,8 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
rb->lcd_update();
rb->backlight_set_timeout(1); /* keep the light on */
#endif
-
+ rb->lcd_getstringsize("A", NULL, &font_height);
+
while (!exit)
{
if (!paused)
@@ -312,9 +494,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
#elif (CONFIG_CODEC == SWCODEC)
rb->pcm_calculate_peaks(&left, &right);
#endif
- animate(left, right);
+ anim(left, right);
}
+ tell_speed = false;
button = rb->button_get(paused);
switch (button)
{
@@ -334,6 +517,15 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
if (++osc_mode >= OSC_MODE_COUNT)
osc_mode = 0;
break;
+
+ case OSCILLOSCOPE_ORIENTATION:
+ anim = (anim == anim_horizontal) ? anim_vertical : anim_horizontal;
+ last_pos = 0;
+ last_tick = 0;
+ displaymsg = false;
+ rb->lcd_clear_display();
+ rb->lcd_update();
+ break;
case OSCILLOSCOPE_PAUSE:
paused = !paused;
@@ -343,12 +535,16 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
case OSCILLOSCOPE_SPEED_UP:
case OSCILLOSCOPE_SPEED_UP | BUTTON_REPEAT:
if (osc_delay > 1)
+ {
osc_delay--;
+ tell_speed = true;
+ }
break;
case OSCILLOSCOPE_SPEED_DOWN:
case OSCILLOSCOPE_SPEED_DOWN | BUTTON_REPEAT:
osc_delay++;
+ tell_speed = true;
break;
case OSCILLOSCOPE_VOL_UP:
@@ -381,8 +577,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
}
if (button != BUTTON_NONE)
lastbutton = button;
+
+ if (tell_speed)
+ {
+ rb->snprintf(message, sizeof(message), "Speed: %d", 100 / osc_delay);
+ displaymsg = true;
+ }
}
cleanup(NULL);
return PLUGIN_OK;
}
-#endif /* if HAVE_LCD_BITMAP */
+#endif /* HAVE_LCD_BITMAP */