1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Jens Arnold 2006-03-10 00:18:58 +00:00
parent ff862e19cc
commit 78e4f4d1b1

View file

@ -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 */