📄 gpeaccel.cpp
字号:
{
//
// 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)
{
DEBUGMSG(GPE_ZONE_CURSOR, (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)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("GPEAccel::WaitForNotBusy\r\n")));
//
// 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_INIT, (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_INIT, (TEXT("GPEAccel::GetPhysicalVideoMemory\r\n")));
*physicalMemoryBase = m_pvFlatFrameBuffer;
*videoMemorySize = m_cbScanLineLength * m_cyPhysicalScreen;
}
//****************************************************************************
// GPEAccel::AllocSurface
//****************************************************************************
// AllocateSurface
SCODE GPEAccel::AllocSurface
(
GPESurf **surface,
INT width,
INT height,
EGPEFormat format,
INT surfaceFlags
)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("GPEAccel::AllocSurface\r\n")));
if (surfaceFlags & GPE_REQUIRE_VIDEO_MEMORY)
{
RETAILMSG(1,(TEXT("AllocSurface out of memory error.\r\n")));
return E_OUTOFMEMORY;
}
//
// Allocate from system memory
//
*surface = new GPESurf(width, height, format);
if (*surface != NULL)
{
//
// Check that the bits were allocated succesfully
//
if (((*surface)->Buffer()) == NULL)
{
//
// Clean up
//
delete *surface;
RETAILMSG(1,(TEXT("BPESurf->Buffer error\r\n")));
}
else
{
return S_OK;
}
}
RETAILMSG(1,(TEXT("New GPESurf() error\r\n")));
return E_OUTOFMEMORY;
}
//****************************************************************************
// GPEAccel::WrappedEmulatedLine
//****************************************************************************
//
//
//
SCODE GPEAccel::WrappedEmulatedLine (GPELineParms *lineParameters)
{
SCODE retval;
WaitForNotBusy();
// 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;
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 ));
int BytesPerPixel = EGPEFormatToBpp[pDst->Format()] >> 3;
int stride = pDst->Stride();
//
// omit the end points
//
if(cPels>0)
{
cPels -= 1;
}
else if(cPels<0)
{
cPels += 1;
}
//
// Check to see if cPels is negative.
//
if(cPels < 0)
{
cPels = -1 * cPels;
iDir = (iDir + 4) & 7 ;
}
//
// 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:
RETAILMSG(1,(TEXT("Invalid direction: %d\r\n"), lineParameters->iDir));
return E_INVALIDARG;
}
//
// Start of the Physical buffer.
//
ulPhysStart = yStart * stride + xStart * BytesPerPixel + pDst->OffsetInVideoMemory();
//
// Wait until the last possible moment to wait for the graphics engine to be finished.
//
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 ;
}
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);
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);
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));
//
// 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) |
( 0xF << LINEPATTRN_CNT_SHIFT);
*GRAPHICS_TRANSPATTRN = 0;
*GRAPHICS_BACKGROUND = lineParameters->solidColor;
*GRAPHICS_BLOCKMASK = lineParameters->solidColor;
//
// I don't think that this is ever necessary.
//
//if (sLine->BackgroundEn)
//{
// Control |= BLOCKCTRL_BACKGROUNDG;
//}
*GRAPHICS_BLOCKCTRL = ulControl |= BLOCKCTRL_BG | BLOCKCTRL_LINE | (BytesPerPixel << (BLOCKCTRL_PIXEL_SHIFT + 1));
*GRAPHICS_BLOCKCTRL = ulControl | BLOCKCTRL_ENABLE;
//
// Wait for operation to complete.
//
// while(Graphics->BLOCKCTRL.Value & GOAT_BLOCKCTRL_EN);
return S_OK;
}
//****************************************************************************
// GPEAccel::Line
//****************************************************************************
//
//
SCODE GPEAccel::Line
(
GPELineParms *lineParameters,
EGPEPhase phase
)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("GPEAccel::Line\r\n")));
if (phase == gpeSingle || phase == gpePrepare)
{
if (( lineParameters->pDst->InVideoMemory()) &&
( (lineParameters->style & 0xFFFF) == (lineParameters->style>>16)) &&
( lineParameters->mix == 0x0d0d ))
{
lineParameters->pLine = (SCODE (GPE::*)(struct GPELineParms *)) AcceleratedLine;
}
else
{
lineParameters->pLine = EmulatedLine;
}
}
return S_OK;
}
//****************************************************************************
// GPEAccel::BltPrepare
//****************************************************************************
//
SCODE GPEAccel::BltPrepare(GPEBltParms *pBltParms)
{
// RECTL rectl;
DEBUGMSG (GPE_ZONE_INIT, (TEXT("GPEAccel::BltPrepare\r\n")));
BOOL bTryAccelSoft = TRUE;
// EGPEFormat Format;
// Format = blitParameters->prclDst->Format();
//
// default to base EmulatedBlt routine
//
pBltParms->pBlt = EmulatedBlt;
//
// Can only hardware accel if Destination is in video memory and
// if the graphics is not performing another operation.
//
if (pBltParms->pDst->InVideoMemory() )
{
switch (pBltParms->rop4)
{
case 0x0000: // BLACKNESS
pBltParms->solidColor = 0x0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -