]> icculus.org git repositories - btb/d2x.git/blob - libmve/decoder8.c
header/extern declaration housekeeping
[btb/d2x.git] / libmve / decoder8.c
1 /* 8 bit decoding routines */
2
3 #include <stdio.h>
4 #include <string.h>
5
6 #include "decoders.h"
7
8 static void dispatchDecoder(unsigned char **pFrame, unsigned char codeType, unsigned char **pData, int *pDataRemain, int *curXb, int *curYb);
9
10 void decodeFrame8(unsigned char *pFrame, unsigned char *pMap, int mapRemain, unsigned char *pData, int dataRemain)
11 {
12         int i, j;
13         int xb, yb;
14
15         xb = g_width >> 3;
16         yb = g_height >> 3;
17         for (j=0; j<yb; j++)
18         {
19                 for (i=0; i<xb/2; i++)
20                 {
21                         dispatchDecoder(&pFrame, (*pMap) & 0xf, &pData, &dataRemain, &i, &j);
22                         if (pFrame < (unsigned char *)g_vBackBuf1)
23                                 fprintf(stderr, "danger!  pointing out of bounds below after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
24                         else if (pFrame >= ((unsigned char *)g_vBackBuf1) + g_width*g_height)
25                                 fprintf(stderr, "danger!  pointing out of bounds above after dispatch decoder: %d, %d (1) [%x]\n", i, j, (*pMap) & 0xf);
26                         dispatchDecoder(&pFrame, (*pMap) >> 4, &pData, &dataRemain, &i, &j);
27                         if (pFrame < (unsigned char *)g_vBackBuf1)
28                                 fprintf(stderr, "danger!  pointing out of bounds below after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
29                         else if (pFrame >= ((unsigned char *)g_vBackBuf1) + g_width*g_height)
30                                 fprintf(stderr, "danger!  pointing out of bounds above after dispatch decoder: %d, %d (2) [%x]\n", i, j, (*pMap) >> 4);
31
32                         ++pMap;
33                         --mapRemain;
34                 }
35
36                 pFrame += 7*g_width;
37         }
38 }
39
40 static void relClose(int i, int *x, int *y)
41 {
42         int ma, mi;
43
44         ma = i >> 4;
45         mi = i & 0xf;
46
47         *x = mi - 8;
48         *y = ma - 8;
49 }
50
51 static void relFar(int i, int sign, int *x, int *y)
52 {
53         if (i < 56)
54         {
55                 *x = sign * (8 + (i % 7));
56                 *y = sign *      (i / 7);
57         }
58         else
59         {
60                 *x = sign * (-14 + (i - 56) % 29);
61                 *y = sign *   (8 + (i - 56) / 29);
62         }
63 }
64
65 /* copies an 8x8 block from pSrc to pDest.
66    pDest and pSrc are both g_width bytes wide */
67 static void copyFrame(unsigned char *pDest, unsigned char *pSrc)
68 {
69         int i;
70
71         for (i=0; i<8; i++)
72         {
73                 memcpy(pDest, pSrc, 8);
74                 pDest += g_width;
75                 pSrc += g_width;
76         }
77 }
78
79 // Fill in the next eight bytes with p[0], p[1], p[2], or p[3],
80 // depending on the corresponding two-bit value in pat0 and pat1
81 static void patternRow4Pixels(unsigned char *pFrame,
82                                                           unsigned char pat0, unsigned char pat1,
83                                                           unsigned char *p)
84 {
85         unsigned short mask=0x0003;
86         unsigned short shift=0;
87         unsigned short pattern = (pat1 << 8) | pat0;
88
89         while (mask != 0)
90         {
91                 *pFrame++ = p[(mask & pattern) >> shift];
92                 mask <<= 2;
93                 shift += 2;
94         }
95 }
96
97 // Fill in the next four 2x2 pixel blocks with p[0], p[1], p[2], or p[3],
98 // depending on the corresponding two-bit value in pat0.
99 static void patternRow4Pixels2(unsigned char *pFrame,
100                                                            unsigned char pat0,
101                                                            unsigned char *p)
102 {
103         unsigned char mask=0x03;
104         unsigned char shift=0;
105         unsigned char pel;
106
107         while (mask != 0)
108         {
109                 pel = p[(mask & pat0) >> shift];
110                 pFrame[0] = pel;
111                 pFrame[1] = pel;
112                 pFrame[g_width + 0] = pel;
113                 pFrame[g_width + 1] = pel;
114                 pFrame += 2;
115                 mask <<= 2;
116                 shift += 2;
117         }
118 }
119
120 // Fill in the next four 2x1 pixel blocks with p[0], p[1], p[2], or p[3],
121 // depending on the corresponding two-bit value in pat.
122 static void patternRow4Pixels2x1(unsigned char *pFrame, unsigned char pat, unsigned char *p)
123 {
124         unsigned char mask=0x03;
125         unsigned char shift=0;
126         unsigned char pel;
127
128         while (mask != 0)
129         {
130                 pel = p[(mask & pat) >> shift];
131                 pFrame[0] = pel;
132                 pFrame[1] = pel;
133                 pFrame += 2;
134                 mask <<= 2;
135                 shift += 2;
136         }
137 }
138
139 // Fill in the next 4x4 pixel block with p[0], p[1], p[2], or p[3],
140 // depending on the corresponding two-bit value in pat0, pat1, pat2, and pat3.
141 static void patternQuadrant4Pixels(unsigned char *pFrame, unsigned char pat0, unsigned char pat1, unsigned char pat2, unsigned char pat3, unsigned char *p)
142 {
143         unsigned long mask = 0x00000003UL;
144         int shift=0;
145         int i;
146         unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
147
148         for (i=0; i<16; i++)
149         {
150                 pFrame[i&3] = p[(pat & mask) >> shift];
151
152                 if ((i&3) == 3)
153                         pFrame += g_width;
154
155                 mask <<= 2;
156                 shift += 2;
157         }
158 }
159
160 // fills the next 8 pixels with either p[0] or p[1], depending on pattern
161 static void patternRow2Pixels(unsigned char *pFrame, unsigned char pat, unsigned char *p)
162 {
163         unsigned char mask=0x01;
164
165         while (mask != 0)
166         {
167                 *pFrame++ = p[(mask & pat) ? 1 : 0];
168                 mask <<= 1;
169         }
170 }
171
172 // fills the next four 2 x 2 pixel boxes with either p[0] or p[1], depending on pattern
173 static void patternRow2Pixels2(unsigned char *pFrame, unsigned char pat, unsigned char *p)
174 {
175         unsigned char pel;
176         unsigned char mask=0x1;
177
178         while (mask != 0x10)
179         {
180                 pel = p[(mask & pat) ? 1 : 0];
181
182                 pFrame[0] = pel;              // upper-left
183                 pFrame[1] = pel;              // upper-right
184                 pFrame[g_width + 0] = pel;    // lower-left
185                 pFrame[g_width + 1] = pel;    // lower-right
186                 pFrame += 2;
187
188                 mask <<= 1;
189         }
190 }
191
192 // fills pixels in the next 4 x 4 pixel boxes with either p[0] or p[1], depending on pat0 and pat1.
193 static void patternQuadrant2Pixels(unsigned char *pFrame, unsigned char pat0, unsigned char pat1, unsigned char *p)
194 {
195         unsigned char pel;
196         unsigned short mask = 0x0001;
197         int i, j;
198         unsigned short pat = (pat1 << 8) | pat0;
199
200         for (i=0; i<4; i++)
201         {
202                 for (j=0; j<4; j++)
203                 {
204                         pel = p[(pat & mask) ? 1 : 0];
205
206                         pFrame[j + i * g_width] = pel;
207
208                         mask <<= 1;
209                 }
210         }
211 }
212
213 static void dispatchDecoder(unsigned char **pFrame, unsigned char codeType, unsigned char **pData, int *pDataRemain, int *curXb, int *curYb)
214 {
215         unsigned char p[4];
216         unsigned char pat[16];
217         int i, j, k;
218         int x, y;
219
220         /* Data is processed in 8x8 pixel blocks.
221            There are 16 ways to encode each block.
222         */
223
224         switch(codeType)
225         {
226         case 0x0:
227                 /* block is copied from block in current frame */
228                 copyFrame(*pFrame, *pFrame + (g_vBackBuf2 - g_vBackBuf1));
229         case 0x1:
230                 /* block is unchanged from two frames ago */
231                 *pFrame += 8;
232                 break;
233
234         case 0x2:
235                 /* Block is copied from nearby (below and/or to the right) within the
236                    new frame.  The offset within the buffer from which to grab the
237                    patch of 8 pixels is given by grabbing a byte B from the data
238                    stream, which is broken into a positive x and y offset according
239                    to the following mapping:
240
241                    if B < 56:
242                    x = 8 + (B % 7)
243                    y = B / 7
244                    else
245                    x = -14 + ((B - 56) % 29)
246                    y =   8 + ((B - 56) / 29)
247                 */
248                 relFar(*(*pData)++, 1, &x, &y);
249                 copyFrame(*pFrame, *pFrame + x + y*g_width);
250                 *pFrame += 8;
251                 --*pDataRemain;
252                 break;
253
254         case 0x3:
255                 /* Block is copied from nearby (above and/or to the left) within the
256                    new frame.
257
258                    if B < 56:
259                    x = -(8 + (B % 7))
260                    y = -(B / 7)
261                    else
262                    x = -(-14 + ((B - 56) % 29))
263                    y = -(  8 + ((B - 56) / 29))
264                 */
265                 relFar(*(*pData)++, -1, &x, &y);
266                 copyFrame(*pFrame, *pFrame + x + y*g_width);
267                 *pFrame += 8;
268                 --*pDataRemain;
269                 break;
270
271         case 0x4:
272                 /* Similar to 0x2 and 0x3, except this method copies from the
273                    "current" frame, rather than the "new" frame, and instead of the
274                    lopsided mapping they use, this one uses one which is symmetric
275                    and centered around the top-left corner of the block.  This uses
276                    only 1 byte still, though, so the range is decreased, since we
277                    have to encode all directions in a single byte.  The byte we pull
278                    from the data stream, I'll call B.  Call the highest 4 bits of B
279                    BH and the lowest 4 bytes BL.  Then the offset from which to copy
280                    the data is:
281
282                    x = -8 + BL
283                    y = -8 + BH
284                 */
285                 relClose(*(*pData)++, &x, &y);
286                 copyFrame(*pFrame, *pFrame + (g_vBackBuf2 - g_vBackBuf1) + x + y*g_width);
287                 *pFrame += 8;
288                 --*pDataRemain;
289                 break;
290
291         case 0x5:
292                 /* Similar to 0x4, but instead of one byte for the offset, this uses
293                    two bytes to encode a larger range, the first being the x offset
294                    as a signed 8-bit value, and the second being the y offset as a
295                    signed 8-bit value.
296                 */
297                 x = (signed char)*(*pData)++;
298                 y = (signed char)*(*pData)++;
299                 copyFrame(*pFrame, *pFrame + (g_vBackBuf2 - g_vBackBuf1) + x + y*g_width);
300                 *pFrame += 8;
301                 *pDataRemain -= 2;
302                 break;
303
304         case 0x6:
305                 /* I can't figure out how any file containing a block of this type
306                    could still be playable, since it appears that it would leave the
307                    internal bookkeeping in an inconsistent state in the BG player
308                    code.  Ahh, well.  Perhaps it was a bug in the BG player code that
309                    just didn't happen to be exposed by any of the included movies.
310                    Anyway, this skips the next two blocks, doing nothing to them.
311                    Note that if you've reached the end of a row, this means going on
312                    to the next row.
313                 */
314                 for (i=0; i<2; i++)
315                 {
316                         *pFrame += 16;
317                         if (++*curXb == (g_width >> 3))
318                         {
319                                 *pFrame += 7*g_width;
320                                 *curXb = 0;
321                                 if (++*curYb == (g_height >> 3))
322                                         return;
323                         }
324                 }
325                 break;
326
327         case 0x7:
328                 /* Ok, here's where it starts to get really...interesting.  This is,
329                    incidentally, the part where they started using self-modifying
330                    code.  So, most of the following encodings are "patterned" blocks,
331                    where we are given a number of pixel values and then bitmapped
332                    values to specify which pixel values belong to which squares.  For
333                    this encoding, we are given the following in the data stream:
334
335                    P0 P1
336
337                    These are pixel values (i.e. 8-bit indices into the palette).  If
338                    P0 <= P1, we then get 8 more bytes from the data stream, one for
339                    each row in the block:
340
341                    B0 B1 B2 B3 B4 B5 B6 B7
342
343                    For each row, the leftmost pixel is represented by the low-order
344                    bit, and the rightmost by the high-order bit.  Use your imagination
345                    in between.  If a bit is set, the pixel value is P1 and if it is
346                    unset, the pixel value is P0.
347
348                    So, for example, if we had:
349
350                    11 22 fe 83 83 83 83 83 83 fe
351
352                    This would represent the following layout:
353
354                    11 22 22 22 22 22 22 22     ; fe == 11111110
355                    22 22 11 11 11 11 11 22     ; 83 == 10000011
356                    22 22 11 11 11 11 11 22     ; 83 == 10000011
357                    22 22 11 11 11 11 11 22     ; 83 == 10000011
358                    22 22 11 11 11 11 11 22     ; 83 == 10000011
359                    22 22 11 11 11 11 11 22     ; 83 == 10000011
360                    22 22 11 11 11 11 11 22     ; 83 == 10000011
361                    11 22 22 22 22 22 22 22     ; fe == 11111110
362
363                    If, on the other hand, P0 > P1, we get two more bytes from the
364                    data stream:
365
366                    B0 B1
367
368                    Each of these bytes contains two 4-bit patterns. These patterns
369                    work like the patterns above with 8 bytes, except each bit
370                    represents a 2x2 pixel region.
371
372                    B0 contains the pattern for the top two rows and B1 contains
373                    the pattern for the bottom two rows.  Note that the low-order
374                    nibble of each byte contains the pattern for the upper of the
375                    two rows that that byte controls.
376
377                    So if we had:
378
379                    22 11 7e 83
380
381                    The output would be:
382
383                    11 11 22 22 22 22 22 22     ; e == 1 1 1 0
384                    11 11 22 22 22 22 22 22     ;
385                    22 22 22 22 22 22 11 11     ; 7 == 0 1 1 1
386                    22 22 22 22 22 22 11 11     ;
387                    11 11 11 11 11 11 22 22     ; 3 == 1 0 0 0
388                    11 11 11 11 11 11 22 22     ;
389                    22 22 22 22 11 11 11 11     ; 8 == 0 0 1 1
390                    22 22 22 22 11 11 11 11     ;
391                 */
392                 p[0] = *(*pData)++;
393                 p[1] = *(*pData)++;
394                 if (p[0] <= p[1])
395                 {
396                         for (i=0; i<8; i++)
397                         {
398                                 patternRow2Pixels(*pFrame, *(*pData)++, p);
399                                 *pFrame += g_width;
400                         }
401                 }
402                 else
403                 {
404                         for (i=0; i<2; i++)
405                         {
406                                 patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
407                                 *pFrame += 2*g_width;
408                                 patternRow2Pixels2(*pFrame, *(*pData)++ >> 4, p);
409                                 *pFrame += 2*g_width;
410                         }
411                 }
412                 *pFrame -= (8*g_width - 8);
413                 break;
414
415         case 0x8:
416                 /* Ok, this one is basically like encoding 0x7, only more
417                    complicated.  Again, we start out by getting two bytes on the data
418                    stream:
419
420                    P0 P1
421
422                    if P0 <= P1 then we get the following from the data stream:
423
424                    B0 B1
425                    P2 P3 B2 B3
426                    P4 P5 B4 B5
427                    P6 P7 B6 B7
428
429                    P0 P1 and B0 B1 are used for the top-left corner, P2 P3 B2 B3 for
430                    the bottom-left corner, P4 P5 B4 B5 for the top-right, P6 P7 B6 B7
431                    for the bottom-right.  (So, each codes for a 4x4 pixel array.)
432                    Since we have 16 bits in B0 B1, there is one bit for each pixel in
433                    the array.  The convention for the bit-mapping is, again, left to
434                    right and top to bottom.
435
436                    So, basically, the top-left quarter of the block is an arbitrary
437                    pattern with 2 pixels, the bottom-left a different arbitrary
438                    pattern with 2 different pixels, and so on.
439
440                    For example if the next 16 bytes were:
441
442                    00 22 f9 9f  44 55 aa 55  11 33 cc 33  66 77 01 ef
443
444                    We'd draw:
445
446                    22 22 22 22 | 11 11 33 33     ; f = 1111, c = 1100
447                    22 00 00 22 | 11 11 33 33     ; 9 = 1001, c = 1100
448                    22 00 00 22 | 33 33 11 11     ; 9 = 1001, 3 = 0011
449                    22 22 22 22 | 33 33 11 11     ; f = 1111, 3 = 0011
450                    ------------+------------
451                    44 55 44 55 | 66 66 66 66     ; a = 1010, 0 = 0000
452                    44 55 44 55 | 77 66 66 66     ; a = 1010, 1 = 0001
453                    55 44 55 44 | 66 77 77 77     ; 5 = 0101, e = 1110
454                    55 44 55 44 | 77 77 77 77     ; 5 = 0101, f = 1111
455
456                    I've added a dividing line in the above to clearly delineate the
457                    quadrants.
458
459
460                    Now, if P0 > P1 then we get 10 more bytes from the data stream:
461
462                    B0 B1 B2 B3 P2 P3 B4 B5 B6 B7
463
464                    Now, if P2 <= P3, then the first six bytes [P0 P1 B0 B1 B2 B3]
465                    represent the left half of the block and the latter six bytes
466                    [P2 P3 B4 B5 B6 B7] represent the right half.
467
468                    For example:
469
470                    22 00 01 37 f7 31   11 66 8c e6 73 31
471
472                    yeilds:
473
474                    22 22 22 22 | 11 11 11 66     ; 0: 0000 | 8: 1000
475                    00 22 22 22 | 11 11 66 66     ; 1: 0001 | C: 1100
476                    00 00 22 22 | 11 66 66 66     ; 3: 0011 | e: 1110
477                    00 00 00 22 | 11 66 11 66     ; 7: 0111 | 6: 0101
478                    00 00 00 00 | 66 66 66 11     ; f: 1111 | 7: 0111
479                    00 00 00 22 | 66 66 11 11     ; 7: 0111 | 3: 0011
480                    00 00 22 22 | 66 66 11 11     ; 3: 0011 | 3: 0011
481                    00 22 22 22 | 66 11 11 11     ; 1: 0001 | 1: 0001
482
483
484                    On the other hand, if P0 > P1 and P2 > P3, then
485                    [P0 P1 B0 B1 B2 B3] represent the top half of the
486                    block and [P2 P3 B4 B5 B6 B7] represent the bottom half.
487
488                    For example:
489
490                    22 00 cc 66 33 19   66 11 18 24 42 81
491
492                    yeilds:
493
494                    22 22 00 00 22 22 00 00     ; cc: 11001100
495                    22 00 00 22 22 00 00 22     ; 66: 01100110
496                    00 00 22 22 00 00 22 22     ; 33: 00110011
497                    00 22 22 00 00 22 22 22     ; 19: 00011001
498                    -----------------------
499                    66 66 66 11 11 66 66 66     ; 18: 00011000
500                    66 66 11 66 66 11 66 66     ; 24: 00100100
501                    66 11 66 66 66 66 11 66     ; 42: 01000010
502                    11 66 66 66 66 66 66 11     ; 81: 10000001
503                 */
504                 if ( (*pData)[0] <= (*pData)[1])
505                 {
506                         // four quadrant case
507                         for (i=0; i<4; i++)
508                         {
509                                 p[0] = *(*pData)++;
510                                 p[1] = *(*pData)++;
511                                 pat[0] = *(*pData)++;
512                                 pat[1] = *(*pData)++;
513                                 patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
514
515                                 // alternate between moving down and moving up and right
516                                 if (i & 1)
517                                         *pFrame += 4 - 4*g_width; // up and right
518                                 else
519                                         *pFrame += 4*g_width;     // down
520                         }
521                 }
522                 else if ( (*pData)[6] <= (*pData)[7])
523                 {
524                         // split horizontal
525                         for (i=0; i<4; i++)
526                         {
527                                 if ((i & 1) == 0)
528                                 {
529                                         p[0] = *(*pData)++;
530                                         p[1] = *(*pData)++;
531                                 }
532                                 pat[0] = *(*pData)++;
533                                 pat[1] = *(*pData)++;
534                                 patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
535
536                                 if (i & 1)
537                                         *pFrame -= (4*g_width - 4);
538                                 else
539                                         *pFrame += 4*g_width;
540                         }
541                 }
542                 else
543                 {
544                         // split vertical
545                         for (i=0; i<8; i++)
546                         {
547                                 if ((i & 3) == 0)
548                                 {
549                                         p[0] = *(*pData)++;
550                                         p[1] = *(*pData)++;
551                                 }
552                                 patternRow2Pixels(*pFrame, *(*pData)++, p);
553                                 *pFrame += g_width;
554                         }
555                         *pFrame -= (8*g_width - 8);
556                 }
557                 break;
558
559         case 0x9:
560                 /* Similar to the previous 2 encodings, only more complicated.  And
561                    it will get worse before it gets better.  No longer are we dealing
562                    with patterns over two pixel values.  Now we are dealing with
563                    patterns over 4 pixel values with 2 bits assigned to each pixel
564                    (or block of pixels).
565
566                    So, first on the data stream are our 4 pixel values:
567
568                    P0 P1 P2 P3
569
570                    Now, if P0 <= P1  AND  P2 <= P3, we get 16 bytes of pattern, each
571                    2 bits representing a 1x1 pixel (00=P0, 01=P1, 10=P2, 11=P3).  The
572                    ordering is again left to right and top to bottom.  The most
573                    significant bits represent the left side at the top, and so on.
574
575                    If P0 <= P1  AND  P2 > P3, we get 4 bytes of pattern, each 2 bits
576                    representing a 2x2 pixel.  Ordering is left to right and top to
577                    bottom.
578
579                    if P0 > P1  AND  P2 <= P3, we get 8 bytes of pattern, each 2 bits
580                    representing a 2x1 pixel (i.e. 2 pixels wide, and 1 high).
581
582                    if P0 > P1  AND  P2 > P3, we get 8 bytes of pattern, each 2 bits
583                    representing a 1x2 pixel (i.e. 1 pixel wide, and 2 high).
584                 */
585                 if ( (*pData)[0] <= (*pData)[1])
586                 {
587                         if ( (*pData)[2] <= (*pData)[3])
588                         {
589                                 p[0] = *(*pData)++;
590                                 p[1] = *(*pData)++;
591                                 p[2] = *(*pData)++;
592                                 p[3] = *(*pData)++;
593
594                                 for (i=0; i<8; i++)
595                                 {
596                                         pat[0] = *(*pData)++;
597                                         pat[1] = *(*pData)++;
598                                         patternRow4Pixels(*pFrame, pat[0], pat[1], p);
599                                         *pFrame += g_width;
600                                 }
601
602                                 *pFrame -= (8*g_width - 8);
603                         }
604                         else
605                         {
606                                 p[0] = *(*pData)++;
607                                 p[1] = *(*pData)++;
608                                 p[2] = *(*pData)++;
609                                 p[3] = *(*pData)++;
610
611                                 patternRow4Pixels2(*pFrame, *(*pData)++, p);
612                                 *pFrame += 2*g_width;
613                                 patternRow4Pixels2(*pFrame, *(*pData)++, p);
614                                 *pFrame += 2*g_width;
615                                 patternRow4Pixels2(*pFrame, *(*pData)++, p);
616                                 *pFrame += 2*g_width;
617                                 patternRow4Pixels2(*pFrame, *(*pData)++, p);
618                                 *pFrame -= (6*g_width - 8);
619                         }
620                 }
621                 else
622                 {
623                         if ( (*pData)[2] <= (*pData)[3])
624                         {
625                                 // draw 2x1 strips
626                                 p[0] = *(*pData)++;
627                                 p[1] = *(*pData)++;
628                                 p[2] = *(*pData)++;
629                                 p[3] = *(*pData)++;
630
631                                 for (i=0; i<8; i++)
632                                 {
633                                         pat[0] = *(*pData)++;
634                                         patternRow4Pixels2x1(*pFrame, pat[0], p);
635                                         *pFrame += g_width;
636                                 }
637
638                                 *pFrame -= (8*g_width - 8);
639                         }
640                         else
641                         {
642                                 // draw 1x2 strips
643                                 p[0] = *(*pData)++;
644                                 p[1] = *(*pData)++;
645                                 p[2] = *(*pData)++;
646                                 p[3] = *(*pData)++;
647
648                                 for (i=0; i<4; i++)
649                                 {
650                                         pat[0] = *(*pData)++;
651                                         pat[1] = *(*pData)++;
652                                         patternRow4Pixels(*pFrame, pat[0], pat[1], p);
653                                         *pFrame += g_width;
654                                         patternRow4Pixels(*pFrame, pat[0], pat[1], p);
655                                         *pFrame += g_width;
656                                 }
657
658                                 *pFrame -= (8*g_width - 8);
659                         }
660                 }
661                 break;
662
663         case 0xa:
664                 /* Similar to the previous, only a little more complicated.
665
666                 We are still dealing with patterns over 4 pixel values with 2 bits
667                 assigned to each pixel (or block of pixels).
668
669                 So, first on the data stream are our 4 pixel values:
670
671                 P0 P1 P2 P3
672
673                 Now, if P0 <= P1, the block is divided into 4 quadrants, ordered
674                 (as with opcode 0x8) TL, BL, TR, BR.  In this case the next data
675                 in the data stream should be:
676
677                 B0  B1  B2  B3
678                 P4  P5  P6  P7  B4  B5  B6  B7
679                 P8  P9  P10 P11 B8  B9  B10 B11
680                 P12 P13 P14 P15 B12 B13 B14 B15
681
682                 Each 2 bits represent a 1x1 pixel (00=P0, 01=P1, 10=P2, 11=P3).
683                 The ordering is again left to right and top to bottom.  The most
684                 significant bits represent the right side at the top, and so on.
685
686                 If P0 > P1 then the next data on the data stream is:
687
688                 B0 B1 B2  B3  B4  B5  B6  B7
689                 P4 P5 P6 P7 B8 B9 B10 B11 B12 B13 B14 B15
690
691                 Now, in this case, if P4 <= P5,
692                 [P0 P1 P2 P3 B0 B1 B2 B3 B4 B5 B6 B7] represent the left half of
693                 the block and the other bytes represent the right half.  If P4 >
694                 P5, then [P0 P1 P2 P3 B0 B1 B2 B3 B4 B5 B6 B7] represent the top
695                 half of the block and the other bytes represent the bottom half.
696                 */
697                 if ( (*pData)[0] <= (*pData)[1])
698                 {
699                         for (i=0; i<4; i++)
700                         {
701                                 p[0] = *(*pData)++;
702                                 p[1] = *(*pData)++;
703                                 p[2] = *(*pData)++;
704                                 p[3] = *(*pData)++;
705                                 pat[0] = *(*pData)++;
706                                 pat[1] = *(*pData)++;
707                                 pat[2] = *(*pData)++;
708                                 pat[3] = *(*pData)++;
709
710                                 patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
711
712                                 if (i & 1)
713                                         *pFrame -= (4*g_width - 4);
714                                 else
715                                         *pFrame += 4*g_width;
716                         }
717                 }
718                 else
719                 {
720                         if ( (*pData)[12] <= (*pData)[13])
721                         {
722                                 // split vertical
723                                 for (i=0; i<4; i++)
724                                 {
725                                         if ((i&1) == 0)
726                                         {
727                                                 p[0] = *(*pData)++;
728                                                 p[1] = *(*pData)++;
729                                                 p[2] = *(*pData)++;
730                                                 p[3] = *(*pData)++;
731                                         }
732
733                                         pat[0] = *(*pData)++;
734                                         pat[1] = *(*pData)++;
735                                         pat[2] = *(*pData)++;
736                                         pat[3] = *(*pData)++;
737
738                                         patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
739
740                                         if (i & 1)
741                                                 *pFrame -= (4*g_width - 4);
742                                         else
743                                                 *pFrame += 4*g_width;
744                                 }
745                         }
746                         else
747                         {
748                                 // split horizontal
749                                 for (i=0; i<8; i++)
750                                 {
751                                         if ((i&3) == 0)
752                                         {
753                                                 p[0] = *(*pData)++;
754                                                 p[1] = *(*pData)++;
755                                                 p[2] = *(*pData)++;
756                                                 p[3] = *(*pData)++;
757                                         }
758
759                                         pat[0] = *(*pData)++;
760                                         pat[1] = *(*pData)++;
761                                         patternRow4Pixels(*pFrame, pat[0], pat[1], p);
762                                         *pFrame += g_width;
763                                 }
764
765                                 *pFrame -= (8*g_width - 8);
766                         }
767                 }
768                 break;
769
770         case 0xb:
771                 /* In this encoding we get raw pixel data in the data stream -- 64
772                    bytes of pixel data.  1 byte for each pixel, and in the standard
773                    order (l->r, t->b).
774                 */
775                 for (i=0; i<8; i++)
776                 {
777                         memcpy(*pFrame, *pData, 8);
778                         *pFrame += g_width;
779                         *pData += 8;
780                         *pDataRemain -= 8;
781                 }
782                 *pFrame -= (8*g_width - 8);
783                 break;
784
785         case 0xc:
786                 /* In this encoding we get raw pixel data in the data stream -- 16
787                    bytes of pixel data.  1 byte for each block of 2x2 pixels, and in
788                    the standard order (l->r, t->b).
789                 */
790                 for (i=0; i<4; i++)
791                 {
792                         for (j=0; j<2; j++)
793                         {
794                                 for (k=0; k<4; k++)
795                                 {
796                                         (*pFrame)[2*k]   = (*pData)[k];
797                                         (*pFrame)[2*k+1] = (*pData)[k];
798                                 }
799                                 *pFrame += g_width;
800                         }
801                         *pData += 4;
802                         *pDataRemain -= 4;
803                 }
804                 *pFrame -= (8*g_width - 8);
805                 break;
806
807         case 0xd:
808                 /* In this encoding we get raw pixel data in the data stream -- 4
809                    bytes of pixel data.  1 byte for each block of 4x4 pixels, and in
810                    the standard order (l->r, t->b).
811                 */
812                 for (i=0; i<2; i++)
813                 {
814                         for (j=0; j<4; j++)
815                         {
816                                 for (k=0; k<4; k++)
817                                 {
818                                         (*pFrame)[k*g_width+j] = (*pData)[0];
819                                         (*pFrame)[k*g_width+j+4] = (*pData)[1];
820                                 }
821                         }
822                         *pFrame += 4*g_width;
823                         *pData += 2;
824                         *pDataRemain -= 2;
825                 }
826                 *pFrame -= (8*g_width - 8);
827                 break;
828
829         case 0xe:
830                 /* This encoding represents a solid 8x8 frame.  We get 1 byte of pixel
831                    data from the data stream.
832                 */
833                 for (i=0; i<8; i++)
834                 {
835                         memset(*pFrame, **pData, 8);
836                         *pFrame += g_width;
837                 }
838                 ++*pData;
839                 --*pDataRemain;
840                 *pFrame -= (8*g_width - 8);
841                 break;
842
843         case 0xf:
844                 /* This encoding represents a "dithered" frame, which is
845                    checkerboarded with alternate pixels of two colors.  We get 2
846                    bytes of pixel data from the data stream, and these bytes are
847                    alternated:
848
849                    P0 P1 P0 P1 P0 P1 P0 P1
850                    P1 P0 P1 P0 P1 P0 P1 P0
851                    ...
852                    P0 P1 P0 P1 P0 P1 P0 P1
853                    P1 P0 P1 P0 P1 P0 P1 P0
854                 */
855                 for (i=0; i<8; i++)
856                 {
857                         for (j=0; j<8; j++)
858                         {
859                                 (*pFrame)[j] = (*pData)[(i+j)&1];
860                         }
861                         *pFrame += g_width;
862                 }
863                 *pData += 2;
864                 *pDataRemain -= 2;
865                 *pFrame -= (8*g_width - 8);
866                 break;
867
868         default:
869                 break;
870         }
871 }