⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blt.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            //
            //  if dest rect overlaps src rect on right side,
            //  start copy from right to left....
            //
            if (prclDst->left>prclSrc->left)
            {
                ulCmd |= 0x100;
                ulDelta = BYTESPERPIXEL(prclSrc->right-prclSrc->left-1);
                ulSrcAddress += ulDelta;
                ulDstAddress += ulDelta;
            }
            //
            //  same for top/bottom rects
            //
            if (prclDst->top>prclSrc->top)
            {
                ulCmd |= 0x200;
                ulDelta = (prclSrc->bottom-prclSrc->top-1)*ulSrcSpan;
                ulSrcAddress += ulDelta;
                ulDstAddress += ulDelta;
            }
        }
    }

    //
    //  wait before touching registers if engine was busy
    //
    if (BltEngineBusy())
        WaitForNotBusy();

    if (pBrush!=NULL)
    {
        DEBUGMSG(CT69K_ZONE_HW, 
            (TEXT("--loading %dx%d brush\r\n"), pptlBrush->x, pptlBrush->y));

        ulCmd |= DownloadBrush( pBrush);
    } else
    {
        DEBUGMSG(CT69K_ZONE_HW, 
            (TEXT("--loading solid brush (%06x)\r\n"), pBltParms->solidColor));

        SetBR( 1, pBltParms->solidColor);
        ulCmd |= (3 << 18);          // force solid brush
    }

    SetBR( 0, ulSrcSpan | (ulDstSpan << 16));
    SetBR( 4, ulCmd);
    SetBR( 6, ulSrcAddress);
    SetBR( 7, ulDstAddress);
    
    ULONG ulWidth=BYTESPERPIXEL(prclDst->right  - prclDst->left);
    ULONG ulHeight=prclDst->bottom - prclDst->top;
    
    SetBR( 8, ulWidth | (ulHeight << 16));
    
    return S_OK;
}



//-----------------------------------------------------------------------
//
//  CT69000::AcceleratedFill
//
//  hardware accelerated solid color fill
//
//-----------------------------------------------------------------------

SCODE 
CT69000::AcceleratedFill(GPEBltParms *pBltParms)
{
    DEBUGMSG(CT69K_ZONE_HW, 
        (TEXT("AcceleratedFill color = 0x%4x\r\n"), pBltParms->solidColor));
    DBGBLTPARMS( CT69K_ZONE_HW, pBltParms);

    ULONG ulDstSpan=pBltParms->pDst->Stride(); 
    ULONG ulDstAddress=pBltParms->pDst->OffsetInVideoMemory();
    ULONG ulWidth=
        BYTESPERPIXEL(pBltParms->prclDst->right  - pBltParms->prclDst->left);
    ULONG ulHeight=pBltParms->prclDst->bottom - pBltParms->prclDst->top;
    ULONG ulColor=pBltParms->solidColor;
    
    ulDstAddress += BYTESPERPIXEL(pBltParms->prclDst->left)+
        pBltParms->prclDst->top*ulDstSpan;

    if (pBltParms->pLookup)
    {
        ulColor = (pBltParms->pLookup)[ulColor];
    } 
    if (pBltParms->pConvert)
    {
        ulColor = (pBltParms->pColorConverter->*(pBltParms->pConvert))(ulColor);
    }

    if (BltEngineBusy())
        WaitForNotBusy();
    
    SetBR( 0, ulDstSpan << 16);         // set dest. span
    SetBR( 1, pBltParms->solidColor);   // set bc color
    SetBR( 4, (pBltParms->rop4 & 0xff) | 
              (1<<19) |                 // force bc color   
              (1<<18));                 // specify mono pattern
    SetBR( 7, ulDstAddress);
    SetBR( 8, ulWidth | (ulHeight << 16));

    return S_OK;
}

//-----------------------------------------------------------------------
//
//  CT69000::AcceleratedPatternFill
//
//  fill dest. rect with an 8x8 pattern brush
//
//-----------------------------------------------------------------------

SCODE 
CT69000::AcceleratedPatternFill(GPEBltParms *pBltParms)
{
    DEBUGMSG(CT69K_ZONE_HW, (TEXT("AcceleratedPatternFill\r\n")));
    DBGBLTPARMS( CT69K_ZONE_HW, pBltParms);

    POINTL  *pptlBrush=pBltParms->pptlBrush;

    ULONG ulDstSpan=pBltParms->pDst->Stride(); 
    ULONG ulDstAddress=pBltParms->pDst->OffsetInVideoMemory();
    ULONG ulWidth=
        BYTESPERPIXEL(pBltParms->prclDst->right  - pBltParms->prclDst->left);
    ULONG ulHeight=pBltParms->prclDst->bottom - pBltParms->prclDst->top;
    ULONG ulCmd=pBltParms->rop4 & 0xff;

    ulCmd |= (pptlBrush->y & 7) << 20;

    if (BltEngineBusy())
        WaitForNotBusy();

    ulCmd |= DownloadBrush(pBltParms->pBrush);
    
    ulDstAddress += BYTESPERPIXEL(pBltParms->prclDst->left)+
                    pBltParms->prclDst->top*ulDstSpan;

    SetBR( 0, ulDstSpan << 16);             // set dest. span
    SetBR( 4, ulCmd); 
    SetBR( 7, ulDstAddress);
    SetBR( 8, ulWidth | (ulHeight << 16));

    return S_OK;
}

//-----------------------------------------------------------------------
//
//  CT69000::DownloadBrush
//
//  load brush to pattern memory and return bits for cmd flag
//
//-----------------------------------------------------------------------

ULONG  
CT69000::DownloadBrush(GPESurf *pBrush)
{
    ULONG  ulCmd=0;
    volatile PULONG pBrushDst;
    PULONG pBrushSrc;

    pBrushSrc=(PULONG)pBrush->Buffer();
    pBrushDst=(PULONG)m_pPatternMemory;

    //
    //  handcoded routines for download to make it really fast...
    //
    if (pBrush->Format()==gpe1Bpp)
    {   
        ulCmd |= (1<<18);
        pBrushDst[0]=pBrushSrc[0];
        pBrushDst[1]=pBrushSrc[1];
    } else if (pBrush->Format()==gpe8Bpp)
    {
        for (INT i=0; i<8; i++)
        {
            pBrushDst[0]=pBrushSrc[0];
            pBrushDst[1]=pBrushSrc[1];
            pBrushDst+=2;
            pBrushSrc = (PULONG)((PUCHAR)pBrushSrc+pBrush->Stride());
        }
    } else if (pBrush->Format()==gpe16Bpp)
    {
        for (INT i=0; i<8; i++)
        {
            pBrushDst[0]=pBrushSrc[0];
            pBrushDst[1]=pBrushSrc[1];
            pBrushDst[2]=pBrushSrc[2];
            pBrushDst[3]=pBrushSrc[3];
            pBrushDst+=4;
            pBrushSrc = (PULONG)((PUCHAR)pBrushSrc+pBrush->Stride());
        }
    } else if (pBrush->Format()==gpe32Bpp)
    {   
        //
        //  pack 32bpp to 24bpp
        //
        for (INT i=0; i<8; i++)
        {   
            pBrushDst[0]= (pBrushSrc[0] & 0xffffff) | (pBrushSrc[1] << 24);
            pBrushDst[1]=((pBrushSrc[1] & 0xffff00)>> 8) | (pBrushSrc[2] << 16);
            pBrushDst[2]=((pBrushSrc[2] & 0xff0000)>> 16) | (pBrushSrc[3] << 8);
            pBrushDst[3]= (pBrushSrc[4] & 0xffffff) | (pBrushSrc[5] << 24);
            pBrushDst[4]=((pBrushSrc[5] & 0xffff00)>> 8) | (pBrushSrc[6] << 16);
            pBrushDst[5]=((pBrushSrc[6] & 0xff0000)>> 16) | (pBrushSrc[7] << 8);
            pBrushDst+=8;
            pBrushSrc = (PULONG)((PUCHAR)pBrushSrc+pBrush->Stride());
        }
    } else if (pBrush->Format()==gpe24Bpp)
    {
        // 
        //  brush for 24bpp is aligned to 32 bytes
        //
        for (INT i=0; i<8; i++)
        {
            pBrushDst[0]=pBrushSrc[0];
            pBrushDst[1]=pBrushSrc[1];
            pBrushDst[2]=pBrushSrc[2];
            pBrushDst[3]=pBrushSrc[3];
            pBrushDst[4]=pBrushSrc[4];
            pBrushDst[5]=pBrushSrc[5];
            pBrushDst+=8;
            pBrushSrc = (PULONG)((PUCHAR)pBrushSrc+pBrush->Stride());
        }
    } else
    {
        DEBUGMSG( 1, (TEXT("unknown brush format! (%d)\r\n"), pBrush->Format()));
    }

    return ulCmd;
}

//-----------------------------------------------------------------------
//
//  CT69000::AcceleratedTextOut1bpp
//
//  output one 1bpp character mask to hardware port to write char 
//  to screen
//
//-----------------------------------------------------------------------

SCODE 
CT69000::AcceleratedTextOut1bpp(GPEBltParms *pBltParms)
{
    DEBUGMSG(CT69K_ZONE_HW, (TEXT("AcceleratedTextOut1bpp\r\n")));
    DBGBLTPARMS( CT69K_ZONE_HW, pBltParms);

    //
    //  note: this textout function works only if surfaces are allocated
    //  on 16 byte boundaries with a stride mod 16
    //

    //
    //  some handy shortcuts for pointers
    //
    RECTL *prclMask=pBltParms->prclMask; 
    RECTL *prclDst=pBltParms->prclDst;
    GPESurf *pMask=pBltParms->pMask;
    GPESurf *pDst=pBltParms->pDst;

    LONG  lDstSpan =pDst->Stride(); 
    LONG  lMaskSpan=pMask->Stride(); 
    ULONG ulAbsMaskSpan=labs(lMaskSpan);
    ULONG ulDstAddress=pDst->OffsetInVideoMemory();
    
    ULONG ulLeftClipBits=prclMask->left & 7;
    ULONG ulLeftClipBytes=prclMask->left >> 3;
    ULONG ulRightClipBits=(ulAbsMaskSpan*8-prclMask->right) & 7;
    ULONG ulRightClipBytes=(ulAbsMaskSpan*8-prclMask->right) >> 3;

    PUCHAR pBuffer=(PUCHAR)pMask->Buffer();

    pBuffer += prclMask->top*lMaskSpan;
    ulDstAddress += BYTESPERPIXEL(prclDst->left)+
                    prclDst->top*lDstSpan;

    //
    //  wait before touching registers if engine was busy
    //
    if (BltEngineBusy())
        WaitForNotBusy();

    SetBR( 0, //(ulAbsMaskSpan & 0xffff) | 
              (lDstSpan << 16));
    SetBR( 2, pBltParms->solidColor);   // set fg color
    SetBR( 3, (2L << 24) |              // byte alignment
              (ulRightClipBits << 8) |  // skip last n bits
               ulLeftClipBits           // skip first n bits
              );    
    SetBR( 4, 0xcc |                    // src copy bits
              (1<<10)   |               // Mask is memory port
              (1<<12)   |               // color depth 1bit
              (1<<13)                   // use 1bpp as write mask
        );
    SetBR( 7, ulDstAddress);
    
    ULONG ulWidth=BYTESPERPIXEL(prclMask->right  - prclMask->left);
    ULONG ulHeight=prclMask->bottom - prclMask->top;
    
    SetBR( 8, ulWidth | (ulHeight << 16));

    volatile PULONG pulDest = (PULONG)&m_pCtrlRegister[CT69000_BITBLT_DATA];

    if (ulRightClipBytes==0 &&
        ulLeftClipBytes==0 &&
        lMaskSpan > 0)
    {
        PULONG pulSrc  = (PULONG)pBuffer;
        INT i=(lMaskSpan*ulHeight+3)>>2;

        // source is aligned for dword writes!!!

        while (i--)
            *pulDest=*pulSrc++;

    } else
    {
        INT iRight = ulAbsMaskSpan - ulRightClipBytes;
        INT v=0;
        ULONG ulData=0;
        
        //
        // complicated text out, do it byte by byte
        // e.g. WBT outputs several characters a time 
        // in one call
        //
        // 69000 accepts only dwords on data port,
        // so collect bytes in temp ulData and write
        // them when dword is full
        //
        while (ulHeight!=0)
        {
            for (INT i=ulLeftClipBytes;i<iRight;i++)
            {
                ulData |= (ULONG)pBuffer[i] << v;
                v += 8;
                if (v>=32) 
                {
                    *pulDest = ulData;
                    v = 0;
                    ulData = 0;
                } 
            }

            pBuffer += lMaskSpan;

            ulHeight--;
        }

        //
        //  write rest of data
        //
        *pulDest = ulData;
    }

    //
    // chip needs additional write ...otherwise it will hang
    //
    // writing ulHeight to avoid compiler optimization....
    // (compiler optimized *pulDest=0 to and [pulDest],0
    //  and caused the hardware to hang because of the 
    //  read from the data port)
    //
    *pulDest=ulHeight;

    return S_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -