📄 gpeflat.cpp
字号:
}
}
}
}
m_CursorVisible = TRUE;
}
}
//****************************************************************************
// GPEFlat::CursorOff
//****************************************************************************
//
//
void GPEFlat::CursorOff (void)
{
UCHAR *ptrScreen = (UCHAR*)m_pPrimarySurface->Buffer();
UCHAR *ptrLine;
UCHAR *cbsLine;
int x, y;
if (!m_CursorForcedOff && !m_CursorDisabled && m_CursorVisible)
{
if (!m_CursorBackingStore)
{
DEBUGMSG (GPE_ZONE_ERROR, (TEXT("GPEFlat::CursorOff - No backing store available\r\n")));
return;
}
for (y = m_CursorRect.top; y < m_CursorRect.bottom; y++)
{
// clip to displayable screen area (top/bottom)
if (y < 0)
{
continue;
}
if (y >= m_nScreenHeight)
{
break;
}
ptrLine = &ptrScreen[y * m_pPrimarySurface->Stride()];
cbsLine = &m_CursorBackingStore[(y - m_CursorRect.top) * (m_CursorSize.x * (m_ulColorDepth >> 3))];
for (x = m_CursorRect.left; x < m_CursorRect.right; x++)
{
// clip to displayable screen area (left/right)
if (x < 0)
{
continue;
}
if (x >= m_nScreenWidth)
{
break;
}
ptrLine[x * (m_ulColorDepth >> 3)] = cbsLine[(x - m_CursorRect.left) * (m_ulColorDepth >> 3)];
if (m_ulColorDepth > 8)
{
ptrLine[x * (m_ulColorDepth >> 3) + 1] = cbsLine[(x - m_CursorRect.left) * (m_ulColorDepth >> 3) + 1];
if (m_ulColorDepth > 16)
{
ptrLine[x * (m_ulColorDepth >> 3) + 2] = cbsLine[(x - m_CursorRect.left) * (m_ulColorDepth >> 3) + 2];
}
}
}
}
m_CursorVisible = FALSE;
}
}
//****************************************************************************
// GPEFlat::SetPointerShape
//****************************************************************************
// Set the pointer shape.
//
SCODE GPEFlat::SetPointerShape
(
GPESurf *pMask,
GPESurf *pColorSurf,
INT xHot,
INT yHot,
INT cX,
INT cY
)
{
UCHAR *andPtr; // input pointer
UCHAR *xorPtr; // input pointer
UCHAR *andLine; // output pointer
UCHAR *xorLine; // output pointer
char bAnd;
char bXor;
int row;
int col;
int i;
int bitMask;
DEBUGMSG(GPE_ZONE_CURSOR,(TEXT("GPEFlat::SetPointerShape(0x%X, 0x%X, %d, %d, %d, %d)\r\n"),pMask, pColorSurf, xHot, yHot, cX, cY));
// turn current cursor off
CursorOff();
// release memory associated with old cursor
if (m_CursorBackingStore)
{
delete (void*)m_CursorBackingStore;
m_CursorBackingStore = NULL;
}
if (m_CursorXorShape)
{
delete (void*)m_CursorXorShape;
m_CursorXorShape = NULL;
}
if (m_CursorAndShape)
{
delete (void*)m_CursorAndShape;
m_CursorAndShape = NULL;
}
if (!pMask) // do we have a new cursor shape
{
m_CursorDisabled = TRUE; // no, so tag as disabled
}
else
{
m_CursorDisabled = FALSE; // yes, so tag as not disabled
// allocate memory based on new cursor size
m_CursorBackingStore = new UCHAR[(cX * (m_ulColorDepth >> 3)) * cY];
m_CursorXorShape = new UCHAR[cX * cY];
m_CursorAndShape = new UCHAR[cX * cY];
// store size and hotspot for new cursor
m_CursorSize.x = cX;
m_CursorSize.y = cY;
m_CursorHotspot.x = xHot;
m_CursorHotspot.y = yHot;
andPtr = (UCHAR*)pMask->Buffer();
xorPtr = (UCHAR*)pMask->Buffer() + (cY * pMask->Stride());
// store OR and AND mask for new cursor
for (row = 0; row < cY; row++)
{
andLine = &m_CursorAndShape[cX * row];
xorLine = &m_CursorXorShape[cX * row];
for (col = 0; col < cX / 8; col++)
{
bAnd = andPtr[row * pMask->Stride() + col];
bXor = xorPtr[row * pMask->Stride() + col];
for (bitMask = 0x0080, i = 0; i < 8; bitMask >>= 1, i++)
{
andLine[(col * 8) + i] = bAnd & bitMask ? 0xFF : 0x00;
xorLine[(col * 8) + i] = bXor & bitMask ? 0xFF : 0x00;
}
}
}
}
return S_OK;
}
//****************************************************************************
// GPEFlat::MovePointer
//****************************************************************************
//
//
SCODE GPEFlat::MovePointer(INT xPosition, INT yPosition)
{
DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("GPEFlat::MovePointer(%d, %d)\r\n"), xPosition, yPosition));
CursorOff();
if (xPosition != -1 || yPosition != -1)
{
// 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;
CursorOn();
}
return S_OK;
}
//****************************************************************************
// GPEFlat::WaitForNotBusy
//****************************************************************************
// In the EP9312 Video is never busy.
//
void GPEFlat::WaitForNotBusy(void)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("GPEFlat::WaitForNotBusy\r\n")));
return;
}
//****************************************************************************
// GPEFlat::IsBusy
//****************************************************************************
// In the EP9312 Video is never busy.
//
int GPEFlat::IsBusy(void)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("GPEFlat::IsBusy\r\n")));
return 0;
}
//****************************************************************************
// GPEFlat::GetPhysicalVideoMemory
//****************************************************************************
// Get the Physical memory base and video memory size.
//
void GPEFlat::GetPhysicalVideoMemory
(
unsigned long *physicalMemoryBase,
unsigned long *videoMemorySize
)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("GPEFlat::GetPhysicalVideoMemory\r\n")));
*physicalMemoryBase = m_pvFlatFrameBuffer;
*videoMemorySize = m_cbScanLineLength * m_cyPhysicalScreen;
}
//****************************************************************************
// GPEFlat::AllocSurface
//****************************************************************************
// AllocateSurface
SCODE GPEFlat::AllocSurface
(
GPESurf **surface,
INT width,
INT height,
EGPEFormat format,
INT surfaceFlags
)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("GPEFlat::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;
}
//****************************************************************************
// GPEFlat::WrappedEmulatedLine
//****************************************************************************
//
//
//
SCODE GPEFlat::WrappedEmulatedLine (GPELineParms *lineParameters)
{
SCODE retval;
RECT bounds;
int N_plus_1; // Minor length of bounding rect + 1
// calculate the bounding-rect to determine overlap with cursor
if (lineParameters->dN) // The line has a diagonal component (we'll refresh the bounding rect)
{
N_plus_1 = 2 + ((lineParameters->cPels * lineParameters->dN) / lineParameters->dM);
}
else
{
N_plus_1 = 1;
}
switch(lineParameters->iDir)
{
case 0:
bounds.left = lineParameters->xStart;
bounds.top = lineParameters->yStart;
bounds.right = lineParameters->xStart + lineParameters->cPels + 1;
bounds.bottom = bounds.top + N_plus_1;
break;
case 1:
bounds.left = lineParameters->xStart;
bounds.top = lineParameters->yStart;
bounds.bottom = lineParameters->yStart + lineParameters->cPels + 1;
bounds.right = bounds.left + N_plus_1;
break;
case 2:
bounds.right = lineParameters->xStart + 1;
bounds.top = lineParameters->yStart;
bounds.bottom = lineParameters->yStart + lineParameters->cPels + 1;
bounds.left = bounds.right - N_plus_1;
break;
case 3:
bounds.right = lineParameters->xStart + 1;
bounds.top = lineParameters->yStart;
bounds.left = lineParameters->xStart - lineParameters->cPels;
bounds.bottom = bounds.top + N_plus_1;
break;
case 4:
bounds.right = lineParameters->xStart + 1;
bounds.bottom = lineParameters->yStart + 1;
bounds.left = lineParameters->xStart - lineParameters->cPels;
bounds.top = bounds.bottom - N_plus_1;
break;
case 5:
bounds.right = lineParameters->xStart + 1;
bounds.bottom = lineParameters->yStart + 1;
bounds.top = lineParameters->yStart - lineParameters->cPels;
bounds.left = bounds.right - N_plus_1;
break;
case 6:
bounds.left = lineParameters->xStart;
bounds.bottom = lineParameters->yStart + 1;
bounds.top = lineParameters->yStart - lineParameters->cPels;
bounds.right = bounds.left + N_plus_1;
break;
case 7:
bounds.left = lineParameters->xStart;
bounds.bottom = lineParameters->yStart + 1;
bounds.right = lineParameters->xStart + lineParameters->cPels + 1;
bounds.top = bounds.bottom - N_plus_1;
break;
default:
RETAILMSG(1,(TEXT("Invalid direction: %d\r\n"), lineParameters->iDir));
return E_INVALIDARG;
}
// check for line overlap with cursor and turn off cursor if overlaps
if (m_CursorVisible && !m_CursorDisabled &&
m_CursorRect.top < bounds.bottom && m_CursorRect.bottom > bounds.top &&
m_CursorRect.left < bounds.right && m_CursorRect.right > bounds.left)
{
CursorOff();
m_CursorForcedOff = TRUE;
}
// do emulated line
retval = EmulatedLine (lineParameters);
// se if cursor was forced off because of overlap with line bouneds and turn back on
if (m_CursorForcedOff)
{
m_CursorForcedOff = FALSE;
CursorOn();
}
return retval;
}
//****************************************************************************
// GPEFlat::Line
//****************************************************************************
//
//
SCODE GPEFlat::Line
(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -