dirty redraw and SDL framebuffer example
[windtk] / example_sdl.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <SDL/SDL.h>
4 #include "windtk.h"
5
6 static int gfx_newcol(int r, int g, int b);
7 static void gfx_color(int c);
8 static void gfx_fillrect(struct wt_rect *r);
9 static void gfx_line(int x0, int y0, int x1, int y1);
10
11 static struct wt_graphics gfx = {
12         0,
13         gfx_newcol, gfx_color,
14         gfx_fillrect,
15         gfx_line
16 };
17
18 static SDL_Surface *fbsurf;
19 static SDL_PixelFormat *pfmt;
20 static int fb_width = 800, fb_height = 600;
21 static uint32_t *fb;
22
23 int main(void)
24 {
25         int i, num_upd;
26         struct wt_rect *rect;
27         SDL_Event ev;
28
29         if(SDL_Init(SDL_INIT_VIDEO) == -1) {
30                 fprintf(stderr, "failed to initialize SDL\n");
31                 return 1;
32         }
33
34         if(!(fbsurf = SDL_SetVideoMode(fb_width, fb_height, 32, SDL_SWSURFACE | SDL_RESIZABLE))) {
35                 fprintf(stderr, "failed to set video mode\n");
36                 SDL_Quit();
37                 return 1;
38         }
39         pfmt = fbsurf->format;
40
41         SDL_FillRect(fbsurf, 0, 0);
42
43         if(wt_init(fb_width, fb_height, &gfx) == -1) {
44                 return 1;
45         }
46         wt_window(0, "foo", WT_WS_DEFAULT, 100, 100, 200, 200);
47
48         while(SDL_WaitEvent(&ev)) {
49                 switch(ev.type) {
50                 case SDL_QUIT:
51                         goto end;
52
53                 case SDL_KEYDOWN:
54                 case SDL_KEYUP:
55                         if(ev.key.keysym.sym == SDLK_ESCAPE) {
56                                 goto end;
57                         }
58                         wt_inp_key(ev.key.keysym.sym, ev.key.state == SDL_PRESSED);
59                         break;
60
61                 case SDL_MOUSEBUTTONDOWN:
62                 case SDL_MOUSEBUTTONUP:
63                         wt_inp_mouse(ev.button.button - SDL_BUTTON_LEFT, ev.button.state == SDL_PRESSED,
64                                         ev.button.x, ev.button.y);
65                         break;
66
67                 case SDL_MOUSEMOTION:
68                         wt_inp_motion(ev.motion.x, ev.motion.y);
69                         break;
70
71                 case SDL_VIDEORESIZE:
72                         fb_width = ev.resize.w;
73                         fb_height = ev.resize.h;
74                         wt_viewport(0, 0, ev.resize.w, ev.resize.h);
75                         break;
76
77                 default:
78                         break;
79                 }
80
81                 if(SDL_MUSTLOCK(fbsurf)) {
82                         SDL_LockSurface(fbsurf);
83                 }
84                 fb = fbsurf->pixels;
85                 wt_draw();
86                 if(SDL_MUSTLOCK(fbsurf)) {
87                         SDL_UnlockSurface(fbsurf);
88                 }
89
90                 num_upd = wt_num_upd();
91                 for(i=0; i<num_upd; i++) {
92                         rect = wt_upd_rect(i);
93                         SDL_UpdateRect(fbsurf, rect->x, rect->y, rect->w, rect->h);
94                 }
95         }
96
97 end:
98         wt_destroy();
99         SDL_Quit();
100         return 0;
101 }
102
103 /* ------ graphics callbacks -------- */
104 static uint32_t colors[32];
105 static int maxcol, curcol;
106
107 static int gfx_newcol(int r, int g, int b)
108 {
109         int i;
110         uint32_t pcol;
111
112         pcol = ((r >> pfmt->Rloss) << pfmt->Rshift) & pfmt->Rmask;
113         pcol |= ((g >> pfmt->Gloss) << pfmt->Gshift) & pfmt->Gmask;
114         pcol |= ((b >> pfmt->Bloss) << pfmt->Bshift) & pfmt->Bmask;
115
116         for(i=0; i<maxcol; i++) {
117                 if(colors[i] == pcol) {
118                         return i;
119                 }
120         }
121
122         if(maxcol >= 32) return -1;
123
124         colors[maxcol] = pcol;
125         return maxcol++;
126 }
127
128 static void gfx_color(int c)
129 {
130         curcol = c;
131 }
132
133 static void gfx_fillrect(struct wt_rect *r)
134 {
135         int i, j, x, y, w, h;
136         uint32_t pcol = colors[curcol];
137         uint32_t *fbptr;
138
139         w = r->w;
140         h = r->h;
141         x = r->x;
142         y = r->y;
143
144         if(x < 0) {
145                 w += x;
146                 x = 0;
147         }
148         if(y < 0) {
149                 h += y;
150                 y = 0;
151         }
152         if(x + w >= fb_width) {
153                 w = fb_width - x;
154         }
155         if(y + h >= fb_height) {
156                 h = fb_height - y;
157         }
158
159         fbptr = fb + y * (fbsurf->pitch >> 2) + x;
160         for(i=0; i<h; i++) {
161                 for(j=0; j<w; j++) {
162                         fbptr[j] = pcol;
163                 }
164                 fbptr += fbsurf->pitch >> 2;
165         }
166 }
167
168 static void gfx_line(int x0, int y0, int x1, int y1)
169 {
170 }