📄 gapi.cpp
字号:
/***************************************************************************
* Name : gapi.cpp
* Title : MBX PocketPC GAPI module
* Author(s) : Imagination Technologies
* Created : March 2004
*
* Copyright : 2004 by Imagination Technologies. All rights reserved.
* : No part of this software, either material or conceptual
* : may be copied or distributed, transmitted, transcribed,
* : stored in a retrieval system or translated into any
* : human or computer language in any form by any means,
* : electronic, mechanical, manual or other-wise, or
* : disclosed to third parties without the express written
* : permission of Imagination Technologies Limited, Unit 8,
* : HomePark Industrial Estate, King's Langley, Hertfordshire,
* : WD4 8LZ, U.K.
*
* Description : MBX PocketPC/WinCE Game API module.
*
* Platform : PocketPC/WinCE
*
* Modifications:-
* $Log: gapi.cpp $
***************************************************************************/
#include "precomp.h"
#include "gamex.h"
// When writing to the slave port, reserve this amount.
#define SP_CHUNK_SIZE 64
static DWORD gdwOpCompleteTag = 0;
static DWORD gdwGapiOpCompletePhysAddr = 0;
static DWORD *gpdwGapiOpCompleteLinAddr = &gdwOpCompleteTag;
#define GAPI_SYSMEM 1 // 0 for gapi surface in video memory, 1 for gapi surface in system mem.
#define GAPI_USE_STRIPE_BUFFER 1
#if GAPI_SYSMEM
static void* pvLinearBase; // Shared linear address of system memory gapi legacy buffer.
#endif
/***********************************************************************************
Function Name : AllocGAPISurf
Inputs : eFormat - format of GAPI legacy surface.
Outputs : m_pclGAPIMemNode->m_psDevMemHandle
Returns : TRUE if successful
Description : Alloc the GAPI legacy surface, 240x320 with same rotation as primary.
************************************************************************************/
BOOL MBX::AllocGAPISurf(EGPEFormat eFormat)
{
#if !GAPI_SYSMEM
ULONG ulSize;
#endif
#if GAPI_SYSMEM
// Reserve a shared linear address range (>2Mb)
pvLinearBase = VirtualAlloc (NULL, (1024*1024*2), MEM_RESERVE, PAGE_NOACCESS);
// Allocate system memory and commit to read/write.
VirtualAlloc (pvLinearBase, (320*240*2), MEM_COMMIT, PAGE_READWRITE);
#endif
// Gapi surface size.
#ifdef ROTATE_ENABLE
if (m_lPrimaryRotation == 90 || m_lPrimaryRotation == 270)
{
m_ui32GapiPhysWidth = 320;
m_ui32GapiPhysHeight = 240;
}
else
#endif
{
// No rotation
m_ui32GapiPhysWidth = 240;
m_ui32GapiPhysHeight = 320;
}
// Stride
m_ui32GapiPhysStride = ((m_ui32GapiPhysWidth * EGPEFormatToBpp[eFormat]) + 7) >> 3; // Round up to next 8 byte boundry
#if !GAPI_SYSMEM
// Alloc video memory
ulSize = m_ui32GapiPhysStride * m_ui32GapiPhysHeight;
m_pclGAPIMemNode = new MemNode (ulSize, &m_sDevData, 4, m_ulReqFBStrategy);
if (!(m_pclGAPIMemNode && m_pclGAPIMemNode->m_psDevMemHandle))
{
// No gapi surface available.
return FALSE;
}
#endif
// Gapi surface allocated, so now allocate the writeback memory.
gpdwGapiOpCompleteLinAddr = m_sCallbacks.sGAPIComplete.pulLinAddr;
gdwGapiOpCompletePhysAddr = m_sCallbacks.sGAPIComplete.ulPhysAddr;
*gpdwGapiOpCompleteLinAddr = gdwOpCompleteTag;
return TRUE;
}//AllocGAPISurf
/***********************************************************************************
Function Name : SaveGapiSurf
Inputs :
Outputs :
Returns :
Description : Saves gapi surface in sys mem before low power state.
************************************************************************************/
void MBX::SaveGapiSurf()
{
#if !GAPI_SYSMEM
if (m_pclGAPIMemNode && m_pclGAPIMemNode->m_psDevMemHandle && m_pclGAPIMemNode->m_psDevMemHandle->pvLinAddr)
{
m_pclGAPIMemNode->m_pbySysMemAddr = (PBYTE)LocalAlloc(LMEM_FIXED, m_pclGAPIMemNode->m_psDevMemHandle->ui32AllocSize);
// Save the Gapi legacy surface to system memory.
if (m_pclGAPIMemNode->m_pbySysMemAddr)
{
memcpy (m_pclGAPIMemNode->m_pbySysMemAddr,
m_pclGAPIMemNode->m_psDevMemHandle->pvLinAddr,
m_pclGAPIMemNode->m_psDevMemHandle->ui32AllocSize);
}
}
#endif
}//SaveGapiSurf
/***********************************************************************************
Function Name : RestoreGapiSurf
Inputs :
Outputs :
Returns :
Description : Restores gapi surface on coming back from low power state.
************************************************************************************/
void MBX::RestoreGapiSurf()
{
#if !GAPI_SYSMEM
if (m_pclGAPIMemNode)
{
// Restore the Gapi legacy surface from system memory.
if (m_pclGAPIMemNode->m_pbySysMemAddr && m_pclGAPIMemNode->m_psDevMemHandle->pvLinAddr)
{
memcpy (m_pclGAPIMemNode->m_psDevMemHandle->pvLinAddr,
m_pclGAPIMemNode->m_pbySysMemAddr,
m_pclGAPIMemNode->m_psDevMemHandle->ui32AllocSize);
}
if (m_pclGAPIMemNode->m_pbySysMemAddr)
{
LocalFree (m_pclGAPIMemNode->m_pbySysMemAddr);
m_pclGAPIMemNode->m_pbySysMemAddr = NULL;
}
// Restore the OpComplete video memory dword
if (gpdwGapiOpCompleteLinAddr)
{
*gpdwGapiOpCompleteLinAddr = gdwOpCompleteTag;
}
}
#endif
}//RestoreGapiSurf
/***********************************************************************************
Function Name : GapiGetGxInfo
Inputs :
Outputs :
Returns :
Description : Old gapi interface.
************************************************************************************/
void MBX::GapiGetGxInfo(GXDeviceInfo *pgxoi)
{
pgxoi->idVersion = kidVersion100; // Version number of this structure
#ifdef OSV_PPC
// Give the legacy Gapi buffer for PocketPC.
#if GAPI_SYSMEM
// Gapi legacy surface is in system memory
pgxoi->pvFrameBuffer = pvLinearBase;
#else
if (m_pclGAPIMemNode && m_pclGAPIMemNode->m_psDevMemHandle)
{
// Gapi legacy surface is in video memory
pgxoi->pvFrameBuffer = m_pclGAPIMemNode->m_psDevMemHandle->pvLinAddr; // Gapi structure
}
else
{
// Fall back to primary surface rather than exception error.
pgxoi->pvFrameBuffer = m_pPrimarySurface->Buffer();
}
#endif//GAPI_SYSMEM
pgxoi->cbStride = m_ui32GapiPhysStride;
pgxoi->cxWidth = 240; // Legacy size is fixed.
pgxoi->cyHeight = 320;
#else
// Give the real frame phys coords buffer for WinCE
pgxoi->pvFrameBuffer = (void*) m_pPrimarySurface->Buffer();
pgxoi->cbStride = m_pPrimarySurface->Stride();
#ifdef ROTATE_ENABLE
if (m_lPrimaryRotation == 90 || m_lPrimaryRotation == 270)
{
pgxoi->cxWidth = m_nScreenWidth;
pgxoi->cyHeight = m_nScreenHeight;
}
#else
{
pgxoi->cxWidth = m_pPrimarySurface->Width();
pgxoi->cyHeight = m_pPrimarySurface->Height();
}
#endif
#endif//OSV_PPC
pgxoi->cBPP = m_ulColorDepth;
switch (m_ulColorDepth)
{
case 8:
{
pgxoi->ffFormat = kfPalette;
break;
}
case 16:
{
pgxoi->ffFormat = kfDirect565;
break;
}
case 24:
case 32:
{
pgxoi->ffFormat = kfDirect888;
break;
}
default:
{
pgxoi->ffFormat = 0;
break;
}
}
#ifdef ROTATE_ENABLE
// Set kfLandscape only if the display orientation is not in its native format.
// For PocketPC this is portrait mode.
#ifdef OSV_PPC
switch(m_lRotationRemap)//PocketPC
#else//OSV_PPC
switch(m_lPrimaryRotation)//WinCE
#endif//OSV_PPC
{
case 90:
case 270:
{
pgxoi->ffFormat |= kfLandscape;
break;
}
}
#endif//ROTATE_ENABLE
pgxoi->vkButtonUpPortrait = VKBUTTON_UP_PORTRAIT;
pgxoi->vkButtonUpLandscape = VKBUTTON_UP_LANDSCAPE;
pgxoi->ptButtonUp.x = PTBUTTON_UP_X;
pgxoi->ptButtonUp.y = PTBUTTON_UP_Y;
pgxoi->vkButtonDownPortrait = VKBUTTON_DOWN_PORTRAIT;
pgxoi->vkButtonDownLandscape = VKBUTTON_DOWN_LANDSCAPE;
pgxoi->ptButtonDown.x = PTBUTTON_DOWN_X;
pgxoi->ptButtonDown.y = PTBUTTON_DOWN_Y;
pgxoi->vkButtonLeftPortrait = VKBUTTON_LEFT_PORTRAIT;
pgxoi->vkButtonLeftLandscape = VKBUTTON_LEFT_LANDSCAPE;
pgxoi->ptButtonLeft.x = PTBUTTON_LEFT_X;
pgxoi->ptButtonLeft.y = PTBUTTON_LEFT_Y;
pgxoi->vkButtonRightPortrait = VKBUTTON_RIGHT_PORTRAIT;
pgxoi->vkButtonRightLandscape = VKBUTTON_RIGHT_LANDSCAPE;
pgxoi->ptButtonRight.x = PTBUTTON_RIGHT_X;
pgxoi->ptButtonRight.y = PTBUTTON_RIGHT_Y;
pgxoi->vkButtonAPortrait = VKBUTTON_A_PORTRAIT;
pgxoi->vkButtonALandscape = VKBUTTON_A_LANDSCAPE;
pgxoi->ptButtonA.x = PTBUTTON_A_X;
pgxoi->ptButtonA.y = PTBUTTON_A_Y;
pgxoi->vkButtonBPortrait = VKBUTTON_B_PORTRAIT;
pgxoi->vkButtonBLandscape = VKBUTTON_B_LANDSCAPE;
pgxoi->ptButtonB.x = PTBUTTON_B_X;
pgxoi->ptButtonB.y = PTBUTTON_B_Y;
pgxoi->vkButtonCPortrait = VKBUTTON_C_PORTRAIT;
pgxoi->vkButtonCLandscape = VKBUTTON_C_LANDSCAPE;
pgxoi->ptButtonC.x = PTBUTTON_C_X;
pgxoi->ptButtonC.y = PTBUTTON_C_Y;
pgxoi->vkButtonStartPortrait = VKBUTTON_START_PORTRAIT;
pgxoi->vkButtonStartLandscape = VKBUTTON_START_LANDSCAPE;
pgxoi->ptButtonStart.x = PTBUTTON_START_X;
pgxoi->ptButtonStart.y = PTBUTTON_START_Y;
pgxoi->pvReserved1 = (void *) 0;
pgxoi->pvReserved2 = (void *) 0;
}//GapiGetGxInfo
#if defined(GETRAWFRAMEBUFFER)
/***********************************************************************************
Function Name : GapiGetRawFramebuffer
Inputs :
Outputs :
Returns :
Description : New gapi interface
GETRAWFRAMEBUFFERINFO should ALWAYS return PORTRAIT (0,0) point.
In the case of Landscape VGA (270) designs this is Buffer() + size of line - one pixel
************************************************************************************/
void MBX::GapiGetRawFramebuffer(RawFrameBufferInfo *pRawInfo)
{
DWORD dwFrameBufferOffset;
DWORD dwBytesPerPixel;
DWORD dwBytesPerLine; // Active pixels not stride
DWORD dwVerticalHeightBytes;
pRawInfo->wBPP = (WORD)m_ulColorDepth;
switch (m_ulColorDepth)
{
case 16:
{
pRawInfo->wFormat = (WORD)FORMAT_565;
break;
}
default:
{
pRawInfo->wFormat = (WORD)FORMAT_OTHER;
}
}
/*
GETRAWFRAMEBUFFERINFO should ALWAYS return PORTRAIT (Logical 0,0) point.
Dont forget to subtract one pixel from pFramePointer member of RawFrameBufferInfo struct.
This is because we want the address of the last pixel in the line,
not the first pixel in the next line.
This applies to panels with a rotation remap of 270 and 180 because
they both have logical 0 address at the end of a line but 90 is just
a vertical offset so no subtraction is necessary.
*/
// Phys metrics
dwBytesPerPixel = m_sModeInfo.Bpp >> 3;
dwBytesPerLine = m_ulPhysicalScreenX * dwBytesPerPixel;
dwVerticalHeightBytes = m_ulPhysicalScreenY * m_ulScanLineLength;
#ifdef ROTATE_ENABLE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -