summaryrefslogtreecommitdiff
path: root/apps/plugins/lib/gray.h
blob: 18be88a2f2e671fac6e0027fb54b5878c059a603 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
/***************************************************************************
*             __________               __   ___.
*   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
*   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
*   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
*   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
*                     \/            \/     \/    \/            \/
* $Id$
*
* Grayscale framework
*
* This is a generic framework to use grayscale display within Rockbox
* plugins. It obviously does not work for the player.
*
* Copyright (C) 2004 Jens Arnold
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/

#ifndef __GRAY_H__
#define __GRAY_H__

#ifndef SIMULATOR /* not for simulator by now */
#include "plugin.h"

#ifdef HAVE_LCD_BITMAP /* and also not for the Player */

/* Initialize the framework
 *
 * every framework needs such a function, and it has to be called as
 * the very first one 
 */
void gray_init(struct plugin_api* newrb);

/**** general functions ****/

/* Prepare the grayscale display buffer
 *
 * arguments:
 *   gbuf      = pointer to the memory area to use (e.g. plugin buffer)
 *   gbuf_size = max usable size of the buffer
 *   width     = width in pixels  (1..112)
 *   bheight   = height in 8-pixel units  (1..8)
 *   depth     = desired number of shades - 1  (1..32)
 *
 * result:
 *   = depth  if there was enough memory
 *   < depth  if there wasn't enough memory. The number of displayable
 *            shades is smaller than desired, but it still works
 *   = 0      if there wasn't even enough memory for 1 bitplane (black & white)
 *
 * You can request any depth from 1 to 32, not just powers of 2. The routine
 * performs "graceful degradation" if the memory is not sufficient for the
 * desired depth. As long as there is at least enough memory for 1 bitplane,
 * it creates as many bitplanes as fit into memory, although 1 bitplane will
 * only deliver black & white display.
 *
 * If you need info about the memory taken by the grayscale buffer, supply an
 * int* as the last parameter. This int will then contain the number of bytes
 * used. The total memory needed can be calculated as follows:
 *   total_mem =
 *     sizeof(tGraybuf)      (= 64 bytes currently)
 *   + sizeof(long)          (=  4 bytes)
 *   + (width * bheight + sizeof(long)) * depth
 *   + 0..3                  (longword alignment of grayscale display buffer)
 */
int gray_init_buffer(unsigned char *gbuf, int gbuf_size, int width,
                     int bheight, int depth, int *buf_taken);
                     
/* Release the grayscale display buffer
 *
 * Switches the grayscale overlay off at first if it is still running,
 * then sets the pointer to NULL.
 * DO CALL either this function or at least gray_show_display(false)
 * before you exit, otherwise nasty things may happen.
 */
void gray_release_buffer(void);

/* Set position of the top left corner of the grayscale overlay
 *
 *   x  = left margin in pixels
 *   by = top margin in 8-pixel units
 *
 * You may set this in a way that the overlay spills across the right or
 * bottom display border. In this case it will simply be clipped by the 
 * LCD controller. You can even set negative values, this will clip at the
 * left or top border. I did not test it, but the limits may be +127 / -128
 *
 * If you use this while the grayscale overlay is running, the now-freed area
 * will be restored.
 */
void gray_position_display(int x, int by);

/* Switch the grayscale overlay on or off
 *
 *   enable = true:  the grayscale overlay is switched on if initialized
 *          = false: the grayscale overlay is switched off and the regular lcd
 *                   content is restored
 *
 * DO NOT call lcd_update() or any other api function that directly accesses
 * the lcd while the grayscale overlay is running! If you need to do
 * lcd_update() to update something outside the grayscale overlay area, use 
 * gray_deferred_update() instead.
 *
 * Other functions to avoid are:
 *   lcd_blit() (obviously), lcd_update_rect(), lcd_set_contrast(),
 *   lcd_set_invert_display(), lcd_set_flip(), lcd_roll()
 *
 * The grayscale display consumes ~50 % CPU power (for a full screen overlay,
 * less if the overlay is smaller) when switched on. You can switch the overlay
 * on and off as many times as you want.
 */
void gray_show_display(bool enable);

/* Set the draw mode for subsequent drawing operations
 *
 *   drawmode =
 *     GRAY_DRAW_INVERSE: Foreground pixels are inverted, background pixels are
 *                        left untouched
 *     GRAY_DRAW_FG:      Only foreground pixels are drawn
 *     GRAY_DRAW_BG:      Only background pixels are drawn
 *     GRAY_DRAW_SOLID:   Foreground and background pixels are drawn
 */
void gray_set_drawmode(int drawmode);

/* Draw modes */
#define GRAY_DRAW_INVERSE 0
#define GRAY_DRAW_FG      1
#define GRAY_DRAW_BG      2
#define GRAY_DRAW_SOLID   3

/* Set the foreground shade for subsequent drawing operations
 *
 * brightness = 0 (black) .. 255 (white)
 */
void gray_set_foreground(int brightness);

/* Set the background shade for subsequent drawing operations
 *
 * brightness = 0 (black) .. 255 (white)
 */
void gray_set_background(int brightness);

/* Set draw mode, foreground and background shades at once
 * 
 * If you hand it -1 (or in fact any other out-of-bounds value) for a
 * parameter, that particular setting won't be changed
 */
void gray_set_drawinfo(int drawmode, int fg_brightness, int bg_brightness);

/**** functions affecting the whole display ****/

/* Clear the grayscale display (sets all pixels to white) */
void gray_clear_display(void);

/* Set the grayscale display to all black */
void gray_black_display(void);

/* Do an lcd_update() to show changes done by rb->lcd_xxx() functions (in areas
 * of the screen not covered by the grayscale overlay).
 *
 * If the grayscale overlay is running, the update will be done in the next
 * call of the interrupt routine, otherwise it will be performed right away.
 * See also comment for the gray_show_display() function.
 */
void gray_deferred_update(void);

/**** Scrolling functions ****/

/* Scroll the whole grayscale buffer left by <count> pixels
 *
 * black_border determines if the pixels scrolled in at the right are black
 * or white
 *
 * Scrolling left/right by an even pixel count is almost twice as fast as
 * scrolling by an odd pixel count.
 */
void gray_scroll_left(int count, bool black_border);

/* Scroll the whole grayscale buffer right by <count> pixels
 *
 * black_border determines if the pixels scrolled in at the left are black
 * or white
 *
 * Scrolling left/right by an even pixel count is almost twice as fast as
 * scrolling by an odd pixel count.
 */
void gray_scroll_right(int count, bool black_border);

/* Scroll the whole grayscale buffer up by 8 pixels
 *
 * black_border determines if the pixels scrolled in at the bottom are black
 * or white
 *
 * Scrolling up/down by 8 pixels is very fast.
 */
void gray_scroll_up8(bool black_border);

/* Scroll the whole grayscale buffer down by 8 pixels
 *
 * black_border determines if the pixels scrolled in at the top are black
 * or white
 *
 * Scrolling up/down by 8 pixels is very fast.
 */
void gray_scroll_down8(bool black_border);

/* Scroll the whole grayscale buffer up by <count> pixels (<= 7)
 *
 * black_border determines if the pixels scrolled in at the bottom are black
 * or white
 *
 * Scrolling up/down pixel-wise is significantly slower than scrolling
 * left/right or scrolling up/down byte-wise because it involves bit
 * shifting. That's why it is asm optimized.
 */
void gray_scroll_up(int count, bool black_border);

/* Scroll the whole grayscale buffer down by <count> pixels (<= 7)
 *
 * black_border determines if the pixels scrolled in at the top are black
 * or white
 *
 * Scrolling up/down pixel-wise is significantly slower than scrolling
 * left/right or scrolling up/down byte-wise because it involves bit
 * shifting. That's why it is asm optimized.
 */
void gray_scroll_down(int count, bool black_border);

/**** Pixel and line functions ****/

/* Set a pixel with the current drawinfo
 * 
 * If the drawmode is GRAY_DRAW_INVERSE, the pixel is inverted
 * GRAY_DRAW_FG and GRAY_DRAW_SOLID draw the pixel in the foreground shade
 * GRAY_DRAW_BG draws the pixel in the background shade
 */
void gray_drawpixel(int x, int y);

/* Draw a line from (x1, y1) to (x2, y2) with the current drawinfo,
 * See gray_drawpixel() for details
 */
void gray_drawline(int x1, int y1, int x2, int y2);

/* Draw a horizontal line from (x1, y) to (x2, y) with the current drawinfo,
 * See gray_drawpixel() for details
 */
void gray_horline(int x1, int x2, int y);

/* Draw a vertical line from (x, y1) to (x, y2) with the current drawinfo,
 * See gray_drawpixel() for details
 *
 * This one uses the block drawing optimization, so it is rather fast.
 */
void gray_verline(int x, int y1, int y2);

/**** Rectangle functions ****/

/* Draw a (hollow) rectangle with the current drawinfo,
 * See gray_drawpixel() for details
 */
void gray_drawrect(int x, int y, int nx, int ny);

/* Draw a filled rectangle with the current drawinfo,
 * See gray_drawpixel() for details
 *
 * This one uses the block drawing optimization, so it is rather fast.
 */
void gray_fillrect(int x, int y, int nx, int ny);

/**** Bitmap functions ****/

/* Copy a grayscale bitmap into the display
 * 
 * A grayscale bitmap contains one byte for every pixel that defines the
 * brightness of the pixel (0..255). Bytes are read in row-major order.
 * The <stride> parameter is useful if you want to show only a part of a
 * bitmap. It should always be set to the "row length" of the bitmap, so
 * for displaying the whole bitmap, nx == stride.
 *
 * This is the only drawing function NOT using the drawinfo.
 */
void gray_drawgraymap(unsigned char *src, int x, int y, int nx, int ny,
                      int stride);

/* Display a bitmap with the current drawinfo
 *
 * The drawmode is used as described for gray_set_drawmode()
 *
 * This (now) uses the same bitmap format as the core b&w graphics routines,
 * so you can use bmp2rb to generate bitmaps for use with this function as
 * well.
 *
 * A bitmap contains one bit for every pixel that defines if that pixel is
 * foreground (1) or background (0). Bits within a byte are arranged
 * vertically, LSB at top.
 * The bytes are stored in row-major order, with byte 0 being top left,
 * byte 1 2nd from left etc. The first row of bytes defines pixel rows
 * 0..7, the second row defines pixel row 8..15 etc.
 *
 * The <stride> parameter is useful if you want to show only a part of a
 * bitmap. It should always be set to the "row length" of the bitmap.
 */
void gray_drawbitmap(unsigned char *src, int x, int y, int nx, int ny,
                     int stride);

/**** Font support ****/

/* Set font for the font routines
 * 
 * newfont can be FONT_SYSFIXED or FONT_UI the same way as with the Rockbox
 * core routines
 */
void gray_setfont(int newfont);

/* Calculate width and height of the given text in pixels when rendered with
 * the currently selected font.
 *
 * This works exactly the same way as the core lcd_getstringsize(), only that
 * it uses the selected font for grayscale.
 */
int gray_getstringsize(unsigned char *str, int *w, int *h);

/* Display text starting at (x, y) with the current font and drawinfo
 *
 * The drawmode is used as described for gray_set_drawmode()
 */
void gray_putsxy(int x, int y, unsigned char *str);

#endif /* HAVE_LCD_BITMAP */
#endif /* SIMULATOR */
#endif /* __GRAY_H__ */