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