Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

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