1
2
3
4
5
6
7#include <errno.h>
8#include <linux/input.h>
9#include <SDL/SDL.h>
10#include <sound.h>
11#include <asm/state.h>
12
13static struct sdl_info {
14 SDL_Surface *screen;
15 int width;
16 int height;
17 int depth;
18 int pitch;
19 uint frequency;
20 uint audio_pos;
21 uint audio_size;
22 uint8_t *audio_data;
23 bool audio_active;
24 bool inited;
25} sdl;
26
27static void sandbox_sdl_poll_events(void)
28{
29
30
31
32
33 extern void reset_cpu(unsigned long addr);
34 SDL_Event event;
35
36 while (SDL_PollEvent(&event)) {
37 switch (event.type) {
38 case SDL_QUIT:
39 puts("LCD window closed - quitting\n");
40 reset_cpu(1);
41 break;
42 }
43 }
44}
45
46static int sandbox_sdl_ensure_init(void)
47{
48 if (!sdl.inited) {
49 if (SDL_Init(0) < 0) {
50 printf("Unable to initialize SDL: %s\n",
51 SDL_GetError());
52 return -EIO;
53 }
54
55 atexit(SDL_Quit);
56
57 sdl.inited = true;
58 }
59 return 0;
60}
61
62int sandbox_sdl_init_display(int width, int height, int log2_bpp)
63{
64 struct sandbox_state *state = state_get_current();
65 int err;
66
67 if (!width || !state->show_lcd)
68 return 0;
69 err = sandbox_sdl_ensure_init();
70 if (err)
71 return err;
72 if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
73 printf("Unable to initialize SDL LCD: %s\n", SDL_GetError());
74 return -EPERM;
75 }
76 SDL_WM_SetCaption("U-Boot", "U-Boot");
77
78 sdl.width = width;
79 sdl.height = height;
80 sdl.depth = 1 << log2_bpp;
81 sdl.pitch = sdl.width * sdl.depth / 8;
82 sdl.screen = SDL_SetVideoMode(width, height, 0, 0);
83 sandbox_sdl_poll_events();
84
85 return 0;
86}
87
88int sandbox_sdl_sync(void *lcd_base)
89{
90 SDL_Surface *frame;
91
92 frame = SDL_CreateRGBSurfaceFrom(lcd_base, sdl.width, sdl.height,
93 sdl.depth, sdl.pitch,
94 0x1f << 11, 0x3f << 5, 0x1f << 0, 0);
95 SDL_BlitSurface(frame, NULL, sdl.screen, NULL);
96 SDL_FreeSurface(frame);
97 SDL_UpdateRect(sdl.screen, 0, 0, 0, 0);
98 sandbox_sdl_poll_events();
99
100 return 0;
101}
102
103#define NONE (-1)
104#define NUM_SDL_CODES (SDLK_UNDO + 1)
105
106static int16_t sdl_to_keycode[NUM_SDL_CODES] = {
107
108 NONE, NONE, NONE, NONE, NONE,
109 NONE, NONE, NONE, KEY_BACKSPACE, KEY_TAB,
110 NONE, NONE, NONE, KEY_ENTER, NONE,
111 NONE, NONE, NONE, NONE, KEY_POWER,
112
113
114 NONE, NONE, NONE, NONE, NONE,
115 NONE, NONE, KEY_ESC, NONE, NONE,
116 NONE, NONE, KEY_SPACE, NONE, NONE,
117 NONE, NONE, NONE, NONE, NONE,
118
119
120 NONE, NONE, NONE, NONE, KEY_COMMA,
121 KEY_MINUS, KEY_DOT, KEY_SLASH, KEY_0, KEY_1,
122 KEY_2, KEY_3, KEY_4, KEY_5, KEY_6,
123 KEY_7, KEY_8, KEY_9, NONE, KEY_SEMICOLON,
124
125
126 NONE, KEY_EQUAL, NONE, NONE, NONE,
127 NONE, NONE, NONE, NONE, NONE,
128 NONE, NONE, NONE, NONE, NONE,
129 NONE, NONE, NONE, NONE, NONE,
130
131
132 NONE, NONE, NONE, NONE, NONE,
133 NONE, NONE, NONE, NONE, NONE,
134 NONE, NONE, KEY_BACKSLASH, NONE, NONE,
135 NONE, KEY_GRAVE, KEY_A, KEY_B, KEY_C,
136
137
138 KEY_D, KEY_E, KEY_F, KEY_G, KEY_H,
139 KEY_I, KEY_J, KEY_K, KEY_L, KEY_M,
140 KEY_N, KEY_O, KEY_P, KEY_Q, KEY_R,
141 KEY_S, KEY_T, KEY_U, KEY_V, KEY_W,
142
143
144 KEY_X, KEY_Y, KEY_Z, NONE, NONE,
145 NONE, NONE, KEY_DELETE, NONE, NONE,
146 NONE, NONE, NONE, NONE, NONE,
147 NONE, NONE, NONE, NONE, NONE,
148
149
150 NONE, NONE, NONE, NONE, NONE,
151 NONE, NONE, NONE, NONE, NONE,
152 NONE, NONE, NONE, NONE, NONE,
153 NONE, NONE, NONE, NONE, NONE,
154
155
156 NONE, NONE, NONE, NONE, NONE,
157 NONE, NONE, NONE, NONE, NONE,
158 NONE, NONE, NONE, NONE, NONE,
159 NONE, NONE, NONE, NONE, NONE,
160
161
162 NONE, NONE, NONE, NONE, NONE,
163 NONE, NONE, NONE, NONE, NONE,
164 NONE, NONE, NONE, NONE, NONE,
165 NONE, NONE, NONE, NONE, NONE,
166
167
168 NONE, NONE, NONE, NONE, NONE,
169 NONE, NONE, NONE, NONE, NONE,
170 NONE, NONE, NONE, NONE, NONE,
171 NONE, NONE, NONE, NONE, NONE,
172
173
174 NONE, NONE, NONE, NONE, NONE,
175 NONE, NONE, NONE, NONE, NONE,
176 NONE, NONE, NONE, NONE, NONE,
177 NONE, NONE, NONE, NONE, NONE,
178
179
180 NONE, NONE, NONE, NONE, NONE,
181 NONE, NONE, NONE, NONE, NONE,
182 NONE, NONE, NONE, NONE, NONE,
183 NONE, KEY_KP0, KEY_KP1, KEY_KP2, KEY_KP3,
184
185
186 KEY_KP4, KEY_KP5, KEY_KP6, KEY_KP7, KEY_KP8,
187 KEY_KP9, KEY_KPDOT, KEY_KPSLASH, KEY_KPASTERISK, KEY_KPMINUS,
188 KEY_KPPLUS, KEY_KPENTER, KEY_KPEQUAL, KEY_UP, KEY_DOWN,
189 KEY_RIGHT, KEY_LEFT, KEY_INSERT, KEY_HOME, KEY_END,
190
191
192 KEY_PAGEUP, KEY_PAGEDOWN, KEY_F1, KEY_F2, KEY_F3,
193 KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8,
194 KEY_F9, KEY_F10, KEY_F11, KEY_F12, NONE,
195 NONE, NONE, NONE, NONE, NONE,
196
197
198 KEY_NUMLOCK, KEY_CAPSLOCK, KEY_SCROLLLOCK, KEY_RIGHTSHIFT,
199 KEY_LEFTSHIFT,
200 KEY_RIGHTCTRL, KEY_LEFTCTRL, KEY_RIGHTALT, KEY_LEFTALT, KEY_RIGHTMETA,
201 KEY_LEFTMETA, NONE, KEY_FN, NONE, KEY_COMPOSE,
202 NONE, KEY_PRINT, KEY_SYSRQ, KEY_PAUSE, NONE,
203
204
205 NONE, NONE, NONE,
206};
207
208int sandbox_sdl_scan_keys(int key[], int max_keys)
209{
210 Uint8 *keystate;
211 int i, count;
212
213 sandbox_sdl_poll_events();
214 keystate = SDL_GetKeyState(NULL);
215 for (i = count = 0; i < NUM_SDL_CODES; i++) {
216 if (count >= max_keys)
217 break;
218 else if (keystate[i])
219 key[count++] = sdl_to_keycode[i];
220 }
221
222 return count;
223}
224
225int sandbox_sdl_key_pressed(int keycode)
226{
227 int key[8];
228 int count;
229 int i;
230
231 count = sandbox_sdl_scan_keys(key, sizeof(key) / sizeof(key[0]));
232 for (i = 0; i < count; i++) {
233 if (key[i] == keycode)
234 return 0;
235 }
236
237 return -ENOENT;
238}
239
240void sandbox_sdl_fill_audio(void *udata, Uint8 *stream, int len)
241{
242 int avail;
243
244 avail = sdl.audio_size - sdl.audio_pos;
245 if (avail < len)
246 len = avail;
247
248 SDL_MixAudio(stream, sdl.audio_data + sdl.audio_pos, len,
249 SDL_MIX_MAXVOLUME);
250 sdl.audio_pos += len;
251
252
253 if (sdl.audio_pos == sdl.audio_size)
254 sdl.audio_pos = 0;
255}
256
257int sandbox_sdl_sound_init(void)
258{
259 SDL_AudioSpec wanted;
260
261 if (sandbox_sdl_ensure_init())
262 return -1;
263
264 if (sdl.audio_active)
265 return 0;
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283 printf("(Warning: sandbox sound disabled)\n");
284 return 0;
285
286
287 wanted.freq = 22050;
288 wanted.format = AUDIO_S16;
289 wanted.channels = 1;
290 wanted.samples = 1024;
291 wanted.callback = sandbox_sdl_fill_audio;
292 wanted.userdata = NULL;
293
294 sdl.audio_size = sizeof(uint16_t) * wanted.freq;
295 sdl.audio_data = malloc(sdl.audio_size);
296 if (!sdl.audio_data) {
297 printf("%s: Out of memory\n", __func__);
298 return -1;
299 }
300 sdl.audio_pos = 0;
301
302 if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
303 printf("Unable to initialize SDL audio: %s\n", SDL_GetError());
304 goto err;
305 }
306
307
308 if (SDL_OpenAudio(&wanted, NULL) < 0) {
309 printf("Couldn't open audio: %s\n", SDL_GetError());
310 goto err;
311 }
312 sdl.audio_active = true;
313
314 return 0;
315
316err:
317 free(sdl.audio_data);
318 return -1;
319}
320
321int sandbox_sdl_sound_start(uint frequency)
322{
323 if (!sdl.audio_active)
324 return -1;
325 sdl.frequency = frequency;
326 sound_create_square_wave((unsigned short *)sdl.audio_data,
327 sdl.audio_size, frequency);
328 sdl.audio_pos = 0;
329 SDL_PauseAudio(0);
330
331 return 0;
332}
333
334int sandbox_sdl_sound_stop(void)
335{
336 if (!sdl.audio_active)
337 return -1;
338 SDL_PauseAudio(1);
339
340 return 0;
341}
342