📄 gpeaccel.cpp
字号:
//
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 + -