diff options
-rw-r--r-- | bootloader/SOURCES | 2 | ||||
-rw-r--r-- | bootloader/format.c | 324 | ||||
-rw-r--r-- | bootloader/format.h | 37 | ||||
-rw-r--r-- | bootloader/snprintf.c | 80 | ||||
-rw-r--r-- | firmware/common/diacritic.c | 12 | ||||
-rw-r--r-- | firmware/drivers/lcd-bitmap-common.c | 67 | ||||
-rw-r--r-- | firmware/scroll_engine.c | 10 |
7 files changed, 529 insertions, 3 deletions
diff --git a/bootloader/SOURCES b/bootloader/SOURCES index 849ed17c40..e775fbe246 100644 --- a/bootloader/SOURCES +++ b/bootloader/SOURCES | |||
@@ -1,4 +1,6 @@ | |||
1 | common.c | 1 | common.c |
2 | format.c | ||
3 | snprintf.c | ||
2 | 4 | ||
3 | #if defined(IPOD_NANO2G) | 5 | #if defined(IPOD_NANO2G) |
4 | ipodnano2g.c | 6 | ipodnano2g.c |
diff --git a/bootloader/format.c b/bootloader/format.c new file mode 100644 index 0000000000..8f28444b8c --- /dev/null +++ b/bootloader/format.c | |||
@@ -0,0 +1,324 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Gary Czvitkovicz | ||
11 | * Copyright (C) 2017 by William Wilgus | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | |||
24 | #include <stdarg.h> | ||
25 | #include <stdbool.h> | ||
26 | #include <limits.h> | ||
27 | #include <string.h> | ||
28 | #include "file.h" | ||
29 | #include "format.h" | ||
30 | |||
31 | static const char hexdigit[] = "0123456789ABCDEF"; | ||
32 | |||
33 | /* smaller compressed binary without inline but 18% slower */ | ||
34 | #define FMT_DECL static inline | ||
35 | |||
36 | FMT_DECL int fmt_width_precision(int *ch, const char **fmt, char **str, va_list *ap) | ||
37 | { | ||
38 | int value = 0; | ||
39 | (void) str; | ||
40 | (void) ap; | ||
41 | |||
42 | while (*ch >= '0' && *ch <= '9') | ||
43 | { | ||
44 | value = 10 * value + (*ch - '0'); | ||
45 | *ch = *(*fmt)++; | ||
46 | } | ||
47 | return value; | ||
48 | } | ||
49 | |||
50 | FMT_DECL int fmt_integer_signed(int *ch, const char **fmt, char **str, va_list *ap) | ||
51 | { | ||
52 | int val, rem, sign; | ||
53 | (void) ch; | ||
54 | (void) fmt; | ||
55 | |||
56 | val = sign = va_arg(*ap, int); | ||
57 | if (val < 0) | ||
58 | val = -val; | ||
59 | do { | ||
60 | rem = val % 10; | ||
61 | val /= 10; | ||
62 | *--(*str) = rem + '0'; | ||
63 | |||
64 | } while (val > 0); | ||
65 | |||
66 | if (sign < 0) | ||
67 | *--(*str) = '-'; | ||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | FMT_DECL int fmt_integer_unsigned(int *ch, const char **fmt, char **str, va_list *ap) | ||
72 | { | ||
73 | unsigned int uval, urem; | ||
74 | (void) ch; | ||
75 | (void) fmt; | ||
76 | |||
77 | uval = va_arg(*ap, unsigned int); | ||
78 | do { | ||
79 | urem = uval % 10; | ||
80 | uval /= 10; | ||
81 | *--(*str) = urem + '0'; | ||
82 | } while (uval > 0); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | FMT_DECL int fmt_long(int *ch, const char **fmt, char **str, va_list *ap) | ||
87 | { | ||
88 | int pad = 0; | ||
89 | long lval, lrem, lsign = 0; | ||
90 | unsigned long ulval, ulrem; | ||
91 | char ch_l = *ch; | ||
92 | |||
93 | *ch = *(*fmt)++; | ||
94 | if (*ch == 'd') { | ||
95 | lval = lsign = va_arg(*ap, long); | ||
96 | |||
97 | if (lval < 0) | ||
98 | lval = -lval; | ||
99 | do { | ||
100 | lrem = lval % 10; | ||
101 | lval /= 10; | ||
102 | *--(*str) = lrem + '0'; | ||
103 | } while (lval > 0); | ||
104 | |||
105 | if (lsign < 0) | ||
106 | *--(*str) = '-'; | ||
107 | } | ||
108 | else if (*ch == 'u') { | ||
109 | ulval = va_arg(*ap, unsigned long); | ||
110 | do { | ||
111 | ulrem = ulval % 10; | ||
112 | ulval /= 10; | ||
113 | *--(*str) = ulrem + '0'; | ||
114 | } while (ulval > 0); | ||
115 | } | ||
116 | else if (*ch == 'x' || *ch == 'X') { | ||
117 | pad++; | ||
118 | ulval = va_arg(*ap, long); | ||
119 | do { | ||
120 | *--(*str) = hexdigit[ulval & 0xf]; | ||
121 | ulval >>= 4; | ||
122 | } while (ulval > 0); | ||
123 | } | ||
124 | else { | ||
125 | *--(*str) = ch_l; | ||
126 | *--(*str) = *ch; | ||
127 | } | ||
128 | return pad; | ||
129 | } | ||
130 | |||
131 | FMT_DECL int fmt_character(int *ch, const char **fmt, char **str, va_list *ap) | ||
132 | { | ||
133 | (void) ch; | ||
134 | (void) fmt; | ||
135 | |||
136 | *--(*str) = va_arg(*ap, int); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | FMT_DECL int fmt_string(int *ch, const char **fmt, char **str, va_list *ap) | ||
141 | { | ||
142 | (void) ch; | ||
143 | (void) fmt; | ||
144 | |||
145 | *str = va_arg (*ap, char*); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | FMT_DECL int fmt_hex_unsigned(int *ch, const char **fmt, char **str, va_list *ap) | ||
150 | { | ||
151 | unsigned int uval; | ||
152 | (void) ch; | ||
153 | (void) fmt; | ||
154 | |||
155 | uval = va_arg(*ap, int); | ||
156 | do { | ||
157 | *--(*str) = hexdigit[uval & 0xf]; | ||
158 | uval >>= 4; | ||
159 | } while (uval > 0); | ||
160 | return 1; | ||
161 | } | ||
162 | |||
163 | FMT_DECL int fmt_pointer(int *ch, const char **fmt, char **str, va_list *ap) | ||
164 | { | ||
165 | int pad = fmt_hex_unsigned(ch, fmt, str, ap); | ||
166 | /* for pointers prepend 0x and act like 'X' */ | ||
167 | *--(*str) = 'x'; | ||
168 | *--(*str) = '0'; | ||
169 | return pad; | ||
170 | } | ||
171 | |||
172 | FMT_DECL int fmt_sizet(int *ch, const char **fmt, char **str, va_list *ap) | ||
173 | { | ||
174 | size_t uszval, uszrem; | ||
175 | ssize_t szval, szrem, szsign; | ||
176 | char ch_z = *ch; | ||
177 | *ch = *(*fmt)++; | ||
178 | |||
179 | if (*ch == 'd') { | ||
180 | szval = szsign = va_arg(*ap, ssize_t); | ||
181 | if (szval < 0) | ||
182 | szval = -szval; | ||
183 | do { | ||
184 | szrem = szval % 10; | ||
185 | szval /= 10; | ||
186 | *--(*str) = szrem + '0'; | ||
187 | } while (szval > 0); | ||
188 | |||
189 | if (szsign < 0) | ||
190 | *--(*str) = '-'; | ||
191 | } | ||
192 | else if (*ch == 'u') { | ||
193 | uszval = va_arg(*ap, size_t); | ||
194 | do { | ||
195 | uszrem = uszval % 10; | ||
196 | uszval /= 10; | ||
197 | *--(*str) = uszrem + '0'; | ||
198 | } while (uszval > 0); | ||
199 | } | ||
200 | else { | ||
201 | *--(*str) = ch_z; | ||
202 | *--(*str) = *ch; | ||
203 | } | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static inline int fmt_next_char(int *ch, const char **fmt, char **str, va_list *ap) | ||
208 | { | ||
209 | (void) fmt; | ||
210 | (void) ap; | ||
211 | |||
212 | *--(*str) = *ch; | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | |||
217 | |||
218 | void format( | ||
219 | /* call 'push()' for each output letter */ | ||
220 | int (*push)(void *userp, unsigned char data), | ||
221 | void *userp, | ||
222 | const char *fmt, | ||
223 | va_list ap) | ||
224 | { | ||
225 | bool ok = true; | ||
226 | char *str; | ||
227 | char tmpbuf[12], pad; | ||
228 | int ch, width, precision, padded; | ||
229 | |||
230 | |||
231 | ch = *fmt++; | ||
232 | tmpbuf[sizeof tmpbuf - 1] = '\0'; | ||
233 | |||
234 | do | ||
235 | { | ||
236 | if (ch == '%') | ||
237 | { | ||
238 | str = tmpbuf + sizeof tmpbuf - 1; | ||
239 | ch = *fmt++; | ||
240 | padded = (ch == '0' ? 1 : 0); | ||
241 | width = fmt_width_precision(&ch, &fmt, &str, &ap); | ||
242 | |||
243 | precision = INT_MAX; | ||
244 | if(ch == '.') | ||
245 | { | ||
246 | ch = *fmt++; | ||
247 | precision = fmt_width_precision(&ch, &fmt, &str, &ap); | ||
248 | } | ||
249 | |||
250 | if (ch == 'd') | ||
251 | fmt_integer_signed(&ch, &fmt, &str, &ap); | ||
252 | else if (ch == 'u') | ||
253 | fmt_integer_unsigned(&ch, &fmt, &str, &ap); | ||
254 | else if (ch == 'l') | ||
255 | padded += fmt_long(&ch, &fmt, &str, &ap); | ||
256 | else if (ch == 'c') | ||
257 | fmt_character(&ch, &fmt, &str, &ap); | ||
258 | else if (ch == 's') | ||
259 | fmt_string(&ch, &fmt, &str, &ap); | ||
260 | else if (ch == 'x' || ch == 'X') | ||
261 | padded += fmt_hex_unsigned(&ch, &fmt, &str, &ap); | ||
262 | else if (ch == 'p' || ch == 'P') | ||
263 | padded += fmt_pointer(&ch, &fmt, &str, &ap); | ||
264 | #if 0 | ||
265 | else if (ch == 'z') | ||
266 | fmt_sizet(&ch, &fmt, &str, &ap); | ||
267 | #endif | ||
268 | else | ||
269 | fmt_next_char(&ch, &fmt, &str, &ap); | ||
270 | |||
271 | width -= strlen (str); | ||
272 | if (width > 0) | ||
273 | { | ||
274 | pad = (padded ? '0' : ' '); | ||
275 | while (width-- > 0 && ok) | ||
276 | ok=push(userp, pad); | ||
277 | } | ||
278 | while(*str != '\0' && ok && precision--) | ||
279 | ok=push(userp, *str++); | ||
280 | } | ||
281 | else | ||
282 | ok=push(userp, ch); | ||
283 | |||
284 | } while ((ch = *fmt++) != '\0' && ok); | ||
285 | } | ||
286 | |||
287 | struct for_fprintf { | ||
288 | int fd; /* where to store it */ | ||
289 | int bytes; /* amount stored */ | ||
290 | }; | ||
291 | |||
292 | static int fprfunc(void *pr, unsigned char letter) | ||
293 | { | ||
294 | struct for_fprintf *fpr = (struct for_fprintf *)pr; | ||
295 | int rc = write(fpr->fd, &letter, 1); | ||
296 | |||
297 | if(rc > 0) { | ||
298 | fpr->bytes++; /* count them */ | ||
299 | return true; /* we are ok */ | ||
300 | } | ||
301 | |||
302 | return false; /* failure */ | ||
303 | } | ||
304 | |||
305 | |||
306 | int fdprintf(int fd, const char *fmt, ...) | ||
307 | { | ||
308 | va_list ap; | ||
309 | struct for_fprintf fpr; | ||
310 | |||
311 | fpr.fd=fd; | ||
312 | fpr.bytes=0; | ||
313 | |||
314 | va_start(ap, fmt); | ||
315 | format(fprfunc, &fpr, fmt, ap); | ||
316 | va_end(ap); | ||
317 | |||
318 | return fpr.bytes; /* return 0 on error */ | ||
319 | } | ||
320 | |||
321 | void vuprintf(int (*push)(void *userp, unsigned char data), void *userp, const char *fmt, va_list ap) | ||
322 | { | ||
323 | format(push, userp, fmt, ap); | ||
324 | } | ||
diff --git a/bootloader/format.h b/bootloader/format.h new file mode 100644 index 0000000000..30a072aca8 --- /dev/null +++ b/bootloader/format.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Felix Arends | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #ifndef __FORMAT_H__ | ||
23 | #define __FORMAT_H__ | ||
24 | |||
25 | void format( | ||
26 | /* call 'push()' for each output letter */ | ||
27 | int (*push)(void *userp, unsigned char data), | ||
28 | void *userp, | ||
29 | const char *fmt, | ||
30 | va_list ap); | ||
31 | |||
32 | /* callback function is called for every output character (byte) with userp and | ||
33 | * should return 0 when ch is a char other than '\0' that should stop printing */ | ||
34 | void vuprintf(int (*push)(void *userp, unsigned char data), | ||
35 | void *userp, const char *fmt, va_list ap); | ||
36 | |||
37 | #endif /* __FORMAT_H__ */ | ||
diff --git a/bootloader/snprintf.c b/bootloader/snprintf.c new file mode 100644 index 0000000000..d64bb32447 --- /dev/null +++ b/bootloader/snprintf.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Gary Czvitkovicz | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | /* | ||
23 | * Minimal printf and snprintf formatting functions | ||
24 | * | ||
25 | * These support %c %s %l %d %u and %x(%p) | ||
26 | * Field width and zero-padding flag only | ||
27 | */ | ||
28 | |||
29 | #include <stdio.h> | ||
30 | #include <stdarg.h> | ||
31 | #include <stdbool.h> | ||
32 | #include <limits.h> | ||
33 | #include "format.h" | ||
34 | |||
35 | struct for_snprintf { | ||
36 | unsigned char *ptr; /* where to store it */ | ||
37 | size_t bytes; /* amount already stored */ | ||
38 | size_t max; /* max amount to store */ | ||
39 | }; | ||
40 | |||
41 | static int sprfunc(void *ptr, unsigned char letter) | ||
42 | { | ||
43 | struct for_snprintf *pr = (struct for_snprintf *)ptr; | ||
44 | if(pr->bytes < pr->max) { | ||
45 | *pr->ptr = letter; | ||
46 | pr->ptr++; | ||
47 | pr->bytes++; | ||
48 | return true; | ||
49 | } | ||
50 | return false; /* filled buffer */ | ||
51 | } | ||
52 | |||
53 | |||
54 | int snprintf(char *buf, size_t size, const char *fmt, ...) | ||
55 | { | ||
56 | int len; | ||
57 | va_list ap; | ||
58 | |||
59 | va_start(ap, fmt); | ||
60 | len = vsnprintf(buf, size, fmt, ap); | ||
61 | va_end(ap); | ||
62 | |||
63 | return len; | ||
64 | } | ||
65 | |||
66 | int vsnprintf(char *buf, size_t size, const char *fmt, va_list ap) | ||
67 | { | ||
68 | struct for_snprintf pr; | ||
69 | |||
70 | pr.ptr = (unsigned char *)buf; | ||
71 | pr.bytes = 0; | ||
72 | pr.max = size; | ||
73 | |||
74 | format(sprfunc, &pr, fmt, ap); | ||
75 | |||
76 | /* make sure it ends with a trailing zero */ | ||
77 | pr.ptr[(pr.bytes < pr.max) ? 0 : -1] = '\0'; | ||
78 | |||
79 | return pr.bytes; | ||
80 | } | ||
diff --git a/firmware/common/diacritic.c b/firmware/common/diacritic.c index 563028cab8..92c2400203 100644 --- a/firmware/common/diacritic.c +++ b/firmware/common/diacritic.c | |||
@@ -194,7 +194,7 @@ static const struct diac_range diac_ranges[] = | |||
194 | }; | 194 | }; |
195 | 195 | ||
196 | #define MRU_MAX_LEN 32 | 196 | #define MRU_MAX_LEN 32 |
197 | 197 | #ifndef BOOTLOADER | |
198 | bool is_diacritic(const unsigned short char_code, bool *is_rtl) | 198 | bool is_diacritic(const unsigned short char_code, bool *is_rtl) |
199 | { | 199 | { |
200 | static uint8_t mru_len = 0; | 200 | static uint8_t mru_len = 0; |
@@ -248,4 +248,12 @@ Found: | |||
248 | 248 | ||
249 | return (char_code < diac->base + (info & DIAC_CNT)); | 249 | return (char_code < diac->base + (info & DIAC_CNT)); |
250 | } | 250 | } |
251 | 251 | #else /*BOOTLOADER*/ | |
252 | inline bool is_diacritic(const unsigned short char_code, bool *is_rtl) | ||
253 | { | ||
254 | (void)char_code; | ||
255 | if (is_rtl) | ||
256 | *is_rtl = false; | ||
257 | return false; | ||
258 | } | ||
259 | #endif /* ndef BOOTLOADER*/ | ||
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c index 22430d4e50..8c38e513c6 100644 --- a/firmware/drivers/lcd-bitmap-common.c +++ b/firmware/drivers/lcd-bitmap-common.c | |||
@@ -118,6 +118,7 @@ void LCDFN(update_viewport_rect)(int x, int y, int width, int height) | |||
118 | LCDFN(update_rect)(current_vp->x + x, current_vp->y + y, width, height); | 118 | LCDFN(update_rect)(current_vp->x + x, current_vp->y + y, width, height); |
119 | } | 119 | } |
120 | 120 | ||
121 | #ifndef BOOTLOADER | ||
121 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | 122 | /* put a string at a given pixel position, skipping first ofs pixel columns */ |
122 | static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) | 123 | static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) |
123 | { | 124 | { |
@@ -257,6 +258,72 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) | |||
257 | } | 258 | } |
258 | font_lock(current_vp->font, false); | 259 | font_lock(current_vp->font, false); |
259 | } | 260 | } |
261 | #else /* BOOTLOADER */ | ||
262 | /* put a string at a given pixel position, skipping first ofs pixel columns */ | ||
263 | static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) | ||
264 | { | ||
265 | unsigned short *ucs; | ||
266 | struct font* pf = font_get(current_vp->font); | ||
267 | int vp_flags = current_vp->flags; | ||
268 | const unsigned char *bits; | ||
269 | int width; | ||
270 | |||
271 | if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0) | ||
272 | { | ||
273 | int w; | ||
274 | |||
275 | LCDFN(getstringsize)(str, &w, NULL); | ||
276 | /* center takes precedence */ | ||
277 | if (vp_flags & VP_FLAG_ALIGN_CENTER) | ||
278 | { | ||
279 | x = ((current_vp->width - w)/ 2) + x; | ||
280 | if (x < 0) | ||
281 | x = 0; | ||
282 | } | ||
283 | else | ||
284 | { | ||
285 | x = current_vp->width - w - x; | ||
286 | x += ofs; | ||
287 | ofs = 0; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | /* allow utf but no diacritics or rtl lang */ | ||
292 | for (ucs = bidi_l2v(str, 1); *ucs; ucs++) | ||
293 | { | ||
294 | const unsigned short next_ch = ucs[1]; | ||
295 | |||
296 | if (x >= current_vp->width) | ||
297 | break; | ||
298 | |||
299 | /* Get proportional width and glyph bits */ | ||
300 | width = font_get_width(pf, *ucs); | ||
301 | |||
302 | if (ofs > width) | ||
303 | { | ||
304 | ofs -= width; | ||
305 | continue; | ||
306 | } | ||
307 | |||
308 | bits = font_get_bits(pf, *ucs); | ||
309 | |||
310 | #if defined(MAIN_LCD) && defined(HAVE_LCD_COLOR) | ||
311 | if (pf->depth) | ||
312 | lcd_alpha_bitmap_part(bits, ofs, 0, width, x, y, | ||
313 | width - ofs, pf->height); | ||
314 | else | ||
315 | #endif | ||
316 | LCDFN(mono_bitmap_part)(bits, ofs, 0, width, x, | ||
317 | y, width - ofs, pf->height); | ||
318 | if (next_ch) | ||
319 | { | ||
320 | x += width - ofs; | ||
321 | ofs = 0; | ||
322 | } | ||
323 | } | ||
324 | } | ||
325 | #endif | ||
326 | |||
260 | 327 | ||
261 | /*** pixel oriented text output ***/ | 328 | /*** pixel oriented text output ***/ |
262 | 329 | ||
diff --git a/firmware/scroll_engine.c b/firmware/scroll_engine.c index b584345a9a..91f9d1f868 100644 --- a/firmware/scroll_engine.c +++ b/firmware/scroll_engine.c | |||
@@ -52,7 +52,6 @@ static const char scroll_tick_table[18] = { | |||
52 | }; | 52 | }; |
53 | 53 | ||
54 | static void scroll_thread(void); | 54 | static void scroll_thread(void); |
55 | static char scroll_stack[DEFAULT_STACK_SIZE*3]; | ||
56 | static const char scroll_name[] = "scroll"; | 55 | static const char scroll_name[] = "scroll"; |
57 | 56 | ||
58 | #include "drivers/lcd-scroll.c" | 57 | #include "drivers/lcd-scroll.c" |
@@ -195,8 +194,11 @@ static void scroll_thread(void) | |||
195 | } | 194 | } |
196 | #endif /* HAVE_REMOTE_LCD */ | 195 | #endif /* HAVE_REMOTE_LCD */ |
197 | 196 | ||
197 | |||
198 | #ifndef BOOTLOADER | ||
198 | void scroll_init(void) | 199 | void scroll_init(void) |
199 | { | 200 | { |
201 | static char scroll_stack[DEFAULT_STACK_SIZE*3]; | ||
200 | #ifdef HAVE_REMOTE_LCD | 202 | #ifdef HAVE_REMOTE_LCD |
201 | queue_init(&scroll_queue, true); | 203 | queue_init(&scroll_queue, true); |
202 | #endif | 204 | #endif |
@@ -205,3 +207,9 @@ void scroll_init(void) | |||
205 | IF_PRIO(, PRIORITY_USER_INTERFACE) | 207 | IF_PRIO(, PRIORITY_USER_INTERFACE) |
206 | IF_COP(, CPU)); | 208 | IF_COP(, CPU)); |
207 | } | 209 | } |
210 | #else | ||
211 | void scroll_init(void) | ||
212 | { | ||
213 | /* DUMMY */ | ||
214 | } | ||
215 | #endif /* ndef BOOTLOADER*/ | ||