/* GLD : Devices and ViewPorts managing with DirectDraw.*/
/* PixFmt.c*/
/* Author : Frederic PHILIPPE*/
/* Last Update : 08/07/1997*/
 
#include "acp_base.h"
 
#include "GldInc.h"
#include "GLD/PixFmt.h"
#include "DLLCaps.h"
 
void GLD_vConvert16bColors2FloatColorMultipliedByFactorAndAddToDest( GLD_tdstPixelFormat *p_stDstPixelFormat, unsigned short *p_PixelSrc , float *p_ColorsDest , unsigned long Lenght , float fYBilinearFactor )
{
    unsigned short *p_PixelSrcLast;
    unsigned long ulRed, ulGreen, ulBlue,lRedDstShift,lGreenDstShift,lBlueDstShift;
    
    p_PixelSrcLast = p_PixelSrc + Lenght;
    lRedDstShift = 8-p_stDstPixelFormat->lRedNbBits;
    lGreenDstShift = 8-p_stDstPixelFormat->lGreenNbBits;
    lBlueDstShift = 8-p_stDstPixelFormat->lBlueNbBits;
    for (;p_PixelSrc < p_PixelSrcLast;p_PixelSrc++,p_ColorsDest += 4)
    {
        ulRed = ((unsigned long)*p_PixelSrc) >> p_stDstPixelFormat->lRedShift;
        ulRed = ulRed << lRedDstShift;
        ulRed &= 0xff;
        *(p_ColorsDest + 1) = ((float)(ulRed)) * fYBilinearFactor;
        ulGreen = ((unsigned long )*p_PixelSrc) >> p_stDstPixelFormat->lGreenShift;
        ulGreen = ulGreen << lGreenDstShift;
        ulGreen &= 0xff;
        *(p_ColorsDest + 2) = ((float)(ulGreen)) * fYBilinearFactor;
        ulBlue = ((unsigned long )*p_PixelSrc) >> p_stDstPixelFormat->lBlueShift;
        ulBlue = ulBlue << lBlueDstShift;
        ulBlue &= 0xff;
        *(p_ColorsDest + 3) = ((float)(ulBlue)) * fYBilinearFactor;
    }
    *(p_ColorsDest) = *(p_ColorsDest - 4);
    p_ColorsDest++;
    *(p_ColorsDest) = *(p_ColorsDest - 4);
    p_ColorsDest++;
    *(p_ColorsDest) = *(p_ColorsDest - 4);
    p_ColorsDest++;
    *(p_ColorsDest) = *(p_ColorsDest - 4);
}
 
void GLD_vConvertFloatColors2ARGBColor(float *p_ColorsSrc ,unsigned char *p_PixelDest ,  unsigned long Lenght )
{
  float *p_ColorsSrcLast;
  p_ColorsSrcLast = p_ColorsSrc + (Lenght << 2);
  for (;p_ColorsSrc < p_ColorsSrcLast;p_ColorsSrc += 4)
  {
    *(p_PixelDest++) = (unsigned char)*(p_ColorsSrc+3);
    *(p_PixelDest++) = (unsigned char)*(p_ColorsSrc+2);
    *(p_PixelDest++) = (unsigned char)*(p_ColorsSrc+1);
  }
}
 
void GLD_vCompressLineAddToDestAA(float *p_PixelSrc , float *p_ColorsDest , unsigned long LenghtSource , unsigned long LenghtDest ,  float fYBilinearFactor )
{
    float fSlaveIncDst , fXSlaveCountDst , fXSlaveCountDstOld , fXLocalFactor;
    float fSourceColorR,fSourceColorG,fSourceColorB;
    float fXBilinearFactor;
    float *p_fCurrentColorDST ;
    unsigned long XCounter , XCounterOld ,XBoucle;
 
 
    if (LenghtSource == LenghtDest)
    {
        for (XCounter = 0 ; XCounter < LenghtSource ; XCounter ++ , p_PixelSrc += 4 , p_ColorsDest += 4)
        {
            *p_PixelSrc = fYBilinearFactor;
            *(p_ColorsDest + 1) += *(p_PixelSrc + 1) * fYBilinearFactor;
            *(p_ColorsDest + 2) += *(p_PixelSrc + 2) * fYBilinearFactor;
            *(p_ColorsDest + 3) += *(p_PixelSrc + 3) * fYBilinearFactor;
        }
        return;
    }
    if (LenghtSource > LenghtDest)
    {
        fSlaveIncDst = (float)LenghtDest / (float)LenghtSource;
        fXSlaveCountDst = 0.0f;
        for (XCounterOld = XCounter = XBoucle = 0 ; XBoucle < LenghtSource ; XBoucle ++ , p_PixelSrc += 4 , fXSlaveCountDst += fSlaveIncDst)
        {
          XCounter = (long)fXSlaveCountDst;
          p_fCurrentColorDST = (p_ColorsDest + (XCounter << 2));
          fXBilinearFactor = fXSlaveCountDst - XCounter;
          fSourceColorR = *(p_PixelSrc + 1);
          fSourceColorG = *(p_PixelSrc + 2);
          fSourceColorB = *(p_PixelSrc + 3);
          if (XCounterOld != XCounter)
          {
            fXLocalFactor = fYBilinearFactor * ((float)XCounter - fXSlaveCountDstOld);
            *(p_fCurrentColorDST - 4) += fXLocalFactor;
            *(p_fCurrentColorDST - 4 + 1) += fXLocalFactor * fSourceColorR;
            *(p_fCurrentColorDST - 4 + 2) += fXLocalFactor * fSourceColorG;
            *(p_fCurrentColorDST - 4 + 3) += fXLocalFactor * fSourceColorB;
            fXLocalFactor = fYBilinearFactor * (fXSlaveCountDst - XCounter);
          }
          else
            fXLocalFactor = fYBilinearFactor * fSlaveIncDst;
          XCounterOld = XCounter;
          fXSlaveCountDstOld = fXSlaveCountDst;
          *(p_fCurrentColorDST) += fXLocalFactor;
          *(p_fCurrentColorDST + 1) += fXLocalFactor * fSourceColorR;
          *(p_fCurrentColorDST + 2) += fXLocalFactor * fSourceColorG;
          *(p_fCurrentColorDST + 3) += fXLocalFactor * fSourceColorB;
        }
      }
      else 
      {
        fSlaveIncDst = (float)LenghtSource / (float)LenghtDest;
        fXSlaveCountDst = 0.0f;
        for (XBoucle = 0 ; XBoucle < LenghtDest ; XBoucle ++ , p_ColorsDest += 4 ,fXSlaveCountDst += fSlaveIncDst)
        {
            XCounter = (long)fXSlaveCountDst;
            fXBilinearFactor = fXSlaveCountDst - XCounter;
            fXLocalFactor = fYBilinearFactor ;
            p_fCurrentColorDST = (p_PixelSrc + (XCounter << 2));
 
            fSourceColorR = (1.0f - fXBilinearFactor) * *(p_fCurrentColorDST + 1) + (fXBilinearFactor) * *(p_fCurrentColorDST + 1 + 4);
            fSourceColorG = (1.0f - fXBilinearFactor) * *(p_fCurrentColorDST + 2) + (fXBilinearFactor) * *(p_fCurrentColorDST + 2 + 4);
            fSourceColorB = (1.0f - fXBilinearFactor) * *(p_fCurrentColorDST + 3) + (fXBilinearFactor) * *(p_fCurrentColorDST + 3 + 4);
            fXLocalFactor = fYBilinearFactor;
            *(p_ColorsDest) += fXLocalFactor;
            *(p_ColorsDest + 1) += fXLocalFactor * fSourceColorR;
            *(p_ColorsDest + 2) += fXLocalFactor * fSourceColorG;
            *(p_ColorsDest + 3) += fXLocalFactor * fSourceColorB;
        }
    }
}
 
extern GLD_tdstViewport *GLD_pGetViewport(GLD_tdhDevice, GLD_tdhViewport);
extern GLD_tdstDevice *GLD_pGetDevice(GLD_tdhDevice);
 
GLD_tdstPixelFormat GLD_g_aDEFstDefinedPixelFormats[GLD_C_lMaxNumberOfPixelFormat] =
{         /*         FORMAT            |ALPHA |     PIXEL        |       RED        |      GREEN       |       BLUE       |       ALPHA      */
    /* 0*/{ GLD_C_xUndefinedPixelFormat, FALSE,  0, 0x00000000, 0, 0,  0, 0x00000000, 0,  0, 0x00000000, 0,  0, 0x00000000, 0,  0, 0x00000000 },
    /* 1*/{  GLD_C_xN1B5G5R5PixelFormat, FALSE, 16, 0x0000FFFF, 2, 5,  0, 0x0000001F, 5,  5, 0x000003E0, 5, 10, 0x00007C00, 0,  0, 0x00000000 },
    /* 2*/{  GLD_C_xA1B5G5R5PixelFormat,  TRUE, 16, 0x0000FFFF, 2, 5,  0, 0x0000001F, 5,  5, 0x000003E0, 5, 10, 0x00007C00, 1, 15, 0x00008000 },
    /* 3*/{  GLD_C_xN1R5G5B5PixelFormat, FALSE, 16, 0x0000FFFF, 2, 5, 10, 0x00007C00, 5,  5, 0x000003E0, 5,  0, 0x0000001F, 0,  0, 0x00000000 },
    /* 4*/{  GLD_C_xA4B4G4R4PixelFormat,  TRUE, 16, 0x0000FFFF, 2, 4,  0, 0x0000000F, 4,  4, 0x000000F0, 4,  8, 0x00000F00, 4, 12, 0x0000F000 },
    /* 5*/{    GLD_C_xB8G8R8PixelFormat, FALSE, 24, 0x00FFFFFF, 3, 8,  0, 0x000000FF, 8,  8, 0x0000FF00, 8, 16, 0x0000FF00, 0,  0, 0x00000000 },
    /* 6*/{  GLD_C_xA8B8G8R8PixelFormat,  TRUE, 32, 0xFFFFFFFF, 4, 8,  0, 0x000000FF, 8,  8, 0x0000FF00, 8, 16, 0x0000FF00, 8, 24, 0xFF000000 },
    /* 7*/{    GLD_C_xB5G6R5PixelFormat, FALSE, 16, 0x0000FFFF, 2, 5,  0, 0x0000001F, 6,  5, 0x000007E0, 5, 11, 0x0000F800, 0,  0, 0x00000000 },
    /* 8*/{    GLD_C_xB6G5R5PixelFormat, FALSE, 16, 0x0000FFFF, 2, 5,  0, 0x0000001F, 5,  5, 0x000003E0, 6, 10, 0x0000FC00, 0,  0, 0x00000000 },
    /* 9*/{    GLD_C_xB5G5R6PixelFormat, FALSE, 16, 0x0000FFFF, 2, 6,  0, 0x0000002F, 5,  6, 0x000007C0, 5, 11, 0x0000F800, 0,  0, 0x00000000 },
    /*10*/{  GLD_C_xB5G5R5A1PixelFormat,  TRUE, 16, 0x0000FFFF, 2, 5,  1, 0x0000003E, 5,  6, 0x000007C0, 5, 11, 0x0000F800, 1,  0, 0x00000001 },
    /*11*/{    GLD_C_xR5G6B5PixelFormat, FALSE, 16, 0x0000FFFF, 2, 5, 11, 0x0000F800, 6,  5, 0x000007E0, 5,  0, 0x0000001F, 0,  0, 0x00000000 },
    /*12*/{    GLD_C_xR6G5B5PixelFormat, FALSE, 16, 0x0000FFFF, 2, 6, 10, 0x0000FC00, 5,  5, 0x000003E0, 5,  0, 0x0000001F, 0,  0, 0x00000000 },
    /*13*/{    GLD_C_xR5G5B6PixelFormat, FALSE, 16, 0x0000FFFF, 2, 5, 11, 0x0000F800, 5,  6, 0x000007C0, 6,  0, 0x0000002F, 0,  0, 0x00000000 }
};
ACP_tdxIndex GLD_g_xNumberOfDefinedPixelFormats = 14;
 
void GLD_vSetDefinedPixelFormat ( GLD_tdpstPixelFormat p_stPixelFormat, ACP_tdxIndex xPixelFormatNumber )
{
    memcpy ( p_stPixelFormat, &GLD_g_aDEFstDefinedPixelFormats[xPixelFormatNumber], sizeof ( GLD_tdstPixelFormat ) );
}
 
void GLD_vCopyPixelFormat ( GLD_tdpstPixelFormat p_stDstPixelFormat, GLD_tdpstPixelFormat p_stSrcPixelFormat )
{
  memcpy ( p_stDstPixelFormat, p_stSrcPixelFormat, sizeof ( GLD_tdstPixelFormat ) );
}
 
GLD_tdstPixelFormat *GLD_fn_p_stGetDefinedPixelFormat( long _lFormatIndex )
{
    if ( (unsigned long) _lFormatIndex >= (unsigned long) GLD_g_xNumberOfDefinedPixelFormats )
        return NULL;
 
    return &GLD_g_aDEFstDefinedPixelFormats[ _lFormatIndex ];
}
 
long GLD_fn_lAddDefinedPixelFormat( GLD_tdstPixelFormat *_p_stNewPF )
{
    if ( GLD_g_xNumberOfDefinedPixelFormats == GLD_C_lMaxNumberOfPixelFormat )
        return -1;
 
    _p_stNewPF->xFormatNumber = GLD_g_xNumberOfDefinedPixelFormats;
    GLD_vCopyPixelFormat( &GLD_g_aDEFstDefinedPixelFormats[ GLD_g_xNumberOfDefinedPixelFormats ], _p_stNewPF );
    GLD_g_xNumberOfDefinedPixelFormats++;
 
    return (_p_stNewPF->xFormatNumber );
}
 
 
/*
long GLD_lConvertMaskToShift ( unsigned long ulMask )
{
    if ( ulMask & 0x00000001 ) return 0;
    if ( ulMask & 0x00000002 ) return 1;
    if ( ulMask & 0x00000004 ) return 2;
    if ( ulMask & 0x00000008 ) return 3;
    if ( ulMask & 0x00000010 ) return 4;
    if ( ulMask & 0x00000020 ) return 5;
    if ( ulMask & 0x00000040 ) return 6;
    if ( ulMask & 0x00000080 ) return 7;
    if ( ulMask & 0x00000100 ) return 8;
    if ( ulMask & 0x00000200 ) return 9;
    if ( ulMask & 0x00000400 ) return 10;
    if ( ulMask & 0x00000800 ) return 11;
    if ( ulMask & 0x00001000 ) return 12;
    if ( ulMask & 0x00002000 ) return 13;
    if ( ulMask & 0x00004000 ) return 14;
    if ( ulMask & 0x00008000 ) return 15;
    if ( ulMask & 0x00010000 ) return 16;
    if ( ulMask & 0x00020000 ) return 17;
    if ( ulMask & 0x00040000 ) return 18;
    if ( ulMask & 0x00080000 ) return 19;
    if ( ulMask & 0x00100000 ) return 20;
    if ( ulMask & 0x00200000 ) return 21;
    if ( ulMask & 0x00400000 ) return 22;
    if ( ulMask & 0x00800000 ) return 23;
    if ( ulMask & 0x01000000 ) return 24;
    if ( ulMask & 0x02000000 ) return 25;
    if ( ulMask & 0x04000000 ) return 26;
    if ( ulMask & 0x08000000 ) return 27;
    if ( ulMask & 0x10000000 ) return 28;
    if ( ulMask & 0x20000000 ) return 29;
    if ( ulMask & 0x40000000 ) return 30;
    if ( ulMask & 0x80000000 ) return 31;
    return 0;
}
 
unsigned long GLD_ulConvertNbBitsToMask ( long lNbBits )
{
    if ( lNbBits == 0  ) return 0x00000000;
    if ( lNbBits == 1  ) return 0x00000001;
    if ( lNbBits == 2  ) return 0x00000003;
    if ( lNbBits == 3  ) return 0x00000007;
    if ( lNbBits == 4  ) return 0x0000000F;
    if ( lNbBits == 5  ) return 0x0000001F;
    if ( lNbBits == 6  ) return 0x0000003F;
    if ( lNbBits == 7  ) return 0x0000007F;
    if ( lNbBits == 8  ) return 0x000000FF;
    if ( lNbBits == 9  ) return 0x000001FF;
    if ( lNbBits == 10 ) return 0x000003FF;
    if ( lNbBits == 11 ) return 0x000007FF;
    if ( lNbBits == 12 ) return 0x00000FFF;
    if ( lNbBits == 13 ) return 0x00001FFF;
    if ( lNbBits == 14 ) return 0x00003FFF;
    if ( lNbBits == 15 ) return 0x00007FFF;
    if ( lNbBits == 16 ) return 0x0000FFFF;
    if ( lNbBits == 17 ) return 0x0001FFFF;
    if ( lNbBits == 18 ) return 0x0003FFFF;
    if ( lNbBits == 19 ) return 0x0007FFFF;
    if ( lNbBits == 20 ) return 0x000FFFFF;
    if ( lNbBits == 21 ) return 0x001FFFFF;
    if ( lNbBits == 22 ) return 0x003FFFFF;
    if ( lNbBits == 23 ) return 0x007FFFFF;
    if ( lNbBits == 24 ) return 0x00FFFFFF;
    if ( lNbBits == 25 ) return 0x01FFFFFF;
    if ( lNbBits == 26 ) return 0x03FFFFFF;
    if ( lNbBits == 27 ) return 0x07FFFFFF;
    if ( lNbBits == 28 ) return 0x0FFFFFFF;
    if ( lNbBits == 29 ) return 0x1FFFFFFF;
    if ( lNbBits == 30 ) return 0x3FFFFFFF;
    if ( lNbBits == 31 ) return 0x7FFFFFFF;
    if ( lNbBits == 32 ) return 0xFFFFFFFF;
    return 0x00000000;
}
 
long GLD_lConvertMaskToNbBits ( unsigned long ulMask )
{
    if ( ulMask == 0x00000000 ) return 0;
    if ( ulMask == 0x00000001 ) return 1;
    if ( ulMask == 0x00000003 ) return 2;
    if ( ulMask == 0x00000007 ) return 3;
    if ( ulMask == 0x0000000F ) return 4;
    if ( ulMask == 0x0000001F ) return 5;
    if ( ulMask == 0x0000003F ) return 6;
    if ( ulMask == 0x0000007F ) return 7;
    if ( ulMask == 0x000000FF ) return 8;
    if ( ulMask == 0x000001FF ) return 9;
    if ( ulMask == 0x000003FF ) return 10;
    if ( ulMask == 0x000007FF ) return 11;
    if ( ulMask == 0x00000FFF ) return 12;
    if ( ulMask == 0x00001FFF ) return 13;
    if ( ulMask == 0x00003FFF ) return 14;
    if ( ulMask == 0x00007FFF ) return 15;
    if ( ulMask == 0x0000FFFF ) return 16;
    if ( ulMask == 0x0001FFFF ) return 17;
    if ( ulMask == 0x0003FFFF ) return 18;
    if ( ulMask == 0x0007FFFF ) return 19;
    if ( ulMask == 0x000FFFFF ) return 20;
    if ( ulMask == 0x001FFFFF ) return 21;
    if ( ulMask == 0x003FFFFF ) return 22;
    if ( ulMask == 0x007FFFFF ) return 23;
    if ( ulMask == 0x00FFFFFF ) return 24;
    if ( ulMask == 0x01FFFFFF ) return 25;
    if ( ulMask == 0x03FFFFFF ) return 26;
    if ( ulMask == 0x07FFFFFF ) return 27;
    if ( ulMask == 0x0FFFFFFF ) return 28;
    if ( ulMask == 0x1FFFFFFF ) return 29;
    if ( ulMask == 0x3FFFFFFF ) return 30;
    if ( ulMask == 0x7FFFFFFF ) return 31;
    if ( ulMask == 0xFFFFFFFF ) return 32;
    return 0;
}
 
/*
ACP_tdxBool GLD_bEqualRGBMask ( GLD_tdpstPixelFormat p_stPixelFormat, DDPIXELFORMAT *p_stDDPixelFormat )
{
    return ( p_stPixelFormat->ulRedMask == p_stDDPixelFormat->dwRBitMask ) && ( p_stPixelFormat->ulGreenMask == p_stDDPixelFormat->dwGBitMask ) && ( p_stPixelFormat->ulBlueMask == p_stDDPixelFormat->dwBBitMask );
}
 
ACP_tdxBool GLD_bEqualRGBAMask ( GLD_tdpstPixelFormat p_stPixelFormat, DDPIXELFORMAT *p_stDDPixelFormat )
{
  return    ( p_stPixelFormat->ulRedMask == p_stDDPixelFormat->dwRBitMask ) && ( p_stPixelFormat->ulGreenMask == p_stDDPixelFormat->dwGBitMask )
         && ( p_stPixelFormat->ulBlueMask == p_stDDPixelFormat->dwBBitMask ) && ( p_stPixelFormat->ulAlphaMask == p_stDDPixelFormat->dwRGBAlphaBitMask );
}
 
void GLD_vConvertDDPixelFormatToPixelFormat ( ACP_tdxIndex xFormatNumber, GLD_tdpstPixelFormat p_stDstPixelFormat, LPDDPIXELFORMAT p_stDDPixelFormat )
{
    p_stDstPixelFormat->xFormatNumber   = xFormatNumber;
    p_stDstPixelFormat->bAlpha          = (unsigned char) (p_stDDPixelFormat->dwFlags & DDPF_ALPHAPIXELS);
 
    p_stDstPixelFormat->lPixelNbBits    = p_stDDPixelFormat->dwRGBBitCount;
    p_stDstPixelFormat->ulPixelMask     = GLD_ulConvertNbBitsToMask ( p_stDstPixelFormat->lPixelNbBits );
    p_stDstPixelFormat->lPixelNbBytes   = p_stDstPixelFormat->lPixelNbBits/8;
 
    p_stDstPixelFormat->ulRedMask       = p_stDDPixelFormat->dwRBitMask;
    p_stDstPixelFormat->lRedShift       = GLD_lConvertMaskToShift ( p_stDstPixelFormat->ulRedMask );
    p_stDstPixelFormat->lRedNbBits      = GLD_lConvertMaskToNbBits ( p_stDstPixelFormat->ulRedMask >> p_stDstPixelFormat->lRedShift );
 
    p_stDstPixelFormat->ulGreenMask     = p_stDDPixelFormat->dwGBitMask;
    p_stDstPixelFormat->lGreenShift     = GLD_lConvertMaskToShift ( p_stDstPixelFormat->ulGreenMask );
    p_stDstPixelFormat->lGreenNbBits    = GLD_lConvertMaskToNbBits ( p_stDstPixelFormat->ulGreenMask >> p_stDstPixelFormat->lGreenShift );
 
    p_stDstPixelFormat->ulBlueMask      = p_stDDPixelFormat->dwBBitMask;
    p_stDstPixelFormat->lBlueShift      = GLD_lConvertMaskToShift ( p_stDstPixelFormat->ulBlueMask );
    p_stDstPixelFormat->lBlueNbBits     = GLD_lConvertMaskToNbBits ( p_stDstPixelFormat->ulBlueMask >> p_stDstPixelFormat->lBlueShift );
 
    if ( p_stDstPixelFormat->bAlpha )
    {
        p_stDstPixelFormat->ulAlphaMask = p_stDDPixelFormat->dwRGBAlphaBitMask;
        p_stDstPixelFormat->lAlphaShift = GLD_lConvertMaskToShift ( p_stDstPixelFormat->ulAlphaMask );
        p_stDstPixelFormat->lAlphaNbBits= GLD_lConvertMaskToNbBits ( p_stDstPixelFormat->ulAlphaMask >> p_stDstPixelFormat->lAlphaShift );
    }
    else
    {
        p_stDstPixelFormat->ulAlphaMask = 0x00000000;
        p_stDstPixelFormat->lAlphaShift = 0;
        p_stDstPixelFormat->lAlphaNbBits= 0;
    }
}
*/
/*
ACP_tdxBool GLD_bConvertDDPixelFormatToDefinedPixelFormat ( GLD_tdpstPixelFormat p_stDstPixelFormat, LPDDPIXELFORMAT p_stDDPixelFormat )
{
  ACP_tdxIndex xFormatIndex;
 
    if ( p_stDDPixelFormat->dwFlags & DDPF_RGB )
    {
        for ( xFormatIndex = 0 ; xFormatIndex < GLD_g_xNumberOfDefinedPixelFormats ; xFormatIndex ++ )
        {
            if ( (unsigned long)(GLD_g_aDEFstDefinedPixelFormats[xFormatIndex].lPixelNbBits) == p_stDDPixelFormat->dwRGBBitCount )
            {
                if ( p_stDDPixelFormat->dwFlags & DDPF_ALPHAPIXELS )
                {
                    if ( ( GLD_g_aDEFstDefinedPixelFormats[xFormatIndex].bAlpha ) && ( GLD_bEqualRGBAMask ( &GLD_g_aDEFstDefinedPixelFormats[xFormatIndex], p_stDDPixelFormat ) ) )
                    {
                        GLD_vSetDefinedPixelFormat ( p_stDstPixelFormat, xFormatIndex );
                        return TRUE;
                    }
                }
                else
                {
                    if ( ( !GLD_g_aDEFstDefinedPixelFormats[xFormatIndex].bAlpha ) && ( GLD_bEqualRGBMask ( &GLD_g_aDEFstDefinedPixelFormats[xFormatIndex], p_stDDPixelFormat ) ) )
                    {
                        GLD_vSetDefinedPixelFormat ( p_stDstPixelFormat, xFormatIndex );
                        return TRUE;
                    }
                }
            }
        }
 
        /* ajout dans la table */
/*
        GLD_vConvertDDPixelFormatToPixelFormat ( xFormatIndex, &(GLD_g_aDEFstDefinedPixelFormats[xFormatIndex]), p_stDDPixelFormat );
        GLD_g_xNumberOfDefinedPixelFormats ++;
 
        GLD_vSetDefinedPixelFormat ( p_stDstPixelFormat, xFormatIndex );
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}
*/
 
ACP_tdxBool GLD_bGetPixelFormatOfDevice ( GLD_tdpstPixelFormat p_stDstPixelFormat, GLD_tdhDevice hDev, GLD_tdhViewport hVP )
{
    GLD_tdpstDevice             p_stDev;     /* Pointer to structure Device*/
    
    p_stDev = GLD_pGetDevice( hDev );
    if (p_stDev == NULL)
        return FALSE;
    
    GLD_vSetDefinedPixelFormat ( p_stDstPixelFormat, GLI_g_stCaps.ucPrimarySurfacePixelFormat );
    /*GLD_vSetDefinedPixelFormat ( p_stDstPixelFormat, GLD_C_xR5G6B5PixelFormat );*/
    
    return TRUE;
}
 
/* attention : convertion entre les formats RGB 16 bits seulement */
void GLD_vBitmapConvert16bPixelFormat ( GLD_tdpstPixelFormat p_stDstPixelFormat, GLD_tdpstPixelFormat p_stSrcPixelFormat, unsigned short *p_usBuffer, long lBufferSize )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    unsigned short  *p_usBufferIndex;
    unsigned short  *p_usBufferEnd;
    unsigned short  usRed;
    unsigned short  usGreen;
    unsigned short  usBlue;
    long            lRedSrcShift;
    long            lGreenSrcShift;
    long            lBlueSrcShift;
    long            lRedDstShift;
    long            lGreenDstShift;
    long            lBlueDstShift;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    
    if ( p_stDstPixelFormat->xFormatNumber != p_stSrcPixelFormat->xFormatNumber )
    {
        lRedSrcShift    = 8-p_stSrcPixelFormat->lRedNbBits;
        lGreenSrcShift  = 8-p_stSrcPixelFormat->lGreenNbBits;
        lBlueSrcShift   = 8-p_stSrcPixelFormat->lBlueNbBits;
 
        lRedDstShift    = 8-p_stDstPixelFormat->lRedNbBits;
        lGreenDstShift  = 8-p_stDstPixelFormat->lGreenNbBits;
        lBlueDstShift   = 8-p_stDstPixelFormat->lBlueNbBits;
 
        /* format intermediaire 888 */
        for ( p_usBufferEnd = p_usBuffer + lBufferSize/2, p_usBufferIndex = p_usBuffer ; p_usBufferIndex < p_usBufferEnd ; p_usBufferIndex ++ )
        {
            usRed   = (*p_usBufferIndex & (unsigned short)(p_stSrcPixelFormat->ulRedMask)) >> p_stSrcPixelFormat->lRedShift;
            usRed   = usRed << lRedSrcShift;
            usRed   = usRed >> lRedDstShift;
            usGreen = (*p_usBufferIndex & (unsigned short)(p_stSrcPixelFormat->ulGreenMask)) >> p_stSrcPixelFormat->lGreenShift;
            usGreen = usGreen << lGreenSrcShift;
            usGreen = usGreen >> lGreenDstShift;
            usBlue  = (*p_usBufferIndex & (unsigned short)(p_stSrcPixelFormat->ulBlueMask)) >> p_stSrcPixelFormat->lBlueShift;
            usBlue  = usBlue << lBlueSrcShift;
            usBlue  = usBlue >> lBlueDstShift;
 
            *p_usBufferIndex = (usRed << p_stDstPixelFormat->lRedShift) | (usGreen << p_stDstPixelFormat->lGreenShift) | (usBlue << p_stDstPixelFormat->lBlueShift);
        }
    }
}
 
/* attention : inversion Y d un buffer RGB 24 bits (source BMP) */
void GLD_vYInvertBitmap24b ( unsigned char *_p_ucBuffer, long _lWidth, long _lHeight )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long            ly;
    unsigned char   *p_ucUpOffset;
    unsigned char   *p_ucBottomOffset;
    long            lLineSize;
    unsigned char   a6144_ucTmp[6144];
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    lLineSize = 3*_lWidth;
    p_ucUpOffset = _p_ucBuffer;
    p_ucBottomOffset = _p_ucBuffer+lLineSize*(_lHeight-1);
 
    for ( ly = 0 ; ly < _lHeight/2 ; ly ++ )
    {
        memcpy ( a6144_ucTmp, p_ucBottomOffset, lLineSize );
        memcpy ( p_ucBottomOffset, p_ucUpOffset, lLineSize );
        memcpy ( p_ucUpOffset, a6144_ucTmp, lLineSize );
        p_ucUpOffset += lLineSize;
        p_ucBottomOffset -= lLineSize;
    }
}
 
/* attention : convertion d une bitmap B8G8R8 24 bits au B5G6R5 16 bits */
void GLD_vBitmapConvert24bTo16bPixelFormat ( unsigned short *_p_usDstBuffer, unsigned char *_p_ucSrcBuffer, long _lWidth, long _lHeight )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long            lx, ly;
    unsigned long   ulRed, ulGreen, ulBlue;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    for ( ly = 0 ; ly < _lHeight ; ly ++ )
    {
        for ( lx = 0 ; lx < _lWidth ; lx ++ )
        {
            ulBlue  = (unsigned long)(*_p_ucSrcBuffer++);
            ulGreen = (unsigned long)(*_p_ucSrcBuffer++);
            ulRed   = (unsigned long)(*_p_ucSrcBuffer++);
 
            _p_usDstBuffer[lx+_lWidth*ly] = (unsigned short)(((ulBlue>>3)<<11) | ((ulGreen>>2)<<5) | (ulRed>>3));
        }
    }
}
 
/* attention : convertion d une bitmap B8G8R8 24 bits au B5G6R5 16 bits */
void GLD_vBitmapConvert24bTo16bPixelFormatAndFiltre ( unsigned short *_p_usDstBuffer, long _lWDst, long _lHDst, unsigned char *_p_ucSrcBuffer, long _lWSrc, long _lHSrc )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long            lXDst;
    long            lYDst;
    long            lXSrc;
    long            lYSrc;
    float           fWSrcDWDst;
    float           fHSrcDHDst;
    float           fXSrc;
    float           fYSrc;
    float           fFactX;
    float           fFactY;
    unsigned char   *p_ucPixel;
    float           fRed, fGreen, fBlue;
    float           fRed1, fGreen1, fBlue1;
    float           fRed2, fGreen2, fBlue2;
    float           fRed3, fGreen3, fBlue3;
    float           fRed4, fGreen4, fBlue4;
    float           fRed5, fGreen5, fBlue5;
    float           fRed6, fGreen6, fBlue6;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    _lWSrc --;
    _lHSrc --;
    fWSrcDWDst = ((float)_lWSrc)/((float)_lWDst);
    fHSrcDHDst = ((float)_lHSrc)/((float)_lHDst);
 
    for ( lYDst = 0, fYSrc = 0.0f ; lYDst < _lHDst ; lYDst ++, fYSrc += fHSrcDHDst )
    {
        for ( lXDst = 0, fXSrc = 0.0f ; lXDst < _lWDst ; lXDst ++, fXSrc += fWSrcDWDst )
        {
            lXSrc = (lXDst * _lWSrc)/_lWDst;
            lYSrc = (lYDst * _lHSrc)/_lHDst;
 
            fFactX = fXSrc - (float)lXSrc;
            fFactY = fYSrc - (float)lYSrc;
 
            p_ucPixel = _p_ucSrcBuffer + 3*(lXSrc+(_lWSrc+1)*lYSrc);
 
            /* ulRed1, ulGreen1, ulBlue1 */
            fBlue1  = (float)(*p_ucPixel++);
            fGreen1 = (float)(*p_ucPixel++);
            fRed1   = (float)(*p_ucPixel++);
 
            /* ulRed2, ulGreen2, ulBlue2 */
            fBlue2  = (float)(*p_ucPixel++);
            fGreen2 = (float)(*p_ucPixel++);
            fRed2   = (float)(*p_ucPixel);
            
            p_ucPixel += 3*(_lWSrc+1)-5;
 
            /* ulRed3, ulGreen3, ulBlue3 */
            fBlue3  = (float)(*p_ucPixel++);
            fGreen3 = (float)(*p_ucPixel++);
            fRed3   = (float)(*p_ucPixel++);
 
            /* ulRed4, ulGreen4, ulBlue4 */
            fBlue4  = (float)(*p_ucPixel++);
            fGreen4 = (float)(*p_ucPixel++);
            fRed4   = (float)(*p_ucPixel);
    
            fRed5   = fRed1 + fFactX * (fRed2 - fRed1);
            fGreen5 = fGreen1 + fFactX * (fGreen2 - fGreen1);
            fBlue5  = fBlue1 + fFactX * (fBlue2 - fBlue1);
 
            fRed6   = fRed3 + fFactX * (fRed4 - fRed3);
            fGreen6 = fGreen3 + fFactX * (fGreen4 - fGreen3);
            fBlue6  = fBlue3 + fFactX * (fBlue4 - fBlue3);
 
            fRed    = fRed5 + fFactY * (fRed6 - fRed5);
            fGreen  = fGreen5 + fFactY * (fGreen6 - fGreen5);
            fBlue   = fBlue5 + fFactY * (fBlue6 - fBlue5);
 
            *_p_usDstBuffer = (unsigned short)((((unsigned long)fBlue>>3)<<11) | (((unsigned long)fGreen>>2)<<5) | ((unsigned long)fRed>>3));
            _p_usDstBuffer ++;
        }
    }
}
 
void GLD_fn_vBlit16b ( long _lW, long _lH, unsigned short *_p_usBufferDst, long _lPitch, unsigned short *_p_usBufferSrc )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long lXDst;
    long lYDst;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
    for ( lYDst = 0 ; lYDst < _lH ; lYDst ++ )
    {
        for ( lXDst = 0 ; lXDst < _lW ; lXDst ++ )
        {
            *_p_usBufferDst = *_p_usBufferSrc;
 
            _p_usBufferDst ++;
            _p_usBufferSrc ++;
        }
        _p_usBufferDst += _lPitch - _lW;
    }
}
 
 
void GLD_fn_vBlitStretched16b ( long _lWDst, long _lHDst, unsigned short *_p_usBufferDst, long _lPitch, long _lWSrc, long _lHSrc, unsigned short *_p_usBufferSrc )
{
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    long            lXDst;
    long            lYDst;
    long            a2048_lOffsetXSrc[2048];
    long            a2048_lOffsetYSrc[2048];
    unsigned short  *p_usOffsetDst;
    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  
    p_usOffsetDst = _p_usBufferDst;
 
    for ( lXDst = 0 ; lXDst < _lWDst ; lXDst ++ )
    {
        a2048_lOffsetXSrc[lXDst] = (lXDst * _lWSrc)/_lWDst;
    }
 
    for ( lYDst = 0 ; lYDst < _lHDst ; lYDst ++ )
    {
        a2048_lOffsetYSrc[lYDst] = _lWSrc * ((lYDst * _lHSrc)/_lHDst);
    }
 
    for ( lYDst = 0 ; lYDst < _lHDst ; lYDst ++ )
    {
        for ( lXDst = 0 ; lXDst < _lWDst ; lXDst ++ )
        {
            *p_usOffsetDst = *(_p_usBufferSrc + a2048_lOffsetXSrc[lXDst] + a2048_lOffsetYSrc[lYDst]);
            p_usOffsetDst ++;
        }
        p_usOffsetDst += _lPitch - _lWDst;
    }
}
 
 
 
void GLD_vBitmapConvertAndBlit24bTo16bPixelFormat ( GLD_tdhDevice _hGLDDevice, GLD_tdhViewport _hGLDViewport, long _lWidth, long _lHeight, unsigned char *_p_ucBufferSrc )
{
    GLD_bFlipDevice ( _hGLDDevice );
}
 
 
void GLD_vGetFrontBufferIn24BitsAA( GLD_tdhDevice _hGLDDevice,GLD_tdhViewport _hGLDViewport,unsigned long _lWidth,unsigned long _lHeight,unsigned char *p_lBufferDst )
{
    static float a2048ConvertBufferForAntialias[2048*4]; /* Count , Red , Green , Blue */
    static float a2048ConvertBufferForAntialiasDest[2048*4]; /* Count , Red , Green , Blue */
 
    GLD_tdstViewportAttributes  stViewportAttr;
    GLD_tdstPixelFormat         stDstPixelFormat;
    BOOL                        bCanWrite;
    unsigned short              *p_usBufferSrc;
    unsigned long               PitchSrc;
    unsigned long               WidthSrc,HeightSrc;
    unsigned long               YCounter,LocalCounter , XMAX;
    unsigned long               XCounter;
    unsigned long               ulYC1 , ulYCOLD ;
    float                       fYInc, fYPos;
  
    GLD_bGetPixelFormatOfDevice ( &stDstPixelFormat, _hGLDDevice, _hGLDViewport );
  
    if ( !GLD_bRequestWriteToViewport2D ( _hGLDDevice, _hGLDViewport, &stViewportAttr, &bCanWrite ) )
        return;
 
    if ( !bCanWrite )
        return;
 
    PitchSrc = stViewportAttr.lPitch >> 1;
    WidthSrc = stViewportAttr.dwWidth;
    HeightSrc = stViewportAttr.dwHeight;
        
    if (stDstPixelFormat.lPixelNbBits == 32 )
    {
        unsigned char *p_ucSrc;
 
        if (HeightSrc != _lHeight)
            return;
 
        p_ucSrc = (unsigned char *) stViewportAttr.p_cVirtualScreen;
        for (YCounter = 0; YCounter < _lHeight; YCounter++ )
        {
            for (XCounter = 0; XCounter < _lWidth; XCounter++)
            {
                *p_lBufferDst++ = *p_ucSrc++;
                *p_lBufferDst++ = *p_ucSrc++;
                *p_lBufferDst++ = *p_ucSrc++;
                p_ucSrc++;
            }
        }
    }
    else if (stDstPixelFormat.lPixelNbBits == 16 )
    {
        if (WidthSrc > _lWidth) 
            XMAX = WidthSrc;
        else 
            XMAX = _lWidth;
        p_usBufferSrc = (unsigned short *)stViewportAttr.p_cVirtualScreen ;
 
        if (HeightSrc == _lHeight)
        {
            /* nothing */
            for (YCounter= 0 ; YCounter < _lHeight ; YCounter++ , p_lBufferDst += 3*_lWidth , p_usBufferSrc += PitchSrc)
            {
                for (LocalCounter = 0 ; LocalCounter < XMAX * 4 ; LocalCounter ++ )
                {
                    a2048ConvertBufferForAntialias[LocalCounter] = 0.0f;
                    a2048ConvertBufferForAntialiasDest[LocalCounter] = 0.0f;
                }
                GLD_vConvert16bColors2FloatColorMultipliedByFactorAndAddToDest(&stDstPixelFormat, p_usBufferSrc , a2048ConvertBufferForAntialias , XMAX , 1.0f );
                GLD_vCompressLineAddToDestAA(a2048ConvertBufferForAntialias , a2048ConvertBufferForAntialiasDest , WidthSrc , _lWidth ,  1.0f);
                GLD_vConvertFloatColors2ARGBColor(a2048ConvertBufferForAntialiasDest,p_lBufferDst ,  _lWidth);
            }
        } 
        else if (_lHeight > HeightSrc)
        {
            /* linear */
            float *P_LineSrc;
            float *P_LineDst;
            float fYPosOld;
            long YPos,YPosOld;
        
            ulYC1 = ulYCOLD = 0;
            fYInc = (float)HeightSrc / (float)_lHeight;
            fYPosOld = fYPos = 0.0f;
            P_LineSrc = a2048ConvertBufferForAntialias;
            P_LineDst = a2048ConvertBufferForAntialiasDest;
            YPos = YPosOld = 0;
            for (YCounter= 0 ; YCounter < _lHeight ; YCounter++ , p_lBufferDst += 3*_lWidth , fYPos += fYInc)
            {
                YPos = (long)fYPos ;
                if (YPos != YPosOld)
                    p_usBufferSrc += PitchSrc;
                YPosOld = YPos ;
                for (LocalCounter = 0 ; LocalCounter < XMAX * 4 ; LocalCounter ++ )
                    P_LineDst[LocalCounter] = 0.0f;
 
                GLD_vConvert16bColors2FloatColorMultipliedByFactorAndAddToDest(&stDstPixelFormat, p_usBufferSrc , P_LineSrc , XMAX , 1.0f );
                GLD_vCompressLineAddToDestAA(P_LineSrc , P_LineDst , WidthSrc , _lWidth ,  1.0f - (fYPos - YPos) );
                GLD_vConvert16bColors2FloatColorMultipliedByFactorAndAddToDest(&stDstPixelFormat, p_usBufferSrc + PitchSrc, P_LineSrc , XMAX , 1.0f );
                GLD_vCompressLineAddToDestAA(P_LineSrc , P_LineDst , WidthSrc , _lWidth ,  (fYPos - YPos));
                GLD_vConvertFloatColors2ARGBColor(P_LineDst,p_lBufferDst ,  _lWidth);
            }
        } 
        else if (_lHeight < HeightSrc)
        {
            /* Antialias */
            float *P_LineSrc;
            float *P_LineDst;
            float fPonderation,fYPosOld;
 
            ulYC1 = ulYCOLD = 0;
            fYInc = (float)_lHeight / (float)HeightSrc;
            fYPosOld = fYPos = 0.0f;
            P_LineSrc = a2048ConvertBufferForAntialias;
            P_LineDst = a2048ConvertBufferForAntialiasDest;
            for (LocalCounter = 0 ; LocalCounter < XMAX * 4 ; LocalCounter ++ )
            {
                a2048ConvertBufferForAntialias[LocalCounter] = 0.0f;
                a2048ConvertBufferForAntialiasDest[LocalCounter] = 0.0f;
            } 
            for (YCounter= 0 ; YCounter < HeightSrc ; YCounter++ , p_usBufferSrc += PitchSrc , fYPos += fYInc)
            {
                ulYC1 = (long)fYPos;
                if (ulYC1 != ulYCOLD) 
                {
                    GLD_vCompressLineAddToDestAA(P_LineSrc , P_LineDst , WidthSrc , _lWidth ,  (float)ulYC1 - fYPosOld);
                    GLD_vConvertFloatColors2ARGBColor(P_LineDst,p_lBufferDst ,  _lWidth);
                    for (LocalCounter = 0 ; LocalCounter < XMAX * 4 ; LocalCounter ++ )
                        P_LineDst[LocalCounter] = 0.0f;
 
                    p_lBufferDst += 3*_lWidth;
                    fPonderation = fYPos - ulYC1;
                }
                else
                    fPonderation = fYInc;
 
                ulYCOLD = ulYC1 ;
                fYPosOld = fYPos;
                GLD_vConvert16bColors2FloatColorMultipliedByFactorAndAddToDest(&stDstPixelFormat, p_usBufferSrc , P_LineSrc , XMAX , 1.0f );
                GLD_vCompressLineAddToDestAA(P_LineSrc , P_LineDst , WidthSrc , _lWidth ,  fPonderation);
            }
        }
    }
    
    GLD_bWriteToViewportFinished2D ( _hGLDDevice, _hGLDViewport );
}
