* removed some more unused stuff in the simulator makefile
[kugel-rb.git] / apps / plugins / oscillograph.c
bloba34aa8bfa9ac8279c145c0e96da70eced8f86f24
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2002 Philipp Pertermann
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "plugin.h"
21 #ifdef HAVE_LCD_BITMAP
22 #ifndef SIMULATOR /* don't want this code in the simulator */
24 /* The different drawing modes */
25 #define DRAW_MODE_FILLED 0
26 #define DRAW_MODE_OUTLINE 1
27 #define DRAW_MODE_PIXEL 2
28 #define DRAW_MODE_COUNT 3
30 #define MAX_PEAK 0x8000
32 /* number of ticks between two volume samples */
33 static int speed = 1;
34 /* roll == true -> lcd rolls */
35 static bool roll = true;
36 /* see DRAW_MODE_XXX constants for valid values */
37 static int drawMode = DRAW_MODE_FILLED;
39 /**
40 * Displays a vertically scrolling oscillosgraph using
41 * hardware scrolling of the display. The user can change
42 * speed
44 enum plugin_status plugin_start(struct plugin_api* rb, void* parameter)
46 /* stores current volume value left */
47 int left;
48 /* stores current volume value right */
49 int right;
50 /* specifies the current position on the lcd */
51 int y = LCD_WIDTH - 1;
53 /* only needed when drawing lines */
54 int lastLeft = 0;
55 int lastRight = 0;
56 int lasty = 0;
58 bool exit = false;
60 TEST_PLUGIN_API(rb);
61 (void)parameter;
63 /* the main loop */
64 while (!exit) {
66 /* read the volume info from MAS */
67 left = rb->mas_codec_readreg(0xC) / (MAX_PEAK / (LCD_WIDTH / 2 - 2));
68 right = rb->mas_codec_readreg(0xD) / (MAX_PEAK / (LCD_WIDTH / 2 - 2));
70 /* delete current line */
71 rb->lcd_clearline(0, y, LCD_WIDTH-1, y);
73 switch (drawMode) {
74 case DRAW_MODE_FILLED:
75 rb->lcd_drawline(LCD_WIDTH / 2 + 1 , y,
76 LCD_WIDTH / 2 + 1 + right, y);
77 rb->lcd_drawline(LCD_WIDTH / 2 - 1 , y,
78 LCD_WIDTH / 2 - 1 -left , y);
79 break;
81 case DRAW_MODE_OUTLINE:
82 /* last position needed for lines */
83 lasty = MAX(y-1, 0);
85 /* Here real lines were neccessary because
86 anything else was ugly. */
87 rb->lcd_drawline(LCD_WIDTH / 2 + right , y,
88 LCD_WIDTH / 2 + lastRight , lasty);
89 rb->lcd_drawline(LCD_WIDTH / 2 - left , y,
90 LCD_WIDTH / 2 - lastLeft, lasty);
92 /* have to store the old values for drawing lines
93 the next time */
94 lastRight = right;
95 lastLeft = left;
96 break;
98 case DRAW_MODE_PIXEL:
99 /* straight and simple */
100 rb->lcd_drawpixel(LCD_WIDTH / 2 + right, y);
101 rb->lcd_drawpixel(LCD_WIDTH / 2 - left, y);
102 break;
106 /* increment and adjust the drawing position */
107 y++;
108 if (y >= LCD_HEIGHT)
109 y = 0;
111 /* I roll before update because otherwise the new
112 line would appear at the wrong end of the display */
113 if (roll)
114 rb->lcd_roll(y);
116 /* now finally make the new sample visible */
117 rb->lcd_update_rect(0, MAX(y-1, 0), LCD_WIDTH, 2);
119 /* There are two mechanisms to alter speed:
120 1.) slowing down is achieved by increasing
121 the time waiting for user input. This
122 mechanism uses positive values.
123 2.) speeding up is achieved by leaving out
124 the user input check for (-speed) volume
125 samples. For this mechanism negative values
126 are used.
129 if (speed >= 0 || ((speed < 0) && (y % (-speed) == 0))) {
130 bool draw = false;
132 /* speed values > 0 slow the oszi down. By user input
133 speed might become < 1. If a value < 1 was
134 passed user input would be disabled. Thus
135 it must be ensured that at least 1 is passed. */
137 /* react to user input */
138 switch (rb->button_get_w_tmo(MAX(speed, 1))) {
139 case BUTTON_UP:
140 speed++;
141 draw = true;
142 break;
144 case BUTTON_DOWN:
145 speed--;
146 draw = true;
147 break;
149 case BUTTON_PLAY:
150 /* pause the demo */
151 rb->button_get(true);
152 break;
154 case BUTTON_F1:
155 /* toggle rolling */
156 roll = !roll;
157 break;
159 case BUTTON_F2:
160 /* step through the display modes */
161 drawMode ++;
162 drawMode = drawMode % DRAW_MODE_COUNT;
164 /* lcd buffer might be rolled so that
165 the transition from LCD_HEIGHT to 0
166 takes place in the middle of the screen.
167 That produces ugly results in DRAW_MODE_OUTLINE
168 mode. If rolling is enabled this change will
169 be reverted before the next update anyway.*/
170 rb->lcd_roll(0);
171 break;
173 case BUTTON_F3:
174 speed = 1;
175 draw = true;
176 break;
178 case BUTTON_OFF:
179 exit = true;
180 break;
182 case SYS_USB_CONNECTED:
183 rb->usb_screen();
184 return PLUGIN_USB_CONNECTED;
187 if (draw) {
188 char buf[16];
189 rb->snprintf(buf, sizeof buf, "Speed: %d", -speed);
190 rb->lcd_putsxy(0, (y + LCD_HEIGHT - 8) % LCD_HEIGHT, buf);
191 rb->lcd_update_rect(0, (y + LCD_HEIGHT - 8) % LCD_HEIGHT,
192 LCD_WIDTH, 8);
197 /* restore to default roll position.
198 Looks funny if you forget to do this... */
199 rb->lcd_roll(0);
200 rb->lcd_update();
202 /* standard return */
203 return PLUGIN_OK;
206 #endif /* #ifndef SIMULATOR */
207 #endif