summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2007-04-06 11:20:39 +0000
committerJens Arnold <amiconn@rockbox.org>2007-04-06 11:20:39 +0000
commit60b99811eb785d67b1bd340ea38dedfa466cb8cd (patch)
tree9e4c812cfe6783aa2a6494d3d8eb821598a84cd0 /firmware/drivers
parent4303ab02a3efbd6a77e809641617c53082f9366f (diff)
downloadrockbox-60b99811eb785d67b1bd340ea38dedfa466cb8cd.tar.gz
rockbox-60b99811eb785d67b1bd340ea38dedfa466cb8cd.zip
Player: Only use one software definable character for different characters using the same glyph. * Some cleanup.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13043 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/lcd-charcell.c91
1 files changed, 46 insertions, 45 deletions
diff --git a/firmware/drivers/lcd-charcell.c b/firmware/drivers/lcd-charcell.c
index 3c8db1ae97..8219a0b317 100644
--- a/firmware/drivers/lcd-charcell.c
+++ b/firmware/drivers/lcd-charcell.c
@@ -26,7 +26,6 @@
26#include <string.h> 26#include <string.h>
27#include <stdlib.h> 27#include <stdlib.h>
28#include "file.h" 28#include "file.h"
29#include "debug.h"
30#include "system.h" 29#include "system.h"
31#include "lcd-charcell.h" 30#include "lcd-charcell.h"
32#include "rbunicode.h" 31#include "rbunicode.h"
@@ -35,6 +34,8 @@
35 34
36#define SCROLLABLE_LINES LCD_HEIGHT 35#define SCROLLABLE_LINES LCD_HEIGHT
37#define VARIABLE_XCHARS 16 /* number of software user-definable characters */ 36#define VARIABLE_XCHARS 16 /* number of software user-definable characters */
37/* There must be mappings for this many characters in the 0xe000 unicode range
38 * in lcd-charset-<target>.c */
38 39
39#define NO_PATTERN (-1) 40#define NO_PATTERN (-1)
40 41
@@ -42,8 +43,8 @@ static int find_xchar(unsigned long ucs);
42 43
43/** globals **/ 44/** globals **/
44 45
45/* The "frame"buffer */ 46unsigned char lcd_charbuffer[LCD_HEIGHT][LCD_WIDTH]; /* The "frame"buffer */
46unsigned char lcd_charbuffer[LCD_HEIGHT][LCD_WIDTH]; 47static unsigned char lcd_substbuffer[LCD_HEIGHT][LCD_WIDTH];
47struct pattern_info lcd_patterns[MAX_HW_PATTERNS]; 48struct pattern_info lcd_patterns[MAX_HW_PATTERNS];
48struct cursor_info lcd_cursor; 49struct cursor_info lcd_cursor;
49 50
@@ -141,44 +142,30 @@ static int find_xchar(unsigned long ucs)
141 return xchar_info_size - 1; 142 return xchar_info_size - 1;
142} 143}
143 144
144static int xchar_to_pat(int xchar) 145static int glyph_to_pat(unsigned glyph)
145{ 146{
146 int i; 147 int i;
147 148
148 for (i = 0; i < lcd_pattern_count; i++) 149 for (i = 0; i < lcd_pattern_count; i++)
149 if (lcd_patterns[i].xchar == xchar) 150 if (lcd_patterns[i].glyph == glyph)
150 return i; 151 return i;
151 152
152 return NO_PATTERN; 153 return NO_PATTERN;
153} 154}
154 155
155static const unsigned char *xchar_to_glyph(int xchar) 156static void lcd_free_pat(int pat)
156{
157 unsigned index = xchar_info[xchar].glyph;
158
159 if (index & 0x8000)
160 return xfont_variable[index & 0x7fff];
161 else
162 return xfont_fixed[index];
163}
164
165static void lcd_free_pat(int xchar)
166{ 157{
167 int x, y; 158 int x, y;
168 unsigned char substitute;
169 int pat = xchar_to_pat(xchar);
170 159
171 if (pat != NO_PATTERN) 160 if (pat != NO_PATTERN)
172 { 161 {
173 substitute = xchar_info[xchar].hw_char;
174
175 for (x = 0; x < LCD_WIDTH; x++) 162 for (x = 0; x < LCD_WIDTH; x++)
176 for (y = 0; y < LCD_HEIGHT; y++) 163 for (y = 0; y < LCD_HEIGHT; y++)
177 if (pat == lcd_charbuffer[y][x]) 164 if (pat == lcd_charbuffer[y][x])
178 lcd_charbuffer[y][x] = substitute; 165 lcd_charbuffer[y][x] = lcd_substbuffer[y][x];
179 166
180 if (lcd_cursor.enabled && pat == lcd_cursor.hw_char) 167 if (lcd_cursor.enabled && pat == lcd_cursor.hw_char)
181 lcd_cursor.hw_char = substitute; 168 lcd_cursor.hw_char = lcd_cursor.subst_char;
182 169
183 lcd_patterns[pat].count = 0; 170 lcd_patterns[pat].count = 0;
184 } 171 }
@@ -190,7 +177,7 @@ static int lcd_get_free_pat(int xchar)
190 177
191 int pat = last_used_pat; /* start from last used pattern */ 178 int pat = last_used_pat; /* start from last used pattern */
192 int least_pat = pat; /* pattern with least priority */ 179 int least_pat = pat; /* pattern with least priority */
193 int least_priority = xchar_info[lcd_patterns[pat].xchar].priority; 180 int least_priority = lcd_patterns[pat].priority;
194 int i; 181 int i;
195 182
196 for (i = 0; i < lcd_pattern_count; i++) 183 for (i = 0; i < lcd_pattern_count; i++)
@@ -200,44 +187,58 @@ static int lcd_get_free_pat(int xchar)
200 187
201 if (lcd_patterns[pat].count == 0) 188 if (lcd_patterns[pat].count == 0)
202 { 189 {
203 lcd_patterns[pat].xchar = xchar;
204 last_used_pat = pat; 190 last_used_pat = pat;
205 return pat; 191 return pat;
206 } 192 }
207 if (xchar_info[lcd_patterns[pat].xchar].priority < least_priority) 193 if (lcd_patterns[pat].priority < least_priority)
208 { 194 {
209 least_priority = xchar_info[lcd_patterns[pat].xchar].priority; 195 least_priority = lcd_patterns[pat].priority;
210 least_pat = pat; 196 least_pat = pat;
211 } 197 }
212 } 198 }
213 if (xchar_info[xchar].priority > least_priority) /* prioritized char */ 199 if (xchar_info[xchar].priority > least_priority) /* prioritized char */
214 { 200 {
215 lcd_free_pat(lcd_patterns[least_pat].xchar); 201 lcd_free_pat(least_pat);
216 lcd_patterns[least_pat].xchar = xchar;
217 last_used_pat = least_pat; 202 last_used_pat = least_pat;
218 return least_pat; 203 return least_pat;
219 } 204 }
220 return NO_PATTERN; 205 return NO_PATTERN;
221} 206}
222 207
223static int map_xchar(int xchar) 208static const unsigned char *glyph_to_pattern(unsigned glyph)
209{
210 if (glyph & 0x8000)
211 return xfont_variable[glyph & 0x7fff];
212 else
213 return xfont_fixed[glyph];
214}
215
216static int map_xchar(int xchar, unsigned char *substitute)
224{ 217{
225 int pat; 218 int pat;
219 unsigned glyph;
226 220
227 if (xchar_info[xchar].priority > 0) /* soft char */ 221 if (xchar_info[xchar].priority > 0) /* soft char */
228 { 222 {
229 pat = xchar_to_pat(xchar); 223 glyph = xchar_info[xchar].glyph;
224 pat = glyph_to_pat(glyph);
230 225
231 if (pat == NO_PATTERN) /* not yet mapped */ 226 if (pat == NO_PATTERN) /* not yet mapped */
232 { 227 {
233 pat = lcd_get_free_pat(xchar); /* try to map */ 228 pat = lcd_get_free_pat(xchar); /* try to map */
229
234 if (pat == NO_PATTERN) /* failed: just use substitute */ 230 if (pat == NO_PATTERN) /* failed: just use substitute */
235 return xchar_info[xchar].hw_char; 231 return xchar_info[xchar].hw_char;
236 else /* define pattern */ 232 else
237 memcpy(lcd_patterns[pat].pattern, xchar_to_glyph(xchar), 233 { /* define pattern */
234 lcd_patterns[pat].priority = xchar_info[xchar].priority;
235 lcd_patterns[pat].glyph = glyph;
236 memcpy(lcd_patterns[pat].pattern, glyph_to_pattern(glyph),
238 HW_PATTERN_SIZE); 237 HW_PATTERN_SIZE);
238 }
239 } 239 }
240 lcd_patterns[pat].count++; /* increase reference count */ 240 lcd_patterns[pat].count++; /* increase reference count */
241 *substitute = xchar_info[xchar].hw_char;
241 return pat; 242 return pat;
242 } 243 }
243 else /* hardware char */ 244 else /* hardware char */
@@ -248,10 +249,10 @@ static void lcd_putxchar(int x, int y, int xchar)
248{ 249{
249 int lcd_char = lcd_charbuffer[y][x]; 250 int lcd_char = lcd_charbuffer[y][x];
250 251
251 if (lcd_char < lcd_pattern_count) /* old char was soft */ 252 if (lcd_char < lcd_pattern_count) /* old char was soft */
252 lcd_patterns[lcd_char].count--; /* decrease old reference count */ 253 lcd_patterns[lcd_char].count--; /* decrease old reference count */
253 254
254 lcd_charbuffer[y][x] = map_xchar(xchar); 255 lcd_charbuffer[y][x] = map_xchar(xchar, &lcd_substbuffer[y][x]);
255} 256}
256 257
257/** user-definable pattern handling **/ 258/** user-definable pattern handling **/
@@ -274,25 +275,25 @@ unsigned long lcd_get_locked_pattern(void)
274void lcd_unlock_pattern(unsigned long ucs) 275void lcd_unlock_pattern(unsigned long ucs)
275{ 276{
276 int xchar = find_xchar(ucs); 277 int xchar = find_xchar(ucs);
277 int index = xchar_info[xchar].glyph; 278 unsigned glyph = xchar_info[xchar].glyph;
278 279
279 if (index & 0x8000) /* variable extended char */ 280 if (glyph & 0x8000) /* variable extended char */
280 { 281 {
281 lcd_free_pat(xchar); 282 lcd_free_pat(glyph_to_pat(glyph));
282 xfont_variable_locked[index & 0x7fff] = false; 283 xfont_variable_locked[glyph & 0x7fff] = false;
283 } 284 }
284} 285}
285 286
286void lcd_define_pattern(unsigned long ucs, const char *pattern) 287void lcd_define_pattern(unsigned long ucs, const char *pattern)
287{ 288{
288 int xchar = find_xchar(ucs); 289 int xchar = find_xchar(ucs);
289 int index = xchar_info[xchar].glyph; 290 unsigned glyph = xchar_info[xchar].glyph;
290 int pat; 291 int pat;
291 292
292 if (index & 0x8000) /* variable extended char */ 293 if (glyph & 0x8000) /* variable extended char */
293 { 294 {
294 memcpy(xfont_variable[index & 0x7fff], pattern, HW_PATTERN_SIZE); 295 memcpy(xfont_variable[glyph & 0x7fff], pattern, HW_PATTERN_SIZE);
295 pat = xchar_to_pat(xchar); 296 pat = glyph_to_pat(glyph);
296 if (pat != NO_PATTERN) 297 if (pat != NO_PATTERN)
297 { 298 {
298 memcpy(lcd_patterns[pat].pattern, pattern, HW_PATTERN_SIZE); 299 memcpy(lcd_patterns[pat].pattern, pattern, HW_PATTERN_SIZE);
@@ -337,7 +338,7 @@ void lcd_put_cursor(int x, int y, unsigned long cursor_ucs)
337 338
338 lcd_cursor.enabled = true; 339 lcd_cursor.enabled = true;
339 lcd_cursor.visible = false; 340 lcd_cursor.visible = false;
340 lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs)); 341 lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs), &lcd_cursor.subst_char);
341 lcd_cursor.x = x; 342 lcd_cursor.x = x;
342 lcd_cursor.y = y; 343 lcd_cursor.y = y;
343 lcd_cursor.downcount = 0; 344 lcd_cursor.downcount = 0;