From 62577c32e9aca6a42809a03c5b2a4da0cbfb2672 Mon Sep 17 00:00:00 2001 From: Thadeu Lima de Souza Cascardo Date: Wed, 13 Aug 2008 19:32:51 -0300 Subject: [PATCH] Calculates the points before showing the video Instead of calculating each point just before showing a frame, calculate all of them and store them on an array that we use to get the next center of image. --- movie.c | 181 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 105 insertions(+), 76 deletions(-) diff --git a/movie.c b/movie.c index f5ef008..b2d85e3 100644 --- a/movie.c +++ b/movie.c @@ -18,6 +18,10 @@ #define WIDTH 800 #define HEIGHT 600 +#define FPS (200) +#define FRAME_INTERVAL (1000/FPS) + +#include #include #include @@ -28,13 +32,49 @@ x ^= y; y ^= x; x ^= y; \ } while (0) -#define ABS(x) ((x) < 0 ? -(x) : (x)) - #define IS_CENTER(cx, cy, x, y) \ ((x + WIDTH/2 == cx) && (y + HEIGHT/2 == cy)) -SDL_Rect *points; -int psize; +GArray *points; +GPtrArray *names; + +void +InsertLine (GArray *points, SDL_Rect *src, SDL_Rect *dst) +{ + SDL_Rect rect; + int inc, err, thre, swap; + int x1, y1, x2, y2; + int x, y; + rect.w = WIDTH; + rect.h = HEIGHT; + err = 0; + swap = 0; + x1 = src->x; + y1 = src->y; + x2 = dst->x; + y2 = dst->y; + inc = y2 - y1; + thre = x2 - x1; + if (ABS (inc) > ABS (thre)) + { + SWAP (inc, thre); + SWAP (x1, y1); + SWAP (x2, y2); + swap = 1; + } + for (y = y1, x = x1; (x2 < x1) ? (x >= x2) : (x <= x2); (x2 < x1) ? x-- : x++) + { + rect.x = (swap ? y : x); + rect.y = (swap ? x : y); + g_array_append_val (points, rect); + err += ABS (inc); + if (err >= ABS (thre)) + { + err -= ABS (thre); + y += (inc < 0) ? -1 : 1; + } + } +} void ReadPoints (char *filename) @@ -43,104 +83,93 @@ ReadPoints (char *filename) char *buffer; char *next; size_t len; - int i; + ssize_t r; + int i = 0; + SDL_Rect last; + SDL_Rect rect; file = fopen (filename, "r"); - fscanf (file, "%d\n", &psize); - points = malloc (sizeof (SDL_Rect) * psize); - if (points == NULL) - abort (); + points = g_array_new (FALSE, TRUE, sizeof (SDL_Rect)); + names = g_ptr_array_new (); buffer = NULL; len = 0; - for (i = 0; i < psize; i++) + rect.x = rect.y = rect.w = rect.h = 0; + last = rect; + while (!feof (file)) { - getline (&buffer, &len, file); - points[i].x = strtol (buffer, &next, 0); - points[i].y = strtol (next+1, NULL, 0); + r = getline (&buffer, &len, file); + buffer[r - 1] = '\0'; + rect.x = strtol (buffer, &next, 0); + rect.y = strtol (next+1, &next, 0); + strtol (next, &next, 0); + if (i > 0) + InsertLine (points, &last, &rect); + while (isspace (*next)) next++; + g_ptr_array_add (names, strdup (next)); + last = rect; + i++; } fclose (file); } -SDL_Rect * -GetNextPoint (void) -{ - static SDL_Rect rect = {0, 0, WIDTH, HEIGHT}; - static int cur = -1; - static int inc, err, thre, swap; - static int x1, y1, x2, y2; - static int x, y; - int next; - next = (cur + 1) % psize; - if ((points[next].x == rect.x && points[next].y == rect.y) || cur == -1) - { - cur = next; - next = (cur + 1) % psize; - err = 0; - swap = 0; - x1 = points[cur].x; - y1 = points[cur].y; - x2 = points[next].x; - y2 = points[next].y; - inc = y2 - y1; - thre = x2 - x1; - if (ABS (inc) > ABS (thre)) - { - SWAP (inc, thre); - SWAP (x1, y1); - SWAP (x2, y2); - swap = 1; - } - x = x1; - y = y1; - } - rect.x = (swap ? y : x); - rect.y = (swap ? x : y); - (x2 < x1) ? x-- : x++; - err += ABS (inc); - if (err >= ABS (thre)) - { - err -= ABS (thre); - y += (inc < 0) ? -1 : 1; - } - return ▭ -} - void -ShowPoint (SDL_Surface *screen, SDL_Surface *image, SDL_Rect *rect) +ShowPoint (SDL_Surface *screen, SDL_Surface *image, SDL_Rect center, double scale) { - SDL_BlitSurface (image, rect, screen, NULL); + center.x = (center.x - WIDTH/2) * scale; + center.y = (center.y - HEIGHT/2) * scale; + center.w = WIDTH; + center.h = HEIGHT; + SDL_BlitSurface (image, ¢er, screen, NULL); SDL_UpdateRect (screen, 0, 0, 0, 0); } -Uint32 -ShowNext (Uint32 interval, void *data) -{ - SDL_UserEvent event; - event.type = SDL_USEREVENT; - event.code = 0; - SDL_PushEvent ((SDL_Event *) &event); - return 33; -} - int main (int argc, char **argv) { SDL_Surface *screen; SDL_Surface *image; + SDL_Rect rect; SDL_Event event; + Uint32 last, now, deslast, start; + int i, des, desl; ReadPoints ("pro-gnu"); SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER); screen = SDL_SetVideoMode (800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); image = IMG_Load ("/home/cascardo/fotos/debconf.jpg"); - SDL_AddTimer (0, ShowNext, NULL); - while (SDL_WaitEvent (&event)) + start = deslast = last = SDL_GetTicks (); + desl = des = i = 0; + while (1) { - if (event.type == SDL_KEYDOWN) - break; - else if (event.type == SDL_USEREVENT) - ShowPoint (screen, image, GetNextPoint ()); + if (SDL_PollEvent (&event)) + { + if (event.type == SDL_KEYDOWN) + break; + } + now = SDL_GetTicks (); + /* skip */ + if (now > deslast + 1000) + { + printf ("%f %f\n", (double) (now - start) / (double) des, (double) (now - deslast) / (double) (des - desl)); + desl = des; + deslast = now; + } + while (now > last + FRAME_INTERVAL) + { + last += FRAME_INTERVAL; + i++; + } + if (i > points->len) + i = 0; + rect = g_array_index (points, SDL_Rect, i); + ShowPoint (screen, image, rect, 1.0); + SDL_Delay (FRAME_INTERVAL - (now - last)); + i++; + des++; } SDL_FreeSurface (image); SDL_Quit (); - free (points); + g_array_free (points, TRUE); + for (i = 0; i < names->len; i++) + free (g_ptr_array_index (names, i)); + g_ptr_array_free (names, TRUE); return 0; } -- 2.20.1