mveplayer working in Visual C++
[btb/d2x.git] / libmve / mve_main.c
1 /* $Id: mve_main.c,v 1.5 2003-11-26 03:07:45 btb Exp $ */
2
3 #include <stdlib.h>
4 #include <assert.h>
5
6 #ifdef _WIN32
7 # include <windows.h>
8 #endif
9
10 #ifdef _WIN32_WCE // should really be checking for "Pocket PC" somehow
11 # define LANDSCAPE
12 #endif
13
14 #include <SDL.h>
15
16 #include "libmve.h"
17
18
19 static SDL_Surface *g_screen;
20 #ifdef LANDSCAPE
21 static SDL_Surface *real_screen;
22 #endif
23 static unsigned char g_palette[768];
24 static int g_truecolor;
25
26 static int doPlay(const char *filename);
27
28 static void usage(void)
29 {
30         fprintf(stderr, "usage: mveplay filename\n");
31         exit(1);
32 }
33
34 int main(int c, char **v)
35 {
36         if (c != 2)
37                 usage();
38
39         if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
40         {
41                 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
42                 exit(1);
43         }
44         atexit(SDL_Quit);
45
46         return doPlay(v[1]);
47 }
48
49
50 #ifdef LANDSCAPE
51 /* Create a new rotated surface for drawing */
52 SDL_Surface *CreateRotatedSurface(SDL_Surface *s)
53 {
54     return(SDL_CreateRGBSurface(s->flags, s->h, s->w,
55     s->format->BitsPerPixel,
56     s->format->Rmask,
57     s->format->Gmask,
58     s->format->Bmask,
59     s->format->Amask));
60 }
61
62 /* Used to copy the rotated scratch surface to the screen */
63 void BlitRotatedSurface(SDL_Surface *from, SDL_Surface *to)
64 {
65
66     int bpp = from->format->BytesPerPixel;
67     int w=from->w, h=from->h, pitch=to->pitch;
68     int i,j;
69     Uint8 *pfrom, *pto, *to0;
70
71     SDL_LockSurface(from);
72     SDL_LockSurface(to);
73     pfrom=(Uint8 *)from->pixels;
74     to0=(Uint8 *) to->pixels+pitch*(w-1);
75     for (i=0; i<h; i++)
76     {
77         to0+=bpp;
78         pto=to0;
79         for (j=0; j<w; j++)
80         {
81             if (bpp==1) *pto=*pfrom;
82             else if (bpp==2) *(Uint16 *)pto=*(Uint16 *)pfrom;
83             else if (bpp==4) *(Uint32 *)pto=*(Uint32 *)pfrom;
84             else if (bpp==3)
85                 {
86                     pto[0]=pfrom[0];
87                     pto[1]=pfrom[1];
88                     pto[2]=pfrom[2];
89                 }
90             pfrom+=bpp;
91             pto-=pitch;
92         }
93     }
94     SDL_UnlockSurface(from);
95     SDL_UnlockSurface(to);
96 }
97 #endif
98
99
100 static unsigned int fileRead(void *handle, void *buf, unsigned int count)
101 {
102         unsigned numread;
103
104         numread = fread(buf, 1, count, (FILE *)handle);
105         return (numread == count);
106 }
107
108 static void showFrame(unsigned char *buf, unsigned int bufw, unsigned int bufh,
109                                           unsigned int sx, unsigned int sy,
110                                           unsigned int w, unsigned int h,
111                                           unsigned int dstx, unsigned int dsty)
112 {
113         int i;
114         unsigned char *pal;
115         SDL_Surface *sprite;
116         SDL_Rect srcRect, destRect;
117
118         assert(bufw == w && bufh == h);
119
120         if (g_truecolor)
121                 sprite = SDL_CreateRGBSurfaceFrom(buf, bufw, bufh, 16, 2 * bufw, 0x7C00, 0x03E0, 0x001F, 0);
122         else
123         {
124                 sprite = SDL_CreateRGBSurfaceFrom(buf, bufw, bufh, 8, bufw, 0x7C00, 0x03E0, 0x001F, 0);
125
126                 pal = g_palette;
127                 for(i = 0; i < 256; i++)
128                 {
129                         sprite->format->palette->colors[i].r = (*pal++) << 2;
130                         sprite->format->palette->colors[i].g = (*pal++) << 2;
131                         sprite->format->palette->colors[i].b = (*pal++) << 2;
132                         sprite->format->palette->colors[i].unused = 0;
133                 }
134         }
135
136         srcRect.x = sx;
137         srcRect.y = sy;
138         srcRect.w = w;
139         srcRect.h = h;
140         destRect.x = dstx;
141         destRect.y = dsty;
142         destRect.w = w;
143         destRect.h = h;
144
145         SDL_BlitSurface(sprite, &srcRect, g_screen, &destRect);
146 #ifdef LANDSCAPE
147         BlitRotatedSurface(g_screen, real_screen);
148         if ( (real_screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF )
149                 SDL_Flip(real_screen);
150         else
151                 SDL_UpdateRect(real_screen, 0, 0, 0, 0);
152 #else
153         if ( (g_screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF )
154                 SDL_Flip(g_screen);
155         else
156                 SDL_UpdateRects(g_screen, 1, &destRect);
157 #endif
158         SDL_FreeSurface(sprite);
159 }
160
161 static void setPalette(unsigned char *p, unsigned start, unsigned count)
162 {
163         //Set color 0 to be black
164         g_palette[0] = g_palette[1] = g_palette[2] = 0;
165
166         //Set color 255 to be our subtitle color
167         g_palette[765] = g_palette[766] = g_palette[767] = 50;
168
169         //movie libs palette into our array
170         memcpy(g_palette + start*3, p+start*3, count*3);
171 }
172
173 static int pollEvents()
174 {
175         SDL_Event event;
176
177         while (SDL_PollEvent(&event))
178         {
179                 switch(event.type)
180                 {
181                 case SDL_QUIT:
182                         return 1;
183                 case SDL_KEYDOWN:
184                         switch (event.key.keysym.sym)
185                         {
186                         case SDLK_ESCAPE:
187                         case SDLK_q:
188                                 return 1;
189                         case SDLK_f:
190                                 SDL_WM_ToggleFullScreen(g_screen);
191                                 break;
192                         default:
193                                 break;
194                         }
195                         break;
196                 default:
197                         break;
198                 }
199         }
200
201         return 0;
202 }
203
204 static int doPlay(const char *filename)
205 {
206         int result;
207         int done = 0;
208         int bpp = 0;
209         FILE *mve;
210         MVE_videoSpec vSpec;
211
212         mve = fopen(filename, "rb");
213         if (mve == NULL) {
214                 fprintf(stderr, "can't open MVE file\n");
215                 return 1;
216         }
217
218         memset(g_palette, 0, 768);
219
220         MVE_sndInit(1);
221         MVE_memCallbacks(malloc, free);
222         MVE_ioCallbacks(fileRead);
223         MVE_sfCallbacks(showFrame);
224         MVE_palCallbacks(setPalette);
225
226         MVE_rmPrepMovie(mve, -1, -1, 1);
227
228         MVE_getVideoSpec(&vSpec);
229
230 #ifndef _WIN32_WCE // doesn't like to change bpp?
231         bpp = vSpec.truecolor?16:8;
232 #endif
233
234 #ifdef LANDSCAPE
235         real_screen = SDL_SetVideoMode(vSpec.screenHeight, vSpec.screenWidth, bpp, SDL_FULLSCREEN);
236         g_screen = CreateRotatedSurface(real_screen);
237 #else
238         g_screen = SDL_SetVideoMode(vSpec.screenWidth, vSpec.screenHeight, bpp, SDL_ANYFORMAT);
239 #endif
240
241         g_truecolor = vSpec.truecolor;
242
243         while (!done && (result = MVE_rmStepMovie()) == 0)
244         {
245                 done = pollEvents();
246         }
247
248         MVE_rmEndMovie();
249
250         fclose(mve);
251
252         return 0;
253 }