]> icculus.org git repositories - taylor/freespace2.git/blob - src/movie/decoder16.cpp
Update to newest movie code with much better video support and audio support from
[taylor/freespace2.git] / src / movie / decoder16.cpp
1 /*
2  * $Logfile: /Freespace2/src/movie/decoder16.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * 16-bit frame decoder for MVEs
8  *
9  * $Log$
10  * Revision 1.2  2005/03/29 07:50:34  taylor
11  * Update to newest movie code with much better video support and audio support from
12  *   Pierre Willenbrock.  Movies are enabled always now (no longer a build option)
13  *   and but can be skipped with the "--nomovies" or "-n" cmdline options.
14  *
15  *
16  *
17  * $NoKeywords: $
18  *
19  */
20
21 #include "pstypes.h"
22
23 extern int g_width, g_height;
24 extern void *g_vBackBuf1, *g_vBackBuf2;
25
26 /* 16 bit decoding routines */
27
28 static ushort *backBuf1, *backBuf2;
29 static int lookup_initialized;
30
31 static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned char **pData, unsigned char **pOffData, int *pDataRemain, int *curXb, int *curYb);
32 static void genLoopkupTable();
33
34 void decodeFrame16(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain)
35 {
36         unsigned char *pOrig;
37         unsigned char *pOffData, *pEnd;
38         ushort offset;
39         int length;
40         int op;
41         int i, j;
42         int xb, yb;
43
44         if (!lookup_initialized) {
45                 genLoopkupTable();
46         }
47
48         backBuf1 = (ushort *)g_vBackBuf1;
49         backBuf2 = (ushort *)g_vBackBuf2;
50
51         xb = g_width >> 3;
52         yb = g_height >> 3;
53
54         offset = pData[0]|(pData[1]<<8);
55
56         pOffData = pData + offset;
57         pEnd = pData + offset;
58
59         pData += 2;
60
61         pOrig = pData;
62         length = offset - 2; /*dataRemain-2;*/
63
64         for (j=0; j<yb; j++) {
65                 for (i=0; i<xb/2; i++) {
66                         op = (*pMap) & 0xf;
67                         dispatchDecoder16((ushort **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
68
69 /*
70                         if ((ushort *)pFrame < backBuf1)
71                                 fprintf(stderr, "danger!  pointing out of bounds below after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
72                         else if ((ushort *)pFrame >= backBuf1 + g_width*g_height)
73                                 fprintf(stderr, "danger!  pointing out of bounds above after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
74 */
75
76                         op = ((*pMap) >> 4) & 0xf;
77                         dispatchDecoder16((ushort **)&pFrame, op, &pData, &pOffData, &dataRemain, &i, &j);
78
79 /*
80                         if ((ushort *)pFrame < backBuf1)
81                                 fprintf(stderr, "danger!  pointing out of bounds below after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
82                         else if ((ushort *)pFrame >= backBuf1 + g_width*g_height)
83                                 fprintf(stderr, "danger!  pointing out of bounds above after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
84 */
85
86                         pMap++;
87                         mapRemain--;
88                 }
89
90                 pFrame += 7*g_width*2;
91         }
92
93         if ((length-(pData-pOrig)) != 0) {
94                 nprintf(("MVE", "DEBUG: junk left over: %d,%d,%d\n", (pData-pOrig), length, (length-(pData-pOrig))));
95         }
96 }
97
98 static ushort GETPIXEL(unsigned char **buf, int off)
99 {
100         ushort val = (*buf)[0+off] | ((*buf)[1+off] << 8);
101         return val;
102 }
103
104 static ushort GETPIXELI(unsigned char **buf, int off)
105 {
106         ushort val = (*buf)[0+off] | ((*buf)[1+off] << 8);
107         (*buf) += 2;
108         return val;
109 }
110
111 static void relClose(int i, int *x, int *y)
112 {
113         int ma, mi;
114
115         ma = i >> 4;
116         mi = i & 0xf;
117
118         *x = mi - 8;
119         *y = ma - 8;
120 }
121
122 static void relFar(int i, int sign, int *x, int *y)
123 {
124         if (i < 56) {
125                 *x = sign * (8 + (i % 7));
126                 *y = sign *       (i / 7);
127         } else {
128                 *x = sign * (-14 + (i - 56) % 29);
129                 *y = sign *   (8 + (i - 56) / 29);
130         }
131 }
132
133 static int close_table[512];
134 static int far_p_table[512];
135 static int far_n_table[512];
136
137 static void genLoopkupTable()
138 {
139         int i;
140         int x, y;
141
142         for (i = 0; i < 256; i++) {
143                 relClose(i, &x, &y);
144
145                 close_table[i*2+0] = x;
146                 close_table[i*2+1] = y;
147
148                 relFar(i, 1, &x, &y);
149
150                 far_p_table[i*2+0] = x;
151                 far_p_table[i*2+1] = y;
152
153                 relFar(i, -1, &x, &y);
154
155                 far_n_table[i*2+0] = x;
156                 far_n_table[i*2+1] = y;
157         }
158
159         lookup_initialized = 1;
160 }
161
162 static void copyFrame(ushort *pDest, ushort *pSrc)
163 {
164         int i;
165
166         for (i=0; i<8; i++) {
167                 memcpy(pDest, pSrc, 16);
168                 pDest += g_width;
169                 pSrc += g_width;
170         }
171 }
172
173 static void patternRow4Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, ushort *p)
174 {
175         ushort mask=0x0003;
176         ushort shift=0;
177         ushort pattern = (pat1 << 8) | pat0;
178
179         while (mask != 0) {
180                 *pFrame++ = p[(mask & pattern) >> shift];
181                 mask <<= 2;
182                 shift += 2;
183         }
184 }
185
186 static void patternRow4Pixels2(ushort *pFrame, unsigned char pat0, ushort *p)
187 {
188         unsigned char mask=0x03;
189         unsigned char shift=0;
190         ushort pel;
191 /* ORIGINAL VERSION IS BUGGY
192         int skip=1;
193
194         while (mask != 0) {
195                 pel = p[(mask & pat0) >> shift];
196                 pFrame[0] = pel;
197                 pFrame[2] = pel;
198                 pFrame[g_width + 0] = pel;
199                 pFrame[g_width + 2] = pel;
200                 pFrame += skip;
201                 skip = 4 - skip;
202                 mask <<= 2;
203                 shift += 2;
204         }
205 */
206         while (mask != 0) {
207                 pel = p[(mask & pat0) >> shift];
208                 pFrame[0] = pel;
209                 pFrame[1] = pel;
210                 pFrame[g_width + 0] = pel;
211                 pFrame[g_width + 1] = pel;
212                 pFrame += 2;
213                 mask <<= 2;
214                 shift += 2;
215         }
216 }
217
218 static void patternRow4Pixels2x1(ushort *pFrame, unsigned char pat, ushort *p)
219 {
220         unsigned char mask=0x03;
221         unsigned char shift=0;
222         ushort pel;
223
224         while (mask != 0) {
225                 pel = p[(mask & pat) >> shift];
226                 pFrame[0] = pel;
227                 pFrame[1] = pel;
228                 pFrame += 2;
229                 mask <<= 2;
230                 shift += 2;
231         }
232 }
233
234 static void patternQuadrant4Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, unsigned char pat2, unsigned char pat3, ushort *p)
235 {
236         unsigned long mask = 0x00000003UL;
237         int shift=0;
238         int i;
239         unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
240
241         for (i=0; i<16; i++) {
242                 pFrame[i&3] = p[(pat & mask) >> shift];
243
244                 if ((i&3) == 3)
245                         pFrame += g_width;
246
247                 mask <<= 2;
248                 shift += 2;
249         }
250 }
251
252 static void patternRow2Pixels(ushort *pFrame, unsigned char pat, ushort *p)
253 {
254         unsigned char mask=0x01;
255
256         while (mask != 0) {
257                 *pFrame++ = p[(mask & pat) ? 1 : 0];
258                 mask <<= 1;
259         }
260 }
261
262 static void patternRow2Pixels2(ushort *pFrame, unsigned char pat, ushort *p)
263 {
264         ushort pel;
265         unsigned char mask=0x1;
266
267 /* ORIGINAL VERSION IS BUGGY
268         int skip=1;
269         while (mask != 0x10) {
270                 pel = p[(mask & pat) ? 1 : 0];
271                 pFrame[0] = pel;
272                 pFrame[2] = pel;
273                 pFrame[g_width + 0] = pel;
274                 pFrame[g_width + 2] = pel;
275                 pFrame += skip;
276                 skip = 4 - skip;
277                 mask <<= 1;
278         }
279 */
280         while (mask != 0x10) {
281                 pel = p[(mask & pat) ? 1 : 0];
282
283                 pFrame[0] = pel;
284                 pFrame[1] = pel;
285                 pFrame[g_width + 0] = pel;
286                 pFrame[g_width + 1] = pel;
287                 pFrame += 2;
288
289                 mask <<= 1;
290         }
291 }
292
293 static void patternQuadrant2Pixels(ushort *pFrame, unsigned char pat0, unsigned char pat1, ushort *p)
294 {
295         ushort mask = 0x0001;
296         int i;
297         ushort pat = (pat1 << 8) | pat0;
298
299         for (i=0; i<16; i++) {
300                 pFrame[i&3] = p[(pat & mask) ? 1 : 0];
301
302                 if ((i&3) == 3)
303                         pFrame += g_width;
304
305                 mask <<= 1;
306         }
307
308 }
309
310 static void dispatchDecoder16(ushort **pFrame, unsigned char codeType, unsigned char **pData, unsigned char **pOffData, int *pDataRemain, int *curXb, int *curYb)
311 {
312         ushort p[4];
313         unsigned char pat[16];
314         int i, j, k;
315         int x, y;
316         ushort *pDstBak;
317
318         pDstBak = *pFrame;
319
320         switch(codeType) {
321                 case 0x0:
322                         copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1));
323                         break; // ADDED
324
325                 case 0x1:
326                         break;
327
328                 case 0x2:
329                         /* relFar(*(*pOffData)++, 1, &x, &y); */
330
331                         k = *(*pOffData)++;
332                         x = far_p_table[k*2+0];
333                         y = far_p_table[k*2+1];
334
335                         copyFrame(*pFrame, *pFrame + x + y*g_width);
336                         *pDataRemain--;
337                         break;
338
339                 case 0x3:
340                         /* relFar(*(*pOffData)++, -1, &x, &y); */
341
342                         k = *(*pOffData)++;
343                         x = far_n_table[k*2+0];
344                         y = far_n_table[k*2+1];
345
346                         copyFrame(*pFrame, *pFrame + x + y*g_width);
347                         *pDataRemain--;                           
348                         break;
349
350                 case 0x4:
351                         /* relClose(*(*pOffData)++, &x, &y); */
352
353                         k = *(*pOffData)++;
354                         x = close_table[k*2+0];
355                         y = close_table[k*2+1];
356
357                         copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
358                         *pDataRemain--;
359                         break;
360
361                 case 0x5:
362                         x = (char)*(*pData)++;
363                         y = (char)*(*pData)++;
364                         copyFrame(*pFrame, *pFrame + (backBuf2 - backBuf1) + x + y*g_width);
365                         *pDataRemain -= 2;
366                         break;
367
368                 case 0x6:
369                         nprintf(("MVE", "STUB: encoding 6 not tested\n"));
370
371                         for (i=0; i<2; i++) {
372                                 *pFrame += 16;
373
374                                 if (++*curXb == (g_width >> 3)) {
375                                         *pFrame += 7*g_width;
376                                         *curXb = 0;
377
378                                         if (++*curYb == (g_height >> 3))
379                                                 return;
380                                 }
381                         }
382                         break;
383
384                 case 0x7:
385                         p[0] = GETPIXELI(pData, 0);
386                         p[1] = GETPIXELI(pData, 0);
387
388                         if (!((p[0]/*|p[1]*/)&0x8000)) {
389                                 for (i=0; i<8; i++) {
390                                         patternRow2Pixels(*pFrame, *(*pData), p);
391                                         (*pData)++;
392
393                                         *pFrame += g_width;
394                                 }
395                         } else {
396                                 for (i=0; i<2; i++) {
397                                         patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
398                                         *pFrame += 2*g_width;
399                                         patternRow2Pixels2(*pFrame, *(*pData) >> 4, p);
400                                         (*pData)++;
401
402                                         *pFrame += 2*g_width;
403                                 }
404                         }
405                         break;
406
407                 case 0x8:
408                         p[0] = GETPIXEL(pData, 0);
409
410                         if (!(p[0] & 0x8000)) {
411                                 for (i=0; i<4; i++) {
412                                         p[0] = GETPIXELI(pData, 0);
413                                         p[1] = GETPIXELI(pData, 0);
414
415                                         pat[0] = (*pData)[0];
416                                         pat[1] = (*pData)[1];
417                                         (*pData) += 2;
418
419                                         patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
420
421                                         if (i & 1) {
422                                                 *pFrame -= (4*g_width - 4);
423                                         } else {
424                                                 *pFrame += 4*g_width;
425                                         }
426                                 }
427                         } else {
428                                 p[2] = GETPIXEL(pData, 8);
429
430                                 if (!(p[2]&0x8000)) {
431                                         for (i=0; i<4; i++) {
432                                                 if ((i & 1) == 0) {
433                                                         p[0] = GETPIXELI(pData, 0);
434                                                         p[1] = GETPIXELI(pData, 0);
435                                                 }
436                                                 pat[0] = *(*pData)++;
437                                                 pat[1] = *(*pData)++;
438                                                 patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
439
440                                                 if (i & 1) {
441                                                         *pFrame -= (4*g_width - 4);
442                                                 } else {
443                                                         *pFrame += 4*g_width;
444                                                 }
445                                         }
446                                 } else {
447                                         for (i=0; i<8; i++) {
448                                                 if ((i & 3) == 0) {
449                                                         p[0] = GETPIXELI(pData, 0);
450                                                         p[1] = GETPIXELI(pData, 0);
451                                                 }
452                                                 patternRow2Pixels(*pFrame, *(*pData), p);
453                                                 (*pData)++;
454
455                                                 *pFrame += g_width;
456                                         }
457                                 }
458                         }
459                         break;
460
461                 case 0x9:
462                         p[0] = GETPIXELI(pData, 0);
463                         p[1] = GETPIXELI(pData, 0);
464                         p[2] = GETPIXELI(pData, 0);
465                         p[3] = GETPIXELI(pData, 0);
466
467                         *pDataRemain -= 8;
468
469                         if (!(p[0] & 0x8000)) {
470                                 if (!(p[2] & 0x8000)) {
471                                         for (i=0; i<8; i++) {
472                                                 pat[0] = (*pData)[0];
473                                                 pat[1] = (*pData)[1];
474                                                 (*pData) += 2;
475                                                 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
476                                                 *pFrame += g_width;
477                                         }
478                                         *pDataRemain -= 16;
479                                 } else {
480                                         patternRow4Pixels2(*pFrame, (*pData)[0], p);
481                                         *pFrame += 2*g_width;
482                                         patternRow4Pixels2(*pFrame, (*pData)[1], p);
483                                         *pFrame += 2*g_width;
484                                         patternRow4Pixels2(*pFrame, (*pData)[2], p);
485                                         *pFrame += 2*g_width;
486                                         patternRow4Pixels2(*pFrame, (*pData)[3], p);
487
488                                         (*pData) += 4;
489                                         *pDataRemain -= 4;
490                                 }
491                         } else {
492                                 if (!(p[2] & 0x8000))  {
493                                         for (i=0; i<8; i++) {
494                                                 pat[0] = (*pData)[0];
495                                                 (*pData) += 1;
496                                                 patternRow4Pixels2x1(*pFrame, pat[0], p);
497                                                 *pFrame += g_width;
498                                         }
499                                         *pDataRemain -= 8;
500                                 } else {
501                                         for (i=0; i<4; i++) {
502                                                 pat[0] = (*pData)[0];
503                                                 pat[1] = (*pData)[1];
504
505                                                 (*pData) += 2;
506
507                                                 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
508                                                 *pFrame += g_width;
509                                                 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
510                                                 *pFrame += g_width;
511                                         }
512                                         *pDataRemain -= 8;
513                                 }
514                         }
515                         break;
516
517                 case 0xa:
518                         p[0] = GETPIXEL(pData, 0);
519
520                         if (!(p[0] & 0x8000)) {
521                                 for (i=0; i<4; i++) {
522                                         p[0] = GETPIXELI(pData, 0);
523                                         p[1] = GETPIXELI(pData, 0);
524                                         p[2] = GETPIXELI(pData, 0);
525                                         p[3] = GETPIXELI(pData, 0);
526                                         pat[0] = (*pData)[0];
527                                         pat[1] = (*pData)[1];
528                                         pat[2] = (*pData)[2];
529                                         pat[3] = (*pData)[3];
530
531                                         (*pData) += 4;
532
533                                         patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
534
535                                         if (i & 1) {
536                                                 *pFrame -= (4*g_width - 4);
537                                         } else {
538                                                 *pFrame += 4*g_width;
539                                         }
540                                 }
541                         } else {
542                                 p[0] = GETPIXEL(pData, 16);
543
544                                 if (!(p[0] & 0x8000)) {
545                                         for (i=0; i<4; i++) {
546                                                 if ((i&1) == 0) {
547                                                         p[0] = GETPIXELI(pData, 0); 
548                                                         p[1] = GETPIXELI(pData, 0);
549                                                         p[2] = GETPIXELI(pData, 0);
550                                                         p[3] = GETPIXELI(pData, 0);
551                                                 }
552
553                                                 pat[0] = (*pData)[0];
554                                                 pat[1] = (*pData)[1];
555                                                 pat[2] = (*pData)[2];
556                                                 pat[3] = (*pData)[3];
557
558                                                 (*pData) += 4;
559
560                                                 patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
561
562                                                 if (i & 1) {
563                                                         *pFrame -= (4*g_width - 4);
564                                                 } else {
565                                                         *pFrame += 4*g_width;
566                                                 }
567                                         }
568                                 } else {
569                                         for (i=0; i<8; i++) {
570                                                 if ((i&3) == 0) {
571                                                         p[0] = GETPIXELI(pData, 0);
572                                                         p[1] = GETPIXELI(pData, 0);
573                                                         p[2] = GETPIXELI(pData, 0);
574                                                         p[3] = GETPIXELI(pData, 0);
575                                                 }
576
577                                                 pat[0] = (*pData)[0];
578                                                 pat[1] = (*pData)[1];
579                                                 patternRow4Pixels(*pFrame, pat[0], pat[1], p);
580                                                 *pFrame += g_width;
581
582                                                 (*pData) += 2;
583                                         }
584                                 }
585                         }
586                         break;
587
588                 case 0xb:
589                         for (i=0; i<8; i++) {
590                                 memcpy(*pFrame, *pData, 16);
591                                 *pFrame += g_width;
592                                 *pData += 16;
593                                 *pDataRemain -= 16;
594                         }
595                         break;
596
597                 case 0xc:
598                         for (i=0; i<4; i++) {
599                                 p[0] = GETPIXEL(pData, 0);
600                                 p[1] = GETPIXEL(pData, 2);
601                                 p[2] = GETPIXEL(pData, 4);
602                                 p[3] = GETPIXEL(pData, 6);
603
604                         /*      for (j=0; j<2; j++) {
605                                         for (k=0; k<4; k++) {
606                                                 (*pFrame)[2*k] = p[k];
607                                                 (*pFrame)[2*k+1] = p[k];
608                                         }
609                                         *pFrame += g_width;
610                                 } */
611
612                                 for (k=0; k<4; k++) {
613                                         (*pFrame)[0+2*k] = p[k];
614                                         (*pFrame)[g_width+0+2*k] = p[k];
615                                         (*pFrame)[1+2*k] = p[k];
616                                         (*pFrame)[g_width+1+2*k] = p[k];
617                                 }
618
619                                 *pFrame += 2*g_width;
620
621                                 *pData += 8;
622                                 *pDataRemain -= 8;
623                         }
624                         break;
625
626                 case 0xd:
627                         for (i=0; i<2; i++) {
628                                 p[0] = GETPIXEL(pData, 0);
629                                 p[1] = GETPIXEL(pData, 2);
630
631                                 for (j=0; j<4; j++) {
632                                         for (k=0; k<4; k++) {
633                                                 (*pFrame)[k*g_width+j] = p[0];
634                                                 (*pFrame)[k*g_width+j+4] = p[1];
635                                         }
636                                 }
637
638                                 *pFrame += 4*g_width;
639
640                                 *pData += 4;
641                                 *pDataRemain -= 4;
642                         }
643                         break;
644
645                 case 0xe:
646                         p[0] = GETPIXEL(pData, 0);
647
648                         for (i = 0; i < 8; i++) {
649                                 for (j = 0; j < 8; j++) {
650                                         (*pFrame)[j] = p[0];
651                                 }
652
653                                 *pFrame += g_width;
654                         }
655
656                         *pData += 2;
657                         *pDataRemain -= 2;
658
659                         break;
660
661                 case 0xf:
662                         p[0] = GETPIXEL(pData, 0);
663                         p[1] = GETPIXEL(pData, 1);
664
665                         for (i=0; i<8; i++) {
666                                 for (j=0; j<8; j++) {
667                                         (*pFrame)[j] = p[(i+j)&1];
668                                 }
669                                 *pFrame += g_width;
670                         }
671
672                         *pData += 4;
673                         *pDataRemain -= 4;
674                         break;
675
676                 default:
677                         break;
678         }
679
680         *pFrame = pDstBak+8;
681 }