Merge commit 'af5ee34c353ea2868a4b04b227bc1b511e1ac42b'
[osmocom-bb.git] / src / target / ui-experiment / sdl.c
1
2 #include <ui/display.h>
3 #include <ui/image.h>
4 #include <ui/sdl.h>
5
6 #include <stdio.h>
7
8 #include <SDL.h>
9
10 #define SDL_PRIV(d) ((struct sdl_display*)(d)->priv)
11
12 #define REFRESH_INTERVAL_MSEC 50
13
14 struct sdl_display {
15         SDL_Surface *display;
16         SDL_TimerID refresh;
17         unsigned width;
18         unsigned height;
19         unsigned scale;
20 };
21
22 static Uint32 sdl_redraw_callback(Uint32 interval, void *param) {
23         struct display *display = (struct display*)param;
24
25         display->draw(display);
26
27         return interval;
28 }
29
30 void
31 sdl_init(struct display *display,
32                  unsigned width, unsigned height, unsigned scale)
33 {
34         if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)) {
35                 printf("Failed to initialize SDL: %s\n", SDL_GetError());
36                 exit(1);
37         }
38
39         atexit(&SDL_Quit);
40
41         struct sdl_display *priv = SDL_PRIV(display);
42
43         priv->width = width;
44         priv->height = height;
45         priv->scale = scale;
46
47         priv->display = SDL_SetVideoMode(width * scale, height * scale, 32, 0);
48         if(!priv->display) {
49                 printf("Failed to set SDL video mode: %s\n", SDL_GetError());
50                 exit(1);
51         }
52
53         priv->refresh = SDL_AddTimer(REFRESH_INTERVAL_MSEC,
54                                                                  &sdl_redraw_callback, display);
55         if(!priv->refresh) {
56                 printf("Failed to add refresh timer: %s\n", SDL_GetError());
57                 exit(1);
58         }
59 }
60
61 void
62 sdl_draw(struct display *display)
63 {
64         struct sdl_display *priv = SDL_PRIV(display);
65
66         struct image *img = display->fbuf;
67
68         SDL_Rect r;
69
70         r.w = priv->scale;
71         r.h = priv->scale;
72
73         if(img->type == PXTYPE_RGB444) {
74                 unsigned stride = img->size.w * 2;
75
76                 unsigned x, y;
77                 for(y = 0; y < img->size.h; y++) {
78                         for(x = 0; x < img->size.w; x++) {
79                                 px_t color = image_get_pixel(img, x, y);
80
81                                 r.x = x * priv->scale;
82                                 r.y = y * priv->scale;
83
84                                 SDL_FillRect(priv->display, &r, color);
85                         }
86                 }
87         } else {
88                 puts("Unsupported framebuffer type for SDL emulator.");
89                 exit(1);
90         }
91
92         SDL_UpdateRect(priv->display, 0, 0, 0, 0);
93 }
94
95
96 static struct sdl_display display_sdl_priv;
97
98 uint8_t sdl_fbuf[96*64*2];
99
100 struct image display_sdl_fbuf = {
101         .type = PXTYPE_RGB444,
102         .size = {96, 64},
103         .data = &sdl_fbuf
104 };
105
106 struct display display_sdl = {
107         .name = "Main Display",
108         .fbuf = &display_sdl_fbuf,
109         .priv = &display_sdl_priv,
110         .draw = &sdl_draw
111 };
112
113 uint16_t fnord_buf[] = {
114         0x0F00,
115         0x00F0,
116         0x000F,
117         0x00FF,
118         0x0F00,
119         0x00F0,
120         0x000F,
121         0x00FF,
122         0x0F00,
123         0x00F0,
124         0x000F,
125         0x00FF,
126         0x0F00,
127         0x00F0,
128         0x000F,
129         0x00FF,
130         0x0F00,
131         0x00F0,
132         0x000F,
133         0x00FF,
134         0x0F00,
135         0x00F0,
136         0x000F,
137         0x00FF,
138         0x0F00,
139         0x00F0,
140         0x000F,
141         0x00FF,
142         0x0F00,
143         0x00F0,
144         0x000F,
145         0x00FF
146
147 };
148
149 struct image fnord = {
150         .type = PXTYPE_RGB444,
151         .size = {8,4},
152         .data = &fnord_buf
153 };
154
155 uint8_t fubar_img[] = {
156         0x01, 0x02, 0x03, 0x04,
157         0x05, 0x06, 0x07, 0x08,
158         0x09, 0x0a, 0x0b, 0x0c,
159         0x0d, 0x0e, 0x0f, 0x0f
160
161 };
162
163 struct image fubar = {
164         .type = PXTYPE_MONO_V8,
165         .size = {8,16},
166         .data = &fubar_img
167 };
168
169 void
170 sdl_run(void)
171 {
172         int r;
173         SDL_Event e;
174
175         while((r = SDL_WaitEvent(&e))) {
176
177                 if(e.type == SDL_KEYDOWN) {
178                         if(e.key.keysym.sym == SDLK_ESCAPE) {
179                                 puts("Bloody quitter!");
180                                 break;
181                         }
182                         if(e.key.keysym.sym == SDLK_SPACE) {
183                                 pxposn_t dp = {0,0};
184                                 pxposn_t sp = {0,0};
185                                 pxdims_t d = {8,4};
186
187                                 image_blit(&display_sdl_fbuf, dp,
188                                                    &fnord, sp,
189                                                    d);
190
191                                 sp.x = 0;
192                                 sp.y = 0;
193                                 dp.x = 5;
194                                 dp.y = 10;
195                                 d.w = 8;
196                                 d.h = 16;
197
198                                 image_blit(&display_sdl_fbuf, dp,
199                                                    &fubar, sp,
200                                                    d);
201
202                                 pxrect_t r = {{12,0},{40,20}};
203                                 image_fill_rect(&display_sdl_fbuf,
204                                                                 r,
205                                                                 0xFF00FF);
206
207
208 #if 0
209                                 dp.x = 0;
210                                 dp.y = 0;
211
212                                 image_draw_string(&display_sdl_fbuf, dp,
213                                                                 "ABCDEFGHI");
214
215                                 dp.y += 10;
216
217                                 image_draw_string(&display_sdl_fbuf, dp,
218                                                                 "abcdefghi");
219
220 #endif
221
222                                 sdl_draw(&display_sdl);
223
224                         }
225                 }
226
227                 switch(e.type) {
228                 case SDL_KEYDOWN:
229                 case SDL_KEYUP:
230                         printf("Key %d %d\n", e.key.keysym.sym, e.key.state);
231                         break;
232                 }
233         }
234
235         if(!r) {
236                 printf("Failed to wait for SDL event: %s\n", SDL_GetError());
237                 exit(1);
238         }
239
240 }
241
242 int
243 main(void)
244 {
245         sdl_init(&display_sdl, 96, 64, 4);
246
247         sdl_run();
248
249         return 0;
250 }