1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * New greyscale framework
13 * This is a generic framework to display 129 shades of grey on low-depth
14 * bitmap LCDs (Archos b&w, Iriver & Ipod 4-grey) within plugins.
16 * Copyright (C) 2008 Jens Arnold
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License
20 * as published by the Free Software Foundation; either version 2
21 * of the License, or (at your option) any later version.
23 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
24 * KIND, either express or implied.
26 ****************************************************************************/
31 /* Default greylib viewport struct */
32 struct viewport _grey_default_vp
;
34 /* Set position of the top left corner of the greyscale overlay
35 Note that depending on the target LCD, either x or y gets rounded
36 to the nearest multiple of 4 or 8 */
37 void grey_set_position(int x
, int y
)
39 #if LCD_PIXELFORMAT == HORIZONTAL_PACKING
40 _grey_info
.bx
= (x
+ 4) >> 3;
41 x
= 8 * _grey_info
.bx
;
42 #else /* vertical packing or vertical interleaved */
43 #if (LCD_DEPTH == 1) || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED)
44 _grey_info
.by
= (y
+ 4) >> 3;
45 y
= 8 * _grey_info
.by
;
47 _grey_info
.by
= (y
+ 2) >> 2;
48 y
= 4 * _grey_info
.by
;
50 #endif /* LCD_PIXELFORMAT */
54 if (_grey_info
.flags
& _GREY_RUNNING
)
57 rb
->sim_lcd_ex_update_rect(_grey_info
.x
, _grey_info
.y
,
60 grey_deferred_lcd_update();
62 _grey_info
.flags
|= _GREY_DEFERRED_UPDATE
;
67 /* Set the draw mode for subsequent drawing operations */
68 void grey_set_drawmode(int mode
)
70 _grey_info
.vp
->drawmode
= mode
& (DRMODE_SOLID
|DRMODE_INVERSEVID
);
73 /* Return the current draw mode */
74 int grey_get_drawmode(void)
76 return _grey_info
.vp
->drawmode
;
79 /* Set the foreground shade for subsequent drawing operations */
80 void grey_set_foreground(unsigned brightness
)
82 _GREY_FG_BRIGHTNESS(_grey_info
.vp
) = brightness
;
85 /* Return the current foreground shade */
86 unsigned grey_get_foreground(void)
88 return _GREY_FG_BRIGHTNESS(_grey_info
.vp
);
91 /* Set the background shade for subsequent drawing operations */
92 void grey_set_background(unsigned brightness
)
94 _GREY_BG_BRIGHTNESS(_grey_info
.vp
) = brightness
;
97 /* Return the current background shade */
98 unsigned grey_get_background(void)
100 return _GREY_BG_BRIGHTNESS(_grey_info
.vp
);
103 /* Set draw mode, foreground and background shades at once */
104 void grey_set_drawinfo(int mode
, unsigned fg_brightness
, unsigned bg_brightness
)
106 grey_set_drawmode(mode
);
107 grey_set_foreground(fg_brightness
);
108 grey_set_background(bg_brightness
);
111 /* Set font for the text output routines */
112 void grey_setfont(int newfont
)
114 _grey_info
.vp
->font
= newfont
;
117 /* Get width and height of a text when printed with the current font */
118 int grey_getstringsize(const unsigned char *str
, int *w
, int *h
)
120 return rb
->font_getstringsize(str
, w
, h
, _grey_info
.vp
->font
);
123 /* Helper to establish visible area between viewport and framebuffer */
124 static void grey_update_clip_rect(void)
126 if (!(_grey_info
.flags
& GREY_BUFFERED
))
127 return; /* no chunky buffer */
129 struct viewport
*vp
= _grey_info
.vp
;
131 if (!vp
|| !_grey_info
.curbuffer
)
134 /* Get overall intersection of framebuffer and viewport in viewport
135 coordinates so that later clipping of drawing is kept as simple as
136 possible. If l <= r and/or b <= t after intersecting, draw routines
137 will see this as an empty area. */
138 _grey_info
.clip_l
= _grey_info
.cb_x
- vp
->x
;
139 _grey_info
.clip_t
= _grey_info
.cb_y
- vp
->y
;
140 _grey_info
.clip_r
= _grey_info
.clip_l
+ _grey_info
.cb_width
;
141 _grey_info
.clip_b
= _grey_info
.clip_t
+ _grey_info
.cb_height
;
143 if (_grey_info
.clip_l
< 0)
144 _grey_info
.clip_l
= 0;
146 if (_grey_info
.clip_t
< 0)
147 _grey_info
.clip_t
= 0;
149 if (_grey_info
.clip_r
> vp
->width
)
150 _grey_info
.clip_r
= vp
->width
;
152 if (_grey_info
.clip_b
> vp
->height
)
153 _grey_info
.clip_b
= vp
->height
;
156 /* Set current grey viewport for draw routines */
157 void grey_set_viewport(struct viewport
*vp
)
160 vp
= &_grey_default_vp
;
162 if (_grey_info
.vp
!= vp
)
165 grey_update_clip_rect();
169 /* Set viewport to default settings */
170 void grey_viewport_set_fullscreen(struct viewport
*vp
,
171 const enum screen_type screen
)
174 vp
= &_grey_default_vp
;
178 vp
->width
= _grey_info
.width
;
179 vp
->height
= _grey_info
.height
;
180 _GREY_FG_BRIGHTNESS(vp
) = 0;
181 _GREY_BG_BRIGHTNESS(vp
) = 255;
182 vp
->drawmode
= DRMODE_SOLID
;
183 vp
->font
= FONT_SYSFIXED
;
185 if (vp
== _grey_info
.vp
)
186 grey_update_clip_rect(); /* is current one in use */
191 void grey_viewport_set_pos(struct viewport
*vp
,
192 int x
, int y
, int width
, int height
)
194 if (vp
== NULL
|| vp
== &_grey_default_vp
)
195 return; /* Cannot be moved or resized */
198 width
= 0; /* 'tis okay */
208 if (vp
== _grey_info
.vp
)
209 grey_update_clip_rect(); /* is current one in use */
212 /* Set current grey chunky buffer for draw routines */
213 void grey_set_framebuffer(unsigned char *buffer
)
215 if (!(_grey_info
.flags
& GREY_BUFFERED
))
216 return; /* no chunky buffer */
219 buffer
= _grey_info
.buffer
; /* Default */
221 if (buffer
!= _grey_info
.curbuffer
)
223 _grey_info
.curbuffer
= buffer
;
225 if (buffer
== _grey_info
.buffer
)
227 /* Setting to default fb resets dimensions */
228 grey_framebuffer_set_pos(0, 0, 0, 0);
233 /* Specify the dimensions of the current framebuffer */
234 void grey_framebuffer_set_pos(int x
, int y
, int width
, int height
)
236 if (!(_grey_info
.flags
& GREY_BUFFERED
))
237 return; /* no chunky buffer */
239 if (_grey_info
.curbuffer
== _grey_info
.buffer
)
241 /* This cannot be moved or resized */
244 width
= _grey_info
.width
;
245 height
= _grey_info
.height
;
247 else if (width
<= 0 || height
<= 0)
250 if (x
== _grey_info
.cb_x
&& y
== _grey_info
.cb_y
&&
251 width
== _grey_info
.cb_width
&& height
== _grey_info
.cb_height
)
252 return; /* No change */
256 _grey_info
.cb_width
= width
;
257 _grey_info
.cb_height
= height
;
259 grey_update_clip_rect();