📄 cursor.cpp
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995, 1996, 1997, 1998 Microsoft Corporation
Copyright (c) 1999-2000 Silicon Motion, Inc.
Module Name: cursor.cpp
Abstract: SMI hardware accelerated cursor
Functions:
Notes:
--*/
#include "precomp.h"
//convert to vgx cursor mask
unsigned char mask_table[]=
{0, 128, 32, 160, 8, 136, 40, 168, 2, 130, 34, 162, 10, 138, 42, 170};
// 00 - 0x00 08 - 0x02
// 01 - 0x80 09 - 0x82
// 02 - 0x20 0A - 0x22
// 03 - 0xA0 0B - 0xA2
// 04 - 0x08 0C - 0x0A
// 05 - 0x88 0D - 0x8A
// 06 - 0x28 0E - 0x2A
// 07 - 0xA8 0F - 0xAA
SCODE SMI::SetPointerShape(GPESurf *pMask, GPESurf *pColorSurf, int xHot, int yHot,
int cx, int cy)
{
PUCHAR pByte;
PUCHAR pBuf;
int i, row, col_byte, stride;
UCHAR and_mask, xor_mask;
DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("SMI::SetPointerShape()\r\n")));
SetCursorColors(0x00ffffff, 0x00000000); // Set colors to black & white
pByte = m_pLAW + m_nCursorMemory;
DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("pByte = %08X, m_nCursorMemory = %08X\r\n"),
pByte, m_nCursorMemory));
// Not sure if this hide cursor is necessary, please verify
DisableCursor();
if (!pMask)
{
DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("+Turning off cursor\r\n")));
for (i = 0; i < 64*64/8*2; i++) // Turn off cursor by setting mask to clear
pByte[i] = 0;
}
else
{
// A cursor shape has been entered, draw it.
DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("+Setting pointer shape\r\n")));
// Setup freq addressed information into local variables.
stride = pMask->Stride();
pBuf = (PUCHAR) pMask->Buffer();
// initialize entire 32 x 32 shape to be ANDs=0xFF and XORs = 0x00
// (i.e. transparent)
m_nXHot = xHot;
m_nYHot = yHot; // we rely on MovePointer being called after this
// Clear Cursor Mem to transparent.
// 1/2/2003. Clear additional 1KB to 0 to patch Hw RevA cursor bottom garbage
// when cursor at bottom of screen.
memset((PUCHAR) m_pLAW+m_nCursorMemory, 0, CURSUR_IMAGE_SIZE);
for (row = 0, i=0; row < cy; row++)
{
i = row * 64/8 * 2;
for (col_byte = 0; col_byte < cx/8; col_byte++)
{
and_mask = mask_table[(~pBuf[row * stride+col_byte ] & 0xF0)>>4];
xor_mask = mask_table[(pBuf[(cy + row) * stride + col_byte] & 0xF0)>>4]/2;
pByte[i++] = and_mask | xor_mask;
and_mask = mask_table[(~pBuf[row * stride+col_byte] & 0x0F)];
xor_mask = mask_table[(pBuf[(cy + row) * stride + col_byte] & 0x0F)]/2;
pByte[i++] = and_mask | xor_mask;
}
}
}
RotateCursorShape(m_iRotate);
AdjustCursorShape(); // For Zoom-In, Zoom-Out Feature
SetCursorAddress(m_nCursorMemory);
DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("+Cursor shape set done\r\n")));
return (S_OK);
}
SCODE SMI::MovePointer(int x, int y)
{
DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("SMI::MovePointer(%d, %d)\r\n"), x, y));
int newX,newY;
#ifdef ROTATION_ENABLE
int nHideCursor = -33;
#else // ! ROTATION_ENABLE
int nHideCursor = -1;
#endif // ROTATION_ENABLE
switch (m_iRotate)
{
#ifdef ROTATION_ENABLE
case DMDO_270:
newX = m_nScreenHeight - y - m_nXHot - 1; // Hot spot is currently 32,32
newY = x - m_nYHot;
break;
case DMDO_180:
newX = m_nScreenWidth - x - m_nXHot - 1;
newY = m_nScreenHeight - y - m_nYHot - 1;
break;
case DMDO_90:
newX = y - m_nXHot;
newY = m_nScreenWidth - x - m_nYHot - 1;
break;
#endif
case 0:
default:
newX = x - m_nXHot;
newY = y - m_nYHot;
break;
}
//Fix hw cursor X,Y out of screen range. 11/01/02
if (newX >= m_nScreenWidthSave)
newX = m_nScreenWidthSave-1;
if (newY >= m_nScreenHeightSave)
newY = m_nScreenHeightSave-1;
if (x == nHideCursor)
DisableCursor();
// Check for Virtual Panning
if ( ((DWORD)m_SMISettings.m_dwCxPanel != m_dwCxZoom) ||
((DWORD)m_SMISettings.m_dwCyPanel != m_dwCyZoom) )
{
// if (newX >= 0)
{
if ((newX+m_nXHot) < m_nPanningX)
{
// Pan left.
m_nPanningX = newX + m_nXHot;
if (m_nPanningX < 0) m_nPanningX = 0;
}
else if ((newX+m_nXHot) >= (m_nPanningX + (int)m_dwCxZoom))
{
// Pan right.
m_nPanningX = (newX + m_nXHot + 1 - (int)m_dwCxZoom);
if (m_nPanningX > m_nScreenWidthSave - (int)m_dwCxZoom)
m_nPanningX = m_nScreenWidthSave - (int)m_dwCxZoom;
}
}
// if (newY >= 0)
{
if ((newY+m_nYHot) < m_nPanningY)
{
// Pan up.
m_nPanningY = newY + m_nYHot;
if (m_nPanningY < 0) m_nPanningY = 0;
}
else if ((newY+m_nYHot) >= (m_nPanningY + (int)m_dwCyZoom))
{
// Pan down.
m_nPanningY = (newY + m_nYHot + 1 - (int)m_dwCyZoom);
if (m_nPanningY > m_nScreenHeightSave - (int)m_dwCyZoom)
m_nPanningY = m_nScreenHeightSave - (int)m_dwCyZoom;
}
}
newX -= m_nPanningX;
newY -= m_nPanningY;
// Adjust newX/newY ratio
newX = (newX * m_SMISettings.m_dwCxPanel)/m_dwCxZoom;
newY = (newY * m_SMISettings.m_dwCyPanel)/m_dwCyZoom;
POKE_32(VIDEO_DISPLAY_CTRL,
FIELD_VALUE(PEEK_32(VIDEO_DISPLAY_CTRL), VIDEO_DISPLAY_CTRL, PIXEL,
((m_nPanningX * (m_nScreenBpp/8)) % 16)/(m_nScreenBpp/8))
);
POKE_32(VIDEO_FB_0_ADDRESS,
FIELD_SET(0, VIDEO_FB_0_ADDRESS, STATUS, PENDING) |
FIELD_VALUE(0, VIDEO_FB_0_ADDRESS, EXT, m_SMISettings.m_bUMA) |
FIELD_VALUE(0, VIDEO_FB_0_ADDRESS, ADDRESS,
VgxSurfAddr(m_pPrimarySurface->OffsetInVideoMemory())
+m_nPanningY*m_nScreenStride+m_nPanningX*m_nScreenBpp/8) |
0);
}
// Check for Virtual Panning
else if ( ((DWORD)m_nScreenWidthSave > m_SMISettings.m_dwCxPanel) ||
((DWORD)m_nScreenHeightSave > m_SMISettings.m_dwCyPanel) )
{
// if (newX >= 0)
{
if ((newX+m_nXHot) < m_nPanningX)
{
// Pan left.
m_nPanningX = newX + m_nXHot;
if (m_nPanningX < 0) m_nPanningX = 0;
}
else if ((newX+m_nXHot) >= (m_nPanningX + (int)m_SMISettings.m_dwCxPanel))
{
// Pan right.
m_nPanningX = (newX + m_nXHot + 1 - (int)m_SMISettings.m_dwCxPanel);
if (m_nPanningX > m_nScreenWidthSave - (int)m_SMISettings.m_dwCxPanel)
m_nPanningX = m_nScreenWidthSave - (int)m_SMISettings.m_dwCxPanel;
}
}
// if (newY >= 0)
{
if ((newY+m_nYHot) < m_nPanningY)
{
// Pan up.
m_nPanningY = newY + m_nYHot;
if (m_nPanningY < 0) m_nPanningY = 0;
}
else if ((newY+m_nYHot) >= (m_nPanningY + (int)m_SMISettings.m_dwCyPanel))
{
// Pan down.
m_nPanningY = (newY + m_nYHot + 1 - (int)m_SMISettings.m_dwCyPanel);
if (m_nPanningY > m_nScreenHeightSave - (int)m_SMISettings.m_dwCyPanel)
m_nPanningY = m_nScreenHeightSave - (int)m_SMISettings.m_dwCyPanel;
}
}
newX -= m_nPanningX;
newY -= m_nPanningY;
POKE_32(PANEL_WINDOW_WIDTH,
FIELD_VALUE(0, PANEL_WINDOW_WIDTH, WIDTH, m_nScreenWidthSave-1) |
FIELD_VALUE(0, PANEL_WINDOW_WIDTH, X, m_nPanningX) );
POKE_32(PANEL_WINDOW_HEIGHT,
FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, HEIGHT, m_nScreenHeightSave-1) |
FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, Y, m_nPanningY) );
}
ULONG dwVal = PEEK_32(PANEL_HWC_LOCATION);
if (newX >= 0)
{
dwVal = FIELD_VALUE(dwVal, PANEL_HWC_LOCATION, X, newX);
dwVal = FIELD_SET(dwVal, PANEL_HWC_LOCATION, LEFT, INSIDE);
}
else
{
dwVal = FIELD_VALUE(dwVal, PANEL_HWC_LOCATION, X, -newX);
dwVal = FIELD_SET(dwVal, PANEL_HWC_LOCATION, LEFT, OUTSIDE);
}
if (newY >= 0)
{
dwVal = FIELD_VALUE(dwVal, PANEL_HWC_LOCATION, Y, newY);
dwVal = FIELD_SET(dwVal, PANEL_HWC_LOCATION, TOP, INSIDE);
}
else
{
dwVal = FIELD_VALUE(dwVal, PANEL_HWC_LOCATION, Y, -newY);
dwVal = FIELD_SET(dwVal, PANEL_HWC_LOCATION, TOP, OUTSIDE);
}
// 1/2/2003. Clear additional 1KB to 0 to patch hw cursor bottom garbage. do not need to WaitForVBlank() now.
// Hardware bugs - Had to wait for VBlank before change position
// WaitForVBlank();
POKE_32(PANEL_HWC_LOCATION, dwVal);
if (x != nHideCursor)
EnableCursor();
return (S_OK);
}
void SMI::SetCursorColors(ULONG foreground, ULONG background)
{
ULONG color3=0x0000; //for invert color, assume it is Black at this time.
DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("SMI::SetCursorColors(0x%x, 0x%x)\r\n"),
foreground, background));
POKE_32(PANEL_HWC_COLOR_01, background<<16 | color3);
POKE_32(PANEL_HWC_COLOR_2, foreground);
}
void SMI::SetCursorAddress(ULONG dwAddress)
{
ULONG dwAdd = PEEK_32(PANEL_HWC_ADDRESS);
dwAdd = FIELD_VALUE(dwAdd, PANEL_HWC_ADDRESS, EXT, m_SMISettings.m_bUMA);
dwAdd = FIELD_VALUE(dwAdd, PANEL_HWC_ADDRESS, ADDRESS, VgxSurfAddr(dwAddress));
dwAdd = FIELD_VALUE(dwAdd, PANEL_HWC_ADDRESS, ENABLE, m_nPanelHwcOnOff);
POKE_32(PANEL_HWC_ADDRESS, dwAdd);
}
void SMI::DisableCursor(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -