14 #include <SDL/SDL_thread.h>
20 #include "mve_audio.h"
27 #define MIN(a,b) ((a)<(b)?(a):(b))
32 static int g_spdFactorNum=0;
33 static int g_spdFactorDenom=10;
35 static short get_short(unsigned char *data)
38 value = data[0] | (data[1] << 8);
42 static int get_int(unsigned char *data)
45 value = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
49 static int default_seg_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
51 Warning("mveplay: unknown chunk type %02x/%02x\n", major, minor);
55 /*************************
57 *************************/
58 static int end_movie_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
63 /*************************
65 *************************/
70 static fix fix_frame_delay = F0_0;
71 static int timer_started = 0;
72 static fix timer_expire = F0_0;
74 static int create_timer_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
77 int micro_frame_delay = get_int(data) * (int)get_short(data+4);
79 if (g_spdFactorNum != 0)
81 temp = micro_frame_delay;
82 temp *= g_spdFactorNum;
83 temp /= g_spdFactorDenom;
84 micro_frame_delay = (int)temp;
86 fix_frame_delay = approx_usec_to_fsec(micro_frame_delay);
91 static void timer_stop(void)
97 static void timer_start(void)
99 timer_expire = timer_get_fixed_seconds();
101 timer_expire += fix_frame_delay;
106 static void do_timer_wait(void)
113 tv = timer_get_fixed_seconds();
115 if (tv > timer_expire)
118 ts = timer_expire - tv;
123 timer_expire += fix_frame_delay;
126 /*************************
128 *************************/
129 static void mve_audio_callback(void *userdata, Uint8 *stream, int len);
130 static short *mve_audio_buffers[64];
131 static int mve_audio_buflens[64];
132 static int mve_audio_curbuf_curpos=0;
133 static int mve_audio_bufhead=0;
134 static int mve_audio_buftail=0;
135 static int mve_audio_playing=0;
136 static int mve_audio_canplay=0;
137 static int mve_audio_compressed=0;
138 static SDL_AudioSpec *mve_audio_spec=NULL;
139 static SDL_mutex *mve_audio_mutex = NULL;
141 static void mve_audio_callback(void *userdata, Uint8 *stream, int len)
145 if (mve_audio_bufhead == mve_audio_buftail)
149 fprintf(stderr, "+ <%d (%d), %d, %d>\n", mve_audio_bufhead, mve_audio_curbuf_curpos, mve_audio_buftail, len);
152 SDL_mutexP(mve_audio_mutex);
154 while (mve_audio_bufhead != mve_audio_buftail /* while we have more buffers */
155 && len > (mve_audio_buflens[mve_audio_bufhead]-mve_audio_curbuf_curpos)) /* and while we need more data */
157 length = mve_audio_buflens[mve_audio_bufhead]-mve_audio_curbuf_curpos;
158 __builtin_memcpy(stream, /* cur output position */
159 mve_audio_buffers[mve_audio_bufhead]+mve_audio_curbuf_curpos, /* cur input position */
160 length); /* cur input length */
163 stream += length; /* advance output */
164 len -= length; /* decrement avail ospace */
165 d_free(mve_audio_buffers[mve_audio_bufhead]); /* free the buffer */
166 mve_audio_buffers[mve_audio_bufhead]=NULL; /* free the buffer */
167 mve_audio_buflens[mve_audio_bufhead]=0; /* free the buffer */
169 if (++mve_audio_bufhead == 64) /* next buffer */
170 mve_audio_bufhead = 0;
171 mve_audio_curbuf_curpos = 0;
175 fprintf(stderr, "= <%d (%d), %d, %d>: %d\n", mve_audio_bufhead, mve_audio_curbuf_curpos, mve_audio_buftail, len, total);
179 if (len != 0 /* ospace remaining */
180 && mve_audio_bufhead != mve_audio_buftail) /* buffers remaining */
182 __builtin_memcpy(stream, /* dest */
183 mve_audio_buffers[mve_audio_bufhead] + mve_audio_curbuf_curpos, /* src */
186 mve_audio_curbuf_curpos += len; /* advance input */
187 stream += len; /* advance output (unnecessary) */
188 len -= len; /* advance output (unnecessary) */
190 if (mve_audio_curbuf_curpos >= mve_audio_buflens[mve_audio_bufhead]) /* if this ends the current chunk */
192 d_free(mve_audio_buffers[mve_audio_bufhead]); /* free buffer */
193 mve_audio_buffers[mve_audio_bufhead]=NULL;
194 mve_audio_buflens[mve_audio_bufhead]=0;
196 if (++mve_audio_bufhead == 64) /* next buffer */
197 mve_audio_bufhead = 0;
198 mve_audio_curbuf_curpos = 0;
203 fprintf(stderr, "- <%d (%d), %d, %d>\n", mve_audio_bufhead, mve_audio_curbuf_curpos, mve_audio_buftail, len);
205 SDL_mutexV(mve_audio_mutex);
208 static int create_audiobuf_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
215 fprintf(stderr, "creating audio buffers\n");
218 mve_audio_mutex = SDL_CreateMutex();
220 flags = get_short(data + 2);
221 sample_rate = get_short(data + 4);
222 desired_buffer = get_int(data + 6);
225 fprintf(stderr, "stereo=%d 16bit=%d compressed=%d sample_rate=%d desired_buffer=%d\n",
226 flags & 1, (flags >> 1) & 1, (flags >> 2) & 1, sample_rate, desired_buffer);
229 mve_audio_compressed = flags & MVE_AUDIO_FLAGS_COMPRESSED;
231 mve_audio_spec = (SDL_AudioSpec *)d_malloc(sizeof(SDL_AudioSpec));
232 mve_audio_spec->freq = sample_rate;
233 #ifdef WORDS_BIGENDIAN
234 mve_audio_spec->format = (flags & MVE_AUDIO_FLAGS_16BIT)?AUDIO_S16MSB:AUDIO_U8;
236 mve_audio_spec->format = (flags & MVE_AUDIO_FLAGS_16BIT)?AUDIO_S16LSB:AUDIO_U8;
238 mve_audio_spec->channels = (flags & MVE_AUDIO_FLAGS_STEREO)?2:1;
239 mve_audio_spec->samples = 32768;
240 mve_audio_spec->callback = mve_audio_callback;
241 mve_audio_spec->userdata = NULL;
242 if (SDL_OpenAudio(mve_audio_spec, NULL) >= 0)
245 fprintf(stderr, " success\n");
247 mve_audio_canplay = 1;
252 fprintf(stderr, " failure : %s\n", SDL_GetError());
254 Warning("mveplay: failed to create audio buffers\n");
255 mve_audio_canplay = 0;
258 memset(mve_audio_buffers, 0, sizeof(mve_audio_buffers));
259 memset(mve_audio_buflens, 0, sizeof(mve_audio_buflens));
264 static int play_audio_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
266 if (mve_audio_canplay && !mve_audio_playing && mve_audio_bufhead != mve_audio_buftail)
269 mve_audio_playing = 1;
275 static int audio_data_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
277 static const int selected_chan=1;
280 if (mve_audio_canplay)
282 if (mve_audio_playing)
285 chan = get_short(data + 2);
286 nsamp = get_short(data + 4);
287 if (chan & selected_chan)
289 SDL_mutexP(mve_audio_mutex);
290 mve_audio_buflens[mve_audio_buftail] = nsamp;
291 if (mve_audio_buffers[mve_audio_buftail])
292 d_free(mve_audio_buffers[mve_audio_buftail]);
293 mve_audio_buffers[mve_audio_buftail] = (short *)d_malloc(nsamp+4);
295 if (mve_audio_compressed)
296 mveaudio_uncompress(mve_audio_buffers[mve_audio_buftail], data, -1); /* XXX */
298 memcpy(mve_audio_buffers[mve_audio_buftail], data + 6, nsamp);
300 memset(mve_audio_buffers[mve_audio_buftail], 0, nsamp); /* XXX */
302 if (++mve_audio_buftail == 64)
303 mve_audio_buftail = 0;
305 if (mve_audio_buftail == mve_audio_bufhead)
306 Warning("mveplay: d'oh! buffer ring overrun (%d)\n", mve_audio_bufhead);
307 SDL_mutexV(mve_audio_mutex);
310 if (mve_audio_playing)
317 /*************************
319 *************************/
320 static grs_bitmap *g_screen;
321 static int g_screenWidth, g_screenHeight;
322 static int g_width, g_height;
323 static unsigned char g_palette[768];
324 static unsigned char *g_vBackBuf1, *g_vBackBuf2 = NULL;
325 static unsigned char *g_pCurMap=NULL;
326 static int g_nMapLength=0;
328 static int create_videobuf_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
332 h = get_short(data+2);
336 fprintf(stderr, "g_width, g_height: %d, %d\n", g_width, g_height);
338 Assert((g_width == g_screen->bm_w) && (g_height == g_screen->bm_h));
340 g_vBackBuf1 = d_malloc(g_width * g_height);
342 g_vBackBuf2 = d_malloc(g_width * g_height);
343 memset(g_vBackBuf1, 0, g_width * g_height);
344 memset(g_vBackBuf2, 0, g_width * g_height);
348 static int display_video_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
350 memcpy(g_screen->bm_data, g_vBackBuf1, g_width * g_height);
355 static int init_video_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
358 width = get_short(data);
359 height = get_short(data+2);
360 g_screenWidth = width;
361 g_screenHeight = height;
362 memset(g_palette, 0, 765);
363 // 255 needs to default to white, for subtitles, etc
364 memset(g_palette + 765, 63, 3);
368 static int video_palette_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
371 start = get_short(data);
372 count = get_short(data+2);
373 memcpy(g_palette + 3*start, data+4, 3*count);
374 gr_palette_load(g_palette);
379 static int video_codemap_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
386 static void decodeFrame(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain);
388 static int video_data_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
390 short nFrameHot, nFrameCold;
391 short nXoffset, nYoffset;
392 short nXsize, nYsize;
396 nFrameHot = get_short(data);
397 nFrameCold = get_short(data+2);
398 nXoffset = get_short(data+4);
399 nYoffset = get_short(data+6);
400 nXsize = get_short(data+8);
401 nYsize = get_short(data+10);
402 nFlags = get_short(data+12);
407 g_vBackBuf1 = g_vBackBuf2;
411 /* convert the frame */
412 decodeFrame(g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
417 static int end_chunk_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
423 /************************************************************
424 * public mveplay functions
425 ************************************************************/
427 void mveplay_initializeMovie(MVESTREAM *mve, grs_bitmap *mve_bitmap)
429 g_screen = mve_bitmap;
431 mve_set_handler(mve, 0x00, end_movie_handler);
432 mve_set_handler(mve, 0x01, end_chunk_handler);
433 mve_set_handler(mve, 0x02, create_timer_handler);
434 mve_set_handler(mve, 0x03, create_audiobuf_handler);
435 mve_set_handler(mve, 0x04, play_audio_handler);
436 mve_set_handler(mve, 0x05, create_videobuf_handler);
437 mve_set_handler(mve, 0x06, default_seg_handler);
438 mve_set_handler(mve, 0x07, display_video_handler);
439 mve_set_handler(mve, 0x08, audio_data_handler);
440 mve_set_handler(mve, 0x09, audio_data_handler);
441 mve_set_handler(mve, 0x0a, init_video_handler);
442 mve_set_handler(mve, 0x0b, default_seg_handler);
443 mve_set_handler(mve, 0x0c, video_palette_handler);
444 mve_set_handler(mve, 0x0d, default_seg_handler);
445 mve_set_handler(mve, 0x0e, default_seg_handler);
446 mve_set_handler(mve, 0x0f, video_codemap_handler);
447 mve_set_handler(mve, 0x10, default_seg_handler);
448 mve_set_handler(mve, 0x11, video_data_handler);
449 mve_set_handler(mve, 0x12, default_seg_handler);
450 //mve_set_handler(mve, 0x13, default_seg_handler);
451 mve_set_handler(mve, 0x14, default_seg_handler);
452 //mve_set_handler(mve, 0x15, default_seg_handler);
455 int mveplay_stepMovie(MVESTREAM *mve)
457 static int init_timer=0;
463 cont = mve_play_next_chunk(mve);
464 if (fix_frame_delay && !init_timer) {
474 void mveplay_restartTimer(MVESTREAM *mve)
479 void mveplay_shutdownMovie(MVESTREAM *mve)
485 for (i = 0; i < 64; i++)
486 if (mve_audio_buffers[i] != NULL)
487 d_free(mve_audio_buffers[i]);
488 memset(mve_audio_buffers, 0, sizeof(mve_audio_buffers));
489 memset(mve_audio_buflens, 0, sizeof(mve_audio_buflens));
490 mve_audio_curbuf_curpos=0;
495 mve_audio_compressed=0;
496 mve_audio_mutex = NULL;
498 d_free(mve_audio_spec);
510 /************************************************************
511 * internal decoding functions
512 ************************************************************/
514 static void dispatchDecoder(unsigned char **pFrame, unsigned char codeType, unsigned char **pData, int *pDataRemain, int *curXb, int *curYb);
516 static void decodeFrame(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain)
525 for (i=0; i<xb/2; i++)
527 dispatchDecoder(&pFrame, (*pMap) & 0xf, &pData, &dataRemain, &i, &j);
528 if (pFrame < g_vBackBuf1)
529 Warning("mveplay: danger! pointing out of bounds below after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
530 else if (pFrame >= g_vBackBuf1 + g_width*g_height)
531 Warning("mveplay: danger! pointing out of bounds above after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
532 dispatchDecoder(&pFrame, (*pMap) >> 4, &pData, &dataRemain, &i, &j);
533 if (pFrame < g_vBackBuf1)
534 Warning("mveplay: danger! pointing out of bounds below after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
535 else if (pFrame >= g_vBackBuf1 + g_width*g_height)
536 Warning("mveplay: danger! pointing out of bounds above after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
546 static void relClose(int i, int *x, int *y)
557 static void relFar(int i, int sign, int *x, int *y)
561 *x = sign * (8 + (i % 7));
566 *x = sign * (-14 + (i - 56) % 29);
567 *y = sign * (8 + (i - 56) / 29);
571 static void copyFrame(unsigned char *pDest, unsigned char *pSrc)
577 memcpy(pDest, pSrc, 8);
583 static void patternRow4Pixels(unsigned char *pFrame,
584 unsigned char pat0, unsigned char pat1,
587 unsigned short mask=0x0003;
588 unsigned short shift=0;
589 unsigned short pattern = (pat1 << 8) | pat0;
593 *pFrame++ = p[(mask & pattern) >> shift];
599 static void patternRow4Pixels2(unsigned char *pFrame,
603 unsigned char mask=0x03;
604 unsigned char shift=0;
610 pel = p[(mask & pat0) >> shift];
613 pFrame[g_width + 0] = pel;
614 pFrame[g_width + 2] = pel;
622 static void patternRow4Pixels2x1(unsigned char *pFrame, unsigned char pat, unsigned char *p)
624 unsigned char mask=0x03;
625 unsigned char shift=0;
630 pel = p[(mask & pat) >> shift];
639 static void patternQuadrant4Pixels(unsigned char *pFrame, unsigned char pat0, unsigned char pat1, unsigned char pat2, unsigned char pat3, unsigned char *p)
641 unsigned long mask = 0x00000003UL;
644 unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
648 pFrame[i&3] = p[(pat & mask) >> shift];
659 static void patternRow2Pixels(unsigned char *pFrame, unsigned char pat, unsigned char *p)
661 unsigned char mask=0x01;
665 *pFrame++ = p[(mask & pat) ? 1 : 0];
670 static void patternRow2Pixels2(unsigned char *pFrame, unsigned char pat, unsigned char *p)
673 unsigned char mask=0x1;
678 pel = p[(mask & pat) ? 1 : 0];
681 pFrame[g_width + 0] = pel;
682 pFrame[g_width + 2] = pel;
689 static void patternQuadrant2Pixels(unsigned char *pFrame, unsigned char pat0, unsigned char pat1, unsigned char *p)
691 unsigned short mask = 0x0001;
693 unsigned short pat = (pat1 << 8) | pat0;
697 pFrame[i&3] = p[(pat & mask) ? 1 : 0];
706 static void dispatchDecoder(unsigned char **pFrame, unsigned char codeType, unsigned char **pData, int *pDataRemain, int *curXb, int *curYb)
709 unsigned char pat[16];
716 copyFrame(*pFrame, *pFrame + (g_vBackBuf2 - g_vBackBuf1));
722 relFar(*(*pData)++, 1, &x, &y);
723 copyFrame(*pFrame, *pFrame + x + y*g_width);
729 relFar(*(*pData)++, -1, &x, &y);
730 copyFrame(*pFrame, *pFrame + x + y*g_width);
736 relClose(*(*pData)++, &x, &y);
737 copyFrame(*pFrame, *pFrame + (g_vBackBuf2 - g_vBackBuf1) + x + y*g_width);
743 x = (char)*(*pData)++;
744 y = (char)*(*pData)++;
745 copyFrame(*pFrame, *pFrame + (g_vBackBuf2 - g_vBackBuf1) + x + y*g_width);
754 if (++*curXb == (g_width >> 3))
756 *pFrame += 7*g_width;
758 if (++*curYb == (g_height >> 3))
771 patternRow2Pixels(*pFrame, *(*pData)++, p);
779 patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
780 *pFrame += 2*g_width;
781 patternRow2Pixels2(*pFrame, *(*pData)++ >> 4, p);
782 *pFrame += 2*g_width;
785 *pFrame -= (8*g_width - 8);
789 if ( (*pData)[0] <= (*pData)[1])
795 pat[0] = *(*pData)++;
796 pat[1] = *(*pData)++;
797 patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
800 *pFrame -= (4*g_width - 4);
802 *pFrame += 4*g_width;
805 else if ( (*pData)[6] <= (*pData)[7])
814 pat[0] = *(*pData)++;
815 pat[1] = *(*pData)++;
816 patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
819 *pFrame -= (4*g_width - 4);
821 *pFrame += 4*g_width;
833 patternRow2Pixels(*pFrame, *(*pData)++, p);
836 *pFrame -= (8*g_width - 8);
841 if ( (*pData)[0] <= (*pData)[1])
843 if ( (*pData)[2] <= (*pData)[3])
852 pat[0] = *(*pData)++;
853 pat[1] = *(*pData)++;
854 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
858 *pFrame -= (8*g_width - 8);
867 patternRow4Pixels2(*pFrame, *(*pData)++, p);
868 *pFrame += 2*g_width;
869 patternRow4Pixels2(*pFrame, *(*pData)++, p);
870 *pFrame += 2*g_width;
871 patternRow4Pixels2(*pFrame, *(*pData)++, p);
872 *pFrame += 2*g_width;
873 patternRow4Pixels2(*pFrame, *(*pData)++, p);
874 *pFrame -= (6*g_width - 8);
879 if ( (*pData)[2] <= (*pData)[3])
888 pat[0] = *(*pData)++;
889 patternRow4Pixels2x1(*pFrame, pat[0], p);
893 *pFrame -= (8*g_width - 8);
904 pat[0] = *(*pData)++;
905 pat[1] = *(*pData)++;
906 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
908 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
912 *pFrame -= (8*g_width - 8);
918 if ( (*pData)[0] <= (*pData)[1])
926 pat[0] = *(*pData)++;
927 pat[1] = *(*pData)++;
928 pat[2] = *(*pData)++;
929 pat[3] = *(*pData)++;
931 patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
934 *pFrame -= (4*g_width - 4);
936 *pFrame += 4*g_width;
941 if ( (*pData)[12] <= (*pData)[13])
953 pat[0] = *(*pData)++;
954 pat[1] = *(*pData)++;
955 pat[2] = *(*pData)++;
956 pat[3] = *(*pData)++;
958 patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
961 *pFrame -= (4*g_width - 4);
963 *pFrame += 4*g_width;
978 pat[0] = *(*pData)++;
979 pat[1] = *(*pData)++;
980 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
984 *pFrame -= (8*g_width - 8);
992 memcpy(*pFrame, *pData, 8);
997 *pFrame -= (8*g_width - 8);
1007 (*pFrame)[j+2*k] = (*pData)[k];
1008 (*pFrame)[g_width+j+2*k] = (*pData)[k];
1015 *pFrame -= (8*g_width - 8);
1025 (*pFrame)[k*g_width+j] = (*pData)[0];
1026 (*pFrame)[k*g_width+j+4] = (*pData)[1];
1029 *pFrame += 4*g_width;
1033 *pFrame -= (8*g_width - 8);
1039 memset(*pFrame, **pData, 8);
1044 *pFrame -= (8*g_width - 8);
1052 (*pFrame)[j] = (*pData)[(i+j)&1];
1058 *pFrame -= (8*g_width - 8);