14 #include <SDL/SDL_thread.h>
19 #include "mve_audio.h"
24 #define MIN(a,b) ((a)<(b)?(a):(b))
27 static int g_spdFactorNum=0;
28 static int g_spdFactorDenom=10;
30 void initializeMovie(MVESTREAM *mve, grs_bitmap *mve_bitmap);
31 void shutdownMovie(MVESTREAM *mve);
33 static short get_short(unsigned char *data)
36 value = data[0] | (data[1] << 8);
40 static int get_int(unsigned char *data)
43 value = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
47 static int default_seg_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
49 fprintf(stderr, "unknown chunk type %02x/%02x\n", major, minor);
53 /*************************
55 *************************/
56 static int end_movie_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
61 /*************************
63 *************************/
68 static int micro_frame_delay=0;
70 static int create_timer_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
73 micro_frame_delay = get_int(data) * (int)get_short(data+4);
74 if (g_spdFactorNum != 0)
76 temp = micro_frame_delay;
77 temp *= g_spdFactorNum;
78 temp /= g_spdFactorDenom;
79 micro_frame_delay = (int)temp;
86 /*************************
88 *************************/
89 static void mve_audio_callback(void *userdata, Uint8 *stream, int len);
90 static short *mve_audio_buffers[64];
91 static int mve_audio_buflens[64];
92 static int mve_audio_curbuf_curpos=0;
93 static int mve_audio_bufhead=0;
94 static int mve_audio_buftail=0;
95 static int mve_audio_playing=0;
96 static int mve_audio_canplay=0;
97 static int mve_audio_compressed=0;
98 static SDL_AudioSpec *mve_audio_spec=NULL;
99 static SDL_mutex *mve_audio_mutex = NULL;
101 static void mve_audio_callback(void *userdata, Uint8 *stream, int len)
105 if (mve_audio_bufhead == mve_audio_buftail)
108 fprintf(stderr, "+ <%d (%d), %d, %d>\n", mve_audio_bufhead, mve_audio_curbuf_curpos, mve_audio_buftail, len);
110 SDL_mutexP(mve_audio_mutex);
112 while (mve_audio_bufhead != mve_audio_buftail /* while we have more buffers */
113 && len > (mve_audio_buflens[mve_audio_bufhead]-mve_audio_curbuf_curpos)) /* and while we need more data */
115 length = mve_audio_buflens[mve_audio_bufhead]-mve_audio_curbuf_curpos;
116 __builtin_memcpy(stream, /* cur output position */
117 mve_audio_buffers[mve_audio_bufhead]+mve_audio_curbuf_curpos, /* cur input position */
118 length); /* cur input length */
121 stream += length; /* advance output */
122 len -= length; /* decrement avail ospace */
123 d_free(mve_audio_buffers[mve_audio_bufhead]); /* free the buffer */
124 mve_audio_buffers[mve_audio_bufhead]=NULL; /* free the buffer */
125 mve_audio_buflens[mve_audio_bufhead]=0; /* free the buffer */
127 if (++mve_audio_bufhead == 64) /* next buffer */
128 mve_audio_bufhead = 0;
129 mve_audio_curbuf_curpos = 0;
132 fprintf(stderr, "= <%d (%d), %d, %d>: %d\n", mve_audio_bufhead, mve_audio_curbuf_curpos, mve_audio_buftail, len, total);
135 if (len != 0 /* ospace remaining */
136 && mve_audio_bufhead != mve_audio_buftail) /* buffers remaining */
138 __builtin_memcpy(stream, /* dest */
139 mve_audio_buffers[mve_audio_bufhead] + mve_audio_curbuf_curpos, /* src */
142 mve_audio_curbuf_curpos += len; /* advance input */
143 stream += len; /* advance output (unnecessary) */
144 len -= len; /* advance output (unnecessary) */
146 if (mve_audio_curbuf_curpos >= mve_audio_buflens[mve_audio_bufhead]) /* if this ends the current chunk */
148 d_free(mve_audio_buffers[mve_audio_bufhead]); /* free buffer */
149 mve_audio_buffers[mve_audio_bufhead]=NULL;
150 mve_audio_buflens[mve_audio_bufhead]=0;
152 if (++mve_audio_bufhead == 64) /* next buffer */
153 mve_audio_bufhead = 0;
154 mve_audio_curbuf_curpos = 0;
158 fprintf(stderr, "- <%d (%d), %d, %d>\n", mve_audio_bufhead, mve_audio_curbuf_curpos, mve_audio_buftail, len);
159 SDL_mutexV(mve_audio_mutex);
162 static int create_audiobuf_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
168 fprintf(stderr, "creating audio buffers\n");
170 mve_audio_mutex = SDL_CreateMutex();
172 flags = get_short(data + 2);
173 sample_rate = get_short(data + 4);
174 desired_buffer = get_int(data + 6);
176 fprintf(stderr, "stereo=%d 16bit=%d compressed=%d sample_rate=%d desired_buffer=%d\n",
177 flags & 1, (flags >> 1) & 1, (flags >> 2) & 1, sample_rate, desired_buffer);
179 mve_audio_compressed = flags & MVE_AUDIO_FLAGS_COMPRESSED;
180 mve_audio_spec = (SDL_AudioSpec *)d_malloc(sizeof(SDL_AudioSpec));
181 mve_audio_spec->freq = sample_rate;
182 #ifdef WORDS_BIGENDIAN
183 mve_audio_spec->format = (flags & MVE_AUDIO_FLAGS_16BIT)?AUDIO_S16MSB:AUDIO_U8;
185 mve_audio_spec->format = (flags & MVE_AUDIO_FLAGS_16BIT)?AUDIO_S16LSB:AUDIO_U8;
187 mve_audio_spec->channels = (flags & MVE_AUDIO_FLAGS_STEREO)?2:1;
188 mve_audio_spec->samples = 32768;
189 mve_audio_spec->callback = mve_audio_callback;
190 mve_audio_spec->userdata = NULL;
191 if (SDL_OpenAudio(mve_audio_spec, NULL) >= 0)
193 fprintf(stderr, " success\n");
194 mve_audio_canplay = 1;
198 fprintf(stderr, " failure : %s\n", SDL_GetError());
199 mve_audio_canplay = 0;
202 memset(mve_audio_buffers, 0, sizeof(mve_audio_buffers));
203 memset(mve_audio_buflens, 0, sizeof(mve_audio_buflens));
208 static int play_audio_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
210 if (mve_audio_canplay && !mve_audio_playing && mve_audio_bufhead != mve_audio_buftail)
213 mve_audio_playing = 1;
219 static int audio_data_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
221 static const int selected_chan=1;
224 if (mve_audio_canplay)
226 if (mve_audio_playing)
229 chan = get_short(data + 2);
230 nsamp = get_short(data + 4);
231 if (chan & selected_chan)
233 SDL_mutexP(mve_audio_mutex);
234 mve_audio_buflens[mve_audio_buftail] = nsamp;
235 mve_audio_buffers[mve_audio_buftail] = (short *)d_malloc(nsamp+4);
237 if (mve_audio_compressed)
238 mveaudio_uncompress(mve_audio_buffers[mve_audio_buftail], data, -1); /* XXX */
240 memcpy(mve_audio_buffers[mve_audio_buftail], data + 6, nsamp);
242 memset(mve_audio_buffers[mve_audio_buftail], 0, nsamp); /* XXX */
244 if (++mve_audio_buftail == 64)
245 mve_audio_buftail = 0;
247 if (mve_audio_buftail == mve_audio_bufhead)
248 fprintf(stderr, "d'oh! buffer ring overrun (%d)\n", mve_audio_bufhead);
249 SDL_mutexV(mve_audio_mutex);
252 if (mve_audio_playing)
259 /*************************
261 *************************/
262 static grs_bitmap *g_screen;
263 static int g_screenWidth, g_screenHeight;
264 static int g_width, g_height;
265 static unsigned char g_palette[768];
266 static unsigned char *g_vBackBuf1, *g_vBackBuf2;
267 static unsigned char *g_pCurMap=NULL;
268 static int g_nMapLength=0;
270 static int create_videobuf_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
274 h = get_short(data+2);
277 printf("mve width, height: %d, %d\n", g_width, g_height);
278 Assert((g_width == g_screen->bm_w) && (g_height == g_screen->bm_h));
279 g_vBackBuf1 = d_malloc(g_width * g_height);
280 g_vBackBuf2 = d_malloc(g_width * g_height);
281 memset(g_vBackBuf1, 0, g_width * g_height);
282 memset(g_vBackBuf2, 0, g_width * g_height);
286 static int display_video_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
288 gr_palette_load(g_palette);
290 memcpy(g_screen->bm_data, g_vBackBuf1, g_width * g_height);
295 static int init_video_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
298 width = get_short(data);
299 height = get_short(data+2);
300 g_screenWidth = width;
301 g_screenHeight = height;
302 memset(g_palette, 0, 768);
306 static int video_palette_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
309 start = get_short(data);
310 count = get_short(data+2);
311 memcpy(g_palette + 3*start, data+4, 3*count);
315 static int video_codemap_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
322 static void decodeFrame(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain);
324 static int video_data_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
326 short nFrameHot, nFrameCold;
327 short nXoffset, nYoffset;
328 short nXsize, nYsize;
332 nFrameHot = get_short(data);
333 nFrameCold = get_short(data+2);
334 nXoffset = get_short(data+4);
335 nYoffset = get_short(data+6);
336 nXsize = get_short(data+8);
337 nYsize = get_short(data+10);
338 nFlags = get_short(data+12);
343 g_vBackBuf1 = g_vBackBuf2;
347 /* convert the frame */
348 decodeFrame(g_vBackBuf1, g_pCurMap, g_nMapLength, data+14, len-14);
353 static int end_chunk_handler(unsigned char major, unsigned char minor, unsigned char *data, int len, void *context)
359 void initializeMovie(MVESTREAM *mve, grs_bitmap *mve_bitmap)
361 g_screen = mve_bitmap;
363 mve_set_handler(mve, 0x00, end_movie_handler);
364 mve_set_handler(mve, 0x01, end_chunk_handler);
365 mve_set_handler(mve, 0x02, create_timer_handler);
366 mve_set_handler(mve, 0x03, create_audiobuf_handler);
367 mve_set_handler(mve, 0x04, play_audio_handler);
368 mve_set_handler(mve, 0x05, create_videobuf_handler);
369 mve_set_handler(mve, 0x06, default_seg_handler);
370 mve_set_handler(mve, 0x07, display_video_handler);
371 mve_set_handler(mve, 0x08, audio_data_handler);
372 mve_set_handler(mve, 0x09, audio_data_handler);
373 mve_set_handler(mve, 0x0a, init_video_handler);
374 mve_set_handler(mve, 0x0b, default_seg_handler);
375 mve_set_handler(mve, 0x0c, video_palette_handler);
376 mve_set_handler(mve, 0x0d, default_seg_handler);
377 mve_set_handler(mve, 0x0e, default_seg_handler);
378 mve_set_handler(mve, 0x0f, video_codemap_handler);
379 mve_set_handler(mve, 0x10, default_seg_handler);
380 mve_set_handler(mve, 0x11, video_data_handler);
381 mve_set_handler(mve, 0x12, default_seg_handler);
382 //mve_set_handler(mve, 0x13, default_seg_handler);
383 mve_set_handler(mve, 0x14, default_seg_handler);
384 //mve_set_handler(mve, 0x15, default_seg_handler);
387 void shutdownMovie(MVESTREAM *mve)
392 for (i = 0; i < 64; i++)
393 if (mve_audio_buffers[i] != NULL) {
394 d_free(mve_audio_buffers[i]);
395 mve_audio_buffers[i] = NULL;
398 d_free(mve_audio_spec);
403 static void dispatchDecoder(unsigned char **pFrame, unsigned char codeType, unsigned char **pData, int *pDataRemain, int *curXb, int *curYb);
405 static void decodeFrame(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain)
414 for (i=0; i<xb/2; i++)
416 dispatchDecoder(&pFrame, (*pMap) & 0xf, &pData, &dataRemain, &i, &j);
417 if (pFrame < g_vBackBuf1)
418 fprintf(stderr, "danger! pointing out of bounds below after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
419 else if (pFrame >= g_vBackBuf1 + g_width*g_height)
420 fprintf(stderr, "danger! pointing out of bounds above after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
421 dispatchDecoder(&pFrame, (*pMap) >> 4, &pData, &dataRemain, &i, &j);
422 if (pFrame < g_vBackBuf1)
423 fprintf(stderr, "danger! pointing out of bounds below after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
424 else if (pFrame >= g_vBackBuf1 + g_width*g_height)
425 fprintf(stderr, "danger! pointing out of bounds above after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
435 static void relClose(int i, int *x, int *y)
446 static void relFar(int i, int sign, int *x, int *y)
450 *x = sign * (8 + (i % 7));
455 *x = sign * (-14 + (i - 56) % 29);
456 *y = sign * (8 + (i - 56) / 29);
460 static void copyFrame(unsigned char *pDest, unsigned char *pSrc)
466 memcpy(pDest, pSrc, 8);
472 static void patternRow4Pixels(unsigned char *pFrame,
473 unsigned char pat0, unsigned char pat1,
476 unsigned short mask=0x0003;
477 unsigned short shift=0;
478 unsigned short pattern = (pat1 << 8) | pat0;
482 *pFrame++ = p[(mask & pattern) >> shift];
488 static void patternRow4Pixels2(unsigned char *pFrame,
492 unsigned char mask=0x03;
493 unsigned char shift=0;
499 pel = p[(mask & pat0) >> shift];
502 pFrame[g_width + 0] = pel;
503 pFrame[g_width + 2] = pel;
511 static void patternRow4Pixels2x1(unsigned char *pFrame, unsigned char pat, unsigned char *p)
513 unsigned char mask=0x03;
514 unsigned char shift=0;
519 pel = p[(mask & pat) >> shift];
528 static void patternQuadrant4Pixels(unsigned char *pFrame, unsigned char pat0, unsigned char pat1, unsigned char pat2, unsigned char pat3, unsigned char *p)
530 unsigned long mask = 0x00000003UL;
533 unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
537 pFrame[i&3] = p[(pat & mask) >> shift];
548 static void patternRow2Pixels(unsigned char *pFrame, unsigned char pat, unsigned char *p)
550 unsigned char mask=0x01;
554 *pFrame++ = p[(mask & pat) ? 1 : 0];
559 static void patternRow2Pixels2(unsigned char *pFrame, unsigned char pat, unsigned char *p)
562 unsigned char mask=0x1;
567 pel = p[(mask & pat) ? 1 : 0];
570 pFrame[g_width + 0] = pel;
571 pFrame[g_width + 2] = pel;
578 static void patternQuadrant2Pixels(unsigned char *pFrame, unsigned char pat0, unsigned char pat1, unsigned char *p)
580 unsigned short mask = 0x0001;
582 unsigned short pat = (pat1 << 8) | pat0;
586 pFrame[i&3] = p[(pat & mask) ? 1 : 0];
595 static void dispatchDecoder(unsigned char **pFrame, unsigned char codeType, unsigned char **pData, int *pDataRemain, int *curXb, int *curYb)
598 unsigned char pat[16];
605 copyFrame(*pFrame, *pFrame + (g_vBackBuf2 - g_vBackBuf1));
611 relFar(*(*pData)++, 1, &x, &y);
612 copyFrame(*pFrame, *pFrame + x + y*g_width);
618 relFar(*(*pData)++, -1, &x, &y);
619 copyFrame(*pFrame, *pFrame + x + y*g_width);
625 relClose(*(*pData)++, &x, &y);
626 copyFrame(*pFrame, *pFrame + (g_vBackBuf2 - g_vBackBuf1) + x + y*g_width);
632 x = (char)*(*pData)++;
633 y = (char)*(*pData)++;
634 copyFrame(*pFrame, *pFrame + (g_vBackBuf2 - g_vBackBuf1) + x + y*g_width);
643 if (++*curXb == (g_width >> 3))
645 *pFrame += 7*g_width;
647 if (++*curYb == (g_height >> 3))
660 patternRow2Pixels(*pFrame, *(*pData)++, p);
668 patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
669 *pFrame += 2*g_width;
670 patternRow2Pixels2(*pFrame, *(*pData)++ >> 4, p);
671 *pFrame += 2*g_width;
674 *pFrame -= (8*g_width - 8);
678 if ( (*pData)[0] <= (*pData)[1])
684 pat[0] = *(*pData)++;
685 pat[1] = *(*pData)++;
686 patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
689 *pFrame -= (4*g_width - 4);
691 *pFrame += 4*g_width;
694 else if ( (*pData)[6] <= (*pData)[7])
703 pat[0] = *(*pData)++;
704 pat[1] = *(*pData)++;
705 patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
708 *pFrame -= (4*g_width - 4);
710 *pFrame += 4*g_width;
722 patternRow2Pixels(*pFrame, *(*pData)++, p);
725 *pFrame -= (8*g_width - 8);
730 if ( (*pData)[0] <= (*pData)[1])
732 if ( (*pData)[2] <= (*pData)[3])
741 pat[0] = *(*pData)++;
742 pat[1] = *(*pData)++;
743 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
747 *pFrame -= (8*g_width - 8);
756 patternRow4Pixels2(*pFrame, *(*pData)++, p);
757 *pFrame += 2*g_width;
758 patternRow4Pixels2(*pFrame, *(*pData)++, p);
759 *pFrame += 2*g_width;
760 patternRow4Pixels2(*pFrame, *(*pData)++, p);
761 *pFrame += 2*g_width;
762 patternRow4Pixels2(*pFrame, *(*pData)++, p);
763 *pFrame -= (6*g_width - 8);
768 if ( (*pData)[2] <= (*pData)[3])
777 pat[0] = *(*pData)++;
778 patternRow4Pixels2x1(*pFrame, pat[0], p);
782 *pFrame -= (8*g_width - 8);
793 pat[0] = *(*pData)++;
794 pat[1] = *(*pData)++;
795 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
797 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
801 *pFrame -= (8*g_width - 8);
807 if ( (*pData)[0] <= (*pData)[1])
815 pat[0] = *(*pData)++;
816 pat[1] = *(*pData)++;
817 pat[2] = *(*pData)++;
818 pat[3] = *(*pData)++;
820 patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
823 *pFrame -= (4*g_width - 4);
825 *pFrame += 4*g_width;
830 if ( (*pData)[12] <= (*pData)[13])
842 pat[0] = *(*pData)++;
843 pat[1] = *(*pData)++;
844 pat[2] = *(*pData)++;
845 pat[3] = *(*pData)++;
847 patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
850 *pFrame -= (4*g_width - 4);
852 *pFrame += 4*g_width;
867 pat[0] = *(*pData)++;
868 pat[1] = *(*pData)++;
869 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
873 *pFrame -= (8*g_width - 8);
881 memcpy(*pFrame, *pData, 8);
886 *pFrame -= (8*g_width - 8);
896 (*pFrame)[j+2*k] = (*pData)[k];
897 (*pFrame)[g_width+j+2*k] = (*pData)[k];
904 *pFrame -= (8*g_width - 8);
914 (*pFrame)[k*g_width+j] = (*pData)[0];
915 (*pFrame)[k*g_width+j+4] = (*pData)[1];
918 *pFrame += 4*g_width;
922 *pFrame -= (8*g_width - 8);
928 memset(*pFrame, **pData, 8);
933 *pFrame -= (8*g_width - 8);
941 (*pFrame)[j] = (*pData)[(i+j)&1];
947 *pFrame -= (8*g_width - 8);