Subversion Repositories Games.Carmageddon

Rev

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

  1. #include "pmmemops.h"
  2. #include "harness/trace.h"
  3.  
  4. #include <string.h>
  5.  
  6. // FIXME: optimize filling memory, eventually using builtins
  7. //        this file should contain a general arch-independent implementation,
  8. //        other files can contain arch-specific implementations, e.g. one for SSE4
  9.  
  10. void pm_mem_fill_colour(br_uint_8* dest, br_uint_32 qual, br_uint_32 nbpixels, br_uint_32 bpp, br_uint_32 colour) {
  11.     LOG_TRACE("(%p, %d, %d, %d, %d)", dest, qual, nbpixels, bpp, colour);
  12.  
  13.     switch (bpp) {
  14.         case 1:
  15.             memset(dest, colour, nbpixels);
  16.             break;
  17.         case 2: {
  18.             br_uint_16 p = colour;
  19.             int i;
  20.             for (i = nbpixels; i != 0; i--, dest+=2) {
  21.                 *(br_uint_16*)dest = colour;
  22.             }
  23.             break;
  24.         }
  25.         break;
  26.         case 3:
  27.         case 4:
  28.             NOT_IMPLEMENTED();
  29.         default:
  30.             TELL_ME_IF_WE_PASS_THIS_WAY();
  31.             return;
  32.     }
  33. }
  34.  
  35. void pm_mem_fill_colour_rect(br_uint_8* dest, br_uint_32 qual, br_uint_32 width, br_uint_32 height, br_uint_32 stride, br_uint_32 bpp, br_uint_32 colour) {
  36.     br_uint_32 x; // Pierre-Marie Baty -- fixed type
  37.     br_uint_32 y; // Pierre-Marie Baty -- fixed type
  38.     LOG_TRACE("(%p, %d, %d, %d, %d, %d, %d)", dest, qual, width, height, stride, bpp, colour);
  39.  
  40.     switch (bpp) {
  41.     case 1:
  42.         for (y = 0; y < height; y++) {
  43.             memset(dest + y * stride, colour, width);
  44.         }
  45.         break;
  46.     case 2:
  47.         for (y = 0; y < height; y++) {
  48.             for (x = 0; x < width; x+=1) {
  49.                 *(br_uint_16*)(dest + y * stride + 2 * x) = colour;
  50.             }
  51.         }
  52.         break;
  53.     case 3:
  54.     case 4:
  55.         NOT_IMPLEMENTED();
  56.     default:
  57.         TELL_ME_IF_WE_PASS_THIS_WAY();
  58.         return;
  59.     }
  60. }
  61.  
  62. void pm_mem_copy_colour(br_uint_8* dest, br_uint_32 dest_qual, br_uint_8* src, br_uint_32 src_qual, br_uint_32 nbpixels, br_uint_32 bpp) {
  63.     LOG_TRACE("(%p, %d, %p, %d, %d, %d)", dest, dest_qual, src, src_qual, nbpixels, bpp);
  64.  
  65.     memcpy(dest, src, nbpixels * bpp);
  66. }
  67.  
  68. void pm_mem_copy_colour_rect(br_uint_8* dest, br_uint_32 dest_qual, br_uint_8* src ,br_uint_32 src_qual,
  69.                  br_uint_32 width, br_uint_32 height, br_uint_32 dest_stride, br_uint_32 src_stride, br_uint_32 bpp) {
  70.     br_uint_32 i; // Pierre-Marie Baty -- fixed type
  71.     LOG_TRACE("(%p, %d, %p, %d, %d, %d, %d, %d, %d)", dest, dest_qual, src, src_qual, width, height, dest_stride, src_stride, bpp);
  72.  
  73.     for (i = 0; i < height; i++) {
  74.         memcpy(dest + i * dest_stride, src + i * src_stride, bpp * width);
  75.     }
  76. }
  77.  
  78. void pm_mem_set_colour(br_uint_8* dest, br_uint_32 dest_qual, br_uint_32 bpp, br_uint_32 colour) {
  79.     switch (bpp) {
  80.     case 1:
  81.         *(br_uint_8*)dest = colour;
  82.         break;
  83.     case 2:
  84.         *(br_uint_16*)dest = colour;
  85.         break;
  86.     case 3:
  87.         ((br_uint_8*)dest)[0] = colour;
  88.         ((br_uint_8*)dest)[1] = colour >> 8;
  89.         ((br_uint_8*)dest)[2] = colour >> 16;
  90.         break;
  91.     case 4:
  92.         *(br_uint_32*)dest = colour;
  93.         break;
  94.     default:
  95.         TELL_ME_IF_WE_PASS_THIS_WAY();
  96.     }
  97. }
  98.  
  99. void pm_mem_copy_bits(br_uint_8* dst, br_uint_32 dst_qual, br_uint_32 dst_stride, br_uint_8* src, br_uint_32 src_stride,
  100.         br_uint_32 start_bit, br_uint_32 end_bit, br_uint_32 height, br_uint_32 bpp, br_uint_32 colour) {
  101.     static br_uint_8 start_mask_lut[9] = { 0xff, 0x7f, 0x3f, 0x1f, 0xf, 0x7, 0x3, 0x1, 0x0 };
  102.     static br_uint_8 end_mask_lut[9] = { 0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
  103.     br_uint_8 start_mask;
  104.     br_uint_8 end_mask;
  105.     br_uint_32 end_bit_byte;
  106.     br_uint_8 mask;
  107.     br_uint_8 colour_byte1;
  108.     br_uint_8 colour_byte2;
  109.     br_uint_8 colour_byte3;
  110.     br_uint_8* tmp_dst;
  111.     br_uint_8* tmp_src;
  112.     LOG_TRACE("(%p, %d, %d, %p, %d, %d, %d, %d, %d)", dst, dst_qual, dst_stride, src, src_stride, start_bit, end_bit, height, bpp, colour);
  113.  
  114.  
  115.     start_mask = start_mask_lut[start_bit];
  116.     end_mask = end_mask_lut[end_bit % 8];
  117.     end_bit_byte = end_bit / 8;
  118.  
  119.     if (end_bit_byte == 0) {
  120.         if (bpp == 1) {
  121.             colour_byte1 = colour;
  122.             for (; height != 0; height--, dst += dst_stride, src += src_stride) {
  123.                 mask = *src & start_mask & end_mask;
  124.                 if (mask & 0x80) {
  125.                     dst[0] = colour_byte1;
  126.                 }
  127.                 if (mask & 0x40) {
  128.                     dst[1] = colour_byte1;
  129.                 }
  130.                 if (mask & 0x20) {
  131.                     dst[2] = colour_byte1;
  132.                 }
  133.                 if (mask & 0x10) {
  134.                     dst[3] = colour_byte1;
  135.                 }
  136.                 if (mask & 0x08) {
  137.                     dst[4] = colour_byte1;
  138.                 }
  139.                 if (mask & 0x04) {
  140.                     dst[5] = colour_byte1;
  141.                 }
  142.                 if (mask & 0x02) {
  143.                     dst[6] = colour_byte1;
  144.                 }
  145.                 if (mask & 0x01) {
  146.                     dst[7] = colour_byte1;
  147.                 }
  148.             }
  149.             return;
  150.         }
  151.         else if (bpp == 2) {
  152.             mask = *src & start_mask & end_mask;
  153.             colour_byte1 = colour;
  154.             colour_byte2 = colour >> 8;
  155.             for (; height != 0; height--, dst += dst_stride, src += src_stride) {
  156.                 if (mask & 0x80) {
  157.                     dst[0] = colour_byte1;
  158.                     dst[1] = colour_byte2;
  159.                 }
  160.                 if (mask & 0x40) {
  161.                     dst[2] = colour_byte1;
  162.                     dst[3] = colour_byte2;
  163.                 }
  164.                 if (mask & 0x20) {
  165.                     dst[4] = colour_byte1;
  166.                     dst[5] = colour_byte2;
  167.                 }
  168.                 if (mask & 0x10) {
  169.                     dst[6] = colour_byte1;
  170.                     dst[7] = colour_byte2;
  171.                 }
  172.                 if (mask & 0x08) {
  173.                     dst[8] = colour_byte1;
  174.                     dst[9] = colour_byte2;
  175.                 }
  176.                 if (mask & 0x04) {
  177.                     dst[10] = colour_byte1;
  178.                     dst[11] = colour_byte2;
  179.                 }
  180.                 if (mask & 0x02) {
  181.                     dst[12] = colour_byte1;
  182.                     dst[13] = colour_byte2;
  183.                 }
  184.                 if (mask & 0x01) {
  185.                     dst[14] = colour_byte1;
  186.                     dst[15] = colour_byte2;
  187.                 }
  188.             }
  189.             return;
  190.         }
  191.         else if (bpp == 3) {
  192.             mask = *src & start_mask & end_mask;
  193.             colour_byte1 = colour;
  194.             colour_byte2 = colour >> 8;
  195.             colour_byte3 = colour >> 16;
  196.             for (; height != 0; height--, dst += dst_stride, src += src_stride) {
  197.                 if (mask & 0x80) {
  198.                     dst[0] = colour_byte1;
  199.                     dst[1] = colour_byte2;
  200.                     dst[2] = colour_byte3;
  201.                 }
  202.                 if (mask & 0x40) {
  203.                     dst[3] = colour_byte1;
  204.                     dst[4] = colour_byte2;
  205.                     dst[5] = colour_byte3;
  206.                 }
  207.                 if (mask & 0x20) {
  208.                     dst[6] = colour_byte1;
  209.                     dst[7] = colour_byte2;
  210.                     dst[8] = colour_byte3;
  211.                 }
  212.                 if (mask & 0x10) {
  213.                     dst[9] = colour_byte1;
  214.                     dst[10] = colour_byte2;
  215.                     dst[11] = colour_byte3;
  216.                 }
  217.                 if (mask & 0x08) {
  218.                     dst[12] = colour_byte1;
  219.                     dst[13] = colour_byte2;
  220.                     dst[14] = colour_byte3;
  221.                 }
  222.                 if (mask & 0x04) {
  223.                     dst[15] = colour_byte1;
  224.                     dst[16] = colour_byte2;
  225.                     dst[17] = colour_byte3;
  226.                 }
  227.                 if (mask & 0x02) {
  228.                     dst[18] = colour_byte1;
  229.                     dst[19] = colour_byte2;
  230.                     dst[20] = colour_byte3;
  231.                 }
  232.                 if (mask & 0x01) {
  233.                     dst[21] = colour_byte1;
  234.                     dst[22] = colour_byte2;
  235.                     dst[23] = colour_byte3;
  236.                 }
  237.             }
  238.             return;
  239.         }
  240.         else if (bpp == 4) {
  241.             mask = *src & start_mask & end_mask;
  242.             for (; height != 0; height--, dst += dst_stride, src += src_stride) {
  243.                 if (mask & 0x80) {
  244.                     ((br_uint_32*)dst)[0] = colour;
  245.                 }
  246.                 if (mask & 0x40) {
  247.                     ((br_uint_32*)dst)[1] = colour;
  248.                 }
  249.                 if (mask & 0x20) {
  250.                     ((br_uint_32*)dst)[2] = colour;
  251.                 }
  252.                 if (mask & 0x10) {
  253.                     ((br_uint_32*)dst)[3] = colour;
  254.                 }
  255.                 if (mask & 0x08) {
  256.                     ((br_uint_32*)dst)[4] = colour;
  257.                 }
  258.                 if (mask & 0x04) {
  259.                     ((br_uint_32*)dst)[5] = colour;
  260.                 }
  261.                 if (mask & 0x02) {
  262.                     ((br_uint_32*)dst)[6] = colour;
  263.                 }
  264.                 if (mask & 0x01) {
  265.                     ((br_uint_32*)dst)[7] = colour;
  266.                 }
  267.             }
  268.             return;
  269.         }
  270.         else {
  271.             return;
  272.         }
  273.     }
  274.     if (bpp == 1) {
  275.         colour_byte1 = colour;
  276.  
  277.         for (; height != 0; height--, src += src_stride, dst += dst_stride) {
  278.             br_uint_8 row_end_bit_byte;
  279.             mask = *src & start_mask;
  280.             tmp_dst = dst;
  281.             tmp_src = src;
  282.             row_end_bit_byte = end_bit_byte;
  283.             while (row_end_bit_byte != 0) {
  284.                 if (mask & 0x80) {
  285.                     tmp_dst[0] = colour_byte1;
  286.                 }
  287.                 if (mask & 0x40) {
  288.                     tmp_dst[1] = colour_byte1;
  289.                 }
  290.                 if (mask & 0x20) {
  291.                     tmp_dst[2] = colour_byte1;
  292.                 }
  293.                 if (mask & 0x10) {
  294.                     tmp_dst[3] = colour_byte1;
  295.                 }
  296.                 if (mask & 0x08) {
  297.                     tmp_dst[4] = colour_byte1;
  298.                 }
  299.                 if (mask & 0x04) {
  300.                     tmp_dst[5] = colour_byte1;
  301.                 }
  302.                 if (mask & 0x02) {
  303.                     tmp_dst[6] = colour_byte1;
  304.                 }
  305.                 if (mask & 0x01) {
  306.                     tmp_dst[7] = colour_byte1;
  307.                 }
  308.                 tmp_dst += 8;
  309.                 tmp_src += 1;
  310.                 row_end_bit_byte -= 1;
  311.                 mask = *tmp_src;
  312.             }
  313.             mask = end_mask;
  314.             if (mask & 0x80) {
  315.                 tmp_dst[0] = colour_byte1;
  316.             }
  317.             if (mask & 0x40) {
  318.                 tmp_dst[1] = colour_byte1;
  319.             }
  320.             if (mask & 0x20) {
  321.                 tmp_dst[2] = colour_byte1;
  322.             }
  323.             if (mask & 0x10) {
  324.                 tmp_dst[3] = colour_byte1;
  325.             }
  326.             if (mask & 0x08) {
  327.                 tmp_dst[4] = colour_byte1;
  328.             }
  329.             if (mask & 0x04) {
  330.                 tmp_dst[5] = colour_byte1;
  331.             }
  332.             if (mask & 0x02) {
  333.                 tmp_dst[6] = colour_byte1;
  334.             }
  335.             if (mask & 0x01) {
  336.                 tmp_dst[7] = colour_byte1;
  337.             }
  338.         }
  339.         return;
  340.     } else {
  341.         TELL_ME_IF_WE_PASS_THIS_WAY();
  342.     }
  343. }
  344.