summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/grayscale.c86
-rw-r--r--apps/plugins/jpeg.c72
-rw-r--r--apps/plugins/lib/SOURCES31
-rw-r--r--apps/plugins/lib/gray.h484
-rw-r--r--apps/plugins/lib/gray_black_display.c44
-rw-r--r--apps/plugins/lib/gray_blockfuncs.c262
-rw-r--r--apps/plugins/lib/gray_clear_display.c44
-rw-r--r--apps/plugins/lib/gray_core.c674
-rw-r--r--apps/plugins/lib/gray_deferred_update.c50
-rw-r--r--apps/plugins/lib/gray_draw.c826
-rw-r--r--apps/plugins/lib/gray_drawbitmap.c116
-rw-r--r--apps/plugins/lib/gray_drawgraymap.c275
-rw-r--r--apps/plugins/lib/gray_drawline.c119
-rw-r--r--apps/plugins/lib/gray_drawpixel.c55
-rw-r--r--apps/plugins/lib/gray_drawrect.c62
-rw-r--r--apps/plugins/lib/gray_fillrect.c92
-rw-r--r--apps/plugins/lib/gray_getstringsize.c64
-rw-r--r--apps/plugins/lib/gray_horline.c65
-rw-r--r--apps/plugins/lib/gray_parm.c107
-rw-r--r--apps/plugins/lib/gray_pixelfuncs.c245
-rw-r--r--apps/plugins/lib/gray_position_display.c57
-rw-r--r--apps/plugins/lib/gray_putsxy.c67
-rw-r--r--apps/plugins/lib/gray_screendump.c141
-rw-r--r--apps/plugins/lib/gray_scroll.c479
-rw-r--r--apps/plugins/lib/gray_scroll_down.c134
-rw-r--r--apps/plugins/lib/gray_scroll_down8.c69
-rw-r--r--apps/plugins/lib/gray_scroll_left.c100
-rw-r--r--apps/plugins/lib/gray_scroll_right.c100
-rw-r--r--apps/plugins/lib/gray_scroll_up.c135
-rw-r--r--apps/plugins/lib/gray_scroll_up8.c69
-rw-r--r--apps/plugins/lib/gray_set_background.c48
-rw-r--r--apps/plugins/lib/gray_set_drawinfo.c49
-rw-r--r--apps/plugins/lib/gray_set_drawmode.c52
-rw-r--r--apps/plugins/lib/gray_set_foreground.c48
-rw-r--r--apps/plugins/lib/gray_setfont.c47
-rw-r--r--apps/plugins/lib/gray_verline.c88
-rw-r--r--apps/plugins/mandelbrot.c21
37 files changed, 2147 insertions, 3330 deletions
diff --git a/apps/plugins/grayscale.c b/apps/plugins/grayscale.c
index 196545c0e7..e543f15427 100644
--- a/apps/plugins/grayscale.c
+++ b/apps/plugins/grayscale.c
@@ -44,7 +44,7 @@ void cleanup(void *parameter)
44{ 44{
45 (void)parameter; 45 (void)parameter;
46 46
47 gray_release_buffer(); /* switch off overlay and deinitialize */ 47 gray_release(); /* switch off overlay and deinitialize */
48 /* restore normal backlight setting */ 48 /* restore normal backlight setting */
49 rb->backlight_set_timeout(rb->global_settings->backlight_timeout); 49 rb->backlight_set_timeout(rb->global_settings->backlight_timeout);
50} 50}
@@ -55,7 +55,7 @@ int main(void)
55 int shades, time; 55 int shades, time;
56 int x, y, i; 56 int x, y, i;
57 int button, scroll_amount; 57 int button, scroll_amount;
58 bool black_border; 58 bool black_border = false;
59 59
60 static const unsigned char rockbox[] = { 60 static const unsigned char rockbox[] = {
61 /* ........................................... 61 /* ...........................................
@@ -138,73 +138,74 @@ int main(void)
138 /* get the remainder of the plugin buffer */ 138 /* get the remainder of the plugin buffer */
139 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size); 139 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size);
140 140
141 /* initialize the grayscale buffer: 141 /* initialize the greyscale buffer:
142 * 112 pixels wide, 7 rows (56 pixels) high, (try to) reserve 142 * 112 pixels wide, 7 rows (56 pixels) high, (try to) reserve
143 * 32 bitplanes for 33 shades of gray. (uses 25268 bytes)*/ 143 * 32 bitplanes for 33 shades of grey. */
144 shades = gray_init_buffer(gbuf, gbuf_size, 112, 7, 32, NULL) + 1; 144 shades = gray_init(rb, gbuf, gbuf_size, true, 112, 7, 32, NULL) + 1;
145 145
146 /* place grayscale overlay 1 row down */ 146 /* place greyscale overlay 1 row down */
147 gray_position_display(0, 1); 147 gray_set_position(0, 1);
148 148
149 rb->snprintf(pbuf, sizeof(pbuf), "Shades: %d", shades); 149 rb->snprintf(pbuf, sizeof(pbuf), "Shades: %d", shades);
150 rb->lcd_puts(0, 0, pbuf); 150 rb->lcd_puts(0, 0, pbuf);
151 rb->lcd_update(); 151 rb->lcd_update();
152 152
153 gray_show_display(true); /* switch on grayscale overlay */ 153 gray_show(true); /* switch on greyscale overlay */
154 154
155 time = *rb->current_tick; /* start time measurement */ 155 time = *rb->current_tick; /* start time measurement */
156 156
157 gray_set_foreground(150); 157 gray_set_background(150);
158 gray_fillrect(0, 0, 112, 56); /* fill everything with gray 150 */ 158 gray_clear_display(); /* fill everything with grey 150 */
159 159
160 /* draw a dark gray line star background */ 160 /* draw a dark grey line star background */
161 gray_set_foreground(80); 161 gray_set_foreground(80);
162 for (y = 0; y < 56; y += 8) /* horizontal part */ 162 for (y = 0; y < 56; y += 8) /* horizontal part */
163 { 163 {
164 gray_drawline(0, y, 111, 55 - y); /* gray lines */ 164 gray_drawline(0, y, 111, 55 - y); /* grey lines */
165 } 165 }
166 for (x = 10; x < 112; x += 10) /* vertical part */ 166 for (x = 10; x < 112; x += 10) /* vertical part */
167 { 167 {
168 gray_drawline(x, 0, 111 - x, 55); /* gray lines */ 168 gray_drawline(x, 0, 111 - x, 55); /* grey lines */
169 } 169 }
170 170
171 gray_set_foreground(0); 171 gray_set_foreground(0);
172 gray_drawrect(0, 0, 112, 56); /* black border */ 172 gray_drawrect(0, 0, 112, 56); /* black border */
173 173
174 /* draw gray tones */ 174 /* draw grey tones */
175 for (i = 0; i < 86; i++) 175 for (i = 0; i < 86; i++)
176 { 176 {
177 x = 13 + i; 177 x = 13 + i;
178 gray_set_foreground(3 * i); 178 gray_set_foreground(3 * i);
179 gray_verline(x, 6, 49); /* vertical lines */ 179 gray_vline(x, 6, 49); /* vertical lines */
180 } 180 }
181 181
182 gray_set_drawmode(GRAY_DRAW_INVERSE); 182 gray_set_drawmode(DRMODE_COMPLEMENT);
183 gray_fillrect(13, 29, 86, 21); /* invert rectangle (lower half) */ 183 gray_fillrect(13, 29, 86, 21); /* invert rectangle (lower half) */
184 gray_drawline(13, 27, 98, 27); /* invert a line */ 184 gray_drawline(13, 27, 98, 27); /* invert a line */
185 185
186 /* show bitmaps (1 bit and 8 bit) */ 186 /* show bitmaps (1 bit and 8 bit) */
187 gray_set_drawinfo(GRAY_DRAW_SOLID, 255, 100); 187 gray_set_drawinfo(DRMODE_SOLID, 255, 100);
188 gray_drawbitmap(rockbox, 14, 13, 43, 7, 43); /* opaque */ 188 gray_mono_bitmap(rockbox, 14, 13, 43, 7); /* opaque */
189 gray_set_drawinfo(GRAY_DRAW_FG, 0, -1); 189 gray_set_drawinfo(DRMODE_FG, 0, 100);
190 gray_drawbitmap(showing, 58, 13, 39, 7, 39); /* transparent */ 190 gray_mono_bitmap(showing, 58, 13, 39, 7); /* transparent */
191 gray_gray_bitmap(grayscale_gray, 28, 35, 55, 7);
191 192
192 gray_drawgraymap(grayscale_gray, 28, 35, 55, 7, 55); 193 gray_update();
193 194
194 time = *rb->current_tick - time; /* end time measurement */ 195 time = *rb->current_tick - time; /* end time measurement */
195 196
196 rb->snprintf(pbuf, sizeof(pbuf), "Shades: %d, %d.%02ds", shades, 197 rb->snprintf(pbuf, sizeof(pbuf), "Shades: %d, %d.%02ds", shades,
197 time / 100, time % 100); 198 time / 100, time % 100);
198 rb->lcd_puts(0, 0, pbuf); 199 rb->lcd_puts(0, 0, pbuf);
199 gray_deferred_update(); /* schedule an lcd_update() */ 200 gray_deferred_lcd_update(); /* schedule an lcd_update() */
200 201
201 /* drawing is now finished, play around with scrolling 202 /* drawing is now finished, play around with scrolling
202 * until you press OFF or connect USB 203 * until you press OFF or connect USB
203 */ 204 */
205 gray_set_background(255);
204 while (true) 206 while (true)
205 { 207 {
206 scroll_amount = 1; 208 scroll_amount = 1;
207 black_border = false;
208 209
209 button = rb->button_get(true); 210 button = rb->button_get(true);
210 211
@@ -213,31 +214,49 @@ int main(void)
213 return PLUGIN_USB_CONNECTED; 214 return PLUGIN_USB_CONNECTED;
214 215
215 if (button & GRAYSCALE_SHIFT) 216 if (button & GRAYSCALE_SHIFT)
216 black_border = true; 217 {
217 218 if (!black_border)
219 {
220 gray_set_background(0);
221 black_border = true;
222 }
223 }
224 else
225 {
226 if (black_border)
227 {
228 gray_set_background(255);
229 black_border = false;
230 }
231 }
232
218 if (button & BUTTON_REPEAT) 233 if (button & BUTTON_REPEAT)
219 scroll_amount = 4; 234 scroll_amount = 4;
220 235
221 switch(button & ~(GRAYSCALE_SHIFT | BUTTON_REPEAT)) 236 switch (button & ~(GRAYSCALE_SHIFT | BUTTON_REPEAT))
222 { 237 {
223 case BUTTON_LEFT: 238 case BUTTON_LEFT:
224 239
225 gray_scroll_left(scroll_amount, black_border); /* scroll left */ 240 gray_scroll_left(scroll_amount); /* scroll left */
241 gray_update();
226 break; 242 break;
227 243
228 case BUTTON_RIGHT: 244 case BUTTON_RIGHT:
229 245
230 gray_scroll_right(scroll_amount, black_border); /* scroll right */ 246 gray_scroll_right(scroll_amount); /* scroll right */
247 gray_update();
231 break; 248 break;
232 249
233 case BUTTON_UP: 250 case BUTTON_UP:
234 251
235 gray_scroll_up(scroll_amount, black_border); /* scroll up */ 252 gray_scroll_up(scroll_amount); /* scroll up */
253 gray_update();
236 break; 254 break;
237 255
238 case BUTTON_DOWN: 256 case BUTTON_DOWN:
239 257
240 gray_scroll_down(scroll_amount, black_border); /* scroll down */ 258 gray_scroll_down(scroll_amount); /* scroll down */
259 gray_update();
241 break; 260 break;
242 261
243 case BUTTON_OFF: 262 case BUTTON_OFF:
@@ -260,9 +279,6 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
260 rb = api; // copy to global api pointer 279 rb = api; // copy to global api pointer
261 (void)parameter; 280 (void)parameter;
262 281
263 /* This plugin uses the grayscale framework, so initialize */
264 gray_init(api);
265
266 return main(); 282 return main();
267} 283}
268 284
diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c
index 7ca59b29cd..5060996639 100644
--- a/apps/plugins/jpeg.c
+++ b/apps/plugins/jpeg.c
@@ -1523,7 +1523,7 @@ void cleanup(void *parameter)
1523{ 1523{
1524 (void)parameter; 1524 (void)parameter;
1525 1525
1526 gray_show_display(false); 1526 gray_show(false);
1527} 1527}
1528 1528
1529/* interactively scroll around the image */ 1529/* interactively scroll around the image */
@@ -1548,13 +1548,12 @@ int scroll_bmp(struct t_disp* pdisp)
1548 move = MIN(10, pdisp->x); 1548 move = MIN(10, pdisp->x);
1549 if (move > 0) 1549 if (move > 0)
1550 { 1550 {
1551 gray_scroll_right(move, false); /* scroll right */ 1551 gray_ub_scroll_right(move); /* scroll right */
1552 pdisp->x -= move; 1552 pdisp->x -= move;
1553 gray_drawgraymap( 1553 gray_ub_gray_bitmap_part(
1554 pdisp->bitmap + pdisp->y * pdisp->stride + pdisp->x, 1554 pdisp->bitmap, pdisp->x, pdisp->y, pdisp->stride,
1555 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), // x, y 1555 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
1556 move, MIN(LCD_HEIGHT, pdisp->height), // w, h 1556 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
1557 pdisp->stride);
1558 } 1557 }
1559 break; 1558 break;
1560 1559
@@ -1563,13 +1562,13 @@ int scroll_bmp(struct t_disp* pdisp)
1563 move = MIN(10, pdisp->width - pdisp->x - LCD_WIDTH); 1562 move = MIN(10, pdisp->width - pdisp->x - LCD_WIDTH);
1564 if (move > 0) 1563 if (move > 0)
1565 { 1564 {
1566 gray_scroll_left(move, false); /* scroll left */ 1565 gray_ub_scroll_left(move); /* scroll left */
1567 pdisp->x += move; 1566 pdisp->x += move;
1568 gray_drawgraymap( 1567 gray_ub_gray_bitmap_part(
1569 pdisp->bitmap + pdisp->y * pdisp->stride + pdisp->x + LCD_WIDTH - move, 1568 pdisp->bitmap, pdisp->x + LCD_WIDTH - move,
1569 pdisp->y, pdisp->stride,
1570 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ 1570 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
1571 move, MIN(LCD_HEIGHT, pdisp->height), /* w, h */ 1571 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
1572 pdisp->stride);
1573 } 1572 }
1574 break; 1573 break;
1575 1574
@@ -1578,16 +1577,12 @@ int scroll_bmp(struct t_disp* pdisp)
1578 move = MIN(8, pdisp->y); 1577 move = MIN(8, pdisp->y);
1579 if (move > 0) 1578 if (move > 0)
1580 { 1579 {
1581 if (move == 8) 1580 gray_ub_scroll_down(move); /* scroll down */
1582 gray_scroll_down8(false); /* scroll down by 8 pixel */
1583 else
1584 gray_scroll_down(move, false); /* scroll down 1..7 pixel */
1585 pdisp->y -= move; 1581 pdisp->y -= move;
1586 gray_drawgraymap( 1582 gray_ub_gray_bitmap_part(
1587 pdisp->bitmap + pdisp->y * pdisp->stride + pdisp->x, 1583 pdisp->bitmap, pdisp->x, pdisp->y, pdisp->stride,
1588 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ 1584 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
1589 MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ 1585 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
1590 pdisp->stride);
1591 } 1586 }
1592 break; 1587 break;
1593 1588
@@ -1596,16 +1591,13 @@ int scroll_bmp(struct t_disp* pdisp)
1596 move = MIN(8, pdisp->height - pdisp->y - LCD_HEIGHT); 1591 move = MIN(8, pdisp->height - pdisp->y - LCD_HEIGHT);
1597 if (move > 0) 1592 if (move > 0)
1598 { 1593 {
1599 if (move == 8) 1594 gray_ub_scroll_up(move); /* scroll up */
1600 gray_scroll_up8(false); /* scroll up by 8 pixel */
1601 else
1602 gray_scroll_up(move, false); /* scroll up 1..7 pixel */
1603 pdisp->y += move; 1595 pdisp->y += move;
1604 gray_drawgraymap( 1596 gray_ub_gray_bitmap_part(
1605 pdisp->bitmap + (pdisp->y + LCD_HEIGHT - move) * pdisp->stride + pdisp->x, 1597 pdisp->bitmap, pdisp->x,
1598 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
1606 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */ 1599 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
1607 MIN(LCD_WIDTH, pdisp->width), move, /* w, h */ 1600 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
1608 pdisp->stride);
1609 } 1601 }
1610 break; 1602 break;
1611 1603
@@ -1806,7 +1798,7 @@ int main(char* filename)
1806 int fd; 1798 int fd;
1807 int filesize; 1799 int filesize;
1808 int grayscales; 1800 int grayscales;
1809 int graysize; // helper 1801 long graysize; // helper
1810 unsigned char* buf_jpeg; /* compressed JPEG image */ 1802 unsigned char* buf_jpeg; /* compressed JPEG image */
1811 static struct jpeg jpg; /* too large for stack */ 1803 static struct jpeg jpg; /* too large for stack */
1812 int status; 1804 int status;
@@ -1830,7 +1822,7 @@ int main(char* filename)
1830 /* initialize the grayscale buffer: 1822 /* initialize the grayscale buffer:
1831 * 112 pixels wide, 8 rows (64 pixels) high, (try to) reserve 1823 * 112 pixels wide, 8 rows (64 pixels) high, (try to) reserve
1832 * 32 bitplanes for 33 shades of gray. (uses 28856 bytes)*/ 1824 * 32 bitplanes for 33 shades of gray. (uses 28856 bytes)*/
1833 grayscales = gray_init_buffer(buf, buf_size, 112, 8, 32, &graysize) + 1; 1825 grayscales = gray_init(rb, buf, buf_size, false, 112, 8, 32, &graysize) + 1;
1834 buf += graysize; 1826 buf += graysize;
1835 buf_size -= graysize; 1827 buf_size -= graysize;
1836 if (grayscales < 33 || buf_size <= 0) 1828 if (grayscales < 33 || buf_size <= 0)
@@ -1907,16 +1899,15 @@ int main(char* filename)
1907 rb->lcd_puts(0, 3, print); 1899 rb->lcd_puts(0, 3, print);
1908 rb->lcd_update(); 1900 rb->lcd_update();
1909 1901
1910 gray_clear_display(); 1902 gray_ub_clear_display();
1911 gray_drawgraymap( 1903 gray_ub_gray_bitmap_part(
1912 p_disp->bitmap + p_disp->y * p_disp->stride + p_disp->x, 1904 p_disp->bitmap, p_disp->x, p_disp->y, p_disp->stride,
1913 MAX(0, (LCD_WIDTH - p_disp->width) / 2), 1905 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
1914 MAX(0, (LCD_HEIGHT - p_disp->height) / 2), 1906 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
1915 MIN(LCD_WIDTH, p_disp->width), 1907 MIN(LCD_WIDTH, p_disp->width),
1916 MIN(LCD_HEIGHT, p_disp->height), 1908 MIN(LCD_HEIGHT, p_disp->height));
1917 p_disp->stride);
1918 1909
1919 gray_show_display(true); /* switch on grayscale overlay */ 1910 gray_show(true); /* switch on grayscale overlay */
1920 1911
1921 /* drawing is now finished, play around with scrolling 1912 /* drawing is now finished, play around with scrolling
1922 * until you press OFF or connect USB 1913 * until you press OFF or connect USB
@@ -1952,12 +1943,12 @@ int main(char* filename)
1952 break; 1943 break;
1953 } 1944 }
1954 1945
1955 gray_show_display(false); /* switch off overlay */ 1946 gray_show(false); /* switch off overlay */
1956 1947
1957 } 1948 }
1958 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED); 1949 while (status != PLUGIN_OK && status != PLUGIN_USB_CONNECTED);
1959 1950
1960 gray_release_buffer(); /* deinitialize */ 1951 gray_release(); /* deinitialize */
1961 1952
1962 return status; 1953 return status;
1963} 1954}
@@ -1973,9 +1964,6 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
1973 1964
1974 rb = api; /* copy to global api pointer */ 1965 rb = api; /* copy to global api pointer */
1975 1966
1976 /* This plugin uses the grayscale framework, so initialize */
1977 gray_init(api);
1978
1979 return main((char*)parameter); 1967 return main((char*)parameter);
1980} 1968}
1981 1969
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index 00cc6d82c4..4b625cc5f8 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -1,35 +1,10 @@
1configfile.c 1configfile.c
2highscore.c 2highscore.c
3#if (CONFIG_LCD == LCD_SSD1815) && !defined(SIMULATOR) 3#if (CONFIG_LCD == LCD_SSD1815) && !defined(SIMULATOR)
4gray_black_display.c
5gray_blockfuncs.c
6gray_clear_display.c
7gray_core.c 4gray_core.c
8gray_deferred_update.c 5gray_draw.c
9gray_drawbitmap.c 6gray_parm.c
10gray_drawgraymap.c 7gray_scroll.c
11gray_drawline.c
12gray_drawpixel.c
13gray_drawrect.c
14gray_fillrect.c
15gray_getstringsize.c
16gray_horline.c
17gray_pixelfuncs.c
18gray_position_display.c
19gray_putsxy.c
20gray_screendump.c
21gray_scroll_down.c
22gray_scroll_down8.c
23gray_scroll_left.c
24gray_scroll_right.c
25gray_scroll_up.c
26gray_scroll_up8.c
27gray_set_background.c
28gray_set_drawinfo.c
29gray_set_drawmode.c
30gray_set_foreground.c
31gray_setfont.c
32gray_verline.c
33#endif 8#endif
34#ifdef HAVE_LCD_BITMAP 9#ifdef HAVE_LCD_BITMAP
35xlcd.c 10xlcd.c
diff --git a/apps/plugins/lib/gray.h b/apps/plugins/lib/gray.h
index 52d6f6c0df..8abf7bc16d 100644
--- a/apps/plugins/lib/gray.h
+++ b/apps/plugins/lib/gray.h
@@ -7,12 +7,12 @@
7* \/ \/ \/ \/ \/ 7* \/ \/ \/ \/ \/
8* $Id$ 8* $Id$
9* 9*
10* Grayscale framework 10* Greyscale framework
11* 11*
12* This is a generic framework to use grayscale display within Rockbox 12* This is a generic framework to use greyscale display within Rockbox
13* plugins. It obviously does not work for the player. 13* plugins. It does not work for the player.
14* 14*
15* Copyright (C) 2004 Jens Arnold 15* Copyright (C) 2004-2005 Jens Arnold
16* 16*
17* All files in this archive are subject to the GNU General Public License. 17* All files in this archive are subject to the GNU General Public License.
18* See the file COPYING in the source tree root for full license agreement. 18* See the file COPYING in the source tree root for full license agreement.
@@ -30,401 +30,94 @@
30 30
31#ifdef HAVE_LCD_BITMAP /* and also not for the Player */ 31#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
32 32
33/*=========================================================================== 33#define GRAY_MAX_LEVEL 255 /* The real value is variable, so normalise */
34 Public functions and definitions, to be used within plugins 34#define GRAY_BLACK 0
35 ============================================================================ 35#define GRAY_WHITE GRAY_MAX_LEVEL
36 */
37 36
38/*--------------------------------------------------------------------------- 37/* Library initialisation and release */
39 Initialize the framework 38int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
40 ---------------------------------------------------------------------------- 39 bool buffered, int width, int bheight, int depth, long *buf_taken);
41 every framework needs such a function, and it has to be called as the very 40void gray_release(void);
42 first one
43 */
44void gray_init(struct plugin_api* newrb);
45 41
46/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 42/* Special functions */
47 General functions 43void gray_show(bool enable);
48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 44void gray_deferred_lcd_update(void);
49 */ 45void gray_screendump(void);
50
51/*---------------------------------------------------------------------------
52 Prepare the grayscale display buffer
53 ----------------------------------------------------------------------------
54 arguments:
55 gbuf = pointer to the memory area to use (e.g. plugin buffer)
56 gbuf_size = max usable size of the buffer
57 width = width in pixels (1..112)
58 bheight = height in 8-pixel units (1..8)
59 depth = desired number of shades - 1 (1..32)
60
61 result:
62 = depth if there was enough memory
63 < depth if there wasn't enough memory. The number of displayable
64 shades is smaller than desired, but it still works
65 = 0 if there wasn't even enough memory for 1 bitplane (black & white)
66
67 You can request any depth from 1 to 32, not just powers of 2. The routine
68 performs "graceful degradation" if the memory is not sufficient for the
69 desired depth. As long as there is at least enough memory for 1 bitplane,
70 it creates as many bitplanes as fit into memory, although 1 bitplane will
71 only deliver black & white display.
72
73 If you need info about the memory taken by the grayscale buffer, supply an
74 int* as the last parameter. This int will then contain the number of bytes
75 used. The total memory needed can be calculated as follows:
76 total_mem =
77 sizeof(_tGraybuf) (= 64 bytes currently)
78 + sizeof(long) (= 4 bytes)
79 + (width * bheight + sizeof(long)) * depth
80 + 0..3 (longword alignment of grayscale display buffer)
81 */
82int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width,
83 int bheight, int depth, int *buf_taken);
84
85/*---------------------------------------------------------------------------
86 Release the grayscale display buffer
87 ----------------------------------------------------------------------------
88 Switches the grayscale overlay off at first if it is still running,
89 then sets the pointer to NULL.
90 DO CALL either this function or at least gray_show_display(false)
91 before you exit, otherwise nasty things may happen.
92 */
93void gray_release_buffer(void);
94
95/*---------------------------------------------------------------------------
96 Switch the grayscale overlay on or off
97 ----------------------------------------------------------------------------
98 enable = true: the grayscale overlay is switched on if initialized
99 = false: the grayscale overlay is switched off and the regular lcd
100 content is restored
101
102 DO NOT call lcd_update() or any other api function that directly accesses
103 the lcd while the grayscale overlay is running! If you need to do
104 lcd_update() to update something outside the grayscale overlay area, use
105 gray_deferred_update() instead.
106
107 Other functions to avoid are:
108 lcd_blit() (obviously), lcd_update_rect(), lcd_set_contrast(),
109 lcd_set_invert_display(), lcd_set_flip(), lcd_roll()
110
111 The grayscale display consumes ~50 % CPU power (for a full screen overlay,
112 less if the overlay is smaller) when switched on. You can switch the overlay
113 on and off as many times as you want.
114 */
115void gray_show_display(bool enable);
116
117/*---------------------------------------------------------------------------
118 Set position of the top left corner of the grayscale overlay
119 ----------------------------------------------------------------------------
120 x = left margin in pixels
121 by = top margin in 8-pixel units
122
123 You may set this in a way that the overlay spills across the right or
124 bottom display border. In this case it will simply be clipped by the
125 LCD controller. You can even set negative values, this will clip at the
126 left or top border. I did not test it, but the limits may be +127 / -128
127
128 If you use this while the grayscale overlay is running, the now-freed area
129 will be restored.
130 */
131void gray_position_display(int x, int by);
132
133/*---------------------------------------------------------------------------
134 Set the draw mode for subsequent drawing operations
135 ----------------------------------------------------------------------------
136 drawmode =
137 GRAY_DRAW_INVERSE: Foreground pixels are inverted, background pixels are
138 left untouched
139 GRAY_DRAW_FG: Only foreground pixels are drawn
140 GRAY_DRAW_BG: Only background pixels are drawn
141 GRAY_DRAW_SOLID: Foreground and background pixels are drawn
142
143 Default after initialization: GRAY_DRAW_SOLID
144 */
145void gray_set_drawmode(int drawmode);
146
147/*---------------------------------------------------------------------------
148 Draw modes, see above
149 ----------------------------------------------------------------------------
150 */
151#define GRAY_DRAW_INVERSE 0
152#define GRAY_DRAW_FG 1
153#define GRAY_DRAW_BG 2
154#define GRAY_DRAW_SOLID 3
155 46
156/*--------------------------------------------------------------------------- 47/* Update functions */
157 Set the foreground shade for subsequent drawing operations 48void gray_update(void);
158 ---------------------------------------------------------------------------- 49void gray_update_rect(int x, int y, int width, int height);
159 brightness = 0 (black) .. 255 (white)
160 50
161 Default after initialization: 0 51/* Parameter handling */
162 */ 52void gray_set_position(int x, int by);
53void gray_set_drawmode(int mode);
54int gray_get_drawmode(void);
163void gray_set_foreground(int brightness); 55void gray_set_foreground(int brightness);
164 56int gray_get_foreground(void);
165/*---------------------------------------------------------------------------
166 Set the background shade for subsequent drawing operations
167 ----------------------------------------------------------------------------
168 brightness = 0 (black) .. 255 (white)
169
170 Default after initialization: 255
171 */
172void gray_set_background(int brightness); 57void gray_set_background(int brightness);
58int gray_get_background(void);
59void gray_set_drawinfo(int mode, int fg_brightness, int bg_brightness);
60void gray_setfont(int newfont);
61int gray_getstringsize(const unsigned char *str, int *w, int *h);
173 62
174/*--------------------------------------------------------------------------- 63/* Whole display */
175 Set draw mode, foreground and background shades at once
176 ----------------------------------------------------------------------------
177 If you hand it -1 (or in fact any other out-of-bounds value) for a
178 parameter, that particular setting won't be changed
179
180 Default after initialization: GRAY_DRAW_SOLID, 0, 255
181 */
182void gray_set_drawinfo(int drawmode, int fg_brightness, int bg_brightness);
183
184/*---------------------------------------------------------------------------
185 Save the current display content (b&w and grayscale overlay) to an 8-bit
186 BMP file in the root directory
187 ----------------------------------------------------------------------------
188 *
189 * This one is rather slow if used with larger bit depths, but it's intended
190 * primary use is for documenting the grayscale plugins. A much faster version
191 * would be possible, but would take more than twice the RAM
192 */
193void gray_screendump(void);
194
195/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
196 Functions affecting the whole display
197 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
198 */
199
200/*---------------------------------------------------------------------------
201 Clear the grayscale display (sets all pixels to white)
202 ----------------------------------------------------------------------------
203 */
204void gray_clear_display(void); 64void gray_clear_display(void);
65void gray_ub_clear_display(void);
205 66
206/*--------------------------------------------------------------------------- 67/* Pixel */
207 Set the grayscale display to all black
208 ----------------------------------------------------------------------------
209 */
210void gray_black_display(void);
211
212/*---------------------------------------------------------------------------
213 Do an lcd_update() to show changes done by rb->lcd_xxx() functions (in areas
214 of the screen not covered by the grayscale overlay).
215 ----------------------------------------------------------------------------
216 If the grayscale overlay is running, the update will be done in the next
217 call of the interrupt routine, otherwise it will be performed right away.
218 See also comment for the gray_show_display() function.
219 */
220void gray_deferred_update(void);
221
222/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
223 Scrolling functions
224 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
225 */
226
227/*---------------------------------------------------------------------------
228 Scroll the whole grayscale buffer left by <count> pixels
229 ----------------------------------------------------------------------------
230 black_border determines if the pixels scrolled in at the right are black
231 or white
232
233 Scrolling left/right by an even pixel count is almost twice as fast as
234 scrolling by an odd pixel count.
235 */
236void gray_scroll_left(int count, bool black_border);
237
238/*---------------------------------------------------------------------------
239 Scroll the whole grayscale buffer right by <count> pixels
240 ----------------------------------------------------------------------------
241 black_border determines if the pixels scrolled in at the left are black
242 or white
243
244 Scrolling left/right by an even pixel count is almost twice as fast as
245 scrolling by an odd pixel count.
246 */
247void gray_scroll_right(int count, bool black_border);
248
249/*---------------------------------------------------------------------------
250 Scroll the whole grayscale buffer up by 8 pixels
251 ----------------------------------------------------------------------------
252 black_border determines if the pixels scrolled in at the bottom are black
253 or white
254
255 Scrolling up/down by 8 pixels is very fast.
256 */
257void gray_scroll_up8(bool black_border);
258
259/*---------------------------------------------------------------------------
260 Scroll the whole grayscale buffer down by 8 pixels
261 ----------------------------------------------------------------------------
262 black_border determines if the pixels scrolled in at the top are black
263 or white
264
265 Scrolling up/down by 8 pixels is very fast.
266 */
267void gray_scroll_down8(bool black_border);
268
269/*---------------------------------------------------------------------------
270 Scroll the whole grayscale buffer up by <count> pixels (<= 7)
271 ----------------------------------------------------------------------------
272 black_border determines if the pixels scrolled in at the bottom are black
273 or white
274
275 Scrolling up/down pixel-wise is significantly slower than scrolling
276 left/right or scrolling up/down byte-wise because it involves bit
277 shifting. That's why it is asm optimized.
278 */
279void gray_scroll_up(int count, bool black_border);
280
281/*---------------------------------------------------------------------------
282 Scroll the whole grayscale buffer down by <count> pixels (<= 7)
283 ----------------------------------------------------------------------------
284 black_border determines if the pixels scrolled in at the top are black
285 or white
286
287 Scrolling up/down pixel-wise is significantly slower than scrolling
288 left/right or scrolling up/down byte-wise because it involves bit
289 shifting. That's why it is asm optimized.
290 */
291void gray_scroll_down(int count, bool black_border);
292
293/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
294 Pixel and line functions
295 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
296 */
297
298/*---------------------------------------------------------------------------
299 Set a pixel with the current drawinfo
300 ----------------------------------------------------------------------------
301 If the drawmode is GRAY_DRAW_INVERSE, the pixel is inverted
302 GRAY_DRAW_FG and GRAY_DRAW_SOLID draw the pixel in the foreground shade
303 GRAY_DRAW_BG draws the pixel in the background shade
304 */
305void gray_drawpixel(int x, int y); 68void gray_drawpixel(int x, int y);
306 69
307/*--------------------------------------------------------------------------- 70/* Lines */
308 Draw a line from (x1, y1) to (x2, y2) with the current drawinfo
309 ----------------------------------------------------------------------------
310 See gray_drawpixel() for details
311 */
312void gray_drawline(int x1, int y1, int x2, int y2); 71void gray_drawline(int x1, int y1, int x2, int y2);
313 72void gray_hline(int x1, int x2, int y);
314/*--------------------------------------------------------------------------- 73void gray_vline(int x, int y1, int y2);
315 Draw a horizontal line from (x1, y) to (x2, y) with the current drawinfo
316 ----------------------------------------------------------------------------
317 See gray_drawpixel() for details
318 */
319void gray_horline(int x1, int x2, int y);
320
321/*---------------------------------------------------------------------------
322 Draw a vertical line from (x, y1) to (x, y2) with the current drawinfo
323 ----------------------------------------------------------------------------
324 See gray_drawpixel() for details
325 This one uses the block drawing optimization, so it is rather fast.
326 */
327void gray_verline(int x, int y1, int y2);
328
329/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
330 Rectangle functions
331 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
332 */
333
334/*---------------------------------------------------------------------------
335 Draw a (hollow) rectangle with the current drawinfo
336 ----------------------------------------------------------------------------
337 See gray_drawpixel() for details
338 */
339void gray_drawrect(int x, int y, int nx, int ny); 74void gray_drawrect(int x, int y, int nx, int ny);
340 75
341/*--------------------------------------------------------------------------- 76/* Filled primitives */
342 Draw a filled rectangle with the current drawinfo
343 ----------------------------------------------------------------------------
344 See gray_drawpixel() for details
345 This one uses the block drawing optimization, so it is rather fast.
346 */
347void gray_fillrect(int x, int y, int nx, int ny); 77void gray_fillrect(int x, int y, int nx, int ny);
348 78void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3);
349/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 79
350 Bitmap functions 80/* Bitmaps */
351 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 81void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
352 */ 82 int stride, int x, int y, int width, int height);
353 83void gray_mono_bitmap(const unsigned char *src, int x, int y, int width,
354/*--------------------------------------------------------------------------- 84 int height);
355 Copy a grayscale bitmap into the display 85void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
356 ---------------------------------------------------------------------------- 86 int stride, int x, int y, int width, int height);
357 A grayscale bitmap contains one byte for every pixel that defines the 87void gray_gray_bitmap(const unsigned char *src, int x, int y, int width,
358 brightness of the pixel (0..255). Bytes are read in row-major order. 88 int height);
359 The <stride> parameter is useful if you want to show only a part of a 89void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
360 bitmap. It should always be set to the "row length" of the bitmap, so 90 int stride, int x, int y, int width, int height);
361 for displaying the whole bitmap, nx == stride. 91void gray_ub_gray_bitmap(const unsigned char *src, int x, int y, int width,
362 92 int height);
363 This is the only drawing function NOT using the drawinfo. 93
364 */ 94/* Text */
365void gray_drawgraymap(const unsigned char *src, int x, int y, int nx, int ny, 95void gray_putsxyofs(int x, int y, int ofs, const unsigned char *str);
366 int stride);
367
368/*---------------------------------------------------------------------------
369 Display a bitmap with the current drawinfo
370 ----------------------------------------------------------------------------
371 The drawmode is used as described for gray_set_drawmode()
372
373 This (now) uses the same bitmap format as the core b&w graphics routines,
374 so you can use bmp2rb to generate bitmaps for use with this function as
375 well.
376
377 A bitmap contains one bit for every pixel that defines if that pixel is
378 foreground (1) or background (0). Bits within a byte are arranged
379 vertically, LSB at top.
380 The bytes are stored in row-major order, with byte 0 being top left,
381 byte 1 2nd from left etc. The first row of bytes defines pixel rows
382 0..7, the second row defines pixel row 8..15 etc.
383
384 The <stride> parameter is useful if you want to show only a part of a
385 bitmap. It should always be set to the "row length" of the bitmap.
386 */
387void gray_drawbitmap(const unsigned char *src, int x, int y, int nx, int ny,
388 int stride);
389
390/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
391 Font support
392 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
393 */
394
395/*---------------------------------------------------------------------------
396 Set font for the font routines
397 ----------------------------------------------------------------------------
398 newfont can be FONT_SYSFIXED or FONT_UI the same way as with the Rockbox
399 core routines
400
401 Default after initialization: FONT_SYSFIXED
402 */
403void gray_setfont(int newfont);
404
405/*---------------------------------------------------------------------------
406 Calculate width and height of the given text in pixels when rendered with
407 the currently selected font.
408 ----------------------------------------------------------------------------
409 This works exactly the same way as the core lcd_getstringsize(), only that
410 it uses the selected font for grayscale.
411 */
412int gray_getstringsize(const unsigned char *str, int *w, int *h);
413
414/*---------------------------------------------------------------------------
415 Display text starting at (x, y) with the current font and drawinfo
416 ----------------------------------------------------------------------------
417 The drawmode is used as described for gray_set_drawmode()
418 */
419void gray_putsxy(int x, int y, const unsigned char *str); 96void gray_putsxy(int x, int y, const unsigned char *str);
420 97
421/*=========================================================================== 98/* Scrolling */
422 Private functions and definitions, for use within the grayscale core only 99void gray_scroll_left(int count);
423 ============================================================================ 100void gray_scroll_right(int count);
424 */ 101void gray_scroll_up(int count);
102void gray_scroll_down(int count);
103void gray_ub_scroll_left(int count);
104void gray_ub_scroll_right(int count);
105void gray_ub_scroll_up(int count);
106void gray_ub_scroll_down(int count);
107
108/*** Internal stuff ***/
109
110#if LCD_DEPTH == 1
111#define _PBLOCK_EXP 3
112#elif LCD_DEPTH == 2
113#define _PBLOCK_EXP 2
114#endif
115#define _PBLOCK (1 << _PBLOCK_EXP)
116#define _MAX_DEPTH (32 / LCD_DEPTH)
117#define _LEVEL_FAC ((1 << LCD_DEPTH) - 1)
425 118
426/* flag definitions */ 119/* flag definitions */
427#define _GRAY_RUNNING 0x0001 /* grayscale overlay is running */ 120#define _GRAY_RUNNING 0x0001 /* greyscale overlay is running */
428#define _GRAY_DEFERRED_UPDATE 0x0002 /* lcd_update() requested */ 121#define _GRAY_DEFERRED_UPDATE 0x0002 /* lcd_update() requested */
429 122
430/* unsigned 16 bit multiplication (a single instruction on the SH) */ 123/* unsigned 16 bit multiplication (a single instruction on the SH) */
@@ -432,36 +125,33 @@ void gray_putsxy(int x, int y, const unsigned char *str);
432 (((unsigned short) (a)) * ((unsigned short) (b)))) 125 (((unsigned short) (a)) * ((unsigned short) (b))))
433 126
434/* The grayscale buffer management structure */ 127/* The grayscale buffer management structure */
435typedef struct 128struct _gray_info
436{ 129{
437 int x; 130 int x;
438 int by; /* 8-pixel units */ 131 int by; /* 8-pixel units */
439 int width; 132 int width;
440 int height; 133 int height;
441 int bheight; /* 8-pixel units */ 134 int bheight; /* 8-pixel units */
442 int plane_size;
443 int depth; /* number_of_bitplanes = (number_of_grayscales - 1) */ 135 int depth; /* number_of_bitplanes = (number_of_grayscales - 1) */
444 int cur_plane; /* for the timer isr */ 136 int cur_plane; /* for the timer isr */
445 unsigned long randmask; /* mask for random value in _writepixel() */
446 unsigned long flags; /* various flags, see #defines */
447 unsigned long *bitpattern; /* pointer to start of pattern table */
448 unsigned char *data; /* pointer to start of bitplane data */
449 unsigned long fg_pattern; /* current foreground pattern */
450 unsigned long bg_pattern; /* current background pattern */
451 int drawmode; /* current draw mode */ 137 int drawmode; /* current draw mode */
452 struct font *curfont; /* current selected font */ 138 int fg_brightness; /* current foreground brightness */
453} _tGraybuf; 139 int bg_brightness; /* current background brightness */
140 long plane_size;
141 unsigned long flags; /* various flags, see #defines */
142 unsigned long randmask; /* mask for random value in _writepixel() */
143 unsigned long *bitpattern; /* start of pattern table */
144 unsigned char *plane_data; /* start of bitplane data */
145 unsigned char *cur_buffer; /* start of current chunky pixel buffer */
146 unsigned char *back_buffer;/* start of chunky pixel back buffer */
147 int curfont; /* current selected font */
148};
454 149
455/* Global variables */ 150/* Global variables */
456extern struct plugin_api *_gray_rb; 151extern struct plugin_api *_gray_rb;
457extern _tGraybuf *_graybuf; 152extern struct _gray_info _gray_info;
458extern short _gray_random_buffer; 153extern short _gray_random_buffer;
459 154
460/* Global function pointers */
461extern void (* const _gray_pixelfuncs[4])(int x, int y, unsigned long pattern);
462extern void (* const _gray_blockfuncs[4])(unsigned char *address, unsigned mask,
463 unsigned bits);
464
465#endif /* HAVE_LCD_BITMAP */ 155#endif /* HAVE_LCD_BITMAP */
466#endif /* SIMULATOR */ 156#endif /* !SIMULATOR */
467#endif /* __GRAY_H__ */ 157#endif /* __GRAY_H__ */
diff --git a/apps/plugins/lib/gray_black_display.c b/apps/plugins/lib/gray_black_display.c
deleted file mode 100644
index 573060eb62..0000000000
--- a/apps/plugins/lib/gray_black_display.c
+++ /dev/null
@@ -1,44 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_black_display() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Set the grayscale display to all black
34 ----------------------------------------------------------------------------
35 */
36void gray_black_display(void)
37{
38 _gray_rb->memset(_graybuf->data, 0xFF, MULU16(_graybuf->depth,
39 _graybuf->plane_size));
40}
41
42#endif // #ifdef HAVE_LCD_BITMAP
43#endif // #ifndef SIMULATOR
44
diff --git a/apps/plugins/lib/gray_blockfuncs.c b/apps/plugins/lib/gray_blockfuncs.c
deleted file mode 100644
index 85af0014e1..0000000000
--- a/apps/plugins/lib/gray_blockfuncs.c
+++ /dev/null
@@ -1,262 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* Low level block drawing functions
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */
30#include "gray.h"
31
32/* Prototypes */
33static void _writeblock(unsigned char *address, unsigned mask, unsigned bits);
34static void _invertblock(unsigned char *address, unsigned mask, unsigned bits);
35static void _writeblockfg(unsigned char *address, unsigned mask, unsigned bits);
36static void _writeblockbg(unsigned char *address, unsigned mask, unsigned bits);
37
38/* Block function pointer array */
39void (* const _gray_blockfuncs[4])(unsigned char *address, unsigned mask,
40 unsigned bits) = {
41 _invertblock, _writeblockfg, _writeblockbg, _writeblock
42};
43
44/* Write an 8-pixel block, defined by foreground and background pattern.
45 * Address is the byte in the first bitplane, mask determines which pixels to
46 * set, and bits determines if the pixel is foreground or background */
47static void _writeblock(unsigned char *address, unsigned mask, unsigned bits)
48{
49 unsigned long pat_stack[8];
50 register unsigned char *end_addr;
51 register unsigned long *pat_ptr = &pat_stack[8];
52
53 /* precalculate the bit patterns with random shifts (same RNG as _writepixel,
54 * see there for an explanation) for all 8 pixels and put them on an
55 * extra stack */
56 asm (
57 "mov #8,r3 \n" /* loop count in r3: 8 pixels */
58 "mov %6,r2 \n" /* copy mask */
59
60 ".wb_loop: \n" /** load pattern for pixel **/
61 "shlr r2 \n" /* shift out lsb of mask */
62 "bf .wb_skip \n" /* skip this pixel */
63
64 "mov %2,r4 \n" /* load foreground pattern */
65 "shlr %7 \n" /* shift out lsb of bits */
66 "bt .wb_fg \n" /* foreground? -> skip next insn */
67 "mov %3,r4 \n" /* load background pattern */
68 ".wb_fg: \n"
69
70 "mov #75,r0 \n"
71 "mulu r0,%0 \n" /* multiply by 75 */
72 "sts macl,%0 \n"
73 "add #74,%0 \n" /* add another 74 */
74 /* Since the lower bits are not very random: */
75 "swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */
76 "and %5,r1 \n" /* mask out unneeded bits */
77
78 "cmp/hs %4,r1 \n" /* random >= depth ? */
79 "bf .wb_ntrim \n"
80 "sub %4,r1 \n" /* yes: random -= depth; */
81 ".wb_ntrim: \n"
82
83 "mov.l .ashlsi3,r0 \n" /** rotate pattern **/
84 "jsr @r0 \n" /* r4 -> r0, shift left by r5 */
85 "mov r1,r5 \n"
86
87 "mov %4,r5 \n"
88 "sub r1,r5 \n" /* r5 = depth - r1 */
89 "mov.l .lshrsi3,r1 \n"
90 "jsr @r1 \n" /* r4 -> r0, shift right by r5 */
91 "mov r0,r1 \n" /* store previous result in r1 */
92
93 "bra .wb_store \n"
94 "or r1,r0 \n" /* rotated_pattern = r0 | r1 */
95
96 ".wb_skip: \n"
97 "shlr %7 \n" /* shift out lsb of bits to keep in sync */
98 "mov #0,r0 \n" /* pattern for skipped pixel must be 0 */
99
100 ".wb_store: \n"
101 "mov.l r0,@-%1 \n" /* push on pattern stack */
102
103 "add #-1,r3 \n" /* decrease loop count */
104 "cmp/pl r3 \n" /* loop count > 0? */
105 "bt .wb_loop \n" /* yes: loop */
106 : /* outputs */
107 /* %0, in & out */ "+r"(_gray_random_buffer),
108 /* %1, in & out */ "+r"(pat_ptr)
109 : /* inputs */
110 /* %2 */ "r"(_graybuf->fg_pattern),
111 /* %3 */ "r"(_graybuf->bg_pattern),
112 /* %4 */ "r"(_graybuf->depth),
113 /* %5 */ "r"(_graybuf->randmask),
114 /* %6 */ "r"(mask),
115 /* %7 */ "r"(bits)
116 : /* clobbers */
117 "r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr"
118 );
119
120 end_addr = address + MULU16(_graybuf->depth, _graybuf->plane_size);
121
122 /* set the bits for all 8 pixels in all bytes according to the
123 * precalculated patterns on the pattern stack */
124 asm volatile (
125 "mov.l @%3+,r1 \n" /* pop all 8 patterns */
126 "mov.l @%3+,r2 \n"
127 "mov.l @%3+,r3 \n"
128 "mov.l @%3+,r8 \n"
129 "mov.l @%3+,r9 \n"
130 "mov.l @%3+,r10 \n"
131 "mov.l @%3+,r11 \n"
132 "mov.l @%3+,r12 \n"
133
134 "not %4,%4 \n" /* "set" mask -> "keep" mask */
135 "extu.b %4,%4 \n" /* mask out high bits */
136 "tst %4,%4 \n" /* nothing to keep? */
137 "bt .wb_sloop \n" /* yes: jump to short loop */
138
139 ".wb_floop: \n" /** full loop (there are bits to keep)**/
140 "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */
141 "rotcl r0 \n" /* rotate t bit into r0 */
142 "shlr r2 \n"
143 "rotcl r0 \n"
144 "shlr r3 \n"
145 "rotcl r0 \n"
146 "shlr r8 \n"
147 "rotcl r0 \n"
148 "shlr r9 \n"
149 "rotcl r0 \n"
150 "shlr r10 \n"
151 "rotcl r0 \n"
152 "shlr r11 \n"
153 "rotcl r0 \n"
154 "shlr r12 \n"
155 "mov.b @%0,%3 \n" /* read old value */
156 "rotcl r0 \n"
157 "and %4,%3 \n" /* mask out unneeded bits */
158 "or r0,%3 \n" /* set new bits */
159 "mov.b %3,@%0 \n" /* store value to bitplane */
160 "add %2,%0 \n" /* advance to next bitplane */
161 "cmp/hi %0,%1 \n" /* last bitplane done? */
162 "bt .wb_floop \n" /* no: loop */
163
164 "bra .wb_end \n"
165 "nop \n"
166
167 ".wb_sloop: \n" /** short loop (nothing to keep) **/
168 "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */
169 "rotcl r0 \n" /* rotate t bit into r0 */
170 "shlr r2 \n"
171 "rotcl r0 \n"
172 "shlr r3 \n"
173 "rotcl r0 \n"
174 "shlr r8 \n"
175 "rotcl r0 \n"
176 "shlr r9 \n"
177 "rotcl r0 \n"
178 "shlr r10 \n"
179 "rotcl r0 \n"
180 "shlr r11 \n"
181 "rotcl r0 \n"
182 "shlr r12 \n"
183 "rotcl r0 \n"
184 "mov.b r0,@%0 \n" /* store byte to bitplane */
185 "add %2,%0 \n" /* advance to next bitplane */
186 "cmp/hi %0,%1 \n" /* last bitplane done? */
187 "bt .wb_sloop \n" /* no: loop */
188
189 ".wb_end: \n"
190 : /* outputs */
191 : /* inputs */
192 /* %0 */ "r"(address),
193 /* %1 */ "r"(end_addr),
194 /* %2 */ "r"(_graybuf->plane_size),
195 /* %3 */ "r"(pat_ptr),
196 /* %4 */ "r"(mask)
197 : /* clobbers */
198 "r0", "r1", "r2", "r3", "r8", "r9", "r10", "r11", "r12"
199 );
200}
201
202/* References to C library routines used in _writeblock */
203asm (
204 ".align 2 \n"
205".ashlsi3: \n" /* C library routine: */
206 ".long ___ashlsi3 \n" /* shift r4 left by r5, return in r0 */
207".lshrsi3: \n" /* C library routine: */
208 ".long ___lshrsi3 \n" /* shift r4 right by r5, return in r0 */
209 /* both routines preserve r4, destroy r5 and take ~16 cycles */
210);
211
212/* Invert pixels within an 8-pixel block.
213 * Address is the byte in the first bitplane, mask and bits determine which
214 * pixels to invert ('And'ed together, for matching the parameters with
215 * _writeblock) */
216static void _invertblock(unsigned char *address, unsigned mask, unsigned bits)
217{
218 bits &= mask;
219 if (!bits)
220 return;
221
222 asm volatile (
223 "mov #0,r1 \n" /* current_plane = 0 */
224
225 ".im_loop: \n"
226 "mov.b @%1,r2 \n" /* get data byte */
227 "add #1,r1 \n" /* current_plane++; */
228 "xor %2,r2 \n" /* invert bits */
229 "mov.b r2,@%1 \n" /* store data byte */
230 "add %3,%1 \n" /* advance address to next bitplane */
231 "cmp/hi r1,%0 \n" /* current_plane < depth ? */
232 "bt .im_loop \n"
233 : /* outputs */
234 : /* inputs */
235 /* %0 */ "r"(_graybuf->depth),
236 /* %1 */ "r"(address),
237 /* %2 */ "r"(bits),
238 /* %3 */ "r"(_graybuf->plane_size)
239 : /* clobbers */
240 "r1", "r2", "macl"
241 );
242}
243
244/* Call _writeblock with the mask modified to draw foreground pixels only */
245static void _writeblockfg(unsigned char *address, unsigned mask, unsigned bits)
246{
247 mask &= bits;
248 if (mask)
249 _writeblock(address, mask, bits);
250}
251
252/* Call _writeblock with the mask modified to draw background pixels only */
253static void _writeblockbg(unsigned char *address, unsigned mask, unsigned bits)
254{
255 mask &= ~bits;
256 if (mask)
257 _writeblock(address, mask, bits);
258}
259
260#endif // #ifdef HAVE_LCD_BITMAP
261#endif // #ifndef SIMULATOR
262
diff --git a/apps/plugins/lib/gray_clear_display.c b/apps/plugins/lib/gray_clear_display.c
deleted file mode 100644
index 835107a7fe..0000000000
--- a/apps/plugins/lib/gray_clear_display.c
+++ /dev/null
@@ -1,44 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_clear_display() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Clear the grayscale display (sets all pixels to white)
34 ----------------------------------------------------------------------------
35 */
36void gray_clear_display(void)
37{
38 _gray_rb->memset(_graybuf->data, 0, MULU16(_graybuf->depth,
39 _graybuf->plane_size));
40}
41
42#endif // #ifdef HAVE_LCD_BITMAP
43#endif // #ifndef SIMULATOR
44
diff --git a/apps/plugins/lib/gray_core.c b/apps/plugins/lib/gray_core.c
index b582cd801a..18b9c3c821 100644
--- a/apps/plugins/lib/gray_core.c
+++ b/apps/plugins/lib/gray_core.c
@@ -7,13 +7,13 @@
7* \/ \/ \/ \/ \/ 7* \/ \/ \/ \/ \/
8* $Id$ 8* $Id$
9* 9*
10* Grayscale framework 10* Greyscale framework
11* Core functions 11* Core & miscellaneous functions
12* 12*
13* This is a generic framework to use grayscale display within Rockbox 13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player. 14* plugins. It obviously does not work for the player.
15* 15*
16* Copyright (C) 2004 Jens Arnold 16* Copyright (C) 2004-2005 Jens Arnold
17* 17*
18* All files in this archive are subject to the GNU General Public License. 18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement. 19* See the file COPYING in the source tree root for full license agreement.
@@ -31,28 +31,28 @@
31 31
32/* Global variables */ 32/* Global variables */
33struct plugin_api *_gray_rb = NULL; /* global api struct pointer */ 33struct plugin_api *_gray_rb = NULL; /* global api struct pointer */
34_tGraybuf *_graybuf = NULL; /* pointer to grayscale buffer */ 34struct _gray_info _gray_info; /* global info structure */
35short _gray_random_buffer; /* buffer for random number generator */ 35short _gray_random_buffer; /* buffer for random number generator */
36 36
37/* Prototypes */ 37/* Prototypes */
38static void _timer_isr(void); 38static void _timer_isr(void);
39 39
40/* timer interrupt handler: display next bitplane */ 40/* Timer interrupt handler: display next bitplane */
41static void _timer_isr(void) 41static void _timer_isr(void)
42{ 42{
43 _gray_rb->lcd_blit(_graybuf->data + MULU16(_graybuf->plane_size, 43 _gray_rb->lcd_blit(_gray_info.plane_data + MULU16(_gray_info.plane_size,
44 _graybuf->cur_plane), _graybuf->x, _graybuf->by, 44 _gray_info.cur_plane), _gray_info.x, _gray_info.by,
45 _graybuf->width, _graybuf->bheight, _graybuf->width); 45 _gray_info.width, _gray_info.bheight, _gray_info.width);
46 46
47 if (++_graybuf->cur_plane >= _graybuf->depth) 47 if (++_gray_info.cur_plane >= _gray_info.depth)
48 _graybuf->cur_plane = 0; 48 _gray_info.cur_plane = 0;
49 49
50 if (_graybuf->flags & _GRAY_DEFERRED_UPDATE) /* lcd_update() requested? */ 50 if (_gray_info.flags & _GRAY_DEFERRED_UPDATE) /* lcd_update() requested? */
51 { 51 {
52 int x1 = MAX(_graybuf->x, 0); 52 int x1 = MAX(_gray_info.x, 0);
53 int x2 = MIN(_graybuf->x + _graybuf->width, LCD_WIDTH); 53 int x2 = MIN(_gray_info.x + _gray_info.width, LCD_WIDTH);
54 int y1 = MAX(_graybuf->by << 3, 0); 54 int y1 = MAX(_gray_info.by << _PBLOCK_EXP, 0);
55 int y2 = MIN((_graybuf->by << 3) + _graybuf->height, LCD_HEIGHT); 55 int y2 = MIN((_gray_info.by << _PBLOCK_EXP) + _gray_info.height, LCD_HEIGHT);
56 56
57 if (y1 > 0) /* refresh part above overlay, full width */ 57 if (y1 > 0) /* refresh part above overlay, full width */
58 _gray_rb->lcd_update_rect(0, 0, LCD_WIDTH, y1); 58 _gray_rb->lcd_update_rect(0, 0, LCD_WIDTH, y1);
@@ -66,90 +66,108 @@ static void _timer_isr(void)
66 if (x2 < LCD_WIDTH) /* refresh part to the right of overlay */ 66 if (x2 < LCD_WIDTH) /* refresh part to the right of overlay */
67 _gray_rb->lcd_update_rect(x2, y1, LCD_WIDTH - x2, y2 - y1); 67 _gray_rb->lcd_update_rect(x2, y1, LCD_WIDTH - x2, y2 - y1);
68 68
69 _graybuf->flags &= ~_GRAY_DEFERRED_UPDATE; /* clear request */ 69 _gray_info.flags &= ~_GRAY_DEFERRED_UPDATE; /* clear request */
70 } 70 }
71} 71}
72 72
73/*--------------------------------------------------------------------------- 73/* Initialise the framework and prepare the greyscale display buffer
74 Initialize the framework
75 ----------------------------------------------------------------------------
76 Every framework needs such a function, and it has to be called as
77 the very first one */
78void gray_init(struct plugin_api* newrb)
79{
80 _gray_rb = newrb;
81}
82 74
83/*---------------------------------------------------------------------------
84 Prepare the grayscale display buffer
85 ----------------------------------------------------------------------------
86 arguments: 75 arguments:
76 newrb = pointer to plugin api
87 gbuf = pointer to the memory area to use (e.g. plugin buffer) 77 gbuf = pointer to the memory area to use (e.g. plugin buffer)
88 gbuf_size = max usable size of the buffer 78 gbuf_size = max usable size of the buffer
89 width = width in pixels (1..112) 79 buffered = use chunky pixel buffering with delta buffer?
90 bheight = height in 8-pixel units (1..8) 80 This allows to use all drawing functions, but needs more
91 depth = desired number of shades - 1 (1..32) 81 memory. Unbuffered operation provides only a subset of
82 drawing functions. (only gray_bitmap drawing and scrolling)
83 width = width in pixels (1..LCD_WIDTH)
84 bheight = height in LCD pixel-block units (8 pixels for b&w LCD,
85 4 pixels for 4-grey LCD) (1..LCD_HEIGHT/block_size)
86 depth = number of bitplanes to use (1..32 for b&w LCD, 1..16 for
87 4-grey LCD).
92 88
93 result: 89 result:
94 = depth if there was enough memory 90 = depth if there was enough memory
95 < depth if there wasn't enough memory. The number of displayable 91 < depth if there wasn't enough memory. The number of displayable
96 shades is smaller than desired, but it still works 92 shades is smaller than desired, but it still works
97 = 0 if there wasn't even enough memory for 1 bitplane (black & white) 93 = 0 if there wasn't even enough memory for 1 bitplane
98 94
99 You can request any depth from 1 to 32, not just powers of 2. The routine 95 You can request any depth in the allowed range, not just powers of 2. The
100 performs "graceful degradation" if the memory is not sufficient for the 96 routine performs "graceful degradation" if the memory is not sufficient for
101 desired depth. As long as there is at least enough memory for 1 bitplane, 97 the desired depth. As long as there is at least enough memory for 1 bitplane,
102 it creates as many bitplanes as fit into memory, although 1 bitplane will 98 it creates as many bitplanes as fit into memory, although 1 bitplane won't
103 only deliver black & white display. 99 deliver an enhancement over the native display.
104 100
105 If you need info about the memory taken by the grayscale buffer, supply an 101 The number of displayable shades is calculated as follows:
106 int* as the last parameter. This int will then contain the number of bytes 102 b&w LCD: shades = depth + 1
107 used. The total memory needed can be calculated as follows: 103 4-grey LCD: shades = 3 * depth + 1
108 total_mem = 104
109 sizeof(_tGraybuf) (= 64 bytes currently) 105 If you need info about the memory taken by the greyscale buffer, supply a
110 + sizeof(long) (= 4 bytes) 106 long* as the last parameter. This long will then contain the number of bytes
111 + (width * bheight + sizeof(long)) * depth 107 used. The total memory needed can be calculated as follows:
112 + 0..3 (longword alignment of grayscale display buffer) 108 total_mem =
113 */ 109 shades * sizeof(long) (bitpatterns)
114int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width, 110 + (width * bheight) * depth (bitplane data)
115 int bheight, int depth, int *buf_taken) 111 + buffered ? (chunky front- & backbuffer)
112 (width * bheight * 8(4) * 2) : 0
113 + 0..3 (longword alignment) */
114int gray_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size,
115 bool buffered, int width, int bheight, int depth, long *buf_taken)
116{ 116{
117 int possible_depth, plane_size; 117 int possible_depth, i, j;
118 int i, j, align; 118 long plane_size, buftaken;
119
120 _gray_rb = newrb;
119 121
120 if ((unsigned) width > LCD_WIDTH 122 if ((unsigned) width > LCD_WIDTH
121 || (unsigned) bheight > (LCD_HEIGHT/8) 123 || (unsigned) bheight > (LCD_HEIGHT/_PBLOCK)
122 || depth < 1) 124 || depth < 1)
123 return 0; 125 return 0;
124 126
125 /* the buffer has to be long aligned */ 127 /* the buffer has to be long aligned */
126 align = 3 - (((unsigned long)gbuf + 3) & 3); 128 buftaken = (-(long)gbuf) & 3;
127 gbuf += align; 129 gbuf += buftaken;
128 gbuf_size -= align; 130
131 /* chunky front- & backbuffer */
132 if (buffered)
133 {
134 plane_size = MULU16(width, bheight << _PBLOCK_EXP);
135 buftaken += 2 * plane_size;
136 if (buftaken > gbuf_size)
137 return 0;
138
139 _gray_info.cur_buffer = gbuf;
140 gbuf += plane_size;
141 /* set backbuffer to 0xFF to guarantee the initial full update */
142 _gray_rb->memset(gbuf, 0xFF, plane_size);
143 _gray_info.back_buffer = gbuf;
144 gbuf += plane_size;
145 }
129 146
130 plane_size = MULU16(width, bheight); 147 plane_size = MULU16(width, bheight);
131 possible_depth = (gbuf_size - sizeof(_tGraybuf) - sizeof(long)) 148 possible_depth = (gbuf_size - buftaken - sizeof(long))
132 / (plane_size + sizeof(long)); 149 / (plane_size + _LEVEL_FAC * sizeof(long));
133 150
134 if (possible_depth < 1) 151 if (possible_depth < 1)
135 return 0; 152 return 0;
136 153
137 depth = MIN(depth, 32); 154 depth = MIN(depth, _MAX_DEPTH);
138 depth = MIN(depth, possible_depth); 155 depth = MIN(depth, possible_depth);
139 156
140 _graybuf = (_tGraybuf *) gbuf; /* global pointer to buffer structure */ 157 _gray_info.x = 0;
141 158 _gray_info.by = 0;
142 _graybuf->x = 0; 159 _gray_info.width = width;
143 _graybuf->by = 0; 160 _gray_info.height = bheight << _PBLOCK_EXP;
144 _graybuf->width = width; 161 _gray_info.bheight = bheight;
145 _graybuf->height = bheight << 3; 162 _gray_info.plane_size = plane_size;
146 _graybuf->bheight = bheight; 163 _gray_info.depth = depth;
147 _graybuf->plane_size = plane_size; 164 _gray_info.cur_plane = 0;
148 _graybuf->depth = depth; 165 _gray_info.flags = 0;
149 _graybuf->cur_plane = 0; 166 _gray_info.plane_data = gbuf;
150 _graybuf->flags = 0; 167 gbuf += depth * plane_size;
151 _graybuf->bitpattern = (unsigned long *) (gbuf + sizeof(_tGraybuf)); 168 _gray_info.bitpattern = (unsigned long *)gbuf;
152 _graybuf->data = (unsigned char *) (_graybuf->bitpattern + depth + 1); 169 buftaken += depth * plane_size
170 + (_LEVEL_FAC * depth + 1) * sizeof(long);
153 171
154 i = depth - 1; 172 i = depth - 1;
155 j = 8; 173 j = 8;
@@ -158,12 +176,10 @@ int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width,
158 i >>= 1; 176 i >>= 1;
159 j--; 177 j--;
160 } 178 }
161 _graybuf->randmask = 0xFFu >> j; 179 _gray_info.randmask = 0xFFu >> j;
162 180
163 /* initial state is all white */
164 _gray_rb->memset(_graybuf->data, 0, MULU16(depth, plane_size));
165
166 /* Precalculate the bit patterns for all possible pixel values */ 181 /* Precalculate the bit patterns for all possible pixel values */
182#if LCD_DEPTH == 1
167 for (i = 0; i <= depth; i++) 183 for (i = 0; i <= depth; i++)
168 { 184 {
169 unsigned long pattern = 0; 185 unsigned long pattern = 0;
@@ -181,72 +197,492 @@ int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width,
181 } 197 }
182 /* now the lower <depth> bits contain the pattern */ 198 /* now the lower <depth> bits contain the pattern */
183 199
184 _graybuf->bitpattern[i] = pattern; 200 _gray_info.bitpattern[i] = pattern;
185 } 201 }
186 202#elif LCD_DEPTH == 2
187 _graybuf->fg_pattern = _graybuf->bitpattern[0]; /* black */ 203 for (i = 0; i < depth; i++)
188 _graybuf->bg_pattern = _graybuf->bitpattern[depth]; /* white */
189 _graybuf->drawmode = GRAY_DRAW_SOLID;
190 _graybuf->curfont = FONT_SYSFIXED;
191
192 if (buf_taken) /* caller requested info about space taken */
193 { 204 {
194 *buf_taken = sizeof(_tGraybuf) + sizeof(long) 205 unsigned long pattern = 0;
195 + MULU16(plane_size + sizeof(long), depth) + align; 206 int value = 0;
207
208 for (j = 0; j < depth; j++)
209 {
210 pattern <<= 2;
211 value += i;
212
213 if (value >= depth)
214 value -= depth;
215 else
216 pattern |= 3;
217 }
218
219 _gray_info.bitpattern[i] = pattern | (~pattern & 0xaaaaaaaa);
220 _gray_info.bitpattern[i+depth] = (pattern & 0xaaaaaaaa)
221 | (~pattern & 0x55555555);
222 _gray_info.bitpattern[i+2*depth] = pattern & 0x55555555;
196 } 223 }
224 _gray_info.bitpattern[3*depth] = 0;
225#endif /* LCD_DEPTH */
226
227 _gray_info.fg_brightness = 0;
228 _gray_info.bg_brightness = _LEVEL_FAC * depth;
229 _gray_info.drawmode = DRMODE_SOLID;
230 _gray_info.curfont = FONT_SYSFIXED;
231
232 if (buf_taken) /* caller requested info about space taken */
233 *buf_taken = buftaken;
197 234
198 return depth; 235 return depth;
199} 236}
200 237
201/*--------------------------------------------------------------------------- 238/* Release the greyscale display buffer and the library
202 Release the grayscale display buffer 239 DO CALL either this function or at least gray_show_display(false)
203 ---------------------------------------------------------------------------- 240 before you exit, otherwise nasty things may happen. */
204 Switches the grayscale overlay off at first if it is still running, 241void gray_release(void)
205 then sets the pointer to NULL.
206 DO CALL either this function or at least gray_show_display(false)
207 before you exit, otherwise nasty things may happen.
208 */
209void gray_release_buffer(void)
210{ 242{
211 gray_show_display(false); 243 gray_show(false);
212 _graybuf = NULL;
213} 244}
214 245
215/*--------------------------------------------------------------------------- 246/* Switch the greyscale overlay on or off
216 Switch the grayscale overlay on or off 247 DO NOT call lcd_update() or any other api function that directly accesses
217 ---------------------------------------------------------------------------- 248 the lcd while the greyscale overlay is running! If you need to do
218 enable = true: the grayscale overlay is switched on if initialized 249 lcd_update() to update something outside the greyscale overlay area, use
219 = false: the grayscale overlay is switched off and the regular lcd 250 gray_deferred_update() instead.
220 content is restored
221
222 DO NOT call lcd_update() or any other api function that directly accesses
223 the lcd while the grayscale overlay is running! If you need to do
224 lcd_update() to update something outside the grayscale overlay area, use
225 gray_deferred_update() instead.
226 251
227 Other functions to avoid are: 252 Other functions to avoid are:
228 lcd_blit() (obviously), lcd_update_rect(), lcd_set_contrast(), 253 lcd_blit() (obviously), lcd_update_rect(), lcd_set_contrast(),
229 lcd_set_invert_display(), lcd_set_flip(), lcd_roll() 254 lcd_set_invert_display(), lcd_set_flip(), lcd_roll() */
230 255void gray_show(bool enable)
231 The grayscale display consumes ~50 % CPU power (for a full screen overlay,
232 less if the overlay is smaller) when switched on. You can switch the overlay
233 on and off as many times as you want.
234 */
235void gray_show_display(bool enable)
236{ 256{
237 if (enable) 257 if (enable)
238 { 258 {
239 _graybuf->flags |= _GRAY_RUNNING; 259 _gray_info.flags |= _GRAY_RUNNING;
240 _gray_rb->plugin_register_timer(FREQ / 67, 1, _timer_isr); 260 _gray_rb->plugin_register_timer(FREQ / 67, 1, _timer_isr);
241 } 261 }
242 else 262 else
243 { 263 {
244 _gray_rb->plugin_unregister_timer(); 264 _gray_rb->plugin_unregister_timer();
245 _graybuf->flags &= ~_GRAY_RUNNING; 265 _gray_info.flags &= ~_GRAY_RUNNING;
246 _gray_rb->lcd_update(); /* restore whatever there was before */ 266 _gray_rb->lcd_update(); /* restore whatever there was before */
247 } 267 }
248} 268}
249 269
250#endif // #ifdef HAVE_LCD_BITMAP 270/* Update a rectangular area of the greyscale overlay */
251#endif // #ifndef SIMULATOR 271void gray_update_rect(int x, int y, int width, int height)
272{
273 int ymax;
274 long srcofs;
275 unsigned char *dst;
276
277 if (width <= 0)
278 return; /* nothing to do */
279
280 /* The Y coordinates have to work on whole pixel block rows */
281 ymax = (y + height - 1) >> _PBLOCK_EXP;
282 y >>= _PBLOCK_EXP;
283
284 if (x + width > _gray_info.width)
285 width = _gray_info.width - x;
286 if (ymax >= _gray_info.bheight)
287 ymax = _gray_info.bheight - 1;
288
289 srcofs = (y << _PBLOCK_EXP) + MULU16(_gray_info.height, x);
290 dst = _gray_info.plane_data + MULU16(_gray_info.width, y) + x;
291
292 /* Copy specified rectange bitmap to hardware */
293 for (; y <= ymax; y++)
294 {
295 long srcofs_row = srcofs;
296 unsigned char *dst_row = dst;
297 unsigned char *dst_end = dst_row + width;
298
299 do
300 {
301#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
302 unsigned mask;
303 unsigned long change;
304 unsigned long pat_stack[8];
305 unsigned long *pat_ptr;
306 unsigned char *end_addr;
307
308 asm (
309 "mov.l @(%3,%1),r1 \n"
310 "mov.l @(%3,%2),r2 \n"
311 "xor r1,r2 \n"
312 "add #4,%3 \n"
313 "mov.l @(%3,%1),r1 \n"
314 "mov.l @(%3,%2),%0 \n"
315 "xor r1,%0 \n"
316 "or r2,%0 \n"
317 : /* outputs */
318 /* %0 */ "=r"(change)
319 : /* inputs */
320 /* %1 */ "r"(_gray_info.cur_buffer),
321 /* %2 */ "r"(_gray_info.back_buffer),
322 /* %3 */ "z"(srcofs_row)
323 : /* clobbers */
324 "r1", "r2"
325 );
326
327 if (change != 0)
328 {
329 pat_ptr = &pat_stack[8];
330
331 /* precalculate the bit patterns with random shifts
332 * for all 8 pixels and put them on an extra "stack" */
333 asm volatile (
334 "add %5,%3 \n"
335 "add %5,%4 \n"
336 "mov #8,r3 \n" /* loop count in r3: 8 pixels */
337
338 ".ur_pre_loop: \n"
339 "mov.b @%3+,r0 \n" /* read current buffer */
340 "mov.b @%4,r1 \n" /* read back buffer */
341 "mov #0,r2 \n" /* preset for skipped pixel */
342 "mov.b r0,@%4 \n" /* update back buffer */
343 "add #1,%4 \n"
344 "cmp/eq r0,r1 \n" /* no change? */
345 "bt .ur_skip \n" /* -> skip */
346
347 "shll2 r0 \n" /* pixel value -> pattern offset */
348 "mov.l @(r0,%7),r4 \n" /* r4 = bitpattern[byte]; */
349
350 "mov #75,r0 \n"
351 "mulu r0,%0 \n" /* multiply by 75 */
352 "sts macl,%0 \n"
353 "add #74,%0 \n" /* add another 74 */
354 /* Since the lower bits are not very random: */
355 "swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */
356 "and %8,r1 \n" /* mask out unneeded bits */
357
358 "cmp/hs %6,r1 \n" /* random >= depth ? */
359 "bf .ur_ntrim \n"
360 "sub %6,r1 \n" /* yes: random -= depth; */
361 ".ur_ntrim: \n"
362
363 "mov.l .ashlsi3,r0 \n" /** rotate pattern **/
364 "jsr @r0 \n" /* r4 -> r0, shift left by r5 */
365 "mov r1,r5 \n"
366
367 "mov %6,r5 \n"
368 "sub r1,r5 \n" /* r5 = depth - r1 */
369 "mov.l .lshrsi3,r1 \n"
370 "jsr @r1 \n" /* r4 -> r0, shift right by r5 */
371 "mov r0,r2 \n" /* store previous result in r2 */
372
373 "or r0,r2 \n" /* rotated_pattern = r2 | r0 */
374 "clrt \n" /* mask bit = 0 (replace) */
375
376 ".ur_skip: \n" /* T == 1 if skipped */
377 "rotcr %2 \n" /* get mask bit */
378 "mov.l r2,@-%1 \n" /* push on pattern stack */
379
380 "add #-1,r3 \n" /* decrease loop count */
381 "cmp/pl r3 \n" /* loop count > 0? */
382 "bt .ur_pre_loop\n" /* yes: loop */
383 "shlr8 %2 \n"
384 "shlr16 %2 \n"
385 : /* outputs */
386 /* %0, in & out */ "+r"(_gray_random_buffer),
387 /* %1, in & out */ "+r"(pat_ptr),
388 /* %2 */ "=&r"(mask)
389 : /* inputs */
390 /* %3 */ "r"(_gray_info.cur_buffer),
391 /* %4 */ "r"(_gray_info.back_buffer),
392 /* %5 */ "2"(srcofs_row),
393 /* %6 */ "r"(_gray_info.depth),
394 /* %7 */ "r"(_gray_info.bitpattern),
395 /* %8 */ "r"(_gray_info.randmask)
396 : /* clobbers */
397 "r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr"
398 );
399
400 end_addr = dst_row + MULU16(_gray_info.depth, _gray_info.plane_size);
401
402 /* set the bits for all 8 pixels in all bytes according to the
403 * precalculated patterns on the pattern stack */
404 asm (
405 "mov.l @%3+,r1 \n" /* pop all 8 patterns */
406 "mov.l @%3+,r2 \n"
407 "mov.l @%3+,r3 \n"
408 "mov.l @%3+,r6 \n"
409 "mov.l @%3+,r7 \n"
410 "mov.l @%3+,r8 \n"
411 "mov.l @%3+,r9 \n"
412 "mov.l @%3+,r10 \n"
413
414 "tst %4,%4 \n" /* nothing to keep? */
415 "bt .ur_sloop \n" /* yes: jump to short loop */
416
417 ".ur_floop: \n" /** full loop (there are bits to keep)**/
418 "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */
419 "rotcl r0 \n" /* rotate t bit into r0 */
420 "shlr r2 \n"
421 "rotcl r0 \n"
422 "shlr r3 \n"
423 "rotcl r0 \n"
424 "shlr r6 \n"
425 "rotcl r0 \n"
426 "shlr r7 \n"
427 "rotcl r0 \n"
428 "shlr r8 \n"
429 "rotcl r0 \n"
430 "shlr r9 \n"
431 "rotcl r0 \n"
432 "shlr r10 \n"
433 "mov.b @%0,%3 \n" /* read old value */
434 "rotcl r0 \n"
435 "and %4,%3 \n" /* mask out unneeded bits */
436 "or r0,%3 \n" /* set new bits */
437 "mov.b %3,@%0 \n" /* store value to bitplane */
438 "add %2,%0 \n" /* advance to next bitplane */
439 "cmp/hi %0,%1 \n" /* last bitplane done? */
440 "bt .ur_floop \n" /* no: loop */
441
442 "bra .ur_end \n"
443 "nop \n"
444
445 ".ur_sloop: \n" /** short loop (nothing to keep) **/
446 "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */
447 "rotcl r0 \n" /* rotate t bit into r0 */
448 "shlr r2 \n"
449 "rotcl r0 \n"
450 "shlr r3 \n"
451 "rotcl r0 \n"
452 "shlr r6 \n"
453 "rotcl r0 \n"
454 "shlr r7 \n"
455 "rotcl r0 \n"
456 "shlr r8 \n"
457 "rotcl r0 \n"
458 "shlr r9 \n"
459 "rotcl r0 \n"
460 "shlr r10 \n"
461 "rotcl r0 \n"
462 "mov.b r0,@%0 \n" /* store byte to bitplane */
463 "add %2,%0 \n" /* advance to next bitplane */
464 "cmp/hi %0,%1 \n" /* last bitplane done? */
465 "bt .ur_sloop \n" /* no: loop */
466
467 ".ur_end: \n"
468 : /* outputs */
469 : /* inputs */
470 /* %0 */ "r"(dst_row),
471 /* %1 */ "r"(end_addr),
472 /* %2 */ "r"(_gray_info.plane_size),
473 /* %3 */ "r"(pat_ptr),
474 /* %4 */ "r"(mask)
475 : /* clobbers */
476 "r0", "r1", "r2", "r3", "r6", "r7", "r8", "r9", "r10"
477 );
478 }
479#endif
480 srcofs_row += _gray_info.height;
481 dst_row++;
482 }
483 while (dst_row < dst_end);
484
485 srcofs += _PBLOCK;
486 dst += _gray_info.width;
487 }
488}
489
490#if CONFIG_CPU == SH7034
491/* References to C library routines used in gray_update_rect() */
492asm (
493 ".align 2 \n"
494".ashlsi3: \n" /* C library routine: */
495 ".long ___ashlsi3 \n" /* shift r4 left by r5, return in r0 */
496".lshrsi3: \n" /* C library routine: */
497 ".long ___lshrsi3 \n" /* shift r4 right by r5, return in r0 */
498 /* both routines preserve r4, destroy r5 and take ~16 cycles */
499);
500#endif
501
502/* Update the whole greyscale overlay */
503void gray_update(void)
504{
505 gray_update_rect(0, 0, _gray_info.width, _gray_info.height);
506}
507
508/* Do an lcd_update() to show changes done by rb->lcd_xxx() functions
509 (in areas of the screen not covered by the greyscale overlay). */
510void gray_deferred_lcd_update(void)
511{
512 if (_gray_info.flags & _GRAY_RUNNING)
513 _gray_info.flags |= _GRAY_DEFERRED_UPDATE;
514 else
515 _gray_rb->lcd_update();
516}
517
518/*** Screenshot ***/
519
520#define BMP_NUMCOLORS (_MAX_DEPTH * _LEVEL_FAC + 1)
521#define BMP_BPP 8
522#define BMP_LINESIZE ((LCD_WIDTH + 3) & ~3)
523#define BMP_HEADERSIZE (54 + 4 * BMP_NUMCOLORS)
524#define BMP_DATASIZE (BMP_LINESIZE * LCD_HEIGHT)
525#define BMP_TOTALSIZE (BMP_HEADERSIZE + BMP_DATASIZE)
526
527#define LE16_CONST(x) (x)&0xff, ((x)>>8)&0xff
528#define LE32_CONST(x) (x)&0xff, ((x)>>8)&0xff, ((x)>>16)&0xff, ((x)>>24)&0xff
529
530static const unsigned char bmpheader[] =
531{
532 0x42, 0x4d, /* 'BM' */
533 LE32_CONST(BMP_TOTALSIZE), /* Total file size */
534 0x00, 0x00, 0x00, 0x00, /* Reserved */
535 LE32_CONST(BMP_HEADERSIZE), /* Offset to start of pixel data */
536
537 0x28, 0x00, 0x00, 0x00, /* Size of (2nd) header */
538 LE32_CONST(LCD_WIDTH), /* Width in pixels */
539 LE32_CONST(LCD_HEIGHT), /* Height in pixels */
540 0x01, 0x00, /* Number of planes (always 1) */
541 LE16_CONST(BMP_BPP), /* Bits per pixel 1/4/8/16/24 */
542 0x00, 0x00, 0x00, 0x00, /* Compression mode, 0 = none */
543 LE32_CONST(BMP_DATASIZE), /* Size of bitmap data */
544 0xc4, 0x0e, 0x00, 0x00, /* Horizontal resolution (pixels/meter) */
545 0xc4, 0x0e, 0x00, 0x00, /* Vertical resolution (pixels/meter) */
546 LE32_CONST(BMP_NUMCOLORS), /* Number of used colours */
547 LE32_CONST(BMP_NUMCOLORS), /* Number of important colours */
548};
549
550#if LCD_DEPTH == 1
551#define BMP_RED 0x90
552#define BMP_GREEN 0xee
553#define BMP_BLUE 0x90
554#elif LCD_DEPTH == 2
555#define BMP_RED 0xad
556#define BMP_GREEN 0xd8
557#define BMP_BLUE 0xe6
558#endif
559
560static unsigned char linebuf[BMP_LINESIZE];
561
562/* Save the current display content (b&w and greyscale overlay) to an 8-bit
563 * BMP file in the root directory. */
564void gray_screendump(void)
565{
566 int fh, i, bright;
567 int x, y, by, mask;
568 int gx, gby;
569 unsigned char *lcdptr, *grayptr, *grayptr2;
570 char filename[MAX_PATH];
571
572#ifdef HAVE_RTC
573 struct tm *tm = _gray_rb->get_time();
574
575 _gray_rb->snprintf(filename, MAX_PATH,
576 "/graydump %04d-%02d-%02d %02d-%02d-%02d.bmp",
577 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
578 tm->tm_hour, tm->tm_min, tm->tm_sec);
579#else
580 {
581 DIR* dir;
582 int max_dump_file = 1; /* default to graydump_0001.bmp */
583 dir = _gray_rb->opendir("/");
584 if (dir) /* found */
585 {
586 /* Search for the highest screendump filename present,
587 increment behind that. So even with "holes"
588 (deleted files), the newest will always have the
589 highest number. */
590 while(true)
591 {
592 struct dirent* entry;
593 int curr_dump_file;
594 /* walk through the directory content */
595 entry = _gray_rb->readdir(dir);
596 if (!entry)
597 {
598 _gray_rb->closedir(dir);
599 break; /* end of dir */
600 }
601 if (_gray_rb->strncasecmp(entry->d_name, "graydump_", 9))
602 continue; /* no screendump file */
603 curr_dump_file = _gray_rb->atoi(&entry->d_name[9]);
604 if (curr_dump_file >= max_dump_file)
605 max_dump_file = curr_dump_file + 1;
606 }
607 }
608 _gray_rb->snprintf(filename, MAX_PATH, "/graydump_%04d.bmp",
609 max_dump_file);
610 }
611#endif
612
613 fh = _gray_rb->creat(filename, O_WRONLY);
614
615 if (fh < 0)
616 return;
617
618 _gray_rb->write(fh, bmpheader, sizeof(bmpheader)); /* write header */
619
620 /* build clut, always 33 entries */
621 linebuf[3] = 0;
622
623 for (i = 0; i < BMP_NUMCOLORS; i++)
624 {
625 bright = MIN(i, _LEVEL_FAC * _gray_info.depth);
626 linebuf[0] = MULU16(BMP_BLUE, bright) / (_LEVEL_FAC * _gray_info.depth);
627 linebuf[1] = MULU16(BMP_GREEN, bright) / (_LEVEL_FAC * _gray_info.depth);
628 linebuf[2] = MULU16(BMP_RED, bright) / (_LEVEL_FAC * _gray_info.depth);
629 _gray_rb->write(fh, linebuf, 4);
630 }
631
632 /* 8-bit BMP image goes bottom -> top */
633 for (y = LCD_HEIGHT - 1; y >= 0; y--)
634 {
635#if LCD_DEPTH == 1
636 _gray_rb->memset(linebuf, BMP_NUMCOLORS-1, LCD_WIDTH);
637
638 mask = 1 << (y & 7);
639 by = y >> 3;
640 lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by);
641 gby = by - _gray_info.by;
642
643 if ((_gray_info.flags & _GRAY_RUNNING)
644 && (unsigned) gby < (unsigned) _gray_info.bheight)
645 {
646 /* line contains greyscale (and maybe b&w) graphics */
647 grayptr = _gray_info.plane_data + MULU16(_gray_info.width, gby);
648
649 for (x = 0; x < LCD_WIDTH; x++)
650 {
651 if (*lcdptr++ & mask)
652 linebuf[x] = 0;
653
654 gx = x - _gray_info.x;
655
656 if ((unsigned)gx < (unsigned)_gray_info.width)
657 {
658 bright = 0;
659 grayptr2 = grayptr + gx;
660
661 for (i = 0; i < _gray_info.depth; i++)
662 {
663 if (!(*grayptr2 & mask))
664 bright++;
665 grayptr2 += _gray_info.plane_size;
666 }
667 linebuf[x] = bright;
668 }
669 }
670 }
671 else
672 {
673 /* line contains only b&w graphics */
674 for (x = 0; x < LCD_WIDTH; x++)
675 if (*lcdptr++ & mask)
676 linebuf[x] = 0;
677 }
678#endif
679
680 _gray_rb->write(fh, linebuf, sizeof(linebuf));
681 }
682
683 _gray_rb->close(fh);
684}
685
686#endif /* HAVE_LCD_BITMAP */
687#endif /* !SIMULATOR */
252 688
diff --git a/apps/plugins/lib/gray_deferred_update.c b/apps/plugins/lib/gray_deferred_update.c
deleted file mode 100644
index 3b6edd869e..0000000000
--- a/apps/plugins/lib/gray_deferred_update.c
+++ /dev/null
@@ -1,50 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_deferred_update() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Do an lcd_update() to show changes done by rb->lcd_xxx() functions (in areas
34 of the screen not covered by the grayscale overlay).
35 ----------------------------------------------------------------------------
36 If the grayscale overlay is running, the update will be done in the next
37 call of the interrupt routine, otherwise it will be performed right away.
38 See also comment for the gray_show_display() function.
39 */
40void gray_deferred_update(void)
41{
42 if (_graybuf->flags & _GRAY_RUNNING)
43 _graybuf->flags |= _GRAY_DEFERRED_UPDATE;
44 else
45 _gray_rb->lcd_update();
46}
47
48#endif // #ifdef HAVE_LCD_BITMAP
49#endif // #ifndef SIMULATOR
50
diff --git a/apps/plugins/lib/gray_draw.c b/apps/plugins/lib/gray_draw.c
new file mode 100644
index 0000000000..0742459d4b
--- /dev/null
+++ b/apps/plugins/lib/gray_draw.c
@@ -0,0 +1,826 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Greyscale framework
11* Drawing functions for buffered mode
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004-2005 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*** low-level drawing functions ***/
33
34static void setpixel(unsigned char *address)
35{
36 *address = _gray_info.fg_brightness;
37}
38
39static void clearpixel(unsigned char *address)
40{
41 *address = _gray_info.bg_brightness;
42}
43
44static void flippixel(unsigned char *address)
45{
46 *address = _LEVEL_FAC * _gray_info.depth - *address;
47}
48
49static void nopixel(unsigned char *address)
50{
51 (void)address;
52}
53
54void (* const _gray_pixelfuncs[8])(unsigned char *address) = {
55 flippixel, nopixel, setpixel, setpixel,
56 nopixel, clearpixel, nopixel, clearpixel
57};
58
59/*** Drawing functions ***/
60
61/* Clear the whole display */
62void gray_clear_display(void)
63{
64 int brightness = (_gray_info.drawmode & DRMODE_INVERSEVID) ?
65 _gray_info.fg_brightness : _gray_info.bg_brightness;
66
67 _gray_rb->memset(_gray_info.cur_buffer, brightness,
68 MULU16(_gray_info.width, _gray_info.height));
69}
70
71/* Set a single pixel */
72void gray_drawpixel(int x, int y)
73{
74 if (((unsigned)x < (unsigned)_gray_info.width)
75 && ((unsigned)y < (unsigned)_gray_info.height))
76 _gray_pixelfuncs[_gray_info.drawmode](&_gray_info.cur_buffer[MULU16(x,
77 _gray_info.height) + y]);
78}
79
80/* Draw a line */
81void gray_drawline(int x1, int y1, int x2, int y2)
82{
83 int numpixels;
84 int i;
85 int deltax, deltay;
86 int d, dinc1, dinc2;
87 int x, xinc1, xinc2;
88 int y, yinc1, yinc2;
89 void (*pfunc)(unsigned char *address) = _gray_pixelfuncs[_gray_info.drawmode];
90
91 deltax = abs(x2 - x1);
92 deltay = abs(y2 - y1);
93 xinc2 = 1;
94 yinc2 = 1;
95
96 if (deltax >= deltay)
97 {
98 numpixels = deltax;
99 d = 2 * deltay - deltax;
100 dinc1 = deltay * 2;
101 dinc2 = (deltay - deltax) * 2;
102 xinc1 = 1;
103 yinc1 = 0;
104 }
105 else
106 {
107 numpixels = deltay;
108 d = 2 * deltax - deltay;
109 dinc1 = deltax * 2;
110 dinc2 = (deltax - deltay) * 2;
111 xinc1 = 0;
112 yinc1 = 1;
113 }
114 numpixels++; /* include endpoints */
115
116 if (x1 > x2)
117 {
118 xinc1 = -xinc1;
119 xinc2 = -xinc2;
120 }
121
122 if (y1 > y2)
123 {
124 yinc1 = -yinc1;
125 yinc2 = -yinc2;
126 }
127
128 x = x1;
129 y = y1;
130
131 for (i = 0; i < numpixels; i++)
132 {
133 if (((unsigned)x < (unsigned)_gray_info.width)
134 && ((unsigned)y < (unsigned)_gray_info.height))
135 pfunc(&_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y]);
136
137 if (d < 0)
138 {
139 d += dinc1;
140 x += xinc1;
141 y += yinc1;
142 }
143 else
144 {
145 d += dinc2;
146 x += xinc2;
147 y += yinc2;
148 }
149 }
150}
151
152/* Draw a horizontal line (optimised) */
153void gray_hline(int x1, int x2, int y)
154{
155 int x;
156 unsigned char *dst, *dst_end;
157 void (*pfunc)(unsigned char *address);
158
159 /* direction flip */
160 if (x2 < x1)
161 {
162 x = x1;
163 x1 = x2;
164 x2 = x;
165 }
166
167 /* nothing to draw? */
168 if (((unsigned)y >= (unsigned)_gray_info.height)
169 || (x1 >= _gray_info.width) || (x2 < 0))
170 return;
171
172 /* clipping */
173 if (x1 < 0)
174 x1 = 0;
175 if (x2 >= _gray_info.width)
176 x2 = _gray_info.width - 1;
177
178 pfunc = _gray_pixelfuncs[_gray_info.drawmode];
179 dst = &_gray_info.cur_buffer[MULU16(x1, _gray_info.height) + y];
180
181 dst_end = dst + MULU16(x2 - x1, _gray_info.height);
182 do
183 {
184 pfunc(dst);
185 dst += _gray_info.height;
186 }
187 while (dst <= dst_end);
188}
189
190/* Draw a vertical line (optimised) */
191void gray_vline(int x, int y1, int y2)
192{
193 int y, bits;
194 unsigned char *dst;
195 bool fillopt;
196 void (*pfunc)(unsigned char *address);
197
198 /* direction flip */
199 if (y2 < y1)
200 {
201 y = y1;
202 y1 = y2;
203 y2 = y;
204 }
205
206 /* nothing to draw? */
207 if (((unsigned)x >= (unsigned)_gray_info.width)
208 || (y1 >= _gray_info.height) || (y2 < 0))
209 return;
210
211 /* clipping */
212 if (y1 < 0)
213 y1 = 0;
214 if (y2 >= _gray_info.height)
215 y2 = _gray_info.height - 1;
216
217 bits = _gray_info.fg_brightness;
218 fillopt = (_gray_info.drawmode & DRMODE_INVERSEVID) ?
219 (_gray_info.drawmode & DRMODE_BG) :
220 (_gray_info.drawmode & DRMODE_FG);
221 if (fillopt &&(_gray_info.drawmode & DRMODE_INVERSEVID))
222 bits = _gray_info.bg_brightness;
223
224 pfunc = _gray_pixelfuncs[_gray_info.drawmode];
225 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y1];
226
227 if (fillopt)
228 _gray_rb->memset(dst, bits, y2 - y1 + 1);
229 else
230 {
231 unsigned char *dst_end = dst + y2 - y1;
232 do
233 pfunc(dst++);
234 while (dst <= dst_end);
235 }
236}
237
238/* Draw a rectangular box */
239void gray_drawrect(int x, int y, int width, int height)
240{
241 if ((width <= 0) || (height <= 0))
242 return;
243
244 int x2 = x + width - 1;
245 int y2 = y + height - 1;
246
247 gray_vline(x, y, y2);
248 gray_vline(x2, y, y2);
249 gray_hline(x, x2, y);
250 gray_hline(x, x2, y2);
251}
252
253/* Fill a rectangular area */
254void gray_fillrect(int x, int y, int width, int height)
255{
256 int bits;
257 unsigned char *dst, *dst_end;
258 bool fillopt;
259 void (*pfunc)(unsigned char *address);
260
261 /* nothing to draw? */
262 if ((width <= 0) || (height <= 0) || (x >= _gray_info.width)
263 || (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0))
264 return;
265
266 /* clipping */
267 if (x < 0)
268 {
269 width += x;
270 x = 0;
271 }
272 if (y < 0)
273 {
274 height += y;
275 y = 0;
276 }
277 if (x + width > _gray_info.width)
278 width = _gray_info.width - x;
279 if (y + height > _gray_info.height)
280 height = _gray_info.height - y;
281
282 bits = _gray_info.fg_brightness;
283 fillopt = (_gray_info.drawmode & DRMODE_INVERSEVID) ?
284 (_gray_info.drawmode & DRMODE_BG) :
285 (_gray_info.drawmode & DRMODE_FG);
286 if (fillopt &&(_gray_info.drawmode & DRMODE_INVERSEVID))
287 bits = _gray_info.bg_brightness;
288
289 pfunc = _gray_pixelfuncs[_gray_info.drawmode];
290 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
291 dst_end = dst + MULU16(width, _gray_info.height);
292
293 do
294 {
295 if (fillopt)
296 _gray_rb->memset(dst, bits, height);
297 else
298 {
299 unsigned char *dst_col = dst;
300 unsigned char *col_end = dst_col + height;
301
302 do
303 pfunc(dst_col++);
304 while (dst_col < col_end);
305 }
306 dst += _gray_info.height;
307 }
308 while (dst < dst_end);
309}
310
311/* Draw a filled triangle */
312void gray_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3)
313{
314 int x, y;
315 long fp_y1, fp_y2, fp_dy1, fp_dy2;
316
317 /* sort vertices by increasing x value */
318 if (x1 > x3)
319 {
320 if (x2 < x3) /* x2 < x3 < x1 */
321 {
322 x = x1; x1 = x2; x2 = x3; x3 = x;
323 y = y1; y1 = y2; y2 = y3; y3 = y;
324 }
325 else if (x2 > x1) /* x3 < x1 < x2 */
326 {
327 x = x1; x1 = x3; x3 = x2; x2 = x;
328 y = y1; y1 = y3; y3 = y2; y2 = y;
329 }
330 else /* x3 <= x2 <= x1 */
331 {
332 x = x1; x1 = x3; x3 = x;
333 y = y1; y1 = y3; y3 = y;
334 }
335 }
336 else
337 {
338 if (x2 < x1) /* x2 < x1 <= x3 */
339 {
340 x = x1; x1 = x2; x2 = x;
341 y = y1; y1 = y2; y2 = y;
342 }
343 else if (x2 > x3) /* x1 <= x3 < x2 */
344 {
345 x = x2; x2 = x3; x3 = x;
346 y = y2; y2 = y3; y3 = y;
347 }
348 /* else already sorted */
349 }
350
351 if (x1 < x3) /* draw */
352 {
353 fp_dy1 = ((y3 - y1) << 16) / (x3 - x1);
354 fp_y1 = (y1 << 16) + (1<<15) + (fp_dy1 >> 1);
355
356 if (x1 < x2) /* first part */
357 {
358 fp_dy2 = ((y2 - y1) << 16) / (x2 - x1);
359 fp_y2 = (y1 << 16) + (1<<15) + (fp_dy2 >> 1);
360 for (x = x1; x < x2; x++)
361 {
362 gray_vline(x, fp_y1 >> 16, fp_y2 >> 16);
363 fp_y1 += fp_dy1;
364 fp_y2 += fp_dy2;
365 }
366 }
367 if (x2 < x3) /* second part */
368 {
369 fp_dy2 = ((y3 - y2) << 16) / (x3 - x2);
370 fp_y2 = (y2 << 16) + (1<<15) + (fp_dy2 >> 1);
371 for (x = x2; x < x3; x++)
372 {
373 gray_vline(x, fp_y1 >> 16, fp_y2 >> 16);
374 fp_y1 += fp_dy1;
375 fp_y2 += fp_dy2;
376 }
377 }
378 }
379}
380
381/* About Rockbox' internal monochrome bitmap format:
382 *
383 * A bitmap contains one bit for every pixel that defines if that pixel is
384 * foreground (1) or background (0). Bits within a byte are arranged
385 * vertically, LSB at top.
386 * The bytes are stored in row-major order, with byte 0 being top left,
387 * byte 1 2nd from left etc. The first row of bytes defines pixel rows
388 * 0..7, the second row defines pixel row 8..15 etc.
389 *
390 * This is similar to the internal lcd hw format. */
391
392/* Draw a partial monochrome bitmap */
393void gray_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
394 int stride, int x, int y, int width, int height)
395{
396 const unsigned char *src_end;
397 unsigned char *dst, *dst_end;
398 void (*fgfunc)(unsigned char *address);
399 void (*bgfunc)(unsigned char *address);
400
401 /* nothing to draw? */
402 if ((width <= 0) || (height <= 0) || (x >= _gray_info.width)
403 || (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0))
404 return;
405
406 /* clipping */
407 if (x < 0)
408 {
409 width += x;
410 src_x -= x;
411 x = 0;
412 }
413 if (y < 0)
414 {
415 height += y;
416 src_y -= y;
417 y = 0;
418 }
419 if (x + width > _gray_info.width)
420 width = _gray_info.width - x;
421 if (y + height > _gray_info.height)
422 height = _gray_info.height - y;
423
424 src += MULU16(stride, src_y >> 3) + src_x; /* move starting point */
425 src_y &= 7;
426 src_end = src + width;
427
428 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
429 fgfunc = _gray_pixelfuncs[_gray_info.drawmode];
430 bgfunc = _gray_pixelfuncs[_gray_info.drawmode ^ DRMODE_INVERSEVID];
431
432 do
433 {
434 const unsigned char *src_col = src++;
435 unsigned char *dst_col = dst;
436 unsigned char data = *src_col >> src_y;
437 int numbits = 8 - src_y;
438
439 dst_end = dst_col + height;
440 do
441 {
442 if (data & 0x01)
443 fgfunc(dst_col++);
444 else
445 bgfunc(dst_col++);
446
447 data >>= 1;
448 if (--numbits == 0)
449 {
450 src_col += stride;
451 data = *src_col;
452 numbits = 8;
453 }
454 }
455 while (dst_col < dst_end);
456
457 dst += _gray_info.height;
458 }
459 while (src < src_end);
460}
461
462/* Draw a full monochrome bitmap */
463void gray_mono_bitmap(const unsigned char *src, int x, int y, int width, int height)
464{
465 gray_mono_bitmap_part(src, 0, 0, width, x, y, width, height);
466}
467
468/* Draw a partial greyscale bitmap, canonical format */
469void gray_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
470 int stride, int x, int y, int width, int height)
471{
472 const unsigned char *src_end;
473 unsigned char *dst, *dst_end;
474
475 /* nothing to draw? */
476 if ((width <= 0) || (height <= 0) || (x >= _gray_info.width)
477 || (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0))
478 return;
479
480 /* clipping */
481 if (x < 0)
482 {
483 width += x;
484 src_x -= x;
485 x = 0;
486 }
487 if (y < 0)
488 {
489 height += y;
490 src_y -= y;
491 y = 0;
492 }
493 if (x + width > _gray_info.width)
494 width = _gray_info.width - x;
495 if (y + height > _gray_info.height)
496 height = _gray_info.height - y;
497
498 src += MULU16(stride, src_y) + src_x; /* move starting point */
499 src_end = src + width;
500 dst = &_gray_info.cur_buffer[MULU16(x, _gray_info.height) + y];
501
502 do
503 {
504 const unsigned char *src_col = src++;
505 unsigned char *dst_col = dst;
506
507 dst_end = dst_col + height;
508 do
509 {
510 unsigned data = MULU16(_LEVEL_FAC * _gray_info.depth, *src_col) + 127;
511 *dst_col++ = (data + (data >> 8)) >> 8; /* approx. data / 255 */
512 src_col += stride;
513 }
514 while (dst_col < dst_end);
515
516 dst += _gray_info.height;
517 }
518 while (src < src_end);
519}
520
521/* Draw a full greyscale bitmap, canonical format */
522void gray_gray_bitmap(const unsigned char *src, int x, int y, int width,
523 int height)
524{
525 gray_gray_bitmap_part(src, 0, 0, width, x, y, width, height);
526}
527
528/* Put a string at a given pixel position, skipping first ofs pixel columns */
529void gray_putsxyofs(int x, int y, int ofs, const unsigned char *str)
530{
531 int ch;
532 struct font* pf = font_get(_gray_info.curfont);
533
534 while ((ch = *str++) != '\0' && x < _gray_info.width)
535 {
536 int width;
537 const unsigned char *bits;
538
539 /* check input range */
540 if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
541 ch = pf->defaultchar;
542 ch -= pf->firstchar;
543
544 /* get proportional width and glyph bits */
545 width = pf->width ? pf->width[ch] : pf->maxwidth;
546
547 if (ofs > width)
548 {
549 ofs -= width;
550 continue;
551 }
552
553 bits = pf->bits + (pf->offset ?
554 pf->offset[ch] : ((pf->height + 7) / 8 * pf->maxwidth * ch));
555
556 gray_mono_bitmap_part(bits, ofs, 0, width, x, y, width - ofs, pf->height);
557
558 x += width - ofs;
559 ofs = 0;
560 }
561}
562
563/* Put a string at a given pixel position */
564void gray_putsxy(int x, int y, const unsigned char *str)
565{
566 gray_putsxyofs(x, y, 0, str);
567}
568
569/*** Unbuffered drawing functions ***/
570
571/* Clear the greyscale display (sets all pixels to white) */
572void gray_ub_clear_display(void)
573{
574 _gray_rb->memset(_gray_info.plane_data, 0, MULU16(_gray_info.depth,
575 _gray_info.plane_size));
576}
577
578/* Write a pixel block, defined by their brightnesses in a greymap.
579 Address is the byte in the first bitplane, src is the greymap start address,
580 stride is the increment for the greymap to get to the next pixel, mask
581 determines which pixels of the destination block are changed. For "0" bits,
582 the src address is not incremented! */
583static void _writearray(unsigned char *address, const unsigned char *src,
584 int stride, unsigned mask)
585{
586#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
587 unsigned long pat_stack[8];
588 unsigned long *pat_ptr = &pat_stack[8];
589 unsigned char *end_addr;
590
591 /* precalculate the bit patterns with random shifts
592 for all 8 pixels and put them on an extra "stack" */
593 asm (
594 "mov #8,r3 \n" /* loop count in r3: 8 pixels */
595 "mov %7,r2 \n" /* copy mask -- gcc bug workaround */
596
597 ".wa_loop: \n" /** load pattern for pixel **/
598 "mov #0,r0 \n" /* pattern for skipped pixel must be 0 */
599 "shlr r2 \n" /* shift out lsb of mask */
600 "bf .wa_skip \n" /* skip this pixel */
601
602 "mov.b @%2,r0 \n" /* load src byte */
603 "extu.b r0,r0 \n" /* extend unsigned */
604 "mulu %4,r0 \n" /* macl = byte * depth; */
605 "sts macl,r1 \n" /* r1 = macl; */
606 "add #127,r1 \n" /* byte += 127; */
607 "mov r1,r0 \n"
608 "shlr8 r1 \n"
609 "add r1,r0 \n" /* byte += byte >> 8; */
610 "shlr8 r0 \n" /* byte >>= 8; */
611 "shll2 r0 \n"
612 "mov.l @(r0,%5),r4 \n" /* r4 = bitpattern[byte]; */
613
614 "mov #75,r0 \n"
615 "mulu r0,%0 \n" /* multiply by 75 */
616 "sts macl,%0 \n"
617 "add #74,%0 \n" /* add another 74 */
618 /* Since the lower bits are not very random: */
619 "swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */
620 "and %6,r1 \n" /* mask out unneeded bits */
621
622 "cmp/hs %4,r1 \n" /* random >= depth ? */
623 "bf .wa_ntrim \n"
624 "sub %4,r1 \n" /* yes: random -= depth; */
625 ".wa_ntrim: \n"
626
627 "mov.l .ashlsi3,r0 \n" /** rotate pattern **/
628 "jsr @r0 \n" /* r4 -> r0, shift left by r5 */
629 "mov r1,r5 \n"
630
631 "mov %4,r5 \n"
632 "sub r1,r5 \n" /* r5 = depth - r1 */
633 "mov.l .lshrsi3,r1 \n"
634 "jsr @r1 \n" /* r4 -> r0, shift right by r5 */
635 "mov r0,r1 \n" /* store previous result in r1 */
636
637 "or r1,r0 \n" /* rotated_pattern = r0 | r1 */
638
639 ".wa_skip: \n"
640 "mov.l r0,@-%1 \n" /* push on pattern stack */
641
642 "add %3,%2 \n" /* src += stride; */
643 "add #-1,r3 \n" /* decrease loop count */
644 "cmp/pl r3 \n" /* loop count > 0? */
645 "bt .wa_loop \n" /* yes: loop */
646 : /* outputs */
647 /* %0, in & out */ "+r"(_gray_random_buffer),
648 /* %1, in & out */ "+r"(pat_ptr)
649 : /* inputs */
650 /* %2 */ "r"(src),
651 /* %3 */ "r"(stride),
652 /* %4 */ "r"(_gray_info.depth),
653 /* %5 */ "r"(_gray_info.bitpattern),
654 /* %6 */ "r"(_gray_info.randmask),
655 /* %7 */ "r"(mask)
656 : /* clobbers */
657 "r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr"
658 );
659
660 end_addr = address + MULU16(_gray_info.depth, _gray_info.plane_size);
661
662 /* set the bits for all 8 pixels in all bytes according to the
663 * precalculated patterns on the pattern stack */
664 asm (
665 "mov.l @%3+,r1 \n" /* pop all 8 patterns */
666 "mov.l @%3+,r2 \n"
667 "mov.l @%3+,r3 \n"
668 "mov.l @%3+,r8 \n"
669 "mov.l @%3+,r9 \n"
670 "mov.l @%3+,r10 \n"
671 "mov.l @%3+,r11 \n"
672 "mov.l @%3+,r12 \n"
673
674 "not %4,%4 \n" /* "set" mask -> "keep" mask */
675 "extu.b %4,%4 \n" /* mask out high bits */
676 "tst %4,%4 \n" /* nothing to keep? */
677 "bt .wa_sloop \n" /* yes: jump to short loop */
678
679 ".wa_floop: \n" /** full loop (there are bits to keep)**/
680 "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */
681 "rotcl r0 \n" /* rotate t bit into r0 */
682 "shlr r2 \n"
683 "rotcl r0 \n"
684 "shlr r3 \n"
685 "rotcl r0 \n"
686 "shlr r8 \n"
687 "rotcl r0 \n"
688 "shlr r9 \n"
689 "rotcl r0 \n"
690 "shlr r10 \n"
691 "rotcl r0 \n"
692 "shlr r11 \n"
693 "rotcl r0 \n"
694 "shlr r12 \n"
695 "mov.b @%0,%3 \n" /* read old value */
696 "rotcl r0 \n"
697 "and %4,%3 \n" /* mask out unneeded bits */
698 "or r0,%3 \n" /* set new bits */
699 "mov.b %3,@%0 \n" /* store value to bitplane */
700 "add %2,%0 \n" /* advance to next bitplane */
701 "cmp/hi %0,%1 \n" /* last bitplane done? */
702 "bt .wa_floop \n" /* no: loop */
703
704 "bra .wa_end \n"
705 "nop \n"
706
707 ".wa_sloop: \n" /** short loop (nothing to keep) **/
708 "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */
709 "rotcl r0 \n" /* rotate t bit into r0 */
710 "shlr r2 \n"
711 "rotcl r0 \n"
712 "shlr r3 \n"
713 "rotcl r0 \n"
714 "shlr r8 \n"
715 "rotcl r0 \n"
716 "shlr r9 \n"
717 "rotcl r0 \n"
718 "shlr r10 \n"
719 "rotcl r0 \n"
720 "shlr r11 \n"
721 "rotcl r0 \n"
722 "shlr r12 \n"
723 "rotcl r0 \n"
724 "mov.b r0,@%0 \n" /* store byte to bitplane */
725 "add %2,%0 \n" /* advance to next bitplane */
726 "cmp/hi %0,%1 \n" /* last bitplane done? */
727 "bt .wa_sloop \n" /* no: loop */
728
729 ".wa_end: \n"
730 : /* outputs */
731 : /* inputs */
732 /* %0 */ "r"(address),
733 /* %1 */ "r"(end_addr),
734 /* %2 */ "r"(_gray_info.plane_size),
735 /* %3 */ "r"(pat_ptr),
736 /* %4 */ "r"(mask)
737 : /* clobbers */
738 "r0", "r1", "r2", "r3", "r8", "r9", "r10", "r11", "r12"
739 );
740#endif
741}
742
743#if CONFIG_CPU == SH7034
744/* References to C library routines used in _writearray() */
745asm (
746 ".align 2 \n"
747".ashlsi3: \n" /* C library routine: */
748 ".long ___ashlsi3 \n" /* shift r4 left by r5, return in r0 */
749".lshrsi3: \n" /* C library routine: */
750 ".long ___lshrsi3 \n" /* shift r4 right by r5, return in r0 */
751 /* both routines preserve r4, destroy r5 and take ~16 cycles */
752);
753#endif
754
755/* Draw a partial greyscale bitmap, canonical format */
756void gray_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
757 int stride, int x, int y, int width, int height)
758{
759 int shift, ny;
760 unsigned char *dst, *dst_end;
761 unsigned mask, mask_bottom;
762
763 /* nothing to draw? */
764 if ((width <= 0) || (height <= 0) || (x >= _gray_info.width)
765 || (y >= _gray_info.height) || (x + width <= 0) || (y + height <= 0))
766 return;
767
768 /* clipping */
769 if (x < 0)
770 {
771 width += x;
772 src_x -= x;
773 x = 0;
774 }
775 if (y < 0)
776 {
777 height += y;
778 src_y -= y;
779 y = 0;
780 }
781 if (x + width > _gray_info.width)
782 width = _gray_info.width - x;
783 if (y + height > _gray_info.height)
784 height = _gray_info.height - y;
785
786 shift = y & (_PBLOCK-1);
787 src += MULU16(stride, src_y) + src_x - MULU16(stride, shift);
788 dst = _gray_info.plane_data + x
789 + MULU16(_gray_info.width, y >> _PBLOCK_EXP);
790 ny = height - 1 + shift;
791
792 mask = 0xFFu << shift; /* ATTN LCD_DEPTH == 2 */
793 mask_bottom = 0xFFu >> (~ny & (_PBLOCK-1));
794
795 for (; ny >= _PBLOCK; ny -= _PBLOCK)
796 {
797 const unsigned char *src_row = src;
798 unsigned char *dst_row = dst;
799
800 dst_end = dst_row + width;
801 do
802 _writearray(dst_row++, src_row++, stride, mask);
803 while (dst_row < dst_end);
804
805 src += stride << _PBLOCK_EXP;
806 dst += _gray_info.width;
807 mask = 0xFFu;
808 }
809 mask &= mask_bottom;
810 dst_end = dst + width;
811 do
812 _writearray(dst++, src++, stride, mask);
813 while (dst < dst_end);
814}
815
816/* Draw a full greyscale bitmap, canonical format */
817void gray_ub_gray_bitmap(const unsigned char *src, int x, int y, int width,
818 int height)
819{
820 gray_ub_gray_bitmap_part(src, 0, 0, width, x, y, width, height);
821}
822
823
824#endif /* HAVE_LCD_BITMAP */
825#endif /* !SIMULATOR */
826
diff --git a/apps/plugins/lib/gray_drawbitmap.c b/apps/plugins/lib/gray_drawbitmap.c
deleted file mode 100644
index 376f76d45e..0000000000
--- a/apps/plugins/lib/gray_drawbitmap.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_drawbitmap() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Display a bitmap with the current drawinfo
34 ----------------------------------------------------------------------------
35 The drawmode is used as described for gray_set_drawmode()
36
37 This (now) uses the same bitmap format as the core b&w graphics routines,
38 so you can use bmp2rb to generate bitmaps for use with this function as
39 well.
40
41 A bitmap contains one bit for every pixel that defines if that pixel is
42 foreground (1) or background (0). Bits within a byte are arranged
43 vertically, LSB at top.
44 The bytes are stored in row-major order, with byte 0 being top left,
45 byte 1 2nd from left etc. The first row of bytes defines pixel rows
46 0..7, the second row defines pixel row 8..15 etc.
47
48 The <stride> parameter is useful if you want to show only a part of a
49 bitmap. It should always be set to the "row length" of the bitmap.
50 */
51void gray_drawbitmap(const unsigned char *src, int x, int y, int nx, int ny,
52 int stride)
53{
54 int shift;
55 unsigned bits, mask_top, mask_bottom;
56 const unsigned char *src_col;
57 unsigned char *dst, *dst_col;
58 void (*blockfunc)(unsigned char *address, unsigned mask, unsigned bits);
59
60 if ((unsigned) x >= (unsigned) _graybuf->width
61 || (unsigned) y >= (unsigned) _graybuf->height)
62 return;
63
64 if ((unsigned) (y + ny) >= (unsigned) _graybuf->height) /* clip bottom */
65 ny = _graybuf->height - y;
66
67 if ((unsigned) (x + nx) >= (unsigned) _graybuf->width) /* clip right */
68 nx = _graybuf->width - x;
69
70 dst = _graybuf->data + x + MULU16(_graybuf->width, y >> 3);
71 shift = y & 7;
72 ny += shift;
73
74 mask_top = 0xFFu << (y & 7);
75 mask_bottom = ~(0xFEu << ((ny - 1) & 7));
76 if (ny <= 8)
77 mask_bottom &= mask_top;
78
79 blockfunc = _gray_blockfuncs[_graybuf->drawmode];
80
81 for(x = 0; x < nx; x++)
82 {
83 src_col = src++;
84 dst_col = dst++;
85 bits = 0;
86 y = 0;
87
88 if (ny > 8)
89 {
90 bits = *src_col << shift;
91 src_col += stride;
92
93 blockfunc(dst_col, mask_top, bits);
94 dst_col += _graybuf->width;
95 bits >>= 8;
96
97 for (y = 8; y < ny - 8; y += 8)
98 {
99 bits |= *src_col << shift;
100 src_col += stride;
101
102 blockfunc(dst_col, 0xFFu, bits);
103 dst_col += _graybuf->width;
104 bits >>= 8;
105 }
106 }
107 if (y + shift < ny)
108 bits |= *src_col << shift;
109
110 blockfunc(dst_col, mask_bottom, bits);
111 }
112}
113
114#endif // #ifdef HAVE_LCD_BITMAP
115#endif // #ifndef SIMULATOR
116
diff --git a/apps/plugins/lib/gray_drawgraymap.c b/apps/plugins/lib/gray_drawgraymap.c
deleted file mode 100644
index 2760d5a96c..0000000000
--- a/apps/plugins/lib/gray_drawgraymap.c
+++ /dev/null
@@ -1,275 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_drawgraymap() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */
30#include "gray.h"
31
32/* Prototypes */
33static void _writearray(unsigned char *address, const unsigned char *src,
34 int stride, unsigned mask);
35
36/* Write an 8-pixel block, defined by their brightnesses in a graymap.
37 * Address is the byte in the first bitplane, src is the graymap start address,
38 * stride is the increment for the graymap to get to the next pixel, mask
39 * determines which pixels of the destination block are changed. For "0" bits,
40 * the src address is not incremented! */
41static void _writearray(unsigned char *address, const unsigned char *src,
42 int stride, unsigned mask)
43{
44 unsigned long pat_stack[8];
45 register unsigned char *end_addr;
46 register unsigned long *pat_ptr = &pat_stack[8];
47
48 /* precalculate the bit patterns with random shifts (same RNG as
49 * _writepixel, see there for an explanation) for all 8 pixels and put them
50 * on an extra "stack" */
51 asm (
52 "mov #8,r3 \n" /* loop count in r3: 8 pixels */
53 "mov %7,r2 \n" /* copy mask */
54
55 ".wa_loop: \n" /** load pattern for pixel **/
56 "mov #0,r0 \n" /* pattern for skipped pixel must be 0 */
57 "shlr r2 \n" /* shift out lsb of mask */
58 "bf .wa_skip \n" /* skip this pixel */
59
60 "mov.b @%2,r0 \n" /* load src byte */
61 "extu.b r0,r0 \n" /* extend unsigned */
62 "mulu %4,r0 \n" /* macl = byte * depth; */
63 "add %3,%2 \n" /* src += stride; */
64 "sts macl,r4 \n" /* r4 = macl; */
65 "add r4,r0 \n" /* byte += r4; */
66 "shlr8 r0 \n" /* byte >>= 8; */
67 "shll2 r0 \n"
68 "mov.l @(r0,%5),r4 \n" /* r4 = bitpattern[byte]; */
69
70 "mov #75,r0 \n"
71 "mulu r0,%0 \n" /* multiply by 75 */
72 "sts macl,%0 \n"
73 "add #74,%0 \n" /* add another 74 */
74 /* Since the lower bits are not very random: */
75 "swap.b %0,r1 \n" /* get bits 8..15 (need max. 5) */
76 "and %6,r1 \n" /* mask out unneeded bits */
77
78 "cmp/hs %4,r1 \n" /* random >= depth ? */
79 "bf .wa_ntrim \n"
80 "sub %4,r1 \n" /* yes: random -= depth; */
81 ".wa_ntrim: \n"
82
83 "mov.l .ashlsi3,r0 \n" /** rotate pattern **/
84 "jsr @r0 \n" /* r4 -> r0, shift left by r5 */
85 "mov r1,r5 \n"
86
87 "mov %4,r5 \n"
88 "sub r1,r5 \n" /* r5 = depth - r1 */
89 "mov.l .lshrsi3,r1 \n"
90 "jsr @r1 \n" /* r4 -> r0, shift right by r5 */
91 "mov r0,r1 \n" /* store previous result in r1 */
92
93 "or r1,r0 \n" /* rotated_pattern = r0 | r1 */
94
95 ".wa_skip: \n"
96 "mov.l r0,@-%1 \n" /* push on pattern stack */
97
98 "add #-1,r3 \n" /* decrease loop count */
99 "cmp/pl r3 \n" /* loop count > 0? */
100 "bt .wa_loop \n" /* yes: loop */
101 : /* outputs */
102 /* %0, in & out */ "+r"(_gray_random_buffer),
103 /* %1, in & out */ "+r"(pat_ptr)
104 : /* inputs */
105 /* %2 */ "r"(src),
106 /* %3 */ "r"(stride),
107 /* %4 */ "r"(_graybuf->depth),
108 /* %5 */ "r"(_graybuf->bitpattern),
109 /* %6 */ "r"(_graybuf->randmask),
110 /* %7 */ "r"(mask)
111 : /* clobbers */
112 "r0", "r1", "r2", "r3", "r4", "r5", "macl", "pr"
113 );
114
115 end_addr = address + MULU16(_graybuf->depth, _graybuf->plane_size);
116
117 /* set the bits for all 8 pixels in all bytes according to the
118 * precalculated patterns on the pattern stack */
119 asm volatile (
120 "mov.l @%3+,r1 \n" /* pop all 8 patterns */
121 "mov.l @%3+,r2 \n"
122 "mov.l @%3+,r3 \n"
123 "mov.l @%3+,r8 \n"
124 "mov.l @%3+,r9 \n"
125 "mov.l @%3+,r10 \n"
126 "mov.l @%3+,r11 \n"
127 "mov.l @%3+,r12 \n"
128
129 "not %4,%4 \n" /* "set" mask -> "keep" mask */
130 "extu.b %4,%4 \n" /* mask out high bits */
131 "tst %4,%4 \n" /* nothing to keep? */
132 "bt .wa_sloop \n" /* yes: jump to short loop */
133
134 ".wa_floop: \n" /** full loop (there are bits to keep)**/
135 "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */
136 "rotcl r0 \n" /* rotate t bit into r0 */
137 "shlr r2 \n"
138 "rotcl r0 \n"
139 "shlr r3 \n"
140 "rotcl r0 \n"
141 "shlr r8 \n"
142 "rotcl r0 \n"
143 "shlr r9 \n"
144 "rotcl r0 \n"
145 "shlr r10 \n"
146 "rotcl r0 \n"
147 "shlr r11 \n"
148 "rotcl r0 \n"
149 "shlr r12 \n"
150 "mov.b @%0,%3 \n" /* read old value */
151 "rotcl r0 \n"
152 "and %4,%3 \n" /* mask out unneeded bits */
153 "or r0,%3 \n" /* set new bits */
154 "mov.b %3,@%0 \n" /* store value to bitplane */
155 "add %2,%0 \n" /* advance to next bitplane */
156 "cmp/hi %0,%1 \n" /* last bitplane done? */
157 "bt .wa_floop \n" /* no: loop */
158
159 "bra .wa_end \n"
160 "nop \n"
161
162 ".wa_sloop: \n" /** short loop (nothing to keep) **/
163 "shlr r1 \n" /* rotate lsb of pattern 1 to t bit */
164 "rotcl r0 \n" /* rotate t bit into r0 */
165 "shlr r2 \n"
166 "rotcl r0 \n"
167 "shlr r3 \n"
168 "rotcl r0 \n"
169 "shlr r8 \n"
170 "rotcl r0 \n"
171 "shlr r9 \n"
172 "rotcl r0 \n"
173 "shlr r10 \n"
174 "rotcl r0 \n"
175 "shlr r11 \n"
176 "rotcl r0 \n"
177 "shlr r12 \n"
178 "rotcl r0 \n"
179 "mov.b r0,@%0 \n" /* store byte to bitplane */
180 "add %2,%0 \n" /* advance to next bitplane */
181 "cmp/hi %0,%1 \n" /* last bitplane done? */
182 "bt .wa_sloop \n" /* no: loop */
183
184 ".wa_end: \n"
185 : /* outputs */
186 : /* inputs */
187 /* %0 */ "r"(address),
188 /* %1 */ "r"(end_addr),
189 /* %2 */ "r"(_graybuf->plane_size),
190 /* %3 */ "r"(pat_ptr),
191 /* %4 */ "r"(mask)
192 : /* clobbers */
193 "r0", "r1", "r2", "r3", "r8", "r9", "r10", "r11", "r12"
194 );
195}
196
197/* References to C library routines used in _writearray */
198asm (
199 ".align 2 \n"
200".ashlsi3: \n" /* C library routine: */
201 ".long ___ashlsi3 \n" /* shift r4 left by r5, return in r0 */
202".lshrsi3: \n" /* C library routine: */
203 ".long ___lshrsi3 \n" /* shift r4 right by r5, return in r0 */
204 /* both routines preserve r4, destroy r5 and take ~16 cycles */
205);
206
207/*---------------------------------------------------------------------------
208 Copy a grayscale bitmap into the display
209 ----------------------------------------------------------------------------
210 A grayscale bitmap contains one byte for every pixel that defines the
211 brightness of the pixel (0..255). Bytes are read in row-major order.
212 The <stride> parameter is useful if you want to show only a part of a
213 bitmap. It should always be set to the "row length" of the bitmap, so
214 for displaying the whole bitmap, nx == stride.
215
216 This is the only drawing function NOT using the drawinfo.
217 */
218void gray_drawgraymap(const unsigned char *src, int x, int y, int nx, int ny,
219 int stride)
220{
221 int shift;
222 unsigned mask_top, mask_bottom;
223 const unsigned char *src_row;
224 unsigned char *dst, *dst_row;
225
226 if ((unsigned) x >= (unsigned) _graybuf->width
227 || (unsigned) y >= (unsigned) _graybuf->height)
228 return;
229
230 if ((unsigned) (y + ny) >= (unsigned) _graybuf->height) /* clip bottom */
231 ny = _graybuf->height - y;
232
233 if ((unsigned) (x + nx) >= (unsigned) _graybuf->width) /* clip right */
234 nx = _graybuf->width - x;
235
236 dst = _graybuf->data + x + MULU16(_graybuf->width, y >> 3);
237 shift = y & 7;
238 ny += shift;
239
240 mask_top = 0xFFu << (y & 7);
241 mask_bottom = ~(0xFEu << ((ny - 1) & 7));
242 if (ny <= 8)
243 mask_bottom &= mask_top;
244
245 if (ny > 8)
246 {
247 src_row = src;
248 dst_row = dst;
249
250 for (x = 0; x < nx; x++)
251 _writearray(dst_row++, src_row++, stride, mask_top);
252
253 src += MULU16(stride, 8 - shift);
254 dst += _graybuf->width;
255
256 for (y = 8; y < ny - 8; y += 8)
257 {
258 src_row = src;
259 dst_row = dst;
260
261 for (x = 0; x < nx; x++)
262 _writearray(dst_row++, src_row++, stride, 0xFFu);
263
264 src += stride << 3;
265 dst += _graybuf->width;
266 }
267 }
268
269 for (x = 0; x < nx; x++)
270 _writearray(dst++, src++, stride, mask_bottom);
271}
272
273#endif // #ifdef HAVE_LCD_BITMAP
274#endif // #ifndef SIMULATOR
275
diff --git a/apps/plugins/lib/gray_drawline.c b/apps/plugins/lib/gray_drawline.c
deleted file mode 100644
index 5ec4967c14..0000000000
--- a/apps/plugins/lib/gray_drawline.c
+++ /dev/null
@@ -1,119 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_drawline() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Draw a line from (x1, y1) to (x2, y2) with the current drawinfo
34 ----------------------------------------------------------------------------
35 See gray_drawpixel() for details
36 */
37void gray_drawline(int x1, int y1, int x2, int y2)
38{
39 int numpixels;
40 int i;
41 int deltax, deltay;
42 int d, dinc1, dinc2;
43 int x, xinc1, xinc2;
44 int y, yinc1, yinc2;
45 unsigned long pattern;
46 void (*pixelfunc)(int x, int y, unsigned long pattern);
47
48 if ((unsigned) x1 >= (unsigned) _graybuf->width
49 || (unsigned) y1 >= (unsigned) _graybuf->height
50 || (unsigned) x2 >= (unsigned) _graybuf->width
51 || (unsigned) y2 >= (unsigned) _graybuf->height)
52 return;
53
54 deltax = abs(x2 - x1);
55 deltay = abs(y2 - y1);
56 xinc2 = 1;
57 yinc2 = 1;
58
59 if (deltax >= deltay)
60 {
61 numpixels = deltax;
62 d = 2 * deltay - deltax;
63 dinc1 = deltay * 2;
64 dinc2 = (deltay - deltax) * 2;
65 xinc1 = 1;
66 yinc1 = 0;
67 }
68 else
69 {
70 numpixels = deltay;
71 d = 2 * deltax - deltay;
72 dinc1 = deltax * 2;
73 dinc2 = (deltax - deltay) * 2;
74 xinc1 = 0;
75 yinc1 = 1;
76 }
77 numpixels++; /* include endpoints */
78
79 if (x1 > x2)
80 {
81 xinc1 = -xinc1;
82 xinc2 = -xinc2;
83 }
84
85 if (y1 > y2)
86 {
87 yinc1 = -yinc1;
88 yinc2 = -yinc2;
89 }
90
91 x = x1;
92 y = y1;
93
94 pixelfunc = _gray_pixelfuncs[_graybuf->drawmode];
95 pattern = (_graybuf->drawmode == GRAY_DRAW_BG) ?
96 _graybuf->bg_pattern : _graybuf->fg_pattern;
97
98 for (i = 0; i < numpixels; i++)
99 {
100 pixelfunc(x, y, pattern);
101
102 if (d < 0)
103 {
104 d += dinc1;
105 x += xinc1;
106 y += yinc1;
107 }
108 else
109 {
110 d += dinc2;
111 x += xinc2;
112 y += yinc2;
113 }
114 }
115}
116
117#endif // #ifdef HAVE_LCD_BITMAP
118#endif // #ifndef SIMULATOR
119
diff --git a/apps/plugins/lib/gray_drawpixel.c b/apps/plugins/lib/gray_drawpixel.c
deleted file mode 100644
index f7601f4360..0000000000
--- a/apps/plugins/lib/gray_drawpixel.c
+++ /dev/null
@@ -1,55 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_drawpixel() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Set a pixel with the current drawinfo
34 ----------------------------------------------------------------------------
35 If the drawmode is GRAY_DRAW_INVERSE, the pixel is inverted
36 GRAY_DRAW_FG and GRAY_DRAW_SOLID draw the pixel in the foreground shade
37 GRAY_DRAW_BG draws the pixel in the background shade
38 */
39void gray_drawpixel(int x, int y)
40{
41 unsigned long pattern;
42
43 if ((unsigned) x >= (unsigned) _graybuf->width
44 || (unsigned) y >= (unsigned) _graybuf->height)
45 return;
46
47 pattern = (_graybuf->drawmode == GRAY_DRAW_BG) ?
48 _graybuf->bg_pattern : _graybuf->fg_pattern;
49
50 _gray_pixelfuncs[_graybuf->drawmode](x, y, pattern);
51}
52
53#endif // #ifdef HAVE_LCD_BITMAP
54#endif // #ifndef SIMULATOR
55
diff --git a/apps/plugins/lib/gray_drawrect.c b/apps/plugins/lib/gray_drawrect.c
deleted file mode 100644
index bd0bb71852..0000000000
--- a/apps/plugins/lib/gray_drawrect.c
+++ /dev/null
@@ -1,62 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_drawrect() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Draw a (hollow) rectangle with the current drawinfo
34 ----------------------------------------------------------------------------
35 See gray_drawpixel() for details
36 */
37void gray_drawrect(int x, int y, int nx, int ny)
38{
39 int x2, y2;
40
41 if ((unsigned) x >= (unsigned) _graybuf->width
42 || (unsigned) y >= (unsigned) _graybuf->height)
43 return;
44
45 if ((unsigned) (y + ny) >= (unsigned) _graybuf->height) /* clip bottom */
46 ny = _graybuf->height - y;
47
48 if ((unsigned) (x + nx) >= (unsigned) _graybuf->width) /* clip right */
49 nx = _graybuf->width - x;
50
51 x2 = x + nx - 1;
52 y2 = y + ny - 1;
53
54 gray_horline(x, x2, y);
55 gray_horline(x, x2, y2);
56 gray_verline(x, y, y2);
57 gray_verline(x2, y, y2);
58}
59
60#endif // #ifdef HAVE_LCD_BITMAP
61#endif // #ifndef SIMULATOR
62
diff --git a/apps/plugins/lib/gray_fillrect.c b/apps/plugins/lib/gray_fillrect.c
deleted file mode 100644
index ac6d4818b9..0000000000
--- a/apps/plugins/lib/gray_fillrect.c
+++ /dev/null
@@ -1,92 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_fillrect() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Draw a filled rectangle with the current drawinfo
34 ----------------------------------------------------------------------------
35 See gray_drawpixel() for details
36
37 This one uses the block drawing optimization, so it is rather fast.
38 */
39void gray_fillrect(int x, int y, int nx, int ny)
40{
41 int shift;
42 unsigned bits, mask_top, mask_bottom;
43 unsigned char *dst, *dst_row;
44 void (*blockfunc)(unsigned char *address, unsigned mask, unsigned bits);
45
46 if ((unsigned) x >= (unsigned) _graybuf->width
47 || (unsigned) y >= (unsigned) _graybuf->height)
48 return;
49
50 if ((unsigned) (y + ny) >= (unsigned) _graybuf->height) /* clip bottom */
51 ny = _graybuf->height - y;
52
53 if ((unsigned) (x + nx) >= (unsigned) _graybuf->width) /* clip right */
54 nx = _graybuf->width - x;
55
56 dst = _graybuf->data + x + MULU16(_graybuf->width, y >> 3);
57 shift = y & 7;
58 ny += shift;
59
60 mask_top = 0xFFu << (y & 7);
61 mask_bottom = ~(0xFEu << ((ny - 1) & 7));
62 if (ny <= 8)
63 mask_bottom &= mask_top;
64
65 blockfunc = _gray_blockfuncs[_graybuf->drawmode];
66 bits = (_graybuf->drawmode == GRAY_DRAW_BG) ? 0u : 0xFFu;
67
68 if (ny > 8)
69 {
70 dst_row = dst;
71 for (x = 0; x < nx; x++)
72 blockfunc(dst_row++, mask_top, bits);
73
74 dst += _graybuf->width;
75
76 for (y = 8; y < ny - 8; y += 8)
77 {
78 dst_row = dst;
79 for (x = 0; x < nx; x++)
80 blockfunc(dst_row++, 0xFFu, bits);
81
82 dst += _graybuf->width;
83 }
84 }
85
86 for (x = 0; x < nx; x++)
87 blockfunc(dst++, mask_bottom, bits);
88}
89
90#endif // #ifdef HAVE_LCD_BITMAP
91#endif // #ifndef SIMULATOR
92
diff --git a/apps/plugins/lib/gray_getstringsize.c b/apps/plugins/lib/gray_getstringsize.c
deleted file mode 100644
index 5b6d3e7c49..0000000000
--- a/apps/plugins/lib/gray_getstringsize.c
+++ /dev/null
@@ -1,64 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_getstringsize() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Calculate width and height of the given text in pixels when rendered with
34 the currently selected font.
35 ----------------------------------------------------------------------------
36 This works exactly the same way as the core lcd_getstringsize(), only that
37 it uses the selected font for grayscale.
38 */
39int gray_getstringsize(const unsigned char *str, int *w, int *h)
40{
41 int ch;
42 int width = 0;
43 struct font *pf = _graybuf->curfont;
44
45 while ((ch = *str++))
46 {
47 /* check input range */
48 if (ch < pf->firstchar || ch >= pf->firstchar + pf->size)
49 ch = pf->defaultchar;
50 ch -= pf->firstchar;
51
52 /* get proportional width */
53 width += pf->width ? pf->width[ch] : pf->maxwidth;
54 }
55 if (w)
56 *w = width;
57 if (h)
58 *h = pf->height;
59 return width;
60}
61
62#endif // #ifdef HAVE_LCD_BITMAP
63#endif // #ifndef SIMULATOR
64
diff --git a/apps/plugins/lib/gray_horline.c b/apps/plugins/lib/gray_horline.c
deleted file mode 100644
index c5ad0046de..0000000000
--- a/apps/plugins/lib/gray_horline.c
+++ /dev/null
@@ -1,65 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_horline() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Draw a horizontal line from (x1, y) to (x2, y) with the current drawinfo
34 ----------------------------------------------------------------------------
35 See gray_drawpixel() for details
36 */
37void gray_horline(int x1, int x2, int y)
38{
39 int x;
40 unsigned long pattern;
41 void (*pixelfunc)(int x, int y, unsigned long pattern);
42
43 if ((unsigned) x1 >= (unsigned) _graybuf->width
44 || (unsigned) x2 >= (unsigned) _graybuf->width
45 || (unsigned) y >= (unsigned) _graybuf->height)
46 return;
47
48 if (x1 > x2)
49 {
50 x = x1;
51 x1 = x2;
52 x2 = x;
53 }
54 pixelfunc = _gray_pixelfuncs[_graybuf->drawmode];
55 pattern = (_graybuf->drawmode == GRAY_DRAW_BG) ?
56 _graybuf->bg_pattern : _graybuf->fg_pattern;
57
58 for (x = x1; x <= x2; x++)
59 pixelfunc(x, y, pattern);
60
61}
62
63#endif // #ifdef HAVE_LCD_BITMAP
64#endif // #ifndef SIMULATOR
65
diff --git a/apps/plugins/lib/gray_parm.c b/apps/plugins/lib/gray_parm.c
new file mode 100644
index 0000000000..c66cc33339
--- /dev/null
+++ b/apps/plugins/lib/gray_parm.c
@@ -0,0 +1,107 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Greyscale framework
11* Parameter handling
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004-2005 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/* Set position of the top left corner of the greyscale overlay
33 Note that by is in pixel-block units (8 on Archos/SH1, 4 on H1x0) */
34void gray_set_position(int x, int by)
35{
36 _gray_info.x = x;
37 _gray_info.by = by;
38
39 if (_gray_info.flags & _GRAY_RUNNING)
40 _gray_info.flags |= _GRAY_DEFERRED_UPDATE;
41}
42
43/* Set the draw mode for subsequent drawing operations */
44void gray_set_drawmode(int mode)
45{
46 _gray_info.drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID);
47}
48
49/* Return the current draw mode */
50int gray_get_drawmode(void)
51{
52 return _gray_info.drawmode;
53}
54
55/* Set the foreground shade for subsequent drawing operations */
56void gray_set_foreground(int brightness)
57{
58 unsigned data = MULU16(_LEVEL_FAC * _gray_info.depth, brightness & 0xFF) + 127;
59
60 _gray_info.fg_brightness = (data + (data >> 8)) >> 8; /* approx. data / 255 */
61}
62
63/* Return the current foreground shade */
64int gray_get_foreground(void)
65{
66 return (_gray_info.fg_brightness * 255 + ((_LEVEL_FAC * _gray_info.depth) >> 1))
67 / (_LEVEL_FAC * _gray_info.depth);
68}
69
70/* Set the background shade for subsequent drawing operations */
71void gray_set_background(int brightness)
72{
73 unsigned data = MULU16(_LEVEL_FAC * _gray_info.depth, brightness & 0xFF) + 127;
74
75 _gray_info.bg_brightness = (data + (data >> 8)) >> 8; /* approx. data / 255 */
76}
77
78/* Return the current background shade */
79int gray_get_background(void)
80{
81 return (_gray_info.bg_brightness * 255 + ((_LEVEL_FAC * _gray_info.depth) >> 1))
82 / (_LEVEL_FAC * _gray_info.depth);
83}
84
85/* Set draw mode, foreground and background shades at once */
86void gray_set_drawinfo(int mode, int fg_brightness, int bg_brightness)
87{
88 gray_set_drawmode(mode);
89 gray_set_foreground(fg_brightness);
90 gray_set_background(bg_brightness);
91}
92
93/* Set font for the text output routines */
94void gray_setfont(int newfont)
95{
96 _gray_info.curfont = newfont;
97}
98
99/* Get width and height of a text when printed with the current font */
100int gray_getstringsize(const unsigned char *str, int *w, int *h)
101{
102 return _gray_rb->font_getstringsize(str, w, h, _gray_info.curfont);
103}
104
105#endif /* HAVE_LCD_BITMAP */
106#endif /* !SIMULATOR */
107
diff --git a/apps/plugins/lib/gray_pixelfuncs.c b/apps/plugins/lib/gray_pixelfuncs.c
deleted file mode 100644
index 31ce8deb3c..0000000000
--- a/apps/plugins/lib/gray_pixelfuncs.c
+++ /dev/null
@@ -1,245 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* Low level pixel drawing functions
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */
30#include "gray.h"
31
32/* Prototypes */
33static void _writepixel(int x, int y, unsigned long pattern);
34static void _invertpixel(int x, int y, unsigned long pattern);
35
36/* function pointer array */
37void (* const _gray_pixelfuncs[4])(int x, int y, unsigned long pattern) = {
38 _invertpixel, _writepixel, _writepixel, _writepixel
39};
40
41/* Set a pixel to a specific bit pattern (low level routine) */
42static void _writepixel(int x, int y, unsigned long pattern)
43{
44 register unsigned mask, random;
45 register unsigned char *address;
46
47 /* Some (pseudo-)random function must be used here to shift the bit
48 * pattern randomly, otherwise you would get flicker and/or moire.
49 * Since rand() is relatively slow, I've implemented a simple, but very
50 * fast pseudo-random generator based on linear congruency in assembler.
51 * It delivers max. 16 pseudo-random bits in each iteration. */
52
53 /* simple but fast pseudo-random generator */
54 asm (
55 "mov #75,r1 \n"
56 "mulu %1,r1 \n" /* multiply by 75 */
57 "sts macl,%1 \n" /* get result */
58 "add #74,%1 \n" /* add another 74 */
59 /* Since the lower bits are not very random: */
60 "swap.b %1,%0 \n" /* get bits 8..15 (need max. 5) */
61 "and %2,%0 \n" /* mask out unneeded bits */
62 : /* outputs */
63 /* %0 */ "=&r"(random),
64 /* %1, in & out */ "+r"(_gray_random_buffer)
65 : /* inputs */
66 /* %2 */ "r"(_graybuf->randmask)
67 : /* clobbers */
68 "r1", "macl"
69 );
70
71 /* precalculate mask and byte address in first bitplane */
72 asm (
73 "mov %3,%0 \n" /* take y as base for address offset */
74 "shlr2 %0 \n" /* shift right by 3 (= divide by 8) */
75 "shlr %0 \n"
76 "mulu %0,%2 \n" /* multiply with width */
77 "and #7,%3 \n" /* get lower 3 bits of y */
78 "sts macl,%0 \n" /* get mulu result */
79 "add %4,%0 \n" /* add base + x to get final address */
80
81 "mov %3,%1 \n" /* move lower 3 bits of y out of r0 */
82 "mova .wp_masktable,%3\n" /* get address of mask table in r0 */
83 "bra .wp_predone \n" /* skip the table */
84 "mov.b @(%3,%1),%1 \n" /* get entry from mask table */
85
86 ".align 2 \n"
87 ".wp_masktable: \n" /* mask table */
88 ".byte 0x01 \n"
89 ".byte 0x02 \n"
90 ".byte 0x04 \n"
91 ".byte 0x08 \n"
92 ".byte 0x10 \n"
93 ".byte 0x20 \n"
94 ".byte 0x40 \n"
95 ".byte 0x80 \n"
96
97 ".wp_predone: \n"
98 : /* outputs */
99 /* %0 */ "=&r"(address),
100 /* %1 */ "=&r"(mask)
101 : /* inputs */
102 /* %2 */ "r"(_graybuf->width),
103 /* %3 = r0 */ "z"(y),
104 /* %4 */ "r"(_graybuf->data + x)
105 : /* clobbers */
106 "macl"
107 );
108
109 /* the hard part: set bits in all bitplanes according to pattern */
110 asm volatile (
111 "cmp/hs %1,%5 \n" /* random >= depth ? */
112 "bf .wp_ntrim \n"
113 "sub %1,%5 \n" /* yes: random -= depth */
114 /* it's sufficient to do this once, since the mask guarantees
115 * random < 2 * depth */
116 ".wp_ntrim: \n"
117
118 /* calculate some addresses */
119 "mulu %4,%1 \n" /* end address offset */
120 "not %3,r1 \n" /* get inverse mask (for "and") */
121 "sts macl,%1 \n" /* result of mulu */
122 "mulu %4,%5 \n" /* address offset of <random>'th plane */
123 "add %2,%1 \n" /* end offset -> end address */
124 "sts macl,%5 \n" /* result of mulu */
125 "add %2,%5 \n" /* address of <random>'th plane */
126 "bra .wp_start1 \n"
127 "mov %5,r2 \n" /* copy address */
128
129 /* first loop: set bits from <random>'th bitplane to last */
130 ".wp_loop1: \n"
131 "mov.b @r2,r3 \n" /* get data byte */
132 "shlr %0 \n" /* shift bit mask, sets t bit */
133 "and r1,r3 \n" /* reset bit (-> "white") */
134 "bf .wp_white1 \n" /* t=0? -> "white" bit */
135 "or %3,r3 \n" /* set bit ("black" bit) */
136 ".wp_white1: \n"
137 "mov.b r3,@r2 \n" /* store data byte */
138 "add %4,r2 \n" /* advance address to next bitplane */
139 ".wp_start1: \n"
140 "cmp/hi r2,%1 \n" /* address < end address ? */
141 "bt .wp_loop1 \n"
142
143 "bra .wp_start2 \n"
144 "nop \n"
145
146 /* second loop: set bits from first to <random-1>'th bitplane
147 * Bit setting works the other way round here to equalize average
148 * execution times for bright and dark pixels */
149 ".wp_loop2: \n"
150 "mov.b @%2,r3 \n" /* get data byte */
151 "shlr %0 \n" /* shift bit mask, sets t bit */
152 "or %3,r3 \n" /* set bit (-> "black") */
153 "bt .wp_black2 \n" /* t=1? -> "black" bit */
154 "and r1,r3 \n" /* reset bit ("white" bit) */
155 ".wp_black2: \n"
156 "mov.b r3,@%2 \n" /* store data byte */
157 "add %4,%2 \n" /* advance address to next bitplane */
158 ".wp_start2: \n"
159 "cmp/hi %2,%5 \n" /* address < <random>'th address ? */
160 "bt .wp_loop2 \n"
161 : /* outputs */
162 : /* inputs */
163 /* %0 */ "r"(pattern),
164 /* %1 */ "r"(_graybuf->depth),
165 /* %2 */ "r"(address),
166 /* %3 */ "r"(mask),
167 /* %4 */ "r"(_graybuf->plane_size),
168 /* %5 */ "r"(random)
169 : /* clobbers */
170 "r1", "r2", "r3", "macl"
171 );
172}
173
174/* invert all bits for one pixel (low level routine) */
175static void _invertpixel(int x, int y, unsigned long pattern)
176{
177 register unsigned mask;
178 register unsigned char *address;
179
180 (void) pattern; /* not used for invert */
181
182 /* precalculate mask and byte address in first bitplane */
183 asm (
184 "mov %3,%0 \n" /* take y as base for address offset */
185 "shlr2 %0 \n" /* shift right by 3 (= divide by 8) */
186 "shlr %0 \n"
187 "mulu %0,%2 \n" /* multiply with width */
188 "and #7,%3 \n" /* get lower 3 bits of y */
189 "sts macl,%0 \n" /* get mulu result */
190 "add %4,%0 \n" /* add base + x to get final address */
191
192 "mov %3,%1 \n" /* move lower 3 bits of y out of r0 */
193 "mova .ip_masktable,%3\n" /* get address of mask table in r0 */
194 "bra .ip_predone \n" /* skip the table */
195 "mov.b @(%3,%1),%1 \n" /* get entry from mask table */
196
197 ".align 2 \n"
198 ".ip_masktable: \n" /* mask table */
199 ".byte 0x01 \n"
200 ".byte 0x02 \n"
201 ".byte 0x04 \n"
202 ".byte 0x08 \n"
203 ".byte 0x10 \n"
204 ".byte 0x20 \n"
205 ".byte 0x40 \n"
206 ".byte 0x80 \n"
207
208 ".ip_predone: \n"
209 : /* outputs */
210 /* %0 */ "=&r"(address),
211 /* %1 */ "=&r"(mask)
212 : /* inputs */
213 /* %2 */ "r"(_graybuf->width),
214 /* %3 = r0 */ "z"(y),
215 /* %4 */ "r"(_graybuf->data + x)
216 : /* clobbers */
217 "macl"
218 );
219
220 /* invert bits in all bitplanes */
221 asm volatile (
222 "mov #0,r1 \n" /* current_plane = 0 */
223
224 ".ip_loop: \n"
225 "mov.b @%1,r2 \n" /* get data byte */
226 "add #1,r1 \n" /* current_plane++; */
227 "xor %2,r2 \n" /* invert bits */
228 "mov.b r2,@%1 \n" /* store data byte */
229 "add %3,%1 \n" /* advance address to next bitplane */
230 "cmp/hi r1,%0 \n" /* current_plane < depth ? */
231 "bt .ip_loop \n"
232 : /* outputs */
233 : /* inputs */
234 /* %0 */ "r"(_graybuf->depth),
235 /* %1 */ "r"(address),
236 /* %2 */ "r"(mask),
237 /* %3 */ "r"(_graybuf->plane_size)
238 : /* clobbers */
239 "r1", "r2"
240 );
241}
242
243#endif // #ifdef HAVE_LCD_BITMAP
244#endif // #ifndef SIMULATOR
245
diff --git a/apps/plugins/lib/gray_position_display.c b/apps/plugins/lib/gray_position_display.c
deleted file mode 100644
index 4ec13ee730..0000000000
--- a/apps/plugins/lib/gray_position_display.c
+++ /dev/null
@@ -1,57 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_position_display() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Set position of the top left corner of the grayscale overlay
34 ----------------------------------------------------------------------------
35 x = left margin in pixels
36 by = top margin in 8-pixel units
37
38 You may set this in a way that the overlay spills across the right or
39 bottom display border. In this case it will simply be clipped by the
40 LCD controller. You can even set negative values, this will clip at the
41 left or top border. I did not test it, but the limits may be +127 / -128
42
43 If you use this while the grayscale overlay is running, the now-freed area
44 will be restored.
45 */
46void gray_position_display(int x, int by)
47{
48 _graybuf->x = x;
49 _graybuf->by = by;
50
51 if (_graybuf->flags & _GRAY_RUNNING)
52 _graybuf->flags |= _GRAY_DEFERRED_UPDATE;
53}
54
55#endif // #ifdef HAVE_LCD_BITMAP
56#endif // #ifndef SIMULATOR
57
diff --git a/apps/plugins/lib/gray_putsxy.c b/apps/plugins/lib/gray_putsxy.c
deleted file mode 100644
index 9b34ad7a65..0000000000
--- a/apps/plugins/lib/gray_putsxy.c
+++ /dev/null
@@ -1,67 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_putsxy() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Display text starting at (x, y) with the current font and drawinfo
34 ----------------------------------------------------------------------------
35 The drawmode is used as described for gray_set_drawmode()
36 */
37void gray_putsxy(int x, int y, const unsigned char *str)
38{
39 int ch, width;
40 const unsigned char *bits;
41 struct font *pf = _graybuf->curfont;
42
43 if ((unsigned) x >= (unsigned) _graybuf->width
44 || (unsigned) y >= (unsigned) _graybuf->height)
45 return;
46
47 while ((ch = *str++) != '\0' && x < _graybuf->width)
48 {
49 /* check input range */
50 if (ch < pf->firstchar || ch >= pf->firstchar + pf->size)
51 ch = pf->defaultchar;
52 ch -= pf->firstchar;
53
54 /* get proportional width and glyph bits */
55 width = pf->width ? pf->width[ch] : pf->maxwidth;
56 bits = pf->bits + (pf->offset ? pf->offset[ch] :
57 MULU16((pf->height + 7) / 8, MULU16(pf->maxwidth, ch)));
58
59 gray_drawbitmap((const unsigned char*) bits, x, y, width, pf->height,
60 width);
61 x += width;
62 }
63}
64
65#endif // #ifdef HAVE_LCD_BITMAP
66#endif // #ifndef SIMULATOR
67
diff --git a/apps/plugins/lib/gray_screendump.c b/apps/plugins/lib/gray_screendump.c
deleted file mode 100644
index fdc88b8547..0000000000
--- a/apps/plugins/lib/gray_screendump.c
+++ /dev/null
@@ -1,141 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_screendump() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32static const unsigned char bmpheader[] =
33{
34 0x42, 0x4d, 0xba, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, 0x00,
35 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x40, 0x00,
36 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c,
37 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0xc4, 0x0e, 0x00, 0x00, 0x21, 0x00,
38 0x00, 0x00, 0x21, 0x00, 0x00, 0x00
39};
40
41static unsigned char linebuf[LCD_WIDTH];
42
43/*---------------------------------------------------------------------------
44 Save the current display content (b&w and grayscale overlay) to an 8-bit
45 BMP file in the root directory
46 ----------------------------------------------------------------------------
47 *
48 * This one is rather slow if used with larger bit depths, but it's intended
49 * primary use is for documenting the grayscale plugins. A much faster version
50 * would be possible, but would take more than twice the RAM
51 */
52void gray_screendump(void)
53{
54 int fh, i, bright;
55 int x, y, by, mask;
56 int gx, gby;
57
58 char filename[MAX_PATH];
59 struct tm *tm = _gray_rb->get_time();
60
61 unsigned char *lcdptr, *grayptr, *grayptr2;
62
63 _gray_rb->snprintf(filename, MAX_PATH,
64 "/graydump %04d-%02d-%02d %02d-%02d-%02d.bmp",
65 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
66 tm->tm_hour, tm->tm_min, tm->tm_sec);
67 fh = _gray_rb->creat(filename, O_WRONLY);
68
69 if (fh < 0)
70 return;
71
72 _gray_rb->write(fh, bmpheader, sizeof(bmpheader)); /* write header */
73
74 /* build clut, always 33 entries */
75
76 linebuf[3] = 0;
77
78 for (i = 0; i < 33; i++)
79 {
80 bright = MIN(i, _graybuf->depth);
81 linebuf[0] = linebuf[2] = MULU16(0x90, bright) / _graybuf->depth;
82 linebuf[1] = MULU16(0xee, bright) / _graybuf->depth;
83 _gray_rb->write(fh, linebuf, 4);
84 }
85
86 /* 8-bit BMP image goes bottom -> top */
87
88 for (y = LCD_HEIGHT - 1; y >= 0; y--)
89 {
90 _gray_rb->memset(linebuf, 32, sizeof(linebuf)); /* max. brightness */
91
92 mask = 1 << (y & 7);
93 by = y / 8;
94 lcdptr = _gray_rb->lcd_framebuffer + MULU16(LCD_WIDTH, by);
95 gby = by - _graybuf->by;
96
97 if ((_graybuf->flags & _GRAY_RUNNING)
98 && (unsigned) gby < (unsigned) _graybuf->bheight)
99 {
100 /* line contains grayscale (and maybe b&w) graphics */
101 grayptr = _graybuf->data + MULU16(_graybuf->width, gby);
102
103 for (x = 0; x < LCD_WIDTH; x++)
104 {
105 if (*lcdptr++ & mask)
106 linebuf[x] = 0;
107
108 gx = x - _graybuf->x;
109
110 if ((unsigned) gx < (unsigned) _graybuf->width)
111 {
112 bright = 0;
113 grayptr2 = grayptr + gx;
114
115 for (i = 0; i < _graybuf->depth; i++)
116 {
117 if (!(*grayptr2 & mask))
118 bright++;
119 grayptr2 += _graybuf->plane_size;
120 }
121 linebuf[x] = bright;
122 }
123 }
124 }
125 else
126 {
127 /* line contains only b&w graphics */
128 for (x = 0; x < LCD_WIDTH; x++)
129 if (*lcdptr++ & mask)
130 linebuf[x] = 0;
131 }
132
133 _gray_rb->write(fh, linebuf, sizeof(linebuf));
134 }
135
136 _gray_rb->close(fh);
137}
138
139#endif // #ifdef HAVE_LCD_BITMAP
140#endif // #ifndef SIMULATOR
141
diff --git a/apps/plugins/lib/gray_scroll.c b/apps/plugins/lib/gray_scroll.c
new file mode 100644
index 0000000000..e4520e7649
--- /dev/null
+++ b/apps/plugins/lib/gray_scroll.c
@@ -0,0 +1,479 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Greyscale framework
11* Scrolling routines
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004-2005 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/* FIXME: intermediate solution until we have properly optimised memmove() */
33static void *my_memmove(void *dst0, const void *src0, size_t len0)
34{
35 char *dst = (char *) dst0;
36 char *src = (char *) src0;
37
38 if (dst <= src)
39 {
40 while (len0--)
41 *dst++ = *src++;
42 }
43 else
44 {
45 dst += len0;
46 src += len0;
47
48 while (len0--)
49 *(--dst) = *(--src);
50 }
51
52 return dst0;
53}
54
55/*** Scrolling ***/
56
57/* Scroll left */
58void gray_scroll_left(int count)
59{
60 long shift, length;
61 int blank;
62
63 if ((unsigned)count >= (unsigned)_gray_info.width)
64 return;
65
66 shift = MULU16(_gray_info.height, count);
67 length = MULU16(_gray_info.height, _gray_info.width - count);
68 blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ?
69 _gray_info.fg_brightness : _gray_info.bg_brightness;
70
71 my_memmove(_gray_info.cur_buffer, _gray_info.cur_buffer + shift, length);
72 _gray_rb->memset(_gray_info.cur_buffer + length, blank, shift);
73}
74
75/* Scroll right */
76void gray_scroll_right(int count)
77{
78 long shift, length;
79 int blank;
80
81 if ((unsigned)count >= (unsigned)_gray_info.width)
82 return;
83
84 shift = MULU16(_gray_info.height, count);
85 length = MULU16(_gray_info.height, _gray_info.width - count);
86 blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ?
87 _gray_info.fg_brightness : _gray_info.bg_brightness;
88
89 my_memmove(_gray_info.cur_buffer + shift, _gray_info.cur_buffer, length);
90 _gray_rb->memset(_gray_info.cur_buffer, blank, shift);
91}
92
93/* Scroll up */
94void gray_scroll_up(int count)
95{
96 unsigned char *data, *data_end;
97 int length, blank;
98
99 if ((unsigned)count >= (unsigned)_gray_info.height)
100 return;
101
102 data = _gray_info.cur_buffer;
103 data_end = data + MULU16(_gray_info.width, _gray_info.height);
104 length = _gray_info.height - count;
105 blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ?
106 _gray_info.fg_brightness : _gray_info.bg_brightness;
107
108 do
109 {
110 my_memmove(data, data + count, length);
111 _gray_rb->memset(data + length, blank, count);
112 data += _gray_info.height;
113 }
114 while (data < data_end);
115}
116
117/* Scroll down */
118void gray_scroll_down(int count)
119{
120 unsigned char *data, *data_end;
121 int length, blank;
122
123 if ((unsigned)count >= (unsigned)_gray_info.height)
124 return;
125
126 data = _gray_info.cur_buffer;
127 data_end = data + MULU16(_gray_info.width, _gray_info.height);
128 length = _gray_info.height - count;
129 blank = (_gray_info.drawmode & DRMODE_INVERSEVID) ?
130 _gray_info.fg_brightness : _gray_info.bg_brightness;
131
132 do
133 {
134 my_memmove(data + count, data, length);
135 _gray_rb->memset(data, blank, count);
136 data += _gray_info.height;
137 }
138 while (data < data_end);
139}
140
141/*** Unbuffered scrolling functions ***/
142
143/* Scroll left */
144void gray_ub_scroll_left(int count)
145{
146 int length;
147 unsigned char *ptr, *ptr_end;
148
149 if ((unsigned) count >= (unsigned) _gray_info.width)
150 return;
151
152 length = _gray_info.width - count;
153 ptr = _gray_info.plane_data;
154 ptr_end = ptr + _gray_info.plane_size;
155
156 /* Scroll row by row to minimize flicker (pixel block rows) */
157 do
158 {
159 unsigned char *ptr_row = ptr;
160 unsigned char *row_end = ptr_row
161 + MULU16(_gray_info.plane_size, _gray_info.depth);
162 do
163 {
164 my_memmove(ptr_row, ptr_row + count, length);
165 _gray_rb->memset(ptr_row + length, 0, count);
166 ptr_row += _gray_info.plane_size;
167 }
168 while (ptr_row < row_end);
169
170 ptr += _gray_info.width;
171 }
172 while (ptr < ptr_end);
173}
174
175/* Scroll right */
176void gray_ub_scroll_right(int count)
177{
178 int length;
179 unsigned char *ptr, *ptr_end;
180
181 if ((unsigned) count >= (unsigned) _gray_info.width)
182 return;
183
184 length = _gray_info.width - count;
185 ptr = _gray_info.plane_data;
186 ptr_end = ptr + _gray_info.plane_size;
187
188 /* Scroll row by row to minimize flicker (pixel block rows) */
189 do
190 {
191 unsigned char *ptr_row = ptr;
192 unsigned char *row_end = ptr_row
193 + MULU16(_gray_info.plane_size, _gray_info.depth);
194 do
195 {
196 my_memmove(ptr_row + count, ptr_row, length);
197 _gray_rb->memset(ptr_row, 0, count);
198 ptr_row += _gray_info.plane_size;
199 }
200 while (ptr_row < row_end);
201
202 ptr += _gray_info.width;
203 }
204 while (ptr < ptr_end);
205}
206
207/* Scroll up */
208void gray_ub_scroll_up(int count)
209{
210 int shift;
211 long blockshift = 0;
212 unsigned char *ptr, *ptr_end1, *ptr_end2;
213
214 if ((unsigned) count >= (unsigned) _gray_info.height)
215 return;
216
217 shift = count >> _PBLOCK_EXP;
218 count &= (_PBLOCK-1);
219
220 if (shift)
221 {
222 blockshift = MULU16(_gray_info.width, shift);
223 ptr = _gray_info.plane_data;
224 ptr_end2 = ptr + _gray_info.plane_size;
225 ptr_end1 = ptr_end2 - blockshift;
226 /* Scroll row by row to minimize flicker (pixel block rows) */
227 do
228 {
229 unsigned char *ptr_row = ptr;
230 unsigned char *row_end = ptr_row
231 + MULU16(_gray_info.plane_size, _gray_info.depth);
232 if (ptr < ptr_end1)
233 {
234 do
235 {
236 _gray_rb->memcpy(ptr_row, ptr_row + blockshift,
237 _gray_info.width);
238 ptr_row += _gray_info.plane_size;
239 }
240 while (ptr_row < row_end);
241 }
242 else
243 {
244 do
245 {
246 _gray_rb->memset(ptr_row, 0, _gray_info.width);
247 ptr_row += _gray_info.plane_size;
248 }
249 while (ptr_row < row_end);
250 }
251
252 ptr += _gray_info.width;
253 }
254 while (ptr < ptr_end2);
255 }
256 if (count)
257 {
258#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
259 /* scroll column by column to minimize flicker */
260 asm (
261 "mov #0,r6 \n" /* x = 0 */
262 "mova .su_shifttbl,r0 \n" /* calculate jump destination for */
263 "mov.b @(r0,%5),%5 \n" /* shift amount from table */
264 "bra .su_cloop \n" /* skip table */
265 "add r0,%5 \n"
266
267 ".align 2 \n"
268 ".su_shifttbl: \n" /* shift jump offset table */
269 ".byte .su_shift0 - .su_shifttbl \n"
270 ".byte .su_shift1 - .su_shifttbl \n"
271 ".byte .su_shift2 - .su_shifttbl \n"
272 ".byte .su_shift3 - .su_shifttbl \n"
273 ".byte .su_shift4 - .su_shifttbl \n"
274 ".byte .su_shift5 - .su_shifttbl \n"
275 ".byte .su_shift6 - .su_shifttbl \n"
276 ".byte .su_shift7 - .su_shifttbl \n"
277
278 ".su_cloop: \n" /* repeat for every column */
279 "mov %1,r2 \n" /* get start address */
280 "mov #0,r3 \n" /* current_plane = 0 */
281
282 ".su_oloop: \n" /* repeat for every bitplane */
283 "mov r2,r4 \n" /* get start address */
284 "mov #0,r5 \n" /* current_row = 0 */
285 "mov #0,r1 \n" /* fill with zero */
286
287 ".su_iloop: \n" /* repeat for all rows */
288 "sub %2,r4 \n" /* address -= width */
289 "mov.b @r4,r0 \n" /* get data byte */
290 "shll8 r1 \n" /* old data to 2nd byte */
291 "extu.b r0,r0 \n" /* extend unsigned */
292 "or r1,r0 \n" /* combine old data */
293 "jmp @%5 \n" /* jump into shift "path" */
294 "extu.b r0,r1 \n" /* store data for next round */
295
296 ".su_shift6: \n" /* shift right by 0..7 bits */
297 "shlr2 r0 \n"
298 ".su_shift4: \n"
299 "shlr2 r0 \n"
300 ".su_shift2: \n"
301 "bra .su_shift0 \n"
302 "shlr2 r0 \n"
303 ".su_shift7: \n"
304 "shlr2 r0 \n"
305 ".su_shift5: \n"
306 "shlr2 r0 \n"
307 ".su_shift3: \n"
308 "shlr2 r0 \n"
309 ".su_shift1: \n"
310 "shlr r0 \n"
311 ".su_shift0: \n"
312
313 "mov.b r0,@r4 \n" /* store data */
314 "add #1,r5 \n" /* current_row++ */
315 "cmp/hi r5,%3 \n" /* current_row < bheight - shift ? */
316 "bt .su_iloop \n"
317
318 "add %4,r2 \n" /* start_address += plane_size */
319 "add #1,r3 \n" /* current_plane++ */
320 "cmp/hi r3,%0 \n" /* current_plane < depth ? */
321 "bt .su_oloop \n"
322
323 "add #1,%1 \n" /* start_address++ */
324 "add #1,r6 \n" /* x++ */
325 "cmp/hi r6,%2 \n" /* x < width ? */
326 "bt .su_cloop \n"
327 : /* outputs */
328 : /* inputs */
329 /* %0 */ "r"(_gray_info.depth),
330 /* %1 */ "r"(_gray_info.plane_data + _gray_info.plane_size - blockshift),
331 /* %2 */ "r"(_gray_info.width),
332 /* %3 */ "r"(_gray_info.bheight - shift),
333 /* %4 */ "r"(_gray_info.plane_size),
334 /* %5 */ "r"(count)
335 : /* clobbers */
336 "r0", "r1", "r2", "r3", "r4", "r5", "r6"
337 );
338#endif
339 }
340}
341
342/* Scroll down */
343void gray_ub_scroll_down(int count)
344{
345 int shift;
346 long blockshift = 0;
347 unsigned char *ptr, *ptr_end1, *ptr_end2;
348
349 if ((unsigned) count >= (unsigned) _gray_info.height)
350 return;
351
352 shift = count >> _PBLOCK_EXP;
353 count &= (_PBLOCK-1);
354
355 if (shift)
356 {
357 blockshift = MULU16(_gray_info.width, shift);
358 ptr_end2 = _gray_info.plane_data;
359 ptr_end1 = ptr_end2 + blockshift;
360 ptr = ptr_end2 + _gray_info.plane_size;
361 /* Scroll row by row to minimize flicker (pixel block rows) */
362 do
363 {
364 unsigned char *ptr_row, *row_end;
365
366 ptr -= _gray_info.width;
367 ptr_row = ptr;
368 row_end = ptr_row + MULU16(_gray_info.plane_size, _gray_info.depth);
369
370 if (ptr >= ptr_end1)
371 {
372 do
373 {
374 _gray_rb->memcpy(ptr_row, ptr_row - blockshift,
375 _gray_info.width);
376 ptr_row += _gray_info.plane_size;
377 }
378 while (ptr_row < row_end);
379 }
380 else
381 {
382 do
383 {
384 _gray_rb->memset(ptr_row, 0, _gray_info.width);
385 ptr_row += _gray_info.plane_size;
386 }
387 while (ptr_row < row_end);
388 }
389 }
390 while (ptr > ptr_end2);
391 }
392 if (count)
393 {
394#if (CONFIG_CPU == SH7034) && (LCD_DEPTH == 1)
395 /* scroll column by column to minimize flicker */
396 asm (
397 "mov #0,r6 \n" /* x = 0 */
398 "mova .sd_shifttbl,r0 \n" /* calculate jump destination for */
399 "mov.b @(r0,%5),%5 \n" /* shift amount from table */
400 "bra .sd_cloop \n" /* skip table */
401 "add r0,%5 \n"
402
403 ".align 2 \n"
404 ".sd_shifttbl: \n" /* shift jump offset table */
405 ".byte .sd_shift0 - .sd_shifttbl \n"
406 ".byte .sd_shift1 - .sd_shifttbl \n"
407 ".byte .sd_shift2 - .sd_shifttbl \n"
408 ".byte .sd_shift3 - .sd_shifttbl \n"
409 ".byte .sd_shift4 - .sd_shifttbl \n"
410 ".byte .sd_shift5 - .sd_shifttbl \n"
411 ".byte .sd_shift6 - .sd_shifttbl \n"
412 ".byte .sd_shift7 - .sd_shifttbl \n"
413
414 ".sd_cloop: \n" /* repeat for every column */
415 "mov %1,r2 \n" /* get start address */
416 "mov #0,r3 \n" /* current_plane = 0 */
417
418 ".sd_oloop: \n" /* repeat for every bitplane */
419 "mov r2,r4 \n" /* get start address */
420 "mov #0,r5 \n" /* current_row = 0 */
421 "mov #0,r1 \n" /* fill with zero */
422
423 ".sd_iloop: \n" /* repeat for all rows */
424 "shlr8 r1 \n" /* shift right to get residue */
425 "mov.b @r4,r0 \n" /* get data byte */
426 "jmp @%5 \n" /* jump into shift "path" */
427 "extu.b r0,r0 \n" /* extend unsigned */
428
429 ".sd_shift6: \n" /* shift left by 0..7 bits */
430 "shll2 r0 \n"
431 ".sd_shift4: \n"
432 "shll2 r0 \n"
433 ".sd_shift2: \n"
434 "bra .sd_shift0 \n"
435 "shll2 r0 \n"
436 ".sd_shift7: \n"
437 "shll2 r0 \n"
438 ".sd_shift5: \n"
439 "shll2 r0 \n"
440 ".sd_shift3: \n"
441 "shll2 r0 \n"
442 ".sd_shift1: \n"
443 "shll r0 \n"
444 ".sd_shift0: \n"
445
446 "or r0,r1 \n" /* combine with last residue */
447 "mov.b r1,@r4 \n" /* store data */
448 "add %2,r4 \n" /* address += width */
449 "add #1,r5 \n" /* current_row++ */
450 "cmp/hi r5,%3 \n" /* current_row < bheight - shift ? */
451 "bt .sd_iloop \n"
452
453 "add %4,r2 \n" /* start_address += plane_size */
454 "add #1,r3 \n" /* current_plane++ */
455 "cmp/hi r3,%0 \n" /* current_plane < depth ? */
456 "bt .sd_oloop \n"
457
458 "add #1,%1 \n" /* start_address++ */
459 "add #1,r6 \n" /* x++ */
460 "cmp/hi r6,%2 \n" /* x < width ? */
461 "bt .sd_cloop \n"
462 : /* outputs */
463 : /* inputs */
464 /* %0 */ "r"(_gray_info.depth),
465 /* %1 */ "r"(_gray_info.plane_data + blockshift),
466 /* %2 */ "r"(_gray_info.width),
467 /* %3 */ "r"(_gray_info.bheight - shift),
468 /* %4 */ "r"(_gray_info.plane_size),
469 /* %5 */ "r"(count)
470 : /* clobbers */
471 "r0", "r1", "r2", "r3", "r4", "r5", "r6"
472 );
473#endif
474 }
475}
476
477#endif /* HAVE_LCD_BITMAP */
478#endif /* !SIMULATOR */
479
diff --git a/apps/plugins/lib/gray_scroll_down.c b/apps/plugins/lib/gray_scroll_down.c
deleted file mode 100644
index 1fb1de8335..0000000000
--- a/apps/plugins/lib/gray_scroll_down.c
+++ /dev/null
@@ -1,134 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_scroll_down() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Scroll the whole grayscale buffer down by <count> pixels (<= 7)
34 ----------------------------------------------------------------------------
35 black_border determines if the pixels scrolled in at the top are black
36 or white
37
38 Scrolling up/down pixel-wise is significantly slower than scrolling
39 left/right or scrolling up/down byte-wise because it involves bit
40 shifting. That's why it is asm optimized.
41 */
42void gray_scroll_down(int count, bool black_border)
43{
44 unsigned filler;
45
46 if ((unsigned) count > 7)
47 return;
48
49 filler = black_border ? (0xFFu << count) : 0;
50
51 /* scroll column by column to minimize flicker */
52 asm volatile (
53 "mov #0,r6 \n" /* x = 0 */
54 "mova .sd_shifttbl,r0 \n" /* calculate jump destination for */
55 "mov.b @(r0,%6),%6 \n" /* shift amount from table */
56 "bra .sd_cloop \n" /* skip table */
57 "add r0,%6 \n"
58
59 ".align 2 \n"
60 ".sd_shifttbl: \n" /* shift jump offset table */
61 ".byte .sd_shift0 - .sd_shifttbl \n"
62 ".byte .sd_shift1 - .sd_shifttbl \n"
63 ".byte .sd_shift2 - .sd_shifttbl \n"
64 ".byte .sd_shift3 - .sd_shifttbl \n"
65 ".byte .sd_shift4 - .sd_shifttbl \n"
66 ".byte .sd_shift5 - .sd_shifttbl \n"
67 ".byte .sd_shift6 - .sd_shifttbl \n"
68 ".byte .sd_shift7 - .sd_shifttbl \n"
69
70 ".sd_cloop: \n" /* repeat for every column */
71 "mov %1,r2 \n" /* get start address */
72 "mov #0,r3 \n" /* current_plane = 0 */
73
74 ".sd_oloop: \n" /* repeat for every bitplane */
75 "mov r2,r4 \n" /* get start address */
76 "mov #0,r5 \n" /* current_row = 0 */
77 "mov %5,r1 \n" /* get filler bits */
78
79 ".sd_iloop: \n" /* repeat for all rows */
80 "shlr8 r1 \n" /* shift right to get residue */
81 "mov.b @r4,r0 \n" /* get data byte */
82 "jmp @%6 \n" /* jump into shift "path" */
83 "extu.b r0,r0 \n" /* extend unsigned */
84
85 ".sd_shift6: \n" /* shift left by 0..7 bits */
86 "shll2 r0 \n"
87 ".sd_shift4: \n"
88 "shll2 r0 \n"
89 ".sd_shift2: \n"
90 "bra .sd_shift0 \n"
91 "shll2 r0 \n"
92 ".sd_shift7: \n"
93 "shll2 r0 \n"
94 ".sd_shift5: \n"
95 "shll2 r0 \n"
96 ".sd_shift3: \n"
97 "shll2 r0 \n"
98 ".sd_shift1: \n"
99 "shll r0 \n"
100 ".sd_shift0: \n"
101
102 "or r0,r1 \n" /* combine with last residue */
103 "mov.b r1,@r4 \n" /* store data */
104 "add %2,r4 \n" /* address += width */
105 "add #1,r5 \n" /* current_row++ */
106 "cmp/hi r5,%3 \n" /* current_row < bheight ? */
107 "bt .sd_iloop \n"
108
109 "add %4,r2 \n" /* start_address += plane_size */
110 "add #1,r3 \n" /* current_plane++ */
111 "cmp/hi r3,%0 \n" /* current_plane < depth ? */
112 "bt .sd_oloop \n"
113
114 "add #1,%1 \n" /* start_address++ */
115 "add #1,r6 \n" /* x++ */
116 "cmp/hi r6,%2 \n" /* x < width ? */
117 "bt .sd_cloop \n"
118 : /* outputs */
119 : /* inputs */
120 /* %0 */ "r"(_graybuf->depth),
121 /* %1 */ "r"(_graybuf->data),
122 /* %2 */ "r"(_graybuf->width),
123 /* %3 */ "r"(_graybuf->bheight),
124 /* %4 */ "r"(_graybuf->plane_size),
125 /* %5 */ "r"(filler),
126 /* %6 */ "r"(count)
127 : /* clobbers */
128 "r0", "r1", "r2", "r3", "r4", "r5", "r6"
129 );
130}
131
132#endif // #ifdef HAVE_LCD_BITMAP
133#endif // #ifndef SIMULATOR
134
diff --git a/apps/plugins/lib/gray_scroll_down8.c b/apps/plugins/lib/gray_scroll_down8.c
deleted file mode 100644
index db716baee7..0000000000
--- a/apps/plugins/lib/gray_scroll_down8.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_scroll_down8() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Scroll the whole grayscale buffer down by 8 pixels
34 ----------------------------------------------------------------------------
35 black_border determines if the pixels scrolled in at the top are black
36 or white
37
38 Scrolling up/down by 8 pixels is very fast.
39 */
40void gray_scroll_down8(bool black_border)
41{
42 int by, d;
43 unsigned filler;
44 unsigned char *ptr;
45
46 filler = black_border ? 0xFF : 0;
47
48 /* Scroll row by row to minimize flicker (byte rows = 8 pixels each) */
49 for (by = _graybuf->bheight - 1; by > 0; by--)
50 {
51 ptr = _graybuf->data + MULU16(_graybuf->width, by);
52 for (d = 0; d < _graybuf->depth; d++)
53 {
54 _gray_rb->memcpy(ptr, ptr - _graybuf->width, _graybuf->width);
55 ptr += _graybuf->plane_size;
56 }
57 }
58 /* fill first row */
59 ptr = _graybuf->data;
60 for (d = 0; d < _graybuf->depth; d++)
61 {
62 _gray_rb->memset(ptr, filler, _graybuf->width);
63 ptr += _graybuf->plane_size;
64 }
65}
66
67#endif // #ifdef HAVE_LCD_BITMAP
68#endif // #ifndef SIMULATOR
69
diff --git a/apps/plugins/lib/gray_scroll_left.c b/apps/plugins/lib/gray_scroll_left.c
deleted file mode 100644
index 5fb9a441c1..0000000000
--- a/apps/plugins/lib/gray_scroll_left.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_scroll_left() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Scroll the whole grayscale buffer left by <count> pixels
34 ----------------------------------------------------------------------------
35 black_border determines if the pixels scrolled in at the right are black
36 or white
37
38 Scrolling left/right by an even pixel count is almost twice as fast as
39 scrolling by an odd pixel count.
40 */
41void gray_scroll_left(int count, bool black_border)
42{
43 int by, d;
44 unsigned filler;
45 unsigned char *ptr;
46
47 if ((unsigned) count >= (unsigned) _graybuf->width)
48 return;
49
50 filler = black_border ? 0xFF : 0;
51
52 /* Scroll row by row to minimize flicker (byte rows = 8 pixels each) */
53 for (by = 0; by < _graybuf->bheight; by++)
54 {
55 ptr = _graybuf->data + MULU16(_graybuf->width, by);
56 for (d = 0; d < _graybuf->depth; d++)
57 {
58 asm volatile (
59 "mov %0,r1 \n" /* check if both source... */
60 "or %2,r1 \n" /* ...and offset are even */
61 "shlr r1 \n" /* -> lsb = 0 */
62 "bf .sl_start2 \n" /* -> copy word-wise */
63
64 "add #-1,%2 \n" /* copy byte-wise */
65 ".sl_loop1: \n"
66 "mov.b @%0+,r1 \n"
67 "mov.b r1,@(%2,%0) \n"
68 "cmp/hi %0,%1 \n"
69 "bt .sl_loop1 \n"
70
71 "bra .sl_end \n"
72 "nop \n"
73
74 ".sl_start2: \n" /* copy word-wise */
75 "add #-2,%2 \n"
76 ".sl_loop2: \n"
77 "mov.w @%0+,r1 \n"
78 "mov.w r1,@(%2,%0) \n"
79 "cmp/hi %0,%1 \n"
80 "bt .sl_loop2 \n"
81
82 ".sl_end: \n"
83 : /* outputs */
84 : /* inputs */
85 /* %0 */ "r"(ptr + count),
86 /* %1 */ "r"(ptr + _graybuf->width),
87 /* %2 */ "z"(-count)
88 : /* clobbers */
89 "r1"
90 );
91
92 _gray_rb->memset(ptr + _graybuf->width - count, filler, count);
93 ptr += _graybuf->plane_size;
94 }
95 }
96}
97
98#endif // #ifdef HAVE_LCD_BITMAP
99#endif // #ifndef SIMULATOR
100
diff --git a/apps/plugins/lib/gray_scroll_right.c b/apps/plugins/lib/gray_scroll_right.c
deleted file mode 100644
index f944319d91..0000000000
--- a/apps/plugins/lib/gray_scroll_right.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_scroll_right() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Scroll the whole grayscale buffer right by <count> pixels
34 ----------------------------------------------------------------------------
35 black_border determines if the pixels scrolled in at the left are black
36 or white
37
38 Scrolling left/right by an even pixel count is almost twice as fast as
39 scrolling by an odd pixel count.
40 */
41void gray_scroll_right(int count, bool black_border)
42{
43 int by, d;
44 unsigned filler;
45 unsigned char *ptr;
46
47 if ((unsigned) count >= (unsigned) _graybuf->width)
48 return;
49
50 filler = black_border ? 0xFF : 0;
51
52 /* Scroll row by row to minimize flicker (byte rows = 8 pixels each) */
53 for (by = 0; by < _graybuf->bheight; by++)
54 {
55 ptr = _graybuf->data + MULU16(_graybuf->width, by);
56 for (d = 0; d < _graybuf->depth; d++)
57 {
58 asm volatile (
59 "mov %0,r1 \n" /* check if both source... */
60 "or %2,r1 \n" /* ...and offset are even */
61 "shlr r1 \n" /* -> lsb = 0 */
62 "bf .sr_start2 \n" /* -> copy word-wise */
63
64 "add #-1,%2 \n" /* copy byte-wise */
65 ".sr_loop1: \n"
66 "mov.b @(%2,%0),r1 \n"
67 "mov.b r1,@-%0 \n"
68 "cmp/hi %1,%0 \n"
69 "bt .sr_loop1 \n"
70
71 "bra .sr_end \n"
72 "nop \n"
73
74 ".sr_start2: \n" /* copy word-wise */
75 "add #-2,%2 \n"
76 ".sr_loop2: \n"
77 "mov.w @(%2,%0),r1 \n"
78 "mov.w r1,@-%0 \n"
79 "cmp/hi %1,%0 \n"
80 "bt .sr_loop2 \n"
81
82 ".sr_end: \n"
83 : /* outputs */
84 : /* inputs */
85 /* %0 */ "r"(ptr + _graybuf->width),
86 /* %1 */ "r"(ptr + count),
87 /* %2 */ "z"(-count)
88 : /* clobbers */
89 "r1"
90 );
91
92 _gray_rb->memset(ptr, filler, count);
93 ptr += _graybuf->plane_size;
94 }
95 }
96}
97
98#endif // #ifdef HAVE_LCD_BITMAP
99#endif // #ifndef SIMULATOR
100
diff --git a/apps/plugins/lib/gray_scroll_up.c b/apps/plugins/lib/gray_scroll_up.c
deleted file mode 100644
index 4c493071af..0000000000
--- a/apps/plugins/lib/gray_scroll_up.c
+++ /dev/null
@@ -1,135 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_scroll_up() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#if CONFIG_LCD == LCD_SSD1815 /* only for Recorder/Ondio */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Scroll the whole grayscale buffer up by <count> pixels (<= 7)
34 ----------------------------------------------------------------------------
35 black_border determines if the pixels scrolled in at the bottom are black
36 or white
37
38 Scrolling up/down pixel-wise is significantly slower than scrolling
39 left/right or scrolling up/down byte-wise because it involves bit
40 shifting. That's why it is asm optimized.
41 */
42void gray_scroll_up(int count, bool black_border)
43{
44 unsigned filler;
45
46 if ((unsigned) count > 7)
47 return;
48
49 filler = black_border ? 0xFFu : 0;
50
51 /* scroll column by column to minimize flicker */
52 asm volatile (
53 "mov #0,r6 \n" /* x = 0 */
54 "mova .su_shifttbl,r0 \n" /* calculate jump destination for */
55 "mov.b @(r0,%6),%6 \n" /* shift amount from table */
56 "bra .su_cloop \n" /* skip table */
57 "add r0,%6 \n"
58
59 ".align 2 \n"
60 ".su_shifttbl: \n" /* shift jump offset table */
61 ".byte .su_shift0 - .su_shifttbl \n"
62 ".byte .su_shift1 - .su_shifttbl \n"
63 ".byte .su_shift2 - .su_shifttbl \n"
64 ".byte .su_shift3 - .su_shifttbl \n"
65 ".byte .su_shift4 - .su_shifttbl \n"
66 ".byte .su_shift5 - .su_shifttbl \n"
67 ".byte .su_shift6 - .su_shifttbl \n"
68 ".byte .su_shift7 - .su_shifttbl \n"
69
70 ".su_cloop: \n" /* repeat for every column */
71 "mov %1,r2 \n" /* get start address */
72 "mov #0,r3 \n" /* current_plane = 0 */
73
74 ".su_oloop: \n" /* repeat for every bitplane */
75 "mov r2,r4 \n" /* get start address */
76 "mov #0,r5 \n" /* current_row = 0 */
77 "mov %5,r1 \n" /* get filler bits */
78
79 ".su_iloop: \n" /* repeat for all rows */
80 "sub %2,r4 \n" /* address -= width */
81 "mov.b @r4,r0 \n" /* get data byte */
82 "shll8 r1 \n" /* old data to 2nd byte */
83 "extu.b r0,r0 \n" /* extend unsigned */
84 "or r1,r0 \n" /* combine old data */
85 "jmp @%6 \n" /* jump into shift "path" */
86 "extu.b r0,r1 \n" /* store data for next round */
87
88 ".su_shift6: \n" /* shift right by 0..7 bits */
89 "shlr2 r0 \n"
90 ".su_shift4: \n"
91 "shlr2 r0 \n"
92 ".su_shift2: \n"
93 "bra .su_shift0 \n"
94 "shlr2 r0 \n"
95 ".su_shift7: \n"
96 "shlr2 r0 \n"
97 ".su_shift5: \n"
98 "shlr2 r0 \n"
99 ".su_shift3: \n"
100 "shlr2 r0 \n"
101 ".su_shift1: \n"
102 "shlr r0 \n"
103 ".su_shift0: \n"
104
105 "mov.b r0,@r4 \n" /* store data */
106 "add #1,r5 \n" /* current_row++ */
107 "cmp/hi r5,%3 \n" /* current_row < bheight ? */
108 "bt .su_iloop \n"
109
110 "add %4,r2 \n" /* start_address += plane_size */
111 "add #1,r3 \n" /* current_plane++ */
112 "cmp/hi r3,%0 \n" /* current_plane < depth ? */
113 "bt .su_oloop \n"
114
115 "add #1,%1 \n" /* start_address++ */
116 "add #1,r6 \n" /* x++ */
117 "cmp/hi r6,%2 \n" /* x < width ? */
118 "bt .su_cloop \n"
119 : /* outputs */
120 : /* inputs */
121 /* %0 */ "r"(_graybuf->depth),
122 /* %1 */ "r"(_graybuf->data + _graybuf->plane_size),
123 /* %2 */ "r"(_graybuf->width),
124 /* %3 */ "r"(_graybuf->bheight),
125 /* %4 */ "r"(_graybuf->plane_size),
126 /* %5 */ "r"(filler),
127 /* %6 */ "r"(count)
128 : /* clobbers */
129 "r0", "r1", "r2", "r3", "r4", "r5", "r6"
130 );
131}
132
133#endif // #ifdef HAVE_LCD_BITMAP
134#endif // #ifndef SIMULATOR
135
diff --git a/apps/plugins/lib/gray_scroll_up8.c b/apps/plugins/lib/gray_scroll_up8.c
deleted file mode 100644
index b181673f22..0000000000
--- a/apps/plugins/lib/gray_scroll_up8.c
+++ /dev/null
@@ -1,69 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_scroll_up8() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Scroll the whole grayscale buffer up by 8 pixels
34 ----------------------------------------------------------------------------
35 black_border determines if the pixels scrolled in at the bottom are black
36 or white
37
38 Scrolling up/down by 8 pixels is very fast.
39 */
40void gray_scroll_up8(bool black_border)
41{
42 int by, d;
43 unsigned filler;
44 unsigned char *ptr;
45
46 filler = black_border ? 0xFF : 0;
47
48 /* Scroll row by row to minimize flicker (byte rows = 8 pixels each) */
49 for (by = 1; by < _graybuf->bheight; by++)
50 {
51 ptr = _graybuf->data + MULU16(_graybuf->width, by);
52 for (d = 0; d < _graybuf->depth; d++)
53 {
54 _gray_rb->memcpy(ptr - _graybuf->width, ptr, _graybuf->width);
55 ptr += _graybuf->plane_size;
56 }
57 }
58 /* fill last row */
59 ptr = _graybuf->data + _graybuf->plane_size - _graybuf->width;
60 for (d = 0; d < _graybuf->depth; d++)
61 {
62 _gray_rb->memset(ptr, filler, _graybuf->width);
63 ptr += _graybuf->plane_size;
64 }
65}
66
67#endif // #ifdef HAVE_LCD_BITMAP
68#endif // #ifndef SIMULATOR
69
diff --git a/apps/plugins/lib/gray_set_background.c b/apps/plugins/lib/gray_set_background.c
deleted file mode 100644
index c78e9ff112..0000000000
--- a/apps/plugins/lib/gray_set_background.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_set_background() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Set the background shade for subsequent drawing operations
34 ----------------------------------------------------------------------------
35 brightness = 0 (black) .. 255 (white)
36
37 Default after initialization: 255
38 */
39void gray_set_background(int brightness)
40{
41 if ((unsigned) brightness <= 255)
42 _graybuf->bg_pattern = _graybuf->bitpattern[MULU16(brightness,
43 _graybuf->depth + 1) >> 8];
44}
45
46#endif // #ifdef HAVE_LCD_BITMAP
47#endif // #ifndef SIMULATOR
48
diff --git a/apps/plugins/lib/gray_set_drawinfo.c b/apps/plugins/lib/gray_set_drawinfo.c
deleted file mode 100644
index 59928882d7..0000000000
--- a/apps/plugins/lib/gray_set_drawinfo.c
+++ /dev/null
@@ -1,49 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_set_drawinfo() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Set draw mode, foreground and background shades at once
34 ----------------------------------------------------------------------------
35 If you hand it -1 (or in fact any other out-of-bounds value) for a
36 parameter, that particular setting won't be changed
37
38 Default after initialization: GRAY_DRAW_SOLID, 0, 255
39 */
40void gray_set_drawinfo(int drawmode, int fg_brightness, int bg_brightness)
41{
42 gray_set_drawmode(drawmode);
43 gray_set_foreground(fg_brightness);
44 gray_set_background(bg_brightness);
45}
46
47#endif // #ifdef HAVE_LCD_BITMAP
48#endif // #ifndef SIMULATOR
49
diff --git a/apps/plugins/lib/gray_set_drawmode.c b/apps/plugins/lib/gray_set_drawmode.c
deleted file mode 100644
index 969b99894f..0000000000
--- a/apps/plugins/lib/gray_set_drawmode.c
+++ /dev/null
@@ -1,52 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_set_drawmode() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Set the draw mode for subsequent drawing operations
34 ----------------------------------------------------------------------------
35 drawmode =
36 GRAY_DRAW_INVERSE: Foreground pixels are inverted, background pixels are
37 left untouched
38 GRAY_DRAW_FG: Only foreground pixels are drawn
39 GRAY_DRAW_BG: Only background pixels are drawn
40 GRAY_DRAW_SOLID: Foreground and background pixels are drawn
41
42 Default after initialization: GRAY_DRAW_SOLID
43 */
44void gray_set_drawmode(int drawmode)
45{
46 if ((unsigned) drawmode <= GRAY_DRAW_SOLID)
47 _graybuf->drawmode = drawmode;
48}
49
50#endif // #ifdef HAVE_LCD_BITMAP
51#endif // #ifndef SIMULATOR
52
diff --git a/apps/plugins/lib/gray_set_foreground.c b/apps/plugins/lib/gray_set_foreground.c
deleted file mode 100644
index afde64f645..0000000000
--- a/apps/plugins/lib/gray_set_foreground.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_set_foreground() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Set the foreground shade for subsequent drawing operations
34 ----------------------------------------------------------------------------
35 brightness = 0 (black) .. 255 (white)
36
37 Default after initialization: 0
38 */
39void gray_set_foreground(int brightness)
40{
41 if ((unsigned) brightness <= 255)
42 _graybuf->fg_pattern = _graybuf->bitpattern[MULU16(brightness,
43 _graybuf->depth + 1) >> 8];
44}
45
46#endif // #ifdef HAVE_LCD_BITMAP
47#endif // #ifndef SIMULATOR
48
diff --git a/apps/plugins/lib/gray_setfont.c b/apps/plugins/lib/gray_setfont.c
deleted file mode 100644
index 714a1f5b17..0000000000
--- a/apps/plugins/lib/gray_setfont.c
+++ /dev/null
@@ -1,47 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11*
12* This is a generic framework to use grayscale display within Rockbox
13* plugins. It obviously does not work for the player.
14*
15* Copyright (C) 2004 Jens Arnold
16* gray_setfont() function
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Set font for the font routines
34 ----------------------------------------------------------------------------
35 newfont can be FONT_SYSFIXED or FONT_UI the same way as with the Rockbox
36 core routines
37
38 Default after initialization: FONT_SYSFIXED
39 */
40void gray_setfont(int newfont)
41{
42 _graybuf->curfont = _gray_rb->font_get(newfont);
43}
44
45#endif // #ifdef HAVE_LCD_BITMAP
46#endif // #ifndef SIMULATOR
47
diff --git a/apps/plugins/lib/gray_verline.c b/apps/plugins/lib/gray_verline.c
deleted file mode 100644
index 15910b41cf..0000000000
--- a/apps/plugins/lib/gray_verline.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Grayscale framework
11* gray_verline() function
12*
13* This is a generic framework to use grayscale display within Rockbox
14* plugins. It obviously does not work for the player.
15*
16* Copyright (C) 2004 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#ifndef SIMULATOR /* not for simulator by now */
27#include "plugin.h"
28
29#ifdef HAVE_LCD_BITMAP /* and also not for the Player */
30#include "gray.h"
31
32/*---------------------------------------------------------------------------
33 Draw a vertical line from (x, y1) to (x, y2) with the current drawinfo
34 ----------------------------------------------------------------------------
35 See gray_drawpixel() for details
36 This one uses the block drawing optimization, so it is rather fast.
37 */
38void gray_verline(int x, int y1, int y2)
39{
40 int shift, y, ny;
41 unsigned bits, mask_top, mask_bottom;
42 unsigned char *dst;
43 void (*blockfunc)(unsigned char *address, unsigned mask, unsigned bits);
44
45 if ((unsigned) x >= (unsigned) _graybuf->width
46 || (unsigned) y1 >= (unsigned) _graybuf->height
47 || (unsigned) y2 >= (unsigned) _graybuf->height)
48 return;
49
50 if (y1 > y2)
51 {
52 y = y1;
53 y1 = y2;
54 y2 = y;
55 }
56 y = y1;
57 ny = y2 - y1 + 1;
58
59 dst = _graybuf->data + x + MULU16(_graybuf->width, y >> 3);
60 shift = y & 7;
61 ny += shift;
62
63 mask_top = 0xFFu << (y & 7);
64 mask_bottom = ~(0xFEu << ((ny - 1) & 7));
65 if (ny <= 8)
66 mask_bottom &= mask_top;
67
68 blockfunc = _gray_blockfuncs[_graybuf->drawmode];
69 bits = (_graybuf->drawmode == GRAY_DRAW_BG) ? 0u : 0xFFu;
70
71 if (ny > 8)
72 {
73 blockfunc(dst, mask_top, bits);
74 dst += _graybuf->width;
75
76 for (y = 8; y < ny - 8; y += 8)
77 {
78 blockfunc(dst, 0xFFu, bits);
79 dst += _graybuf->width;
80 }
81 }
82
83 blockfunc(dst, mask_bottom, bits);
84}
85
86#endif // #ifdef HAVE_LCD_BITMAP
87#endif // #ifndef SIMULATOR
88
diff --git a/apps/plugins/mandelbrot.c b/apps/plugins/mandelbrot.c
index bb96b9b71c..1037212b15 100644
--- a/apps/plugins/mandelbrot.c
+++ b/apps/plugins/mandelbrot.c
@@ -94,7 +94,7 @@ void calc_mandelbrot_set(void){
94 94
95 start_tick = last_yield = *rb->current_tick; 95 start_tick = last_yield = *rb->current_tick;
96 96
97 gray_clear_display(); 97 gray_ub_clear_display();
98 98
99 x_fact = (x_max - x_min) / LCD_WIDTH; 99 x_fact = (x_max - x_min) / LCD_WIDTH;
100 y_fact = (y_max - y_min) / LCD_HEIGHT; 100 y_fact = (y_max - y_min) / LCD_HEIGHT;
@@ -124,7 +124,7 @@ void calc_mandelbrot_set(void){
124 if (n_iter > max_iter){ 124 if (n_iter > max_iter){
125 brightness = 0; // black 125 brightness = 0; // black
126 } else { 126 } else {
127 brightness = 255 - (31 * (n_iter & 7)); 127 brightness = 255 - (32 * (n_iter & 7));
128 } 128 }
129 graybuffer[y_pixel]=brightness; 129 graybuffer[y_pixel]=brightness;
130 /* be nice to other threads: 130 /* be nice to other threads:
@@ -134,7 +134,7 @@ void calc_mandelbrot_set(void){
134 last_yield = *rb->current_tick; 134 last_yield = *rb->current_tick;
135 } 135 }
136 } 136 }
137 gray_drawgraymap(graybuffer, x_pixel, 0, 1, LCD_HEIGHT, 1); 137 gray_ub_gray_bitmap(graybuffer, x_pixel, 0, 1, LCD_HEIGHT);
138 } 138 }
139} 139}
140 140
@@ -142,7 +142,7 @@ void cleanup(void *parameter)
142{ 142{
143 (void)parameter; 143 (void)parameter;
144 144
145 gray_release_buffer(); 145 gray_release();
146} 146}
147 147
148enum plugin_status plugin_start(struct plugin_api* api, void* parameter) 148enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
@@ -156,17 +156,14 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
156 rb = api; 156 rb = api;
157 (void)parameter; 157 (void)parameter;
158 158
159 /* This plugin uses the grayscale framework, so initialize */
160 gray_init(api);
161
162 /* get the remainder of the plugin buffer */ 159 /* get the remainder of the plugin buffer */
163 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size); 160 gbuf = (unsigned char *) rb->plugin_get_buffer(&gbuf_size);
164 161
165 /* initialize the grayscale buffer: 162 /* initialize the grayscale buffer:
166 * 112 pixels wide, 8 rows (64 pixels) high, (try to) reserve 163 * 112 pixels wide, 8 rows (64 pixels) high, (try to) reserve
167 * 16 bitplanes for 17 shades of gray.*/ 164 * 16 bitplanes for 17 shades of gray.*/
168 grayscales = gray_init_buffer(gbuf, gbuf_size, 112, 8, 16, NULL) + 1; 165 grayscales = gray_init(rb, gbuf, gbuf_size, false, 112, 8, 8, NULL) + 1;
169 if (grayscales != 17){ 166 if (grayscales != 9){
170 rb->snprintf(buff, sizeof(buff), "%d", grayscales); 167 rb->snprintf(buff, sizeof(buff), "%d", grayscales);
171 rb->lcd_puts(0, 1, buff); 168 rb->lcd_puts(0, 1, buff);
172 rb->lcd_update(); 169 rb->lcd_update();
@@ -174,7 +171,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
174 return(0); 171 return(0);
175 } 172 }
176 173
177 gray_show_display(true); /* switch on grayscale overlay */ 174 gray_show(true); /* switch on greyscale overlay */
178 175
179 init_mandelbrot_set(); 176 init_mandelbrot_set();
180 lcd_aspect_ratio = ((LCD_WIDTH<<13) / LCD_HEIGHT)<<13; 177 lcd_aspect_ratio = ((LCD_WIDTH<<13) / LCD_HEIGHT)<<13;
@@ -189,7 +186,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
189 button = rb->button_get(true); 186 button = rb->button_get(true);
190 switch (button) { 187 switch (button) {
191 case MANDELBROT_QUIT: 188 case MANDELBROT_QUIT:
192 gray_release_buffer(); 189 gray_release();
193 return PLUGIN_OK; 190 return PLUGIN_OK;
194 191
195 case MANDELBROT_ZOOM_OUT: 192 case MANDELBROT_ZOOM_OUT:
@@ -270,7 +267,7 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
270 if (button != BUTTON_NONE) 267 if (button != BUTTON_NONE)
271 lastbutton = button; 268 lastbutton = button;
272 } 269 }
273 gray_release_buffer(); 270 gray_release();
274 return PLUGIN_OK; 271 return PLUGIN_OK;
275} 272}
276#endif 273#endif