Musepack speed optimization. Speep up 64 bit precision synthesizer by another 1.5MHz...
[kugel-rb.git] / apps / gui / splash.c
blob1ead051b0660e8aaec3caefcff53a84a49fae7f3
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) Daniel Stenberg (2002)
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "stdarg.h"
20 #include "string.h"
21 #include "rbunicode.h"
22 #include "stdio.h"
23 #include "kernel.h"
24 #include "screen_access.h"
25 #include "lang.h"
26 #include "settings.h"
27 #include "talk.h"
28 #include "splash.h"
30 #ifndef MAX
31 #define MAX(a, b) (((a)>(b))?(a):(b))
32 #endif
34 #ifdef HAVE_LCD_BITMAP
36 #define MAXLINES (LCD_HEIGHT/6)
37 #define MAXBUFFER 512
39 #else /* HAVE_LCD_CHARCELLS */
41 #define MAXLINES 2
42 #define MAXBUFFER 64
44 #endif
46 static void splash(struct screen * screen, const char *fmt, va_list ap)
48 char splash_buf[MAXBUFFER];
49 short widths[MAXLINES];
50 char *lines[MAXLINES];
52 char *next;
53 char *lastbreak = NULL;
54 char *store = NULL;
55 int line = 0;
56 int x = 0;
57 int y, i;
58 int space_w, w, h;
59 #ifdef HAVE_LCD_BITMAP
60 int maxw = 0;
61 #if LCD_DEPTH > 1
62 unsigned prevfg = 0;
63 #endif
65 screen->getstringsize(" ", &space_w, &h);
66 #else /* HAVE_LCD_CHARCELLS */
68 space_w = h = 1;
69 screen->double_height (false);
70 #endif
71 y = h;
73 vsnprintf(splash_buf, sizeof(splash_buf), fmt, ap);
74 va_end(ap);
76 /* break splash string into display lines, doing proper word wrap */
78 next = strtok_r(splash_buf, " ", &store);
79 if (!next)
80 return; /* nothing to display */
82 lines[0] = next;
83 while (true)
85 #ifdef HAVE_LCD_BITMAP
86 screen->getstringsize(next, &w, NULL);
87 #else
88 w = utf8length(next);
89 #endif
90 if (lastbreak)
92 if (x + (next - lastbreak) * space_w + w > screen->width)
93 { /* too wide, wrap */
94 widths[line] = x;
95 #ifdef HAVE_LCD_BITMAP
96 if (x > maxw)
97 maxw = x;
98 #endif
99 if ((y + h > screen->height) || (line >= (MAXLINES-1)))
100 break; /* screen full or out of lines */
101 x = 0;
102 y += h;
103 lines[++line] = next;
105 else
107 /* restore & calculate spacing */
108 *lastbreak = ' ';
109 x += (next - lastbreak) * space_w;
112 x += w;
113 lastbreak = next + strlen(next);
114 next = strtok_r(NULL, " ", &store);
115 if (!next)
116 { /* no more words */
117 widths[line] = x;
118 #ifdef HAVE_LCD_BITMAP
119 if (x > maxw)
120 maxw = x;
121 #endif
122 break;
126 /* prepare screen */
128 screen->stop_scroll();
130 #ifdef HAVE_LCD_BITMAP
131 /* If we center the display, then just clear the box we need and put
132 a nice little frame and put the text in there! */
133 y = (screen->height - y) / 2; /* height => y start position */
134 x = (screen->width - maxw) / 2 - 2;
136 #if LCD_DEPTH > 1
137 if (screen->depth > 1)
139 prevfg = screen->get_foreground();
140 screen->set_drawmode(DRMODE_FG);
141 screen->set_foreground(
142 SCREEN_COLOR_TO_NATIVE(screen, LCD_LIGHTGRAY));
144 else
145 #endif
146 screen->set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
148 screen->fillrect(x, y-2, maxw+4, screen->height-y*2+4);
150 #if LCD_DEPTH > 1
151 if (screen->depth > 1)
152 screen->set_foreground(SCREEN_COLOR_TO_NATIVE(screen, LCD_BLACK));
153 else
154 #endif
155 screen->set_drawmode(DRMODE_SOLID);
157 screen->drawrect(x, y-2, maxw+4, screen->height-y*2+4);
158 #else /* HAVE_LCD_CHARCELLS */
159 y = 0; /* vertical centering on 2 lines would be silly */
160 x = 0;
161 screen->clear_display();
162 #endif
164 /* print the message to screen */
166 for (i = 0; i <= line; i++)
168 x = MAX((screen->width - widths[i]) / 2, 0);
170 #ifdef HAVE_LCD_BITMAP
171 screen->putsxy(x, y, lines[i]);
172 #else
173 screen->puts(x, y, lines[i]);
174 #endif
175 y += h;
178 #if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH > 1)
179 if (screen->depth > 1)
181 screen->set_foreground(prevfg);
182 screen->set_drawmode(DRMODE_SOLID);
184 #endif
185 screen->update();
188 void gui_splash(struct screen * screen, int ticks,
189 const char *fmt, ...)
191 va_list ap;
192 va_start( ap, fmt );
193 splash(screen, fmt, ap);
194 va_end( ap );
196 if(ticks)
197 sleep(ticks);
200 void gui_syncsplash(int ticks, const char *fmt, ...)
202 va_list ap;
203 int i;
204 #if !defined(SIMULATOR) || CONFIG_CODEC == SWCODEC
205 long id;
206 /* fmt may be a so called virtual pointer. See settings.h. */
207 if((id = P2ID((unsigned char *)fmt)) >= 0)
208 /* If fmt specifies a voicefont ID, and voice menus are
209 enabled, then speak it. */
210 cond_talk_ids_fq(id);
211 #endif
212 /* If fmt is a lang ID then get the corresponding string (which
213 still might contain % place holders). */
214 fmt = P2STR((unsigned char *)fmt);
215 va_start( ap, fmt );
216 FOR_NB_SCREENS(i)
218 screens[i].set_viewport(NULL);
219 splash(&(screens[i]), fmt, ap);
221 va_end( ap );
223 if(ticks)
224 sleep(ticks);