merged libmovie from physfs branch
[btb/d2x.git] / libmve / mve_main.c
1 /* $Id: mve_main.c,v 1.3 2003-06-10 04:46:16 btb Exp $ */
2
3 #include <stdlib.h>
4 #include <assert.h>
5
6 #include <SDL.h>
7
8 #include "libmve.h"
9
10
11 static SDL_Surface *g_screen;
12 static unsigned char g_palette[768];
13 static int g_truecolor;
14
15 static int doPlay(const char *filename);
16
17 static void usage(void)
18 {
19         fprintf(stderr, "usage: mveplay filename\n");
20         exit(1);
21 }
22
23 int main(int c, char **v)
24 {
25         if (c != 2)
26                 usage();
27
28         if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
29         {
30                 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
31                 exit(1);
32         }
33         atexit(SDL_Quit);
34
35         return doPlay(v[1]);
36 }
37
38 static unsigned int fileRead(void *handle, void *buf, unsigned int count)
39 {
40         unsigned numread;
41
42         numread = fread(buf, 1, count, (FILE *)handle);
43         return (numread == count);
44 }
45
46 static void showFrame(unsigned char *buf, unsigned int bufw, unsigned int bufh,
47                                           unsigned int sx, unsigned int sy,
48                                           unsigned int w, unsigned int h,
49                                           unsigned int dstx, unsigned int dsty)
50 {
51         int i;
52         unsigned char *pal;
53         SDL_Surface *sprite;
54         SDL_Rect srcRect, destRect;
55
56         assert(bufw == w && bufh == h);
57
58         if (g_truecolor)
59                 sprite = SDL_CreateRGBSurfaceFrom(buf, bufw, bufh, 16, 2 * bufw, 0x7C00, 0x03E0, 0x001F, 0);
60         else
61         {
62                 sprite = SDL_CreateRGBSurfaceFrom(buf, bufw, bufh, 8, bufw, 0x7C00, 0x03E0, 0x001F, 0);
63
64                 pal = g_palette;
65                 for(i = 0; i < 256; i++)
66                 {
67                         sprite->format->palette->colors[i].r = (*pal++) << 2;
68                         sprite->format->palette->colors[i].g = (*pal++) << 2;
69                         sprite->format->palette->colors[i].b = (*pal++) << 2;
70                         sprite->format->palette->colors[i].unused = 0;
71                 }
72         }
73
74         srcRect.x = sx;
75         srcRect.y = sy;
76         srcRect.w = w;
77         srcRect.h = h;
78         destRect.x = dstx;
79         destRect.y = dsty;
80         destRect.w = w;
81         destRect.h = h;
82
83         SDL_BlitSurface(sprite, &srcRect, g_screen, &destRect);
84         if ( (g_screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF )
85                 SDL_Flip(g_screen);
86         else
87                 SDL_UpdateRects(g_screen, 1, &destRect);
88         SDL_FreeSurface(sprite);
89 }
90
91 static void setPalette(unsigned char *p, unsigned start, unsigned count)
92 {
93         //Set color 0 to be black
94         g_palette[0] = g_palette[1] = g_palette[2] = 0;
95
96         //Set color 255 to be our subtitle color
97         g_palette[765] = g_palette[766] = g_palette[767] = 50;
98
99         //movie libs palette into our array
100         memcpy(g_palette + start*3, p+start*3, count*3);
101 }
102
103 static int pollEvents()
104 {
105         SDL_Event event;
106
107         while (SDL_PollEvent(&event))
108         {
109                 switch(event.type)
110                 {
111                 case SDL_QUIT:
112                         return 1;
113                 case SDL_KEYDOWN:
114                         switch (event.key.keysym.sym)
115                         {
116                         case SDLK_ESCAPE:
117                         case SDLK_q:
118                                 return 1;
119                         case SDLK_f:
120                                 SDL_WM_ToggleFullScreen(g_screen);
121                                 break;
122                         default:
123                                 break;
124                         }
125                         break;
126                 default:
127                         break;
128                 }
129         }
130
131         return 0;
132 }
133
134 static int doPlay(const char *filename)
135 {
136         int result;
137         int done = 0;
138         FILE *mve;
139         MVE_videoSpec vSpec;
140
141         mve = fopen(filename, "rb");
142         if (mve == NULL) {
143                 fprintf(stderr, "can't open MVE file\n");
144                 return 1;
145         }
146
147         memset(g_palette, 0, 768);
148
149         MVE_sndInit(1);
150         MVE_memCallbacks(malloc, free);
151         MVE_ioCallbacks(fileRead);
152         MVE_sfCallbacks(showFrame);
153         MVE_palCallbacks(setPalette);
154
155         MVE_rmPrepMovie(mve, -1, -1, 1);
156
157         MVE_getVideoSpec(&vSpec);
158
159         g_screen = SDL_SetVideoMode(vSpec.screenWidth, vSpec.screenHeight, vSpec.truecolor?16:8, SDL_ANYFORMAT);
160
161         g_truecolor = vSpec.truecolor;
162
163         while (!done && (result = MVE_rmStepMovie()) == 0)
164         {
165                 done = pollEvents();
166         }
167
168         MVE_rmEndMovie();
169
170         fclose(mve);
171
172         return 0;
173 }