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

📄 gpeaccel.cpp

📁 EP9315 BSP for WinCE 源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// 
SCODE   GPEAccel::SetPointerShape
(
    GPESurf     *pMask, 
    GPESurf     *pColorSurf, 
    INT         xHot, 
    INT         yHot, 
    INT         cX, 
    INT         cY
)
{
    char    bAnd;
    char    bXor;
    int     row;
    int     col;
    // int     bitMask;
    int     i;
    UCHAR   *andPtr;        // input pointer
    UCHAR   *xorPtr;        // input pointer
    ULONG   ulCursorSize = 0;
    USHORT  usMask;
    ULONG   ulXYLOC;
    BOOL    bSizeChanged= FALSE;
    
    if(!pMask)
    {
        if(m_bCursorHasShape)
        {
            m_bCursorHasShape   = FALSE;
            *RASTER_CURSORXYLOC = 0;
        }
    }

    //
    // Check to see if the size changed.
    //
    if(cX != m_CursorSize.x && cY != m_CursorSize.y)
    {
        bSizeChanged = TRUE;
    }

    //
    // If the Size has changed then 
    //
    switch(cX)
    {
        case 16:
            ulCursorSize = CURSORSIZE_CWID_16PIXELS | CURSORSIZE_CSTEP_16PIXELS;
            break;
        case 32:
            ulCursorSize = CURSORSIZE_CWID_32PIXELS | CURSORSIZE_CSTEP_32PIXELS;
            break;
        case 48:
            ulCursorSize = CURSORSIZE_CWID_48PIXELS | CURSORSIZE_CSTEP_48PIXELS;
            break;
        case 64:
            ulCursorSize = CURSORSIZE_CWID_64PIXELS | CURSORSIZE_CSTEP_64PIXELS;
            break;
        default:
            //
            // Return that it is not ok.
            //
            DEBUGMSG (GPE_ZONE_LINE, (TEXT("GPEAccel::SetPointerShape Invalid Cursor Width, cX = 0%08x\r\n"), cX));
            return  S_FALSE;
    }

    //
    // Store size and hotspot for new cursor
    //
    m_CursorSize.x      = cX;
    m_CursorSize.y      = cY;
    m_CursorHotspot.x   = xHot;
    m_CursorHotspot.y   = yHot;

    //
    // Disable the cursor if the size has changed.
    //
    if(m_bCursorEnabled && bSizeChanged)
    {
        *RASTER_CURSORXYLOC &= ~CURSORXYLOC_CEN;

        //
        // Program in the cursor size register.
        //
        *RASTER_CURSORSIZE =  ulCursorSize |  ((cY - 1)<<CURSORSIZE_CLINS_SHIFT);
    }


    //
    // store OR and AND mask for new cursor
    //
    for (row = 0; row < cY; row++)
    {
        andPtr = (UCHAR*)pMask->Buffer();
        xorPtr = (UCHAR*)pMask->Buffer() + (cY * pMask->Stride());
        for (col = 0; col < cX / 8; col++)
        {
            bAnd = ~andPtr[row * pMask->Stride() + col];
            bXor = xorPtr[row * pMask->Stride() + col];
            usMask = 0;
            for ( i = 0; i < 4;  i++)
            {
                usMask |=  (bAnd & (0x80>>i))?  0x80>>(i * 2): 0 ;
                usMask |=  (bXor & (0x80>>i))?  0x40>>(i * 2): 0;
                usMask |=  (bAnd & (0x8>>i) )?  0x8000>>(i * 2 ): 0 ;
                usMask |=  (bXor & (0x8>>i) )?  0x4000>>(i * 2): 0;
            }
            ((PUSHORT)m_pCursor)[col + ((row * cX)>>3)] = usMask;
        }
    }

    //
    // Cursor has been initialized.
    //
    m_bCursorHasShape = TRUE;

    //
    // Enable the cursor and display the new cursor.
    //
    if(m_bCursorEnabled)
    {
        //
        // Compute new cursor rect
        //
        m_CursorRect.left   = m_xPosition - m_CursorHotspot.x;
        m_CursorRect.right  = m_CursorRect.left + m_CursorSize.x;
        m_CursorRect.top    = m_yPosition - m_CursorHotspot.y;
        m_CursorRect.bottom = m_CursorRect.top + m_CursorSize.y;

        ulXYLOC = CURSORXYLOC_XMASK & ((m_StartStop.ulHActiveStart - m_CursorRect.left)<<CURSORXYLOC_XSHIFT);
        ulXYLOC |= CURSORXYLOC_YMASK & ((m_StartStop.ulVActiveStart - m_CursorRect.top)<<CURSORXYLOC_YSHIFT);
        ulXYLOC |= m_bCursorEnabled? CURSORXYLOC_CEN: 0;

        //
        // Write the New XY Cursor value.
        //
        *RASTER_CURSORXYLOC = ulXYLOC;
    }

    //
    // Renable the cursor if the size has changed.
    //
    if(m_bCursorEnabled && bSizeChanged)
    {
        *RASTER_CURSORXYLOC |= CURSORXYLOC_CEN;
    }


    return  S_OK;
}

//****************************************************************************
// GPEAccel::MovePointer
//****************************************************************************
// 
// 
SCODE GPEAccel::MovePointer(INT xPosition, INT yPosition)
{
//    RETAILMSG(1, (TEXT("GPEAccel::MovePointer(%d, %d)\r\n"), xPosition, yPosition));
    ULONG ulXYLOC;

    if (xPosition != -1 || yPosition != -1)
    {
        m_xPosition = xPosition;
        m_yPosition = yPosition;

        //
        // Compute new cursor rect
        //
        m_CursorRect.left = xPosition - m_CursorHotspot.x;
        m_CursorRect.right = m_CursorRect.left + m_CursorSize.x;
        m_CursorRect.top = yPosition - m_CursorHotspot.y;
        m_CursorRect.bottom = m_CursorRect.top + m_CursorSize.y;

        if(m_bCursorHasShape)
        {
            ulXYLOC = CURSORXYLOC_XMASK & ((m_StartStop.ulHActiveStart  - m_CursorRect.left)<<CURSORXYLOC_XSHIFT);
            ulXYLOC |= CURSORXYLOC_YMASK & ((m_StartStop.ulVActiveStart - m_CursorRect.top)<<CURSORXYLOC_YSHIFT);
            ulXYLOC |= m_bCursorEnabled? CURSORXYLOC_CEN: 0;

        }
        m_bCursorEnabled = TRUE;
    }
    else
    {
        ulXYLOC             = 0;
        m_bCursorEnabled    = FALSE;        
    }

    //
    // Write the New XY Cursor value.
    //
    *RASTER_CURSORXYLOC = ulXYLOC;


    return  S_OK;
}

//****************************************************************************
// GPEAccel::WaitForNotBusy
//****************************************************************************
// In the EP9312 Video is never busy. 
//
void   GPEAccel::WaitForNotBusy(void)
{
    //
    // TODO TODO TODO this should have a timeout.
    //
    while(*GRAPHICS_BLOCKCTRL & BLOCKCTRL_ENABLE);

    return;
}

//****************************************************************************
// GPEAccel::IsBusy
//****************************************************************************
// In the EP9312 Video is never busy. 
// 
int  GPEAccel::IsBusy(void)
{
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("GPEAccel::IsBusy\r\n")));
    return  (*GRAPHICS_BLOCKCTRL & BLOCKCTRL_ENABLE)? TRUE:FALSE;
}

//****************************************************************************
// GPEAccel::GetPhysicalVideoMemory
//****************************************************************************
// Get the Physical memory base and video memory size.
//
void  GPEAccel::GetPhysicalVideoMemory
(
    unsigned long *physicalMemoryBase, 
    unsigned long *videoMemorySize
)
{
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("GPEAccel::GetPhysicalVideoMemory\r\n")));

    *physicalMemoryBase = m_pvFlatFrameBuffer;
    *videoMemorySize    = m_cbScanLineLength * m_cyPhysicalScreen;
}

#ifdef  DD_ENABLE
void    GPEAccel::GetVirtualVideoMemory(unsigned long *virtualMemoryBase, unsigned long *videoMemorySize)
{
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("GPEAccel::GetVirtualVideoMemory\r\n")));

    *virtualMemoryBase = m_VirtualFrameBuffer;
    *videoMemorySize = m_cbScanLineLength * m_cyPhysicalScreen;
}
#endif  // DD_ENABLE

//****************************************************************************
// GPEAccel::WrappedEmulatedLine
//****************************************************************************
// 
// 
//
SCODE GPEAccel::WrappedEmulatedLine (GPELineParms *lineParameters)
{
    SCODE   retval;

    // do emulated line
    retval = EmulatedLine (lineParameters);

    return  retval;

}

//****************************************************************************
// GPEAccel::AcceleratedLine
//****************************************************************************
// Performs a hardware accelerate line draw.
// 
//
SCODE  GPEAccel::AcceleratedLine (GPELineParms *lineParameters)
{
    ULONG   ulControl   = 0;
    int     iDir        = lineParameters->iDir;
    ULONG   dN          = lineParameters->dN;
    ULONG   dM          = lineParameters->dM;
    int     cPels       = lineParameters->cPels;
    int     xStart      = lineParameters->xStart;
    int     yStart      = lineParameters->yStart;
    int     iXdir;
    int     iYdir;
    ULONG   ulPhysStart;
    ULONG   ulPhysEnd;
    GPESurf  *pDst      = lineParameters->pDst;
    ULONG   ulRight;

//    RETAILMSG(1, (TEXT("AcceleratedLine xStart %d yStart %d cPels %d style 0x%08x\r\n"), xStart, yStart, cPels, lineParameters->style));
    
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("GPEAccel::AcceleratedLine")));
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("   xStart = %d"),xStart ));
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("   yStart = %d"),yStart ));
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("   cPels  = %d"),cPels ));
/*
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("   xStart = %d"),xStart ));
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("   yStart = %d"),yStart ));
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("   cPels  = %d"),cPels ));
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("   iDir  = %d"),iDir ));
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("   style = 0x%08x"),lineParameters->style ));
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("   dN  = %d"),dN ));
    DEBUGMSG (GPE_ZONE_LINE, (TEXT("   dM  = %d\r\n"),dM ));
*/    
    
    int     BytesPerPixel   = EGPEFormatToBpp[pDst->Format()] >> 3;
    int     stride          = pDst->Stride();

    // Line drawing in negative X direction is not supported.
    if( lineParameters->iDir == 2 || lineParameters->iDir == 3 ||
        lineParameters->iDir == 4 || lineParameters->iDir == 5 )
        return EmulatedLine(lineParameters);

    if( dN != 0 )   // Accelerate only horizontal and vertical lines.
        return EmulatedLine(lineParameters);

    //
    // Check to see if cPels is negative.
    //
    if(cPels < 0)
    {
        cPels = -1 * cPels;
        iDir  = (iDir + 4) & 7 ;
    }
    //
    // omit the end points
    //
    if(cPels > 0) cPels--;

    //
    // Figure out which direction the line is going.
    //
    switch(iDir)
    {
        case 0:
        case 1:
            ulControl   = 0;
            iXdir       = 1;
            iYdir       = 1;
            
            break;
        case 2:
        case 3:
            ulControl   = BLOCKCTRL_DXDIR;
            iXdir       =  -1;
            iYdir       = 1;
            break;
        case 4:
        case 5:
            ulControl   = BLOCKCTRL_DXDIR | BLOCKCTRL_DYDIR;
            iXdir       = -1;
            iYdir       = -1;
            break;
        case 6:
        case 7:
            ulControl   = BLOCKCTRL_DYDIR;
            iXdir       = 1;
            iYdir       = -1;
            break;
        default:
            DEBUGMSG (GPE_ZONE_LINE,(TEXT("Invalid direction: %d\r\n"), lineParameters->iDir));
            return E_INVALIDARG;
    }

    //
    // Start of the Physical buffer.
    //
    ulPhysStart = yStart * stride + xStart * BytesPerPixel +  pDst->OffsetInVideoMemory() + FRAMEBUF_PHYSICAL_MEMORY;

    //
    // Wait until the last possible moment to wait for the graphics engine to be finished.
    //
#ifdef  DD_ENABLE
    FlushDCache();
#endif
    WaitForNotBusy();

    if(dN == dM)
    {
        //
        // Its what the spec says to do if xDiff == yDiff
        //
        *GRAPHICS_LINEINC = 4095 | (4095 << LINEINC_YINC_SHIFT);

        //
        // Calculate the ending physical address.  The real ending address commented out.
        // We just need to know the ending byte inside of the word.  Since stride is always
        // on a word boundary we can get rid of the term.
        //
        ulPhysEnd        = ulPhysStart + cPels * BytesPerPixel * iXdir + cPels * stride * iYdir ;
        ulRight         = cPels * BytesPerPixel * iXdir;
    }
    else
    {
        switch(iDir)
        {
            //
            //     (xDiff > yDiff)
            //
            case 0:
            case 3:
            case 4:
            case 7:

                //
                // Its what the spec says to do if xDiff > yDiff
                //
                *GRAPHICS_LINEINC = 4095 | 
                                   (((dN * 4095) / dM) << LINEINC_YINC_SHIFT);

                //
                // The real address
                //
                ulPhysEnd        = ulPhysStart + cPels * (iXdir * BytesPerPixel + iYdir *stride * dN / dM);
                ulRight         = cPels * iXdir * BytesPerPixel;
                
                break;
            //
            // (yDiff > xDiff)
            //
            case 1:
            case 2:
            case 5:
            case 6:

                //
                // Its what the spec says to do if xDiff < yDiff
                //
                *GRAPHICS_LINEINC = (((dN * 4095) / dM) << LINEINC_XINC_SHIFT)  | 
                                    (4095 << LINEINC_YINC_SHIFT);
                ulPhysEnd         = ulPhysStart + iYdir * cPels * stride  + ( (iXdir * BytesPerPixel * cPels * dN) / dM);
                ulRight         = ( (iXdir * BytesPerPixel * cPels * dN) / dM);
                break;
        }
    }    

    //
    // BLKDESTWIDTH = xDiff % 4096
    //
    *GRAPHICS_BLKDESTWIDTH      = cPels & 0xfff;

    //
    // BLKDESTHEIGT = xDiff / 4096
    //
    *GRAPHICS_BLKDESTHEIGHT     = cPels >> 12;

    *GRAPHICS_BLKDESTSTRT       = ulPhysStart;

    *GRAPHICS_DESTPIXELSTRT     = ((ulPhysStart & 0x3) << 3) |
                                  //((ulPhysEnd   & 0x3) << (DESTPIXELSTRT_EPEL_SHIFT + 3));
                                  (((ulRight-BytesPerPixel)   & 0x3) << (DESTPIXELSTRT_EPEL_SHIFT + 3));

    //
    // The number of words in a scan line.
    //
    *GRAPHICS_DESTLINELENGTH    = (stride>>2);


    *GRAPHICS_BLKSRCSTRT        = 0;
    *GRAPHICS_SRCPIXELSTRT      = 0;
    *GRAPHICS_BLKSRCWIDTH       = 0;
    *GRAPHICS_SRCLINELENGTH     = 0;


    *GRAPHICS_LINEINIT          = 2048 | 
                                  (2048 << LINEINIT_YINIT_SHIFT);

    *GRAPHICS_LINEPATTRN        = (lineParameters->style & LINEPATTRN_PTRN_MASK) | 

⌨️ 快捷键说明

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