📄 lpc32xx_lcd.cpp
字号:
CursorOff();
m_cursorForcedOff = TRUE;
}
}
// Check if source overlap with cursor
if (
pBltParms->pSrc == m_pPrimarySurface &&
m_cursorVisible && !m_cursorDisabled
) {
if (pBltParms->prclSrc != NULL) {
rect = *pBltParms->prclSrc;
} else {
rect = m_cursorRect;
}
if (
m_cursorRect.top < rect.bottom && m_cursorRect.bottom > rect.top &&
m_cursorRect.left < rect.right && m_cursorRect.right > rect.left
) {
CursorOff();
m_cursorForcedOff = TRUE;
}
}
return S_OK;
}
//------------------------------------------------------------------------------
//
// Method: BltComplete
//
// This method executes to complete a blit sequence.
//
SCODE LPC32XXLCD::BltComplete(GPEBltParms *pBtlParms)
{
// If cursor was forced off turn it back on
if (m_cursorForcedOff) {
m_cursorForcedOff = FALSE;
CursorOn();
}
return S_OK;
}
//------------------------------------------------------------------------------
//
// Method: CursorOn
//
VOID LPC32XXLCD::CursorOn()
{
UCHAR *pFrame;
UCHAR *pFrameLine, *pStoreLine, *pXorLine, *pAndLine, data;
int bytesPerPixel, bytesPerLine;
int xf, yf, xc, yc, i;
DEBUGMSG(ZONE_FUNCTION, (L"+LPC32XXLCD::CursonOn\r\n"));
// If cursor should not be visible or already is then exit
if (m_cursorForcedOff || m_cursorDisabled || m_cursorVisible) goto cleanUp;
if (m_cursorStore == NULL) {
DEBUGMSG(ZONE_WARN, (L"LPC32XXLCD::CursorOn: "
L"No cursor store available\r\n"
));
goto cleanUp;
}
// We support only 1,2,3 and 4 bytes per pixel
bytesPerPixel = (m_gpeMode.Bpp + 7) >> 3;
if (bytesPerPixel <= 0 || bytesPerPixel > 4) goto cleanUp;
// Get some base metrics
pFrame = (UCHAR*)m_pPrimarySurface->Buffer();
bytesPerLine = m_pPrimarySurface->Stride();
for (yf = m_cursorRect.top, yc = 0; yf < m_cursorRect.bottom; yf++, yc++) {
// Check if we are done
if (yf < 0) continue;
if (yf >= m_gpeMode.height) break;
pFrameLine = &pFrame[yf * bytesPerLine];
pStoreLine = &m_cursorStore[yc * m_cursorSize.x * bytesPerPixel];
pAndLine = &m_cursorAnd[yc * m_cursorSize.x * bytesPerPixel];
pXorLine = &m_cursorXor[yc * m_cursorSize.x * bytesPerPixel];
for (
xf = m_cursorRect.left, xc = 0; xf < m_cursorRect.right; xf++, xc++
) {
// Check if we are done
if (xf < 0) continue;
if (xf >= m_gpeMode.width) break;
// Depending on bytes per pixel
switch (bytesPerPixel) {
case 1:
pStoreLine[xc] = pFrameLine[xf];
pFrameLine[xf] &= pAndLine[xc];
pFrameLine[xf] ^= pXorLine[xc];
break;
case 2:
((USHORT*)pStoreLine)[xc] = ((USHORT*)pFrameLine)[xf];
((USHORT*)pFrameLine)[xf] &= ((USHORT*)pAndLine)[xc];
((USHORT*)pFrameLine)[xf] ^= ((USHORT*)pXorLine)[xc];
break;
case 3:
for (i = 0; i < bytesPerPixel; i++) {
data = pFrameLine[xf * bytesPerPixel + i];
pStoreLine[xc * bytesPerPixel + i] = data;
data &= pAndLine[xc * bytesPerPixel + i];
data ^= pXorLine[xc * bytesPerPixel + i];
pFrameLine[xf * bytesPerPixel + i] = data;
}
break;
case 4:
((ULONG*)pStoreLine)[xc] = ((ULONG*)pFrameLine)[xf];
((ULONG*)pFrameLine)[xf] &= ((ULONG*)pAndLine)[xc];
((ULONG*)pFrameLine)[xf] ^= ((ULONG*)pXorLine)[xc];
break;
}
}
}
// Cursor is visible now
m_cursorVisible = TRUE;
cleanUp:
DEBUGMSG(ZONE_FUNCTION, (L"-LPC32XXLCD::CursonOn\r\n"));
return;
}
//------------------------------------------------------------------------------
VOID LPC32XXLCD::CursorOff()
{
UCHAR *pFrame, *pFrameLine, *pStoreLine, data;
int bytesPerPixel, bytesPerLine;
int xf, yf, xc, yc, i;
DEBUGMSG(ZONE_FUNCTION, (L"+LPC32XXLCD::CursonOff\r\n"));
if (m_cursorForcedOff || m_cursorDisabled || !m_cursorVisible) goto cleanUp;
if (m_cursorStore == NULL) {
DEBUGMSG(ZONE_WARN, (L"LPC32XXLCD::CursorOff: "
L"No cursor store available\r\n"
));
goto cleanUp;
}
// We support only 1,2,3 and 4 bytes per pixel
bytesPerPixel = (m_gpeMode.Bpp + 7) >> 3;
if (bytesPerPixel <= 0 || bytesPerPixel > 4) goto cleanUp;
// Get some base metrics
pFrame = (UCHAR*)m_pPrimarySurface->Buffer();
bytesPerLine = m_pPrimarySurface->Stride();
for (yf = m_cursorRect.top, yc = 0; yf < m_cursorRect.bottom; yf++, yc++) {
// Check if we are done
if (yf < 0) continue;
if (yf >= m_gpeMode.height) break;
pFrameLine = &pFrame[yf * bytesPerLine];
pStoreLine = &m_cursorStore[yc * m_cursorSize.x * bytesPerPixel];
for (
xf = m_cursorRect.left, xc = 0; xf < m_cursorRect.right; xf++, xc++
) {
// Check if we are done
if (xf < 0) continue;
if (xf >= m_gpeMode.width) break;
// Depending on bytes per pixel
switch (bytesPerPixel) {
case 1:
pFrameLine[xf] = pStoreLine[xc];
break;
case 2:
((USHORT*)pFrameLine)[xf] = ((USHORT*)pStoreLine)[xc];
break;
case 3:
for (i = 0; i < bytesPerPixel; i++) {
data = pStoreLine[xc * bytesPerPixel + i];
pFrameLine[xf * bytesPerPixel + i] = data;
}
break;
case 4:
((ULONG*)pFrameLine)[xf] = ((ULONG*)pStoreLine)[xc];
break;
}
}
}
// Cursor isn't visible now
m_cursorVisible = FALSE;
cleanUp:
DEBUGMSG(ZONE_FUNCTION, (L"-LPC32XXLCD::CursonOff\r\n"));
return;
}
//------------------------------------------------------------------------------
//
// Method: SetPointerShape
//
// This method sets the shape of the pointer, the hot spot of the pointer,
// and the colors to use for the cursor if the cursor is multicolored.
//
SCODE LPC32XXLCD::SetPointerShape(
GPESurf* pMask, GPESurf* pColorSurf, int xHotspot, int yHotspot,
int xSize, int ySize
) {
SCODE sc = S_OK;
UCHAR *pAndPtr, *pXorPtr, *pAndLine, *pXorLine;
UCHAR andPtr, xorPtr, mask;
ULONG size;
int bytesPerPixel;
int row, col, i;
DEBUGMSG(ZONE_INFO, (
L"+LPC32XXLCD::SetPointerShape(0x%08x, 0x%08x, %d, %d, %d, %d)\r\n",
pMask, pColorSurf, xHotspot, yHotspot, xSize, ySize
));
// Turn current cursor off
CursorOff();
// Release memory associated with old cursor
delete [] m_cursorStore; m_cursorStore = NULL;
delete [] m_cursorXor; m_cursorXor = NULL;
delete [] m_cursorAnd; m_cursorAnd = NULL;
// Is there a new mask?
if (pMask == NULL) {
// No, so tag as disabled
m_cursorDisabled = TRUE;
} else {
// Yes, so tag as not disabled
m_cursorDisabled = FALSE;
// Check if cursor size is correct
if (xSize > m_nScreenWidth || ySize > m_nScreenHeight) {
DEBUGMSG(ZONE_ERROR, (L"LPC32XXLCD::SetPointerShape: "
L"Invalid cursor size %d, %d\r\n", xSize, ySize
));
sc = E_FAIL;
goto cleanUp;
}
// How many bytes we need per pixel on screen
bytesPerPixel = (m_gpeMode.Bpp + 7) >> 3;
// Cursor mask & store size
size = xSize * ySize * bytesPerPixel;
// Allocate memory based on new cursor size
m_cursorStore = new UCHAR[size];
m_cursorXor = new UCHAR[size];
m_cursorAnd = new UCHAR[size];
if (
m_cursorStore == NULL || m_cursorXor == NULL || m_cursorAnd == NULL
) {
DEBUGMSG(ZONE_ERROR, (L"LPC32XXLCD::SetPointerShape: "
L"Memory allocation for cursor buffers failed\r\n"
));
sc = E_OUTOFMEMORY;
goto cleanUp;
}
// Store size and hotspot for new cursor
m_cursorSize.x = xSize;
m_cursorSize.y = ySize;
m_cursorHotspot.x = xHotspot;
m_cursorHotspot.y = yHotspot;
// Pointers to AND and XOR masks
pAndPtr = (UCHAR*)pMask->Buffer();
pXorPtr = (UCHAR*)pMask->Buffer() + (ySize * pMask->Stride());
// store OR and AND mask for new cursor
for (row = 0; row < ySize; row++) {
pAndLine = &m_cursorAnd[row * xSize * bytesPerPixel];
pXorLine = &m_cursorXor[row * xSize * bytesPerPixel];
for (col = 0; col < xSize; col++) {
andPtr = pAndPtr[row * pMask->Stride() + (col >> 3)];
xorPtr = pXorPtr[row * pMask->Stride() + (col >> 3)];
mask = 0x80 >> (col & 0x7);
for (i = 0; i < bytesPerPixel; i++) {
pAndLine[col * bytesPerPixel + i] = andPtr&mask?0xFF:0x00;
pXorLine[col * bytesPerPixel + i] = xorPtr&mask?0xFF:0x00;
}
}
}
}
cleanUp:
DEBUGMSG(ZONE_FUNCTION, (L"-LPC32XXLCD::SetPointerShape(sc = 0x%08x)\r\n", sc));
return sc;
}
//------------------------------------------------------------------------------
//
// Method: MovePointer
//
// This method executes from applications either to move the hot spot
// of the cursor to a specific screen location or to hide the cursor (x == -1).
//
SCODE LPC32XXLCD::MovePointer(int x, int y)
{
DEBUGMSG(ZONE_FUNCTION, (L"+LPC32XXLCD::MovePointer(%d, %d)\r\n", x, y));
CursorOff();
if (x != -1 || y != -1) {
// Compute new cursor rect
m_cursorRect.left = x - m_cursorHotspot.x;
m_cursorRect.right = m_cursorRect.left + m_cursorSize.x;
m_cursorRect.top = y - m_cursorHotspot.y;
m_cursorRect.bottom = m_cursorRect.top + m_cursorSize.y;
CursorOn();
}
DEBUGMSG(ZONE_FUNCTION, (L"-LPC32XXLCD::MovePointer(sc = 0x%08x)\r\n", S_OK));
return S_OK;
}
//------------------------------------------------------------------------------
//
// Method: InVBlank
//
int LPC32XXLCD::InVBlank()
{
return 1;
}
//------------------------------------------------------------------------------
//
// Method: SetPalette
//
SCODE LPC32XXLCD::SetPalette(
const PALETTEENTRY *pSource, WORD firstEntry, WORD numEntries
) {
DEBUGMSG(ZONE_FUNCTION, (
L"+LPC32XXLCD::SetPalette(0x%08x, %d, %d)\r\n", pSource, firstEntry,
numEntries));
return S_OK;
}
//------------------------------------------------------------------------------
//
// Method: PowerHandler
//
VOID LPC32XXLCD::PowerHandler(BOOL off)
{
ULONG commands[2];
// Ask HAL to set power
commands[0] = DDHAL_COMMAND_POWER;
commands[1] = off;
if (!KernelIoControl(
IOCTL_HAL_DDI, commands, sizeof(commands), NULL, 0, NULL
)) {
DEBUGMSG(ZONE_WARN, (L"LPC32XXLCD::PowerHandler: "
L"IOCTL_HAL!DDI_POWER failed for off flag %d\r\n", off
));
}
}
//------------------------------------------------------------------------------
void LPC32XXLCD::WaitForNotBusy()
{
return;
}
int LPC32XXLCD::IsBusy()
{
return 0; // Never busy as there is no acceleration
}
void LPC32XXLCD::GetPhysicalVideoMemory(
unsigned long * pPhysicalMemoryBase,
unsigned long * pVideoMemorySize
)
{
*pPhysicalMemoryBase = (ULONG)m_VirtualFrameBuffer;
*pVideoMemorySize = m_FrameBufferSize;
}
void LPC32XXLCD::GetVirtualVideoMemory(
unsigned long * pVirtualMemoryBase,
unsigned long * pVideoMemorySize
)
{
*pVirtualMemoryBase = (unsigned)(m_pPrimarySurface->Buffer());
*pVideoMemorySize = m_FrameBufferSize;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -