Rewrite this one later.
[cascardo/movie.git] / movie.c
1 /*
2  *  Copyright (C) 2008  Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #define WIDTH 800
20 #define HEIGHT 600
21 #define FPS (25)
22 #define FRAME_INTERVAL (1000/FPS)
23
24 #include <glib.h>
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <SDL.h>
29 #include <SDL_image.h>
30
31 #define SWAP(x, y) do { \
32         x ^= y; y ^= x; x ^= y; \
33         } while (0)
34
35 #define IS_CENTER(cx, cy, x, y) \
36         ((x + WIDTH/2 == cx) && (y + HEIGHT/2 == cy))
37
38 GArray *points;
39 GPtrArray *names;
40
41 void
42 InsertLine (GArray *points, SDL_Rect *src, SDL_Rect *dst)
43 {
44   SDL_Rect rect;
45   int inc, err, thre, swap;
46   int x1, y1, x2, y2;
47   int x, y;
48   rect.w = WIDTH;
49   rect.h = HEIGHT;
50   err = 0;
51   swap = 0;
52   x1 = src->x;
53   y1 = src->y;
54   x2 = dst->x;
55   y2 = dst->y;
56   inc = y2 - y1;
57   thre = x2 - x1;
58   if (ABS (inc) > ABS (thre))
59   {
60     SWAP (inc, thre);
61     SWAP (x1, y1);
62     SWAP (x2, y2);
63     swap = 1;
64   }
65   for (y = y1, x = x1; (x2 < x1) ? (x >= x2) : (x <= x2); (x2 < x1) ? x-- : x++)
66   {
67     rect.x = (swap ? y : x);
68     rect.y = (swap ? x : y);
69     g_array_append_val (points, rect);
70     err += ABS (inc);
71     if (err >= ABS (thre))
72     {
73       err -= ABS (thre);
74       y += (inc < 0) ? -1 : 1;
75     }
76   }
77 }
78
79 void
80 ReadPoints (char *filename)
81 {
82   FILE *file;
83   char *buffer;
84   char *next;
85   size_t len;
86   ssize_t r;
87   int i = 0;
88   SDL_Rect last;
89   SDL_Rect rect;
90   file = fopen (filename, "r");
91   points = g_array_new (FALSE, TRUE, sizeof (SDL_Rect));
92   names = g_ptr_array_new ();
93   buffer = NULL;
94   len = 0;
95   rect.x = rect.y = rect.w = rect.h = 0;
96   last = rect;
97   while (!feof (file))
98   {
99     r = getline (&buffer, &len, file);
100     buffer[r - 1] = '\0';
101     rect.x = strtol (buffer, &next, 0);
102     rect.y = strtol (next+1, &next, 0);
103     strtol (next, &next, 0);
104     if (i > 0)
105       InsertLine (points, &last, &rect);
106     while (isspace (*next)) next++;
107     g_ptr_array_add (names, strdup (next));
108     last = rect;
109     i++;
110   }
111   fclose (file);
112 }
113
114 void
115 ShowPoint (SDL_Surface *screen, SDL_Surface *image, SDL_Rect center, double scale)
116 {
117   center.x = (center.x * scale) - WIDTH/2;
118   center.y = (center.y * scale) - HEIGHT/2;
119   center.w = WIDTH;
120   center.h = HEIGHT;
121   SDL_BlitSurface (image, &center, screen, NULL);
122   SDL_UpdateRect (screen, 0, 0, 0, 0);
123 }
124
125 #define SCALE 2.0
126
127 int
128 main (int argc, char **argv)
129 {
130   SDL_Surface *screen;
131   SDL_Surface *image;
132   SDL_Surface *scaled_image;
133   SDL_Rect rect;
134   SDL_Event event;
135   Uint32 last, now, deslast, start;
136   int i, des, desl;
137   ReadPoints ("pro-gnu");
138   SDL_Init (SDL_INIT_VIDEO | SDL_INIT_TIMER);
139   screen = SDL_SetVideoMode (800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
140   image = IMG_Load ("/home/cascardo/fotos/debconf.jpg");
141   scaled_image = CairoScale (image, SCALE);
142   start = deslast = last = SDL_GetTicks ();
143   desl = des = i = 0;
144   while (1)
145   {
146     if (SDL_PollEvent (&event))
147     {
148       if (event.type == SDL_KEYDOWN)
149         break;
150     }
151     now = SDL_GetTicks ();
152     /* skip */
153     while (now > last + FRAME_INTERVAL)
154     {
155       last += FRAME_INTERVAL;
156       i++;
157     }
158     last = now;
159     if (now > deslast + 1000)
160     {
161       printf ("%f %f %d\n", (double) des / (double) (now - start) * 1000, (double) (des - desl) / (double) (now - deslast) * 1000, i - des);
162       desl = des;
163       deslast = now;
164     }
165     if (i > points->len)
166     {
167       des -= i;
168       i = 0;
169     }
170     rect = g_array_index (points, SDL_Rect, i);
171     ShowPoint (screen, scaled_image, rect, SCALE);
172     SDL_Delay (FRAME_INTERVAL - (now - last));
173     i++;
174     des++;
175   }
176   SDL_FreeSurface (image);
177   SDL_Quit ();
178   g_array_free (points, TRUE);
179   for (i = 0; i < names->len; i++)
180     free (g_ptr_array_index (names, i));
181   g_ptr_array_free (names, TRUE);
182   return 0;
183 }