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