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