dirty redraw and SDL framebuffer example
[windtk] / example_sdl.c
diff --git a/example_sdl.c b/example_sdl.c
new file mode 100644 (file)
index 0000000..deb7fce
--- /dev/null
@@ -0,0 +1,170 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <SDL/SDL.h>
+#include "windtk.h"
+
+static int gfx_newcol(int r, int g, int b);
+static void gfx_color(int c);
+static void gfx_fillrect(struct wt_rect *r);
+static void gfx_line(int x0, int y0, int x1, int y1);
+
+static struct wt_graphics gfx = {
+       0,
+       gfx_newcol, gfx_color,
+       gfx_fillrect,
+       gfx_line
+};
+
+static SDL_Surface *fbsurf;
+static SDL_PixelFormat *pfmt;
+static int fb_width = 800, fb_height = 600;
+static uint32_t *fb;
+
+int main(void)
+{
+       int i, num_upd;
+       struct wt_rect *rect;
+       SDL_Event ev;
+
+       if(SDL_Init(SDL_INIT_VIDEO) == -1) {
+               fprintf(stderr, "failed to initialize SDL\n");
+               return 1;
+       }
+
+       if(!(fbsurf = SDL_SetVideoMode(fb_width, fb_height, 32, SDL_SWSURFACE | SDL_RESIZABLE))) {
+               fprintf(stderr, "failed to set video mode\n");
+               SDL_Quit();
+               return 1;
+       }
+       pfmt = fbsurf->format;
+
+       SDL_FillRect(fbsurf, 0, 0);
+
+       if(wt_init(fb_width, fb_height, &gfx) == -1) {
+               return 1;
+       }
+       wt_window(0, "foo", WT_WS_DEFAULT, 100, 100, 200, 200);
+
+       while(SDL_WaitEvent(&ev)) {
+               switch(ev.type) {
+               case SDL_QUIT:
+                       goto end;
+
+               case SDL_KEYDOWN:
+               case SDL_KEYUP:
+                       if(ev.key.keysym.sym == SDLK_ESCAPE) {
+                               goto end;
+                       }
+                       wt_inp_key(ev.key.keysym.sym, ev.key.state == SDL_PRESSED);
+                       break;
+
+               case SDL_MOUSEBUTTONDOWN:
+               case SDL_MOUSEBUTTONUP:
+                       wt_inp_mouse(ev.button.button - SDL_BUTTON_LEFT, ev.button.state == SDL_PRESSED,
+                                       ev.button.x, ev.button.y);
+                       break;
+
+               case SDL_MOUSEMOTION:
+                       wt_inp_motion(ev.motion.x, ev.motion.y);
+                       break;
+
+               case SDL_VIDEORESIZE:
+                       fb_width = ev.resize.w;
+                       fb_height = ev.resize.h;
+                       wt_viewport(0, 0, ev.resize.w, ev.resize.h);
+                       break;
+
+               default:
+                       break;
+               }
+
+               if(SDL_MUSTLOCK(fbsurf)) {
+                       SDL_LockSurface(fbsurf);
+               }
+               fb = fbsurf->pixels;
+               wt_draw();
+               if(SDL_MUSTLOCK(fbsurf)) {
+                       SDL_UnlockSurface(fbsurf);
+               }
+
+               num_upd = wt_num_upd();
+               for(i=0; i<num_upd; i++) {
+                       rect = wt_upd_rect(i);
+                       SDL_UpdateRect(fbsurf, rect->x, rect->y, rect->w, rect->h);
+               }
+       }
+
+end:
+       wt_destroy();
+       SDL_Quit();
+       return 0;
+}
+
+/* ------ graphics callbacks -------- */
+static uint32_t colors[32];
+static int maxcol, curcol;
+
+static int gfx_newcol(int r, int g, int b)
+{
+       int i;
+       uint32_t pcol;
+
+       pcol = ((r >> pfmt->Rloss) << pfmt->Rshift) & pfmt->Rmask;
+       pcol |= ((g >> pfmt->Gloss) << pfmt->Gshift) & pfmt->Gmask;
+       pcol |= ((b >> pfmt->Bloss) << pfmt->Bshift) & pfmt->Bmask;
+
+       for(i=0; i<maxcol; i++) {
+               if(colors[i] == pcol) {
+                       return i;
+               }
+       }
+
+       if(maxcol >= 32) return -1;
+
+       colors[maxcol] = pcol;
+       return maxcol++;
+}
+
+static void gfx_color(int c)
+{
+       curcol = c;
+}
+
+static void gfx_fillrect(struct wt_rect *r)
+{
+       int i, j, x, y, w, h;
+       uint32_t pcol = colors[curcol];
+       uint32_t *fbptr;
+
+       w = r->w;
+       h = r->h;
+       x = r->x;
+       y = r->y;
+
+       if(x < 0) {
+               w += x;
+               x = 0;
+       }
+       if(y < 0) {
+               h += y;
+               y = 0;
+       }
+       if(x + w >= fb_width) {
+               w = fb_width - x;
+       }
+       if(y + h >= fb_height) {
+               h = fb_height - y;
+       }
+
+       fbptr = fb + y * (fbsurf->pitch >> 2) + x;
+       for(i=0; i<h; i++) {
+               for(j=0; j<w; j++) {
+                       fbptr[j] = pcol;
+               }
+               fbptr += fbsurf->pitch >> 2;
+       }
+}
+
+static void gfx_line(int x0, int y0, int x1, int y1)
+{
+}