diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/lcd-charcell.c | 91 |
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 */ | 46 | unsigned char lcd_charbuffer[LCD_HEIGHT][LCD_WIDTH]; /* The "frame"buffer */ |
46 | unsigned char lcd_charbuffer[LCD_HEIGHT][LCD_WIDTH]; | 47 | static unsigned char lcd_substbuffer[LCD_HEIGHT][LCD_WIDTH]; |
47 | struct pattern_info lcd_patterns[MAX_HW_PATTERNS]; | 48 | struct pattern_info lcd_patterns[MAX_HW_PATTERNS]; |
48 | struct cursor_info lcd_cursor; | 49 | struct 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 | ||
144 | static int xchar_to_pat(int xchar) | 145 | static 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 | ||
155 | static const unsigned char *xchar_to_glyph(int xchar) | 156 | static 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 | |||
165 | static 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 | ||
223 | static int map_xchar(int xchar) | 208 | static 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 | |||
216 | static 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) | |||
274 | void lcd_unlock_pattern(unsigned long ucs) | 275 | void 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 | ||
286 | void lcd_define_pattern(unsigned long ucs, const char *pattern) | 287 | void 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; |