📄 s3c2443disp.cpp
字号:
ptrLine[x * (m_colorDepth >> 3) + 1] = cbsLine[(x - m_CursorRect.left) * (m_colorDepth >> 3) + 1];
if (m_colorDepth > 16)
{
ptrLine[x * (m_colorDepth >> 3) + 2] = cbsLine[(x - m_CursorRect.left) * (m_colorDepth >> 3) + 2];
}
}
}
}
m_CursorRect = rSave;
m_CursorVisible = FALSE;
}
}
SCODE S3C2443DISP::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("S3C2443DISP::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 (!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
// 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;
}
SCODE S3C2443DISP::MovePointer(INT xPosition, INT yPosition)
{
DEBUGMSG(GPE_ZONE_CURSOR, (TEXT("S3C2443DISP::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;
}
void S3C2443DISP::WaitForNotBusy(void)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2443DISP::WaitForNotBusy\r\n")));
return;
}
int S3C2443DISP::IsBusy(void)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2443DISP::IsBusy\r\n")));
return 0;
}
void S3C2443DISP::GetPhysicalVideoMemory(unsigned long *physicalMemoryBase, unsigned long *videoMemorySize)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2443DISP::GetPhysicalVideoMemory\r\n")));
*physicalMemoryBase = m_pvFlatFrameBuffer;
*videoMemorySize = m_cbScanLineLength * m_cyPhysicalScreen;
}
void
S3C2443DISP::GetVirtualVideoMemory(
unsigned long *virtualMemoryBase,
unsigned long *videoMemorySize
)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2443DISP::GetVirtualVideoMemory\r\n")));
*virtualMemoryBase = m_VirtualFrameBuffer;
// *videoMemorySize = m_cbScanLineLength * m_cyPhysicalScreen;
*videoMemorySize = 0x100000;
}
SCODE
S3C2443DISP::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:
DEBUGMSG(GPE_ZONE_ERROR,(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)
{
RotateRectl(&m_CursorRect);
if (m_CursorRect.top < bounds.bottom && m_CursorRect.bottom > bounds.top &&
m_CursorRect.left < bounds.right && m_CursorRect.right > bounds.left)
{
RotateRectlBack(&m_CursorRect);
CursorOff();
m_CursorForcedOff = TRUE;
}
else
RotateRectlBack(&m_CursorRect);
}
// 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;
}
SCODE S3C2443DISP::Line(GPELineParms *lineParameters, EGPEPhase phase)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2443DISP::Line\r\n")));
if (phase == gpeSingle || phase == gpePrepare)
{
DispPerfStart(ROP_LINE);
if ((lineParameters->pDst != m_pPrimarySurface))
{
lineParameters->pLine = EmulatedLine;
}
else
{
lineParameters->pLine = (SCODE (GPE::*)(struct GPELineParms *)) WrappedEmulatedLine;
}
}
else if (phase == gpeComplete)
{
DispPerfEnd(0);
}
return S_OK;
}
SCODE S3C2443DISP::BltPrepare(GPEBltParms *blitParameters)
{
RECTL rectl;
int iSwapTmp;
BOOL bRotate = FALSE;
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2443DISP::BltPrepare\r\n")));
DispPerfStart(blitParameters->rop4);
// default to base EmulatedBlt routine
blitParameters->pBlt = EmulatedBlt;
// see if we need to deal with cursor
// check for destination overlap with cursor and turn off cursor if overlaps
if (blitParameters->pDst == m_pPrimarySurface) // only care if dest is main display surface
{
if (m_CursorVisible && !m_CursorDisabled)
{
if (blitParameters->prclDst != NULL) // make sure there is a valid prclDst
{
rectl = *blitParameters->prclDst; // if so, use it
// There is no guarantee of a well ordered rect in blitParamters
// due to flipping and mirroring.
if(rectl.top > rectl.bottom)
{
iSwapTmp = rectl.top;
rectl.top = rectl.bottom;
rectl.bottom = iSwapTmp;
}
if(rectl.left > rectl.right)
{
iSwapTmp = rectl.left;
rectl.left = rectl.right;
rectl.right = iSwapTmp;
}
}
else
{
rectl = m_CursorRect; // if not, use the Cursor rect - this forces the cursor to be turned off in this case
}
if (m_CursorRect.top <= rectl.bottom && m_CursorRect.bottom >= rectl.top &&
m_CursorRect.left <= rectl.right && m_CursorRect.right >= rectl.left)
{
CursorOff();
m_CursorForcedOff = TRUE;
}
}
if (m_iRotate )
{
bRotate = TRUE;
}
}
// check for source overlap with cursor and turn off cursor if overlaps
if (blitParameters->pSrc == m_pPrimarySurface) // only care if source is main display surface
{
if (m_CursorVisible && !m_CursorDisabled)
{
if (blitParameters->prclSrc != NULL) // make sure there is a valid prclSrc
{
rectl = *blitParameters->prclSrc; // if so, use it
}
else
{
rectl = m_CursorRect; // if not, use the CUrsor rect - this forces the cursor to be turned off in this case
}
if (m_CursorRect.top < rectl.bottom && m_CursorRect.bottom > rectl.top &&
m_CursorRect.left < rectl.right && m_CursorRect.right > rectl.left)
{
CursorOff();
m_CursorForcedOff = TRUE;
}
}
if (m_iRotate) //if rotated
{
bRotate = TRUE;
}
}
if (bRotate)
{
blitParameters->pBlt = (SCODE (GPE::*)(GPEBltParms *))EmulatedBltRotate;
}
return S_OK;
}
SCODE S3C2443DISP::BltComplete(GPEBltParms *blitParameters)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2443DISP::BltComplete\r\n")));
// see if cursor was forced off because of overlap with source or destination and turn back on
if (m_CursorForcedOff)
{
m_CursorForcedOff = FALSE;
CursorOn();
}
DispPerfEnd(0);
return S_OK;
}
INT S3C2443DISP::InVBlank(void)
{
static BOOL value = FALSE;
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2443DISP::InVBlank\r\n")));
value = !value;
return value;
}
SCODE S3C2443DISP::SetPalette(const PALETTEENTRY *source, USHORT firstEntry, USHORT numEntries)
{
DEBUGMSG (GPE_ZONE_INIT, (TEXT("S3C2443DISP::SetPalette\r\n")));
if (firstEntry < 0 || firstEntry + numEntries > 256 || source == NULL)
{
return E_INVALIDARG;
}
return S_OK;
}
int
S3C2443DISP::GetGameXInfo(
ULONG iEsc,
ULONG cjIn,
PVOID pvIn,
ULONG cjOut,
PVOID pvOut
)
{
int RetVal = 0; // Default not supported
GXDeviceInfo * pgxoi;
// GAPI only support P8, RGB444, RGB555, RGB565, and RGB888
if ((cjOut >= sizeof(GXDeviceInfo)) && (pvOut != NULL)
&& (m_pMode->Bpp == 8 || m_pMode->Bpp == 16 || m_pMode->Bpp == 24 || m_pMode->Bpp == 32))
{
if (((GXDeviceInfo *) pvOut)->idVersion == kidVersion100)
{
pgxoi = (GXDeviceInfo *) pvOut;
pgxoi->idVersion = kidVersion100;
pgxoi->pvFrameBuffer = (void *)m_pPrimarySurface->Buffer();
pgxoi->cbStride = m_pPrimarySurface->Stride();
pgxoi->cxWidth = m_pPrimarySurface->Width();
pgxoi->cyHeight = m_pPrimarySurface->Height();
if (m_pMode->Bpp == 8)
{
pgxoi->cBPP = 8;
pgxoi->ffFormat = kfPalette;
}
else if (m_pMode->Bpp == 16)
{
pgxoi->cBPP = 16;
pgxoi->ffFormat= kfDirect | kfDirect565;
}
else if (m_pMode->Bpp == 24)
{
pgxoi->cBPP = 24;
pgxoi->ffFormat = kfDirect | kfDirect888;
}
else
{
pgxoi->cBPP = 32;
pgxoi->ffFormat = kfDirect | kfDirect888;
}
pgxoi->vkButtonUpPortrait = VK_UP;
pgxoi->vkButtonUpLandscape = VK_LEFT;
pgxoi->vkButtonDownPortrait = VK_DOWN;
pgxoi->vkButtonDownLandscape = VK_RIGHT;
pgxoi->vkButtonLeftPortrait = VK_LEFT;
pgxoi->vkButtonLeftLandscape = VK_DOWN;
pgxoi->vkButtonRightPortrait = VK_RIGHT;
pgxoi->vkButtonRightLandscape = VK_UP;
pgxoi->vkButtonAPortrait = 0xC3; // far right button
pgxoi->vkButtonALandscape = 0xC5; // record button on side
pgxoi->vkButtonBPortrait = 0xC4; // second from right button
pgxoi->vkButtonBLandscape = 0xC1;
pgxoi->vkButtonCPortrait = 0xC5; // far left button
pgxoi->vkButtonCLandscape = 0xC2; // far left button
pgxoi->vkButtonStartPortrait = 134; // action button
pgxoi->vkButtonStartLandscape = 134;
pgxoi->ptButtonUp.x = 120;
pgxoi->ptButtonUp.y = 330;
pgxoi->ptButtonDown.x = 120;
pgxoi->ptButtonDown.y = 390;
pgxoi->ptButtonLeft.x = 90;
pgxoi->ptButtonLeft.y = 360;
pgxoi->ptButtonRight.x = 150;
pgxoi->ptButtonRight.y = 360;
pgxoi->ptButtonA.x = 180;
pgxoi->ptButtonA.y = 330;
pgxoi->ptButtonB.x = 210;
pgxoi->ptButtonB.y = 345;
pgxoi->ptButtonC.x = -50;
pgxoi->ptButtonC.y = 0;
pgxoi->ptButtonStart.x = 120;
pgxoi->ptButtonStart.y = 360;
pgxoi->pvReserved1 = (void *) 0;
pgxoi->pvReserved2 = (void *) 0;
RetVal = 1;
}
else
{
SetLastError (ERROR_INVALID_PARAMETER);
RetVal = -1;
}
}
else
{
SetLastError (ERROR_INVALID_PARAMETER);
RetVal = -1;
}
return(RetVal);
}
VIDEO_POWER_STATE
PmToVideoPowerState(CEDEVICE_POWER_STATE pmDx)
{
VIDEO_POWER_STATE vps;
RETAILMSG(0,(_T("++PmToVideoPowerState\r\n")));
switch(pmDx) {
case D0: // turn the display on
vps = VideoPowerOn;
break;
case D1: // if asked for a state we don't support, go to the next lower one
case D2:
case D3:
case D4:
vps = VideoPowerOff;
break;
default:
RETAILMSG(0 , (L"PmToVideoPowerState: mapping unknown PM state %d to VideoPowerOn\r\n", pmDx));
vps = VideoPowerOn;
break;
}
return vps;
}
// this routine maps video power states to PM power states.
CEDEVICE_POWER_STATE
VideoToPmPowerState(VIDEO_POWER_STATE vps)
{
CEDEVICE_POWER_STATE pmDx;
RETAILMSG(0,(_T("++VideoToPmPowerState\r\n")));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -