|  | /****************************************************************************** | 
|  |  | 
|  | @file         Shell/PVRShell.cpp | 
|  | @copyright    Copyright (c) Imagination Technologies Limited. | 
|  | @brief        Makes programming for 3D APIs easier by wrapping surface | 
|  | initialization, Texture allocation and other functions for use by a demo. | 
|  |  | 
|  | ******************************************************************************/ | 
|  |  | 
|  | #include <stdio.h> | 
|  | #include <stdlib.h> | 
|  | #include <string.h> | 
|  | #include <stdarg.h> | 
|  | #include <math.h> | 
|  |  | 
|  | #include "PVRShell.h" | 
|  | #include "PVRShellOS.h" | 
|  | #include "PVRShellAPI.h" | 
|  | #include "PVRShellImpl.h" | 
|  |  | 
|  | /*! This file simply defines a version string. It can be commented out. */ | 
|  | #include "sdkver.h" | 
|  | #ifndef PVRSDK_VERSION | 
|  | #define PVRSDK_VERSION "n.nn.nn.nnnn" | 
|  | #endif | 
|  |  | 
|  | /*! Define to automatically stop the app after x frames. If negative, run forever. */ | 
|  | #ifndef PVRSHELL_QUIT_AFTER_FRAME | 
|  | #define PVRSHELL_QUIT_AFTER_FRAME -1 | 
|  | #endif | 
|  |  | 
|  | /*! Define to automatically stop the app after x amount of seconds. If negative, run forever. */ | 
|  | #ifndef PVRSHELL_QUIT_AFTER_TIME | 
|  | #define PVRSHELL_QUIT_AFTER_TIME -1 | 
|  | #endif | 
|  |  | 
|  | /*! Define for the screen shot file name. */ | 
|  | #define PVRSHELL_SCREENSHOT_NAME	"PVRShell" | 
|  |  | 
|  | #if defined(_WIN32) | 
|  | #define snprintf _snprintf | 
|  | #endif | 
|  |  | 
|  | // No Doxygen for CPP files, due to documentation duplication | 
|  | /// @cond NO_DOXYGEN | 
|  |  | 
|  | // Define DISABLE_SWIPE_MAPPING to disable the PVRShell's simple mapping of swipes to key commands. | 
|  | //#define DISABLE_SWIPE_MAPPING 1 | 
|  | /***************************************************************************** | 
|  | ** Prototypes | 
|  | *****************************************************************************/ | 
|  | static bool StringCopy(char *&pszStr, const char * const pszSrc); | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Class: PVRShell | 
|  | ****************************************************************************/ | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief		Constructor | 
|  | *************************************************************************/ | 
|  | PVRShell::PVRShell() | 
|  | { | 
|  | m_pShellInit = NULL; | 
|  | m_pShellData = new PVRShellData; | 
|  |  | 
|  | m_pShellData->nShellPosX=0; | 
|  | m_pShellData->nShellPosY=0; | 
|  |  | 
|  | m_pShellData->bFullScreen = false;	// note this may be overridden by some OS versions of PVRShell | 
|  |  | 
|  | m_pShellData->nAASamples= 0; | 
|  | m_pShellData->nColorBPP = 0; | 
|  | m_pShellData->nDepthBPP = 0; | 
|  |  | 
|  | m_pShellData->nDieAfterFrames = PVRSHELL_QUIT_AFTER_FRAME; | 
|  | m_pShellData->fDieAfterTime = PVRSHELL_QUIT_AFTER_TIME; | 
|  |  | 
|  | m_pShellData->bNeedPbuffer = false; | 
|  | m_pShellData->bNeedPixmap = false; | 
|  | m_pShellData->bNeedPixmapDisableCopy = false; | 
|  | m_pShellData->bNeedZbuffer = true; | 
|  | m_pShellData->bLockableBackBuffer = false; | 
|  | m_pShellData->bSoftwareRender = false; | 
|  | m_pShellData->bNeedStencilBuffer = false; | 
|  |  | 
|  | m_pShellData->bNeedAlphaFormatPre = false; | 
|  | m_pShellData->bUsingPowerSaving = true; | 
|  | m_pShellData->bOutputInfo = false; | 
|  | m_pShellData->bNoShellSwapBuffer = false; | 
|  |  | 
|  | m_pShellData->pszAppName = 0; | 
|  | m_pShellData->pszExitMessage = 0; | 
|  |  | 
|  | m_pShellData->nSwapInterval = 1; | 
|  | m_pShellData->nInitRepeats = 0; | 
|  |  | 
|  | m_pShellData->nCaptureFrameStart = -1; | 
|  | m_pShellData->nCaptureFrameStop  = -1; | 
|  | m_pShellData->nCaptureFrameScale = 1; | 
|  |  | 
|  | m_pShellData->nPriority = 2; | 
|  |  | 
|  | m_pShellData->bForceFrameTime = false; | 
|  | m_pShellData->nFrameTime = 33; | 
|  |  | 
|  | // Internal Data | 
|  | m_pShellData->bShellPosWasDefault = true; | 
|  | m_pShellData->nShellCurFrameNum = 0; | 
|  | #ifdef PVRSHELL_FPS_OUTPUT | 
|  | m_pShellData->bOutputFPS = false; | 
|  | #endif | 
|  | m_pShellData->bDiscardFrameColor=false; | 
|  | m_pShellData->bDiscardFrameDepth=true; | 
|  | m_pShellData->bDiscardFrameStencil=true; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief		Destructor | 
|  | *************************************************************************/ | 
|  | PVRShell::~PVRShell() | 
|  | { | 
|  | delete m_pShellData; | 
|  | m_pShellData = NULL; | 
|  | } | 
|  |  | 
|  | // Allow user to set preferences from within InitApplication | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief     This function is used to pass preferences to the PVRShell. | 
|  | If used, this function must be called from InitApplication(). | 
|  | @param[in] prefName    Name of preference to set to value | 
|  | @param[in] value       Value | 
|  | @return    true for success | 
|  | *************************************************************************/ | 
|  |  | 
|  | bool PVRShell::PVRShellSet(const prefNameBoolEnum prefName, const bool value) | 
|  | { | 
|  | switch(prefName) | 
|  | { | 
|  | case prefFullScreen: | 
|  | m_pShellData->bFullScreen = value; | 
|  | return true; | 
|  |  | 
|  | case prefPBufferContext: | 
|  | m_pShellData->bNeedPbuffer = value; | 
|  | return true; | 
|  |  | 
|  | case prefPixmapContext: | 
|  | m_pShellData->bNeedPixmap = value; | 
|  | return true; | 
|  |  | 
|  | case prefPixmapDisableCopy: | 
|  | m_pShellData->bNeedPixmapDisableCopy = value; | 
|  | return true; | 
|  |  | 
|  | case prefZbufferContext: | 
|  | m_pShellData->bNeedZbuffer = value; | 
|  | return true; | 
|  |  | 
|  | case prefLockableBackBuffer: | 
|  | m_pShellData->bLockableBackBuffer = value; | 
|  | return true; | 
|  |  | 
|  | case prefSoftwareRendering: | 
|  | m_pShellData->bSoftwareRender = value; | 
|  | return true; | 
|  |  | 
|  | case prefStencilBufferContext: | 
|  | m_pShellData->bNeedStencilBuffer = value; | 
|  | return true; | 
|  |  | 
|  | case prefAlphaFormatPre: | 
|  | m_pShellData->bNeedAlphaFormatPre = value; | 
|  | return true; | 
|  |  | 
|  | case prefPowerSaving: | 
|  | m_pShellData->bUsingPowerSaving = value; | 
|  | return true; | 
|  |  | 
|  | case prefOutputInfo: | 
|  | m_pShellData->bOutputInfo = value; | 
|  | return true; | 
|  |  | 
|  | case prefNoShellSwapBuffer: | 
|  | m_pShellData->bNoShellSwapBuffer = value; | 
|  | return true; | 
|  |  | 
|  | case prefForceFrameTime: | 
|  | m_pShellData->bForceFrameTime = value; | 
|  | return true; | 
|  |  | 
|  | #ifdef PVRSHELL_FPS_OUTPUT | 
|  | case prefOutputFPS: | 
|  | m_pShellData->bOutputFPS = value; | 
|  | return true; | 
|  | #endif | 
|  |  | 
|  | case prefDiscardColor: | 
|  | m_pShellData->bDiscardFrameColor = value; | 
|  | return true; | 
|  | case prefDiscardDepth: | 
|  | m_pShellData->bDiscardFrameDepth = value; | 
|  | return true; | 
|  | case prefDiscardStencil: | 
|  | m_pShellData->bDiscardFrameStencil = value; | 
|  | return true; | 
|  | default: | 
|  | return m_pShellInit->OsSet(prefName, value); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief      This function is used to get parameters from the PVRShell. | 
|  | It can be called from anywhere in the program. | 
|  | @param[in]  prefName    Name of preference to set to value | 
|  | @return     The requested value. | 
|  | *************************************************************************/ | 
|  |  | 
|  | bool PVRShell::PVRShellGet(const prefNameBoolEnum prefName) const | 
|  | { | 
|  | switch(prefName) | 
|  | { | 
|  | case prefFullScreen:	return m_pShellData->bFullScreen; | 
|  | case prefIsRotated:	return (m_pShellData->nShellDimY > m_pShellData->nShellDimX); | 
|  | case prefPBufferContext:	return m_pShellData->bNeedPbuffer; | 
|  | case prefPixmapContext:	return m_pShellData->bNeedPixmap; | 
|  | case prefPixmapDisableCopy:	return m_pShellData->bNeedPixmapDisableCopy; | 
|  | case prefZbufferContext:	return m_pShellData->bNeedZbuffer; | 
|  | case prefLockableBackBuffer:	return m_pShellData->bLockableBackBuffer; | 
|  | case prefSoftwareRendering:	return m_pShellData->bSoftwareRender; | 
|  | case prefNoShellSwapBuffer: return m_pShellData->bNoShellSwapBuffer; | 
|  | case prefStencilBufferContext:	return m_pShellData->bNeedStencilBuffer; | 
|  | case prefAlphaFormatPre: return m_pShellData->bNeedAlphaFormatPre; | 
|  | case prefPowerSaving: return m_pShellData->bUsingPowerSaving; | 
|  | case prefOutputInfo:	return m_pShellData->bOutputInfo; | 
|  | case prefForceFrameTime: return m_pShellData->bForceFrameTime; | 
|  | #ifdef PVRSHELL_FPS_OUTPUT | 
|  | case prefOutputFPS: return m_pShellData->bOutputFPS; | 
|  | #endif | 
|  | case prefDiscardColor: return m_pShellData->bDiscardFrameColor; | 
|  | case prefDiscardDepth: return m_pShellData->bDiscardFrameDepth; | 
|  | case prefDiscardStencil: return m_pShellData->bDiscardFrameStencil; | 
|  | default:	return false; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief     This function is used to pass preferences to the PVRShell. | 
|  | If used, this function must be called from InitApplication(). | 
|  | @param[in] prefName    Name of preference to set to value | 
|  | @param[in] value       Value | 
|  | @return    true for success | 
|  | *************************************************************************/ | 
|  |  | 
|  | bool PVRShell::PVRShellSet(const prefNameFloatEnum prefName, const float value) | 
|  | { | 
|  | switch(prefName) | 
|  | { | 
|  | case prefQuitAfterTime: | 
|  | m_pShellData->fDieAfterTime = value; | 
|  | return true; | 
|  |  | 
|  | default: | 
|  | break; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief      This function is used to get parameters from the PVRShell. | 
|  | It can be called from anywhere in the program. | 
|  | @param[in]  prefName    Name of preference to set to value | 
|  | @return     The requested value. | 
|  | *************************************************************************/ | 
|  | float PVRShell::PVRShellGet(const prefNameFloatEnum prefName) const | 
|  | { | 
|  | switch(prefName) | 
|  | { | 
|  | case prefQuitAfterTime:	return m_pShellData->fDieAfterTime; | 
|  | default:	return -1; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief     This function is used to pass preferences to the PVRShell. | 
|  | If used, this function must be called from InitApplication(). | 
|  | @param[in] prefName    Name of preference to set to value | 
|  | @param[in] value       Value | 
|  | @return    true for success | 
|  | *************************************************************************/ | 
|  | bool PVRShell::PVRShellSet(const prefNameIntEnum prefName, const int value) | 
|  | { | 
|  | switch(prefName) | 
|  | { | 
|  | case prefWidth: | 
|  | if(value > 0) | 
|  | { | 
|  | m_pShellData->nShellDimX = value; | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  |  | 
|  | case prefHeight: | 
|  | if(value > 0) | 
|  | { | 
|  | m_pShellData->nShellDimY = value; | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  |  | 
|  | case prefPositionX: | 
|  | m_pShellData->bShellPosWasDefault = false; | 
|  | m_pShellData->nShellPosX = value; | 
|  | return true; | 
|  |  | 
|  | case prefPositionY: | 
|  | m_pShellData->bShellPosWasDefault = false; | 
|  | m_pShellData->nShellPosY = value; | 
|  | return true; | 
|  |  | 
|  | case prefQuitAfterFrame: | 
|  | m_pShellData->nDieAfterFrames = value; | 
|  | return true; | 
|  |  | 
|  | case prefInitRepeats: | 
|  | m_pShellData->nInitRepeats = value; | 
|  | return true; | 
|  |  | 
|  | case prefAASamples: | 
|  | if(value >= 0) | 
|  | { | 
|  | m_pShellData->nAASamples = value; | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  |  | 
|  | case prefColorBPP: | 
|  | if(value >= 0) | 
|  | { | 
|  | m_pShellData->nColorBPP = value; | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  |  | 
|  | case prefDepthBPP: | 
|  | if(value >= 0) | 
|  | { | 
|  | m_pShellData->nDepthBPP = value; | 
|  | return true; | 
|  | } | 
|  | return false; | 
|  |  | 
|  | case prefRotateKeys: | 
|  | { | 
|  | switch((PVRShellKeyRotate)value) | 
|  | { | 
|  | case PVRShellKeyRotateNone: | 
|  | m_pShellInit->m_eKeyMapUP = PVRShellKeyNameUP; | 
|  | m_pShellInit->m_eKeyMapLEFT = PVRShellKeyNameLEFT; | 
|  | m_pShellInit->m_eKeyMapDOWN = PVRShellKeyNameDOWN; | 
|  | m_pShellInit->m_eKeyMapRIGHT = PVRShellKeyNameRIGHT; | 
|  | break; | 
|  | case PVRShellKeyRotate90: | 
|  | m_pShellInit->m_eKeyMapUP = PVRShellKeyNameLEFT; | 
|  | m_pShellInit->m_eKeyMapLEFT = PVRShellKeyNameDOWN; | 
|  | m_pShellInit->m_eKeyMapDOWN = PVRShellKeyNameRIGHT; | 
|  | m_pShellInit->m_eKeyMapRIGHT = PVRShellKeyNameUP; | 
|  | break; | 
|  | case PVRShellKeyRotate180: | 
|  | m_pShellInit->m_eKeyMapUP = PVRShellKeyNameDOWN; | 
|  | m_pShellInit->m_eKeyMapLEFT = PVRShellKeyNameRIGHT; | 
|  | m_pShellInit->m_eKeyMapDOWN = PVRShellKeyNameUP; | 
|  | m_pShellInit->m_eKeyMapRIGHT = PVRShellKeyNameLEFT; | 
|  | break; | 
|  | case PVRShellKeyRotate270: | 
|  | m_pShellInit->m_eKeyMapUP = PVRShellKeyNameRIGHT; | 
|  | m_pShellInit->m_eKeyMapLEFT = PVRShellKeyNameUP; | 
|  | m_pShellInit->m_eKeyMapDOWN = PVRShellKeyNameLEFT; | 
|  | m_pShellInit->m_eKeyMapRIGHT = PVRShellKeyNameDOWN; | 
|  | break; | 
|  | default: | 
|  | return false; | 
|  | } | 
|  | } | 
|  | return true; | 
|  | case prefCaptureFrameStart: | 
|  | m_pShellData->nCaptureFrameStart = value; | 
|  | return true; | 
|  | case prefCaptureFrameStop: | 
|  | m_pShellData->nCaptureFrameStop  = value; | 
|  | return true; | 
|  | case prefCaptureFrameScale: | 
|  | m_pShellData->nCaptureFrameScale  = value; | 
|  | return true; | 
|  | case prefFrameTimeValue: | 
|  | m_pShellData->nFrameTime = value; | 
|  | return true; | 
|  | default: | 
|  | { | 
|  | if(m_pShellInit->ApiSet(prefName, value)) | 
|  | return true; | 
|  |  | 
|  | return m_pShellInit->OsSet(prefName, value); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief      This function is used to get parameters from the PVRShell. | 
|  | It can be called from anywhere in the program. | 
|  | @param[in]  prefName    Name of preference to set to value | 
|  | @return     The requested value. | 
|  | *************************************************************************/ | 
|  | int PVRShell::PVRShellGet(const prefNameIntEnum prefName) const | 
|  | { | 
|  | switch(prefName) | 
|  | { | 
|  | case prefWidth:	return m_pShellData->nShellDimX; | 
|  | case prefHeight:	return m_pShellData->nShellDimY; | 
|  | case prefPositionX:	return m_pShellData->nShellPosX; | 
|  | case prefPositionY:	return m_pShellData->nShellPosY; | 
|  | case prefQuitAfterFrame:	return m_pShellData->nDieAfterFrames; | 
|  | case prefSwapInterval:	return m_pShellData->nSwapInterval; | 
|  | case prefInitRepeats:	return m_pShellData->nInitRepeats; | 
|  | case prefAASamples:	return m_pShellData->nAASamples; | 
|  | case prefCommandLineOptNum:	return m_pShellInit->m_CommandLine.m_nOptLen; | 
|  | case prefColorBPP: return m_pShellData->nColorBPP; | 
|  | case prefDepthBPP: return m_pShellData->nDepthBPP; | 
|  | case prefCaptureFrameStart: return m_pShellData->nCaptureFrameStart; | 
|  | case prefCaptureFrameStop: return m_pShellData->nCaptureFrameStop; | 
|  | case prefCaptureFrameScale: return m_pShellData->nCaptureFrameScale; | 
|  | case prefFrameTimeValue: return m_pShellData->nFrameTime; | 
|  | case prefPriority: return m_pShellData->nPriority; | 
|  | default: | 
|  | { | 
|  | int n; | 
|  |  | 
|  | if(m_pShellInit->ApiGet(prefName, &n)) | 
|  | return n; | 
|  | if(m_pShellInit->OsGet(prefName, &n)) | 
|  | return n; | 
|  | return -1; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief     This function is used to pass preferences to the PVRShell. | 
|  | If used, this function must be called from InitApplication(). | 
|  | @param[in] prefName    Name of preference to set to value | 
|  | @param[in] value       Value | 
|  | @return    true for success | 
|  | *************************************************************************/ | 
|  | bool PVRShell::PVRShellSet(const prefNamePtrEnum prefName, const void * const ptrValue) | 
|  | { | 
|  | PVRSHELL_UNREFERENCED_PARAMETER(prefName); | 
|  | PVRSHELL_UNREFERENCED_PARAMETER(ptrValue); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief      This function is used to get parameters from the PVRShell. | 
|  | It can be called from anywhere in the program. | 
|  | @param[in]  prefName    Name of preference to set to value | 
|  | @return     The requested value. | 
|  | *************************************************************************/ | 
|  | void *PVRShell::PVRShellGet(const prefNamePtrEnum prefName) const | 
|  | { | 
|  | switch(prefName) | 
|  | { | 
|  | case prefNativeWindowType:	return m_pShellInit->OsGetNativeWindowType(); | 
|  | case prefPointerLocation: | 
|  | if (m_pShellInit->m_bTouching) | 
|  | return m_pShellInit->m_vec2PointerLocation; | 
|  | break; | 
|  | default: | 
|  | { | 
|  | void *p; | 
|  |  | 
|  | if(m_pShellInit->ApiGet(prefName, &p)) | 
|  | return p; | 
|  | if(m_pShellInit->OsGet(prefName, &p)) | 
|  | return p; | 
|  | } | 
|  | } | 
|  | return NULL; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief     This function is used to pass preferences to the PVRShell. | 
|  | If used, this function must be called from InitApplication(). | 
|  | @param[in] prefName    Name of preference to set to value | 
|  | @param[in] value       Value | 
|  | @return    true for success | 
|  | *************************************************************************/ | 
|  | bool PVRShell::PVRShellSet(const prefNameConstPtrEnum prefName, const void * const ptrValue) | 
|  | { | 
|  | switch(prefName) | 
|  | { | 
|  | case prefAppName: | 
|  | StringCopy(m_pShellData->pszAppName, (char*)ptrValue); | 
|  | return true; | 
|  | case prefExitMessage: | 
|  | StringCopy(m_pShellData->pszExitMessage, (char*)ptrValue); | 
|  | PVRShellOutputDebug("Exit message has been set to: \"%s\".\n", ptrValue); | 
|  | return true; | 
|  | default: | 
|  | break; | 
|  | } | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief      This function is used to get parameters from the PVRShell. | 
|  | It can be called from anywhere in the program. | 
|  | @param[in]  prefName    Name of preference to set to value | 
|  | @return     The requested value. | 
|  | *************************************************************************/ | 
|  | const void *PVRShell::PVRShellGet(const prefNameConstPtrEnum prefName) const | 
|  | { | 
|  | switch(prefName) | 
|  | { | 
|  | case prefAppName: | 
|  | return m_pShellData->pszAppName; | 
|  | case prefExitMessage: | 
|  | return m_pShellData->pszExitMessage; | 
|  | case prefReadPath: | 
|  | return m_pShellInit->GetReadPath(); | 
|  | case prefWritePath: | 
|  | return m_pShellInit->GetWritePath(); | 
|  | case prefCommandLine: | 
|  | return m_pShellInit->m_CommandLine.m_psOrig; | 
|  | case prefCommandLineOpts: | 
|  | return m_pShellInit->m_CommandLine.m_pOpt; | 
|  | case prefVersion: | 
|  | return PVRSDK_VERSION; | 
|  | default: | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	     It will be stored as 24-bit per pixel, 8-bit per chanel RGB. | 
|  | The memory should be freed with free() when no longer needed. | 
|  | @param[in]	 Width		size of image to capture (relative to 0,0) | 
|  | @param[in]	 Height		size of image to capture (relative to 0,0) | 
|  | @param[out] pLines		receives a pointer to an area of memory containing the screen buffer. | 
|  | @return	 true for success | 
|  | *************************************************************************/ | 
|  | bool PVRShell::PVRShellScreenCaptureBuffer(const int Width, const int Height, unsigned char **pLines) | 
|  | { | 
|  | /* Allocate memory for line */ | 
|  | *pLines=(unsigned char *)calloc(Width*Height*3, sizeof(unsigned char)); | 
|  | if (!(*pLines)) return false; | 
|  |  | 
|  | return m_pShellInit->ApiScreenCaptureBuffer(Width, Height, *pLines); | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief 	Writes out the image data to a BMP file with basename fname. | 
|  | @details   The file written will be fname suffixed with a number to make the file unique. | 
|  | For example, if fname is "abc", this function will attempt | 
|  | to save to "abc0000.bmp"; if that file already exists, it | 
|  | will try "abc0001.bmp", repeating until a new filename is | 
|  | found. The final filename used is returned in ofname. | 
|  | @param[in]	 fname		base of file to save screen to | 
|  | @param[in]	 Width		size of image to capture (relative to 0,0) | 
|  | @param[in]	 Height		size of image to capture (relative to 0,0) | 
|  | @param[in]  pLines		image data to write out (24bpp, 8-bit per channel RGB) | 
|  | @param[in]  ui32PixelReplicate    expand pixels through replication (1 = no scale) | 
|  | @param[out] ofname		If non-NULL, receives the filename actually used | 
|  | @return	 true for success | 
|  | *************************************************************************/ | 
|  | int PVRShell::PVRShellScreenSave( | 
|  | const char			* const fname, | 
|  | const int			Width, | 
|  | const int			Height, | 
|  | const unsigned char	* const pLines, | 
|  | const unsigned int	ui32PixelReplicate, | 
|  | char				* const ofname) | 
|  | { | 
|  | char *pszFileName; | 
|  |  | 
|  | /* | 
|  | Choose a filename | 
|  | */ | 
|  | { | 
|  | FILE		*file = 0; | 
|  | const char	*pszWritePath; | 
|  | int			nScreenshotCount; | 
|  |  | 
|  | pszWritePath = (const char*)PVRShellGet(prefWritePath); | 
|  |  | 
|  | size_t	nFileNameSize = strlen(pszWritePath) + 200; | 
|  | pszFileName = (char*)malloc(nFileNameSize); | 
|  |  | 
|  | /* Look for the first file name that doesn't already exist */ | 
|  | for(nScreenshotCount = 0; nScreenshotCount < 10000; ++nScreenshotCount) | 
|  | { | 
|  | snprintf(pszFileName, nFileNameSize, "%s%s%04d.bmp", pszWritePath, fname, nScreenshotCount); | 
|  |  | 
|  | file = fopen(pszFileName,"r"); | 
|  | if(!file) | 
|  | break; | 
|  | fclose(file); | 
|  | } | 
|  |  | 
|  | /* If all files already exist, replace the first one */ | 
|  | if (nScreenshotCount==10000) | 
|  | { | 
|  | snprintf(pszFileName, nFileNameSize, "%s%s0000.bmp", pszWritePath, fname); | 
|  | PVRShellOutputDebug("PVRShell: *WARNING* : Overwriting %s\n", pszFileName); | 
|  | } | 
|  |  | 
|  | if(ofname)	// requested the output file name | 
|  | { | 
|  | strcpy(ofname, pszFileName); | 
|  | } | 
|  | } | 
|  |  | 
|  | const int err = PVRShellWriteBMPFile(pszFileName, Width, Height, pLines, ui32PixelReplicate); | 
|  | FREE(pszFileName); | 
|  | if (err) | 
|  | { | 
|  | return 10*err+1; | 
|  | } | 
|  | else | 
|  | { | 
|  | // No problem occurred | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief       Swaps the bytes in pBytes from little to big endian (or vice versa) | 
|  | @param[in]	  pBytes     The bytes to swap | 
|  | @param[in]	  i32ByteNo  The number of bytes to swap | 
|  | *************************************************************************/ | 
|  | inline void PVRShellByteSwap(unsigned char* pBytes, int i32ByteNo) | 
|  | { | 
|  | int i = 0, j = i32ByteNo - 1; | 
|  |  | 
|  | while(i < j) | 
|  | { | 
|  | unsigned char cTmp = pBytes[i]; | 
|  | pBytes[i] = pBytes[j]; | 
|  | pBytes[j] = cTmp; | 
|  |  | 
|  | ++i; | 
|  | --j; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	        Writes out the image data to a BMP file with name fname. | 
|  | @param[in]		pszFilename		file to save screen to | 
|  | @param[in]		ui32Width		the width of the data | 
|  | @param[in]		ui32Height		the height of the data | 
|  | @param[in]		pImageData		image data to write out (24bpp, 8-bit per channel RGB) | 
|  | @return		0 on success | 
|  | *************************************************************************/ | 
|  | int PVRShell::PVRShellWriteBMPFile( | 
|  | const char			* const pszFilename, | 
|  | const unsigned int	ui32Width, | 
|  | const unsigned int	ui32Height, | 
|  | const void			* const pImageData, | 
|  | const unsigned int	ui32PixelReplicate) | 
|  | { | 
|  | #define ByteSwap(x) PVRShellByteSwap((unsigned char*) &x, sizeof(x)) | 
|  |  | 
|  | const int		i32BMPHeaderSize = 14; /* The size of a BMP header */ | 
|  | const int		i32BMPInfoSize   = 40; /* The size of a BMP info header */ | 
|  | int				Result = 1; | 
|  | FILE*			fpDumpfile = 0; | 
|  |  | 
|  | fpDumpfile = fopen(pszFilename, "wb"); | 
|  |  | 
|  | if (fpDumpfile != 0) | 
|  | { | 
|  | const short int word = 0x0001; | 
|  | const char * const byte = (char*) &word; | 
|  | bool bLittleEndian = byte[0] ? true : false; | 
|  |  | 
|  | unsigned int i32OutBytesPerLine = ui32Width * 3 * ui32PixelReplicate; | 
|  | unsigned int i32OutAlign = 0; | 
|  |  | 
|  | // round up to a dword boundary | 
|  | if(i32OutBytesPerLine & 3) | 
|  | { | 
|  | i32OutBytesPerLine |= 3; | 
|  | ++i32OutBytesPerLine; | 
|  | i32OutAlign = i32OutBytesPerLine - ui32Width * 3 * ui32PixelReplicate; | 
|  | } | 
|  |  | 
|  | unsigned char *pData = (unsigned char*) pImageData; | 
|  |  | 
|  | { | 
|  | int ui32RealSize = i32OutBytesPerLine * ui32Height * ui32PixelReplicate; | 
|  |  | 
|  | // BMP Header | 
|  | unsigned short  bfType = 0x4D42; | 
|  | unsigned int   bfSize = i32BMPHeaderSize + i32BMPInfoSize + ui32RealSize; | 
|  | unsigned short  bfReserved1 = 0; | 
|  | unsigned short  bfReserved2 = 0; | 
|  | unsigned int   bfOffBits = i32BMPHeaderSize + i32BMPInfoSize; | 
|  |  | 
|  | // BMP Info Header | 
|  | unsigned int  biSize = i32BMPInfoSize; | 
|  | unsigned int  biWidth = ui32Width * ui32PixelReplicate; | 
|  | unsigned int  biHeight = ui32Height * ui32PixelReplicate; | 
|  | unsigned short biPlanes = 1; | 
|  | unsigned short biBitCount = 24; | 
|  | unsigned int  biCompression = 0L; | 
|  | unsigned int  biSizeImage = ui32RealSize; | 
|  | unsigned int  biXPelsPerMeter = 0; | 
|  | unsigned int  biYPelsPerMeter = 0; | 
|  | unsigned int  biClrUsed = 0; | 
|  | unsigned int  biClrImportant = 0; | 
|  |  | 
|  | if(!bLittleEndian) | 
|  | { | 
|  | for(unsigned int i = 0; i < ui32Width * ui32Height; ++i) | 
|  | PVRShellByteSwap(pData + (3 * i), 3); | 
|  |  | 
|  | ByteSwap(bfType); | 
|  | ByteSwap(bfSize); | 
|  | ByteSwap(bfOffBits); | 
|  | ByteSwap(biSize); | 
|  | ByteSwap(biWidth); | 
|  | ByteSwap(biHeight); | 
|  | ByteSwap(biPlanes); | 
|  | ByteSwap(biBitCount); | 
|  | ByteSwap(biCompression); | 
|  | ByteSwap(biSizeImage); | 
|  | } | 
|  |  | 
|  | // Write Header. | 
|  | fwrite(&bfType		, 1, sizeof(bfType)		, fpDumpfile); | 
|  | fwrite(&bfSize		, 1, sizeof(bfSize)		, fpDumpfile); | 
|  | fwrite(&bfReserved1	, 1, sizeof(bfReserved1), fpDumpfile); | 
|  | fwrite(&bfReserved2	, 1, sizeof(bfReserved2), fpDumpfile); | 
|  | fwrite(&bfOffBits	, 1, sizeof(bfOffBits)	, fpDumpfile); | 
|  |  | 
|  | // Write info header. | 
|  | fwrite(&biSize			, 1, sizeof(biSize)			, fpDumpfile); | 
|  | fwrite(&biWidth			, 1, sizeof(biWidth)		, fpDumpfile); | 
|  | fwrite(&biHeight		, 1, sizeof(biHeight)		, fpDumpfile); | 
|  | fwrite(&biPlanes		, 1, sizeof(biPlanes)		, fpDumpfile); | 
|  | fwrite(&biBitCount		, 1, sizeof(biBitCount)		, fpDumpfile); | 
|  | fwrite(&biCompression	, 1, sizeof(biCompression)	, fpDumpfile); | 
|  | fwrite(&biSizeImage		, 1, sizeof(biSizeImage)	, fpDumpfile); | 
|  | fwrite(&biXPelsPerMeter	, 1, sizeof(biXPelsPerMeter), fpDumpfile); | 
|  | fwrite(&biYPelsPerMeter	, 1, sizeof(biYPelsPerMeter), fpDumpfile); | 
|  | fwrite(&biClrUsed		, 1, sizeof(biClrUsed)		, fpDumpfile); | 
|  | fwrite(&biClrImportant	, 1, sizeof(biClrImportant)	, fpDumpfile); | 
|  | } | 
|  |  | 
|  | // Write image. | 
|  | for(unsigned int nY = 0; nY < ui32Height; ++nY) | 
|  | { | 
|  | const unsigned char * pRow = &pData[3 * ui32Width * nY]; | 
|  | for(unsigned int nRepY = 0; nRepY < ui32PixelReplicate; ++nRepY) | 
|  | { | 
|  | for(unsigned int nX = 0; nX < ui32Width; ++nX) | 
|  | { | 
|  | const unsigned char * pPixel = &pRow[3 * nX]; | 
|  | for(unsigned int nRepX = 0; nRepX < ui32PixelReplicate; ++nRepX) | 
|  | { | 
|  | fwrite(pPixel, 1, 3, fpDumpfile); | 
|  | } | 
|  | } | 
|  |  | 
|  | fwrite("\0\0\0\0", i32OutAlign, 1, fpDumpfile); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Last but not least close the file. | 
|  | fclose(fpDumpfile); | 
|  |  | 
|  | Result = 0; | 
|  | } | 
|  | else | 
|  | { | 
|  | PVRShellOutputDebug("PVRShell: Failed to open \"%s\" for writing screen dump.\n", pszFilename); | 
|  | } | 
|  |  | 
|  | return Result; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	    The number itself should be considered meaningless; an | 
|  | application should use this function to determine how much | 
|  | time has passed between two points (e.g. between each | 
|  | frame). | 
|  | @return	A value which increments once per millisecond. | 
|  | *************************************************************************/ | 
|  | unsigned long PVRShell::PVRShellGetTime() | 
|  | { | 
|  | if(m_pShellData->bForceFrameTime) | 
|  | { | 
|  | // Return a "time" value based on the current frame number | 
|  | return (unsigned long) m_pShellData->nShellCurFrameNum * m_pShellData->nFrameTime; | 
|  | } | 
|  | else | 
|  | { | 
|  | // Read timer from a platform dependant function | 
|  | return m_pShellInit->OsGetTime(); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	    Check if a key was pressed. The keys on various devices | 
|  | are mapped to the PVRShell-supported keys (listed in @a PVRShellKeyName) in | 
|  | a platform-dependent manner, since most platforms have different input | 
|  | devices. Check the <a href="modules.html">Modules page</a> for your OS | 
|  | for details on how the enum values map to your device's key code input. | 
|  | @param[in]	key		Code of the key to test | 
|  | @return	true if key was pressed | 
|  | *************************************************************************/ | 
|  | bool PVRShell::PVRShellIsKeyPressed(const PVRShellKeyName key) | 
|  | { | 
|  | if(!m_pShellInit) | 
|  | return false; | 
|  |  | 
|  | return m_pShellInit->DoIsKeyPressed(key); | 
|  | } | 
|  |  | 
|  | // class PVRShellCommandLine | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief		Constructor | 
|  | *************************************************************************/ | 
|  | PVRShellCommandLine::PVRShellCommandLine() | 
|  | { | 
|  | memset(this, 0, sizeof(*this)); | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief		Destructor | 
|  | *************************************************************************/ | 
|  | PVRShellCommandLine::~PVRShellCommandLine() | 
|  | { | 
|  | delete [] m_psOrig; | 
|  | delete [] m_psSplit; | 
|  | FREE(m_pOpt); | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	    Set command-line options to pStr | 
|  | @param[in]	pStr   Input string | 
|  | *************************************************************************/ | 
|  | void PVRShellCommandLine::Set(const char *pStr) | 
|  | { | 
|  | delete [] m_psOrig; | 
|  | m_psOrig = 0; | 
|  |  | 
|  | if(pStr) | 
|  | { | 
|  | size_t len = strlen(pStr)+1; | 
|  | m_psOrig = new char[len]; | 
|  | strcpy(m_psOrig, pStr); | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	    Prepend command-line options to m_psOrig | 
|  | @param[in]	pStr Input string | 
|  | *************************************************************************/ | 
|  | void PVRShellCommandLine::Prefix(const char *pStr) | 
|  | { | 
|  | if(!m_psOrig) | 
|  | Set(pStr); | 
|  | else if(!pStr) | 
|  | return; | 
|  | else | 
|  | { | 
|  | char *pstmp = m_psOrig; | 
|  | size_t lenA = strlen(pStr); | 
|  | size_t TotalLen = lenA + 1 + strlen(m_psOrig); | 
|  |  | 
|  | m_psOrig = new char[TotalLen + 1]; | 
|  |  | 
|  | strcpy(m_psOrig, pStr); | 
|  | m_psOrig[lenA] = ' '; | 
|  | strcpy(m_psOrig + lenA + 1, pstmp); | 
|  | m_psOrig[TotalLen] = '\0'; | 
|  |  | 
|  | delete[] pstmp; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	    Prepend command-line options to m_psOrig from a file | 
|  | @param[in]	pFileName   Input string | 
|  | *************************************************************************/ | 
|  | bool PVRShellCommandLine::PrefixFromFile(const char *pFileName) | 
|  | { | 
|  | char* nl; | 
|  | FILE *pFile = fopen(pFileName, "rb"); | 
|  |  | 
|  | if(pFile) | 
|  | { | 
|  | // Get the file size | 
|  | fseek(pFile, 0, SEEK_END); | 
|  | long m_Size = ftell(pFile) + 2; | 
|  | fseek(pFile, 0, SEEK_SET); | 
|  |  | 
|  | char *pFullFile = new char[m_Size]; | 
|  |  | 
|  | if(pFullFile) | 
|  | { | 
|  | size_t offset = 0; | 
|  | while(fgets(pFullFile + offset, (int) (m_Size - offset), pFile)) | 
|  | { | 
|  | offset = strlen(pFullFile); | 
|  |  | 
|  | // Replace new lines with spaces | 
|  | nl = strrchr(pFullFile, '\r'); | 
|  | if(nl) *nl = ' '; | 
|  |  | 
|  | nl = strrchr(pFullFile, '\n'); | 
|  | if(nl) *nl = ' '; | 
|  | } | 
|  |  | 
|  | pFullFile[offset] = '\0'; | 
|  | Prefix(pFullFile); | 
|  |  | 
|  | delete[] pFullFile; | 
|  | fclose(pFile); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | fclose(pFile); | 
|  | } | 
|  |  | 
|  | return false; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	  Parse m_psOrig for command-line options and store them in m_pOpt | 
|  | *************************************************************************/ | 
|  | void PVRShellCommandLine::Parse() | 
|  | { | 
|  | size_t		len; | 
|  | int			nIn, nOut; | 
|  | bool		bInQuotes; | 
|  | SCmdLineOpt	opt; | 
|  |  | 
|  | if(!m_psOrig) | 
|  | return; | 
|  |  | 
|  | // Delete/free up any options we may have parsed recently | 
|  | delete [] m_psSplit; | 
|  | FREE(m_pOpt); | 
|  |  | 
|  | // Take a copy to be edited | 
|  | len = strlen(m_psOrig) + 1; | 
|  | m_psSplit = new char[len]; | 
|  |  | 
|  | // Break the command line into options | 
|  | bInQuotes = false; | 
|  | opt.pArg = NULL; | 
|  | opt.pVal = NULL; | 
|  | nIn = -1; | 
|  | nOut = 0; | 
|  |  | 
|  | do | 
|  | { | 
|  | ++nIn; | 
|  | if(m_psOrig[nIn] == '"') | 
|  | { | 
|  | bInQuotes = !bInQuotes; | 
|  | } | 
|  | else | 
|  | { | 
|  | if(bInQuotes && m_psOrig[nIn] != 0) | 
|  | { | 
|  | if(!opt.pArg) | 
|  | opt.pArg = &m_psSplit[nOut]; | 
|  |  | 
|  | m_psSplit[nOut++] = m_psOrig[nIn]; | 
|  | } | 
|  | else | 
|  | { | 
|  | switch(m_psOrig[nIn]) | 
|  | { | 
|  | case '=': | 
|  | m_psSplit[nOut++] = 0; | 
|  | opt.pVal = &m_psSplit[nOut]; | 
|  | break; | 
|  |  | 
|  | case ' ': | 
|  | case '\t': | 
|  | case '\0': | 
|  | m_psSplit[nOut++] = 0; | 
|  | if(opt.pArg || opt.pVal) | 
|  | { | 
|  | // Increase list length if necessary | 
|  | if(m_nOptLen == m_nOptMax) | 
|  | m_nOptMax = m_nOptMax * 2 + 1; | 
|  | SCmdLineOpt* pTmp = (SCmdLineOpt*)realloc(m_pOpt, m_nOptMax * sizeof(*m_pOpt)); | 
|  | if(!pTmp) | 
|  | { | 
|  | FREE(m_pOpt); | 
|  | return; | 
|  | } | 
|  |  | 
|  | m_pOpt = pTmp; | 
|  |  | 
|  | // Add option to list | 
|  | m_pOpt[m_nOptLen++] = opt; | 
|  | opt.pArg = NULL; | 
|  | opt.pVal = NULL; | 
|  | } | 
|  | break; | 
|  |  | 
|  | default: | 
|  | if(!opt.pArg) | 
|  | opt.pArg = &m_psSplit[nOut]; | 
|  |  | 
|  | m_psSplit[nOut++] = m_psOrig[nIn]; | 
|  | break; | 
|  | } | 
|  | } | 
|  | } | 
|  | } while(m_psOrig[nIn]); | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	      Apply the command-line options to shell | 
|  | @param[in]	  shell | 
|  | *************************************************************************/ | 
|  | void PVRShellCommandLine::Apply(PVRShell &shell) | 
|  | { | 
|  | int i; | 
|  | const char *arg, *val; | 
|  |  | 
|  | for(i = 0; i < m_nOptLen; ++i) | 
|  | { | 
|  | arg = m_pOpt[i].pArg; | 
|  | val = m_pOpt[i].pVal; | 
|  |  | 
|  | if(!arg) | 
|  | continue; | 
|  |  | 
|  | if(val) | 
|  | { | 
|  | if(_stricmp(arg, "-width") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefWidth, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-height") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefHeight, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-aasamples") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefAASamples, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-fullscreen") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefFullScreen, (atoi(val) != 0)); | 
|  | } | 
|  | else if(_stricmp(arg, "-sw") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefSoftwareRendering, (atoi(val) != 0)); | 
|  | } | 
|  | else if(_stricmp(arg, "-quitafterframe") == 0 || _stricmp(arg, "-qaf") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefQuitAfterFrame, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-quitaftertime") == 0 || _stricmp(arg, "-qat") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefQuitAfterTime, (float)atof(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-posx") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefPositionX, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-posy") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefPositionY, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-vsync") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefSwapInterval, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-powersaving") == 0 || _stricmp(arg, "-ps") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefPowerSaving, (atoi(val) != 0)); | 
|  | } | 
|  | else if(_stricmp(arg, "-colourbpp") == 0 || _stricmp(arg, "-colorbpp") == 0 ||_stricmp(arg, "-cbpp") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefColorBPP, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-depthbpp") == 0 || _stricmp(arg, "-dbpp") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefDepthBPP, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-rotatekeys") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefRotateKeys, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-c") == 0) | 
|  | { | 
|  | const char* pDash = strchr(val, '-'); | 
|  |  | 
|  | shell.PVRShellSet(prefCaptureFrameStart, atoi(val)); | 
|  |  | 
|  | if(!pDash) | 
|  | shell.PVRShellSet(prefCaptureFrameStop, atoi(val)); | 
|  | else | 
|  | shell.PVRShellSet(prefCaptureFrameStop, atoi(pDash + 1)); | 
|  | } | 
|  | else if(_stricmp(arg, "-screenshotscale") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefCaptureFrameScale, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-priority") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefPriority, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-config") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefRequestedConfig, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-display") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefNativeDisplay, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-forceframetime") == 0 || _stricmp(arg, "-fft") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefForceFrameTime, true); | 
|  | shell.PVRShellSet(prefFrameTimeValue, atoi(val)); | 
|  | } | 
|  | else if(_stricmp(arg, "-discardframeall") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefDiscardColor, (atoi(val) != 0)); | 
|  | shell.PVRShellSet(prefDiscardDepth, (atoi(val) != 0)); | 
|  | shell.PVRShellSet(prefDiscardStencil, (atoi(val) != 0)); | 
|  | } | 
|  | else if(_stricmp(arg, "-discardframecolor") == 0 || _stricmp(arg, "-discardframecolour") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefDiscardColor, (atoi(val) != 0)); | 
|  | } | 
|  | else if(_stricmp(arg, "-discardframedepth") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefDiscardDepth, (atoi(val) != 0)); | 
|  | } | 
|  | else if(_stricmp(arg, "-discardframestencil") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefDiscardStencil, (atoi(val) != 0)); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | if(_stricmp(arg, "-version") == 0) | 
|  | { | 
|  | shell.PVRShellOutputDebug("Version: \"%s\"\n", shell.PVRShellGet(prefVersion)); | 
|  | } | 
|  | #ifdef PVRSHELL_FPS_OUTPUT | 
|  | else if(_stricmp(arg, "-fps") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefOutputFPS, true); | 
|  | } | 
|  | #endif | 
|  | else if(_stricmp(arg, "-info") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefOutputInfo, true); | 
|  | } | 
|  | else if(_stricmp(arg, "-forceframetime") == 0 || _stricmp(arg, "-fft") == 0) | 
|  | { | 
|  | shell.PVRShellSet(prefForceFrameTime, true); | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // @Class  PVRShellInit | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	Constructor | 
|  | *************************************************************************/ | 
|  | PVRShellInit::PVRShellInit() | 
|  | { | 
|  | memset(this, 0, sizeof(*this)); | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	Destructor | 
|  | *************************************************************************/ | 
|  | PVRShellInit::~PVRShellInit() | 
|  | { | 
|  | Deinit(); | 
|  |  | 
|  | delete [] m_pReadPath; | 
|  | m_pReadPath = NULL; | 
|  |  | 
|  | delete [] m_pWritePath; | 
|  | m_pWritePath = NULL; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	     PVRShell deinitialisation. | 
|  | @param[in]	 Shell | 
|  | *************************************************************************/ | 
|  | void PVRShellInit::Deinit() | 
|  | { | 
|  | if(m_pShell) | 
|  | { | 
|  | // Is the App currently running? | 
|  | if(m_eState > ePVRShellInitApp && m_eState < ePVRShellExit) | 
|  | { | 
|  | // If so force it to go through the exit procedure | 
|  | if(m_eState < ePVRShellReleaseView) | 
|  | m_eState = ePVRShellReleaseView; | 
|  |  | 
|  | // Class the App as done | 
|  | gShellDone = true; | 
|  |  | 
|  | // Run through the exiting states | 
|  | while(Run()){}; | 
|  | } | 
|  |  | 
|  | delete m_pShell; | 
|  | m_pShell = 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	    PVRShell Initialisation. | 
|  | @Function	Init | 
|  | @param[in]	Shell | 
|  | @return	True on success and false on failure | 
|  | *************************************************************************/ | 
|  | bool PVRShellInit::Init() | 
|  | { | 
|  | Deinit(); | 
|  |  | 
|  | m_pShell = NewDemo(); | 
|  |  | 
|  | if(!m_pShell) | 
|  | return false; | 
|  |  | 
|  | m_pShell->m_pShellInit	= this; | 
|  |  | 
|  | // set default direction key mappings | 
|  | m_eKeyMapDOWN = PVRShellKeyNameDOWN; | 
|  | m_eKeyMapLEFT = PVRShellKeyNameLEFT; | 
|  | m_eKeyMapUP = PVRShellKeyNameUP; | 
|  | m_eKeyMapRIGHT = PVRShellKeyNameRIGHT; | 
|  | nLastKeyPressed = PVRShellKeyNameNull; | 
|  |  | 
|  | OsInit(); | 
|  |  | 
|  | gShellDone = false; | 
|  | m_eState = ePVRShellInitApp; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	    Receives the command-line from the application. | 
|  | @param[in]	str A string containing the command-line | 
|  | *************************************************************************/ | 
|  | void PVRShellInit::CommandLine(const char *str) | 
|  | { | 
|  | m_CommandLine.Set(str); | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	    Receives the command-line from the application. | 
|  | @param[in]  argc Number of strings in argv | 
|  | @param[in]  argv An array of strings | 
|  | *************************************************************************/ | 
|  | void PVRShellInit::CommandLine(int argc, char **argv) | 
|  | { | 
|  | size_t	tot, len; | 
|  | char	*buf; | 
|  | int		i; | 
|  |  | 
|  | tot = 0; | 
|  | for(i = 0; i < argc; ++i) | 
|  | tot += strlen(argv[i]); | 
|  |  | 
|  | if(!tot) | 
|  | { | 
|  | CommandLine((char*) ""); | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Add room for spaces and the \0 | 
|  | tot += argc; | 
|  |  | 
|  | buf = new char[tot]; | 
|  | tot = 0; | 
|  | for(i = 0; i < argc; ++i) | 
|  | { | 
|  | len = strlen(argv[i]); | 
|  | strncpy(&buf[tot], argv[i], len); | 
|  | tot += len; | 
|  | buf[tot++] = ' '; | 
|  | } | 
|  | buf[tot-1] = 0; | 
|  |  | 
|  | CommandLine(buf); | 
|  |  | 
|  | delete [] buf; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	    Return 'true' if the specific key has been pressed. | 
|  | @param[in]	key   The key we're querying for | 
|  | *************************************************************************/ | 
|  | bool PVRShellInit::DoIsKeyPressed(const PVRShellKeyName key) | 
|  | { | 
|  | if(key == nLastKeyPressed) | 
|  | { | 
|  | nLastKeyPressed = PVRShellKeyNameNull; | 
|  | return true; | 
|  | } | 
|  | else | 
|  | { | 
|  | return false; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	     Used by the OS-specific code to tell the Shell that a key has been pressed. | 
|  | @param[in]  nKey The key that has been pressed | 
|  | *************************************************************************/ | 
|  | void PVRShellInit::KeyPressed(PVRShellKeyName nKey) | 
|  | { | 
|  | nLastKeyPressed = nKey; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	     Used by the OS-specific code to tell the Shell that a touch has began at a location. | 
|  | @param[in]	 vec2Location   The position of a click/touch on the screen when it first touches | 
|  | *************************************************************************/ | 
|  | void PVRShellInit::TouchBegan(const float vec2Location[2]) | 
|  | { | 
|  | m_bTouching = true; | 
|  | m_vec2PointerLocationStart[0] = m_vec2PointerLocation[0] = vec2Location[0]; | 
|  | m_vec2PointerLocationStart[1] = m_vec2PointerLocation[1] = vec2Location[1]; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	     Used by the OS-specific code to tell the Shell that a touch has began at a location. | 
|  | @param[in]	 vec2Location The position of the pointer/touch pressed on the screen | 
|  | *************************************************************************/ | 
|  | void PVRShellInit::TouchMoved(const float vec2Location[2]) | 
|  | { | 
|  | if(m_bTouching) | 
|  | { | 
|  | m_vec2PointerLocation[0] = vec2Location[0]; | 
|  | m_vec2PointerLocation[1] = vec2Location[1]; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	    Used by the OS-specific code to tell the Shell that the current touch has ended at a location. | 
|  | @param[in] vec2Location The position of the pointer/touch on the screen when it is released | 
|  | *************************************************************************/ | 
|  | void PVRShellInit::TouchEnded(const float vec2Location[2]) | 
|  | { | 
|  | if(m_bTouching) | 
|  | { | 
|  | m_bTouching = false; | 
|  | m_vec2PointerLocationEnd[0] = m_vec2PointerLocation[0] = vec2Location[0]; | 
|  | m_vec2PointerLocationEnd[1] = m_vec2PointerLocation[1] = vec2Location[1]; | 
|  |  | 
|  | #if !defined(DISABLE_SWIPE_MAPPING) | 
|  | float fX = m_vec2PointerLocationEnd[0] - m_vec2PointerLocationStart[0]; | 
|  | float fY = m_vec2PointerLocationEnd[1] - m_vec2PointerLocationStart[1]; | 
|  | float fTmp = fX * fX + fY * fY; | 
|  |  | 
|  | if(fTmp > 0.005f) | 
|  | { | 
|  | fTmp = 1.0f / sqrt(fTmp); | 
|  | fY *= fTmp; | 
|  | float fAngle = acos(fY); | 
|  |  | 
|  | const float pi = 3.1415f; | 
|  | const float pi_half = pi * 0.5f; | 
|  | const float error = 0.25f; | 
|  |  | 
|  | if(fAngle < error) | 
|  | KeyPressed(m_eKeyMapDOWN); | 
|  | else if(fAngle > (pi - error)) | 
|  | KeyPressed(m_eKeyMapUP); | 
|  | else if(fAngle > (pi_half - error) && fAngle < (pi_half + error)) | 
|  | KeyPressed((fX < 0) ? m_eKeyMapLEFT : m_eKeyMapRIGHT); | 
|  | } | 
|  | else if(fTmp < 0.09f) | 
|  | { | 
|  | if (m_vec2PointerLocationEnd[0] <= 0.3f) // Left half of the screen | 
|  | KeyPressed(PVRShellKeyNameACTION1); | 
|  | else if (m_vec2PointerLocationEnd[0] >= 0.7f) // Right half of the screen | 
|  | KeyPressed(PVRShellKeyNameACTION2); | 
|  | } | 
|  | #endif | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	  Used by the OS-specific code to tell the Shell where to read external files from | 
|  | @return  A path the application is capable of reading from | 
|  | *************************************************************************/ | 
|  | const char* PVRShellInit::GetReadPath() const | 
|  | { | 
|  | return m_pReadPath; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	   Used by the OS-specific code to tell the Shell where to write to | 
|  | @return   A path the applications is capable of writing to | 
|  | *************************************************************************/ | 
|  | const char* PVRShellInit::GetWritePath() const | 
|  | { | 
|  | return m_pWritePath; | 
|  | } | 
|  |  | 
|  | /*!**************************************************************************** | 
|  | @brief     Sets the default app name (to be displayed by the OS) | 
|  | @param[in]	str   The application name | 
|  | *******************************************************************************/ | 
|  | void PVRShellInit::SetAppName(const char * const str) | 
|  | { | 
|  | const char *pName = strrchr(str, PVRSHELL_DIR_SYM); | 
|  |  | 
|  | if(pName) | 
|  | { | 
|  | ++pName; | 
|  | } | 
|  | else | 
|  | { | 
|  | pName = str; | 
|  | } | 
|  | m_pShell->PVRShellSet(prefAppName, pName); | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	     Set the path to where the application expects to read from. | 
|  | @param[in]  str   The read path | 
|  | *************************************************************************/ | 
|  | void PVRShellInit::SetReadPath(const char * const str) | 
|  | { | 
|  | m_pReadPath = new char[strlen(str)+1]; | 
|  |  | 
|  | if(m_pReadPath) | 
|  | { | 
|  | strcpy(m_pReadPath, str); | 
|  | char* lastSlash = strrchr(m_pReadPath, PVRSHELL_DIR_SYM); | 
|  |  | 
|  | if(lastSlash) | 
|  | lastSlash[1] = 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief     Set the path to where the application expects to write to. | 
|  | @param[in] str   The write path | 
|  | *************************************************************************/ | 
|  | void PVRShellInit::SetWritePath(const char * const str) | 
|  | { | 
|  | m_pWritePath = new char[strlen(str)+1]; | 
|  |  | 
|  | if(m_pWritePath) | 
|  | { | 
|  | strcpy(m_pWritePath, str); | 
|  | char* lastSlash = strrchr(m_pWritePath, PVRSHELL_DIR_SYM); | 
|  |  | 
|  | if(lastSlash) | 
|  | lastSlash[1] = 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | #ifdef PVRSHELL_FPS_OUTPUT | 
|  | /***************************************************************************** | 
|  | @fn       FpsUpdate | 
|  | @brief    Calculates a value for frames-per-second (FPS). | 
|  | @details  This is only compiled in to the application if PVRSHELL_FPS_OUTPUT is defined. | 
|  | *****************************************************************************/ | 
|  | void PVRShellInit::FpsUpdate() | 
|  | { | 
|  | unsigned int ui32TimeDelta, ui32Time; | 
|  |  | 
|  | ui32Time = m_pShell->PVRShellGetTime(); | 
|  | ++m_i32FpsFrameCnt; | 
|  | ui32TimeDelta = ui32Time - m_i32FpsTimePrev; | 
|  |  | 
|  | if(ui32TimeDelta >= 1000) | 
|  | { | 
|  | float fFPS = 1000.0f * (float) m_i32FpsFrameCnt / (float) ui32TimeDelta; | 
|  |  | 
|  | m_pShell->PVRShellOutputDebug("PVRShell: frame %d, FPS %.1f.\n", | 
|  | m_pShell->m_pShellData->nShellCurFrameNum, fFPS); | 
|  |  | 
|  | m_i32FpsFrameCnt = 0; | 
|  | m_i32FpsTimePrev = ui32Time; | 
|  | } | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /***************************************************************************** | 
|  | @brief    Main message loop / render loop | 
|  | @return   false when the app should quit | 
|  | *****************************************************************************/ | 
|  | bool PVRShellInit::Run() | 
|  | { | 
|  | static unsigned long StartTime = 0; | 
|  |  | 
|  | switch(m_eState) | 
|  | { | 
|  | case ePVRShellInitApp: | 
|  | { | 
|  | // Make sure the shell isn't done | 
|  | gShellDone = false; | 
|  |  | 
|  | // Prepend command-line options from PVRShellCL.txt | 
|  | const char * const pCL = "PVRShellCL.txt"; | 
|  | const char *pPath = (const char*) m_pShell->PVRShellGet(prefReadPath); | 
|  | size_t nSize = strlen(pPath) + strlen(pCL) + 1; | 
|  | char *pString = new char[nSize]; | 
|  |  | 
|  | if(pString) | 
|  | { | 
|  | snprintf(pString, nSize, "%s%s", pPath, pCL); | 
|  |  | 
|  | if(!m_CommandLine.PrefixFromFile(pString)) | 
|  | { | 
|  | delete[] pString; | 
|  | pPath = (const char*) m_pShell->PVRShellGet(prefWritePath); | 
|  | nSize = strlen(pPath) + strlen(pCL) + 1; | 
|  | pString = new char[nSize]; | 
|  |  | 
|  | snprintf(pString, nSize, "%s%s", pPath, pCL); | 
|  |  | 
|  | if(m_CommandLine.PrefixFromFile(pString)) | 
|  | m_pShell->PVRShellOutputDebug("Loaded command-line options from %s.\n", pString); | 
|  | } | 
|  | else | 
|  | m_pShell->PVRShellOutputDebug("Loaded command-line options from %s.\n", pString); | 
|  |  | 
|  | delete[] pString; | 
|  | } | 
|  |  | 
|  | // Parse the command-line | 
|  | m_CommandLine.Parse(); | 
|  |  | 
|  | #if defined(_DEBUG) | 
|  | m_pShell->PVRShellOutputDebug("PVRShell command line: %d/%d\n", m_CommandLine.m_nOptLen, m_CommandLine.m_nOptMax); | 
|  | for(int i = 0; i < m_CommandLine.m_nOptLen; ++i) | 
|  | { | 
|  | m_pShell->PVRShellOutputDebug("CL %d: \"%s\"\t= \"%s\".\n", i, | 
|  | m_CommandLine.m_pOpt[i].pArg ? m_CommandLine.m_pOpt[i].pArg : "", | 
|  | m_CommandLine.m_pOpt[i].pVal ? m_CommandLine.m_pOpt[i].pVal : ""); | 
|  | } | 
|  | #endif | 
|  | // Call InitApplication | 
|  | if(!m_pShell->InitApplication()) | 
|  | { | 
|  | m_eState = ePVRShellExit; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | m_eState = ePVRShellInitInstance; | 
|  | return true; | 
|  | } | 
|  | case ePVRShellInitInstance: | 
|  | { | 
|  | m_CommandLine.Apply(*m_pShell); | 
|  |  | 
|  | // Output non-api specific data if required | 
|  | OutputInfo(); | 
|  |  | 
|  | // Perform OS initialisation | 
|  | if(!OsInitOS()) | 
|  | { | 
|  | m_pShell->PVRShellOutputDebug("InitOS failed!\n"); | 
|  | m_eState = ePVRShellQuitApp; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Initialize the 3D API | 
|  | if(!OsDoInitAPI()) | 
|  | { | 
|  | m_pShell->PVRShellOutputDebug("InitAPI failed!\n"); | 
|  | m_eState = ePVRShellReleaseOS; | 
|  | gShellDone = true; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | // Output api specific data if required | 
|  | OutputAPIInfo(); | 
|  |  | 
|  | // Initialise the app | 
|  | if(!m_pShell->InitView()) | 
|  | { | 
|  | m_pShell->PVRShellOutputDebug("InitView failed!\n"); | 
|  | m_eState = ePVRShellReleaseAPI; | 
|  | gShellDone = true; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | if(StartTime==0) | 
|  | { | 
|  | StartTime = OsGetTime(); | 
|  | } | 
|  |  | 
|  | m_eState = ePVRShellRender; | 
|  | return true; | 
|  | } | 
|  | case ePVRShellRender: | 
|  | { | 
|  | // Main message loop: | 
|  | if(!m_pShell->RenderScene()) | 
|  | break; | 
|  |  | 
|  | ApiRenderComplete(); | 
|  | OsRenderComplete(); | 
|  |  | 
|  | #ifdef PVRSHELL_FPS_OUTPUT | 
|  | if(m_pShell->m_pShellData->bOutputFPS) | 
|  | FpsUpdate(); | 
|  | #endif | 
|  | int nCurrentFrame = m_pShell->m_pShellData->nShellCurFrameNum; | 
|  |  | 
|  | if(DoIsKeyPressed(PVRShellKeyNameScreenshot) || (nCurrentFrame >= m_pShell->m_pShellData->nCaptureFrameStart && nCurrentFrame <= m_pShell->m_pShellData->nCaptureFrameStop)) | 
|  | { | 
|  | unsigned char *pBuf; | 
|  | const int nWidth = m_pShell->PVRShellGet(prefWidth); | 
|  | const int nHeight = m_pShell->PVRShellGet(prefHeight); | 
|  | if(m_pShell->PVRShellScreenCaptureBuffer(nWidth, nHeight, &pBuf)) | 
|  | { | 
|  | if(m_pShell->PVRShellScreenSave(PVRSHELL_SCREENSHOT_NAME, nWidth, nHeight, pBuf, m_pShell->m_pShellData->nCaptureFrameScale) != 0) | 
|  | { | 
|  | m_pShell->PVRShellSet(prefExitMessage, "Screen-shot save failed.\n"); | 
|  | } | 
|  | } | 
|  | else | 
|  | { | 
|  | m_pShell->PVRShellSet(prefExitMessage, "Screen capture failed.\n"); | 
|  | } | 
|  | FREE(pBuf); | 
|  | } | 
|  |  | 
|  | if(DoIsKeyPressed(PVRShellKeyNameQUIT)) | 
|  | gShellDone = true; | 
|  |  | 
|  | if(gShellDone) | 
|  | break; | 
|  |  | 
|  | /* Quit if maximum number of allowed frames is reached */ | 
|  | if((m_pShell->m_pShellData->nDieAfterFrames>=0) && (nCurrentFrame >= m_pShell->m_pShellData->nDieAfterFrames)) | 
|  | break; | 
|  |  | 
|  | /* Quit if maximum time is reached */ | 
|  | if((m_pShell->m_pShellData->fDieAfterTime>=0.0f) && (((OsGetTime()-StartTime)*0.001f) >= m_pShell->m_pShellData->fDieAfterTime)) | 
|  | break; | 
|  |  | 
|  | m_pShell->m_pShellData->nShellCurFrameNum++; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | case ePVRShellReleaseView: | 
|  | m_pShell->ReleaseView(); | 
|  |  | 
|  | case ePVRShellReleaseAPI: | 
|  | OsDoReleaseAPI(); | 
|  |  | 
|  | case ePVRShellReleaseOS: | 
|  | OsReleaseOS(); | 
|  |  | 
|  | if(!gShellDone && m_pShell->m_pShellData->nInitRepeats) | 
|  | { | 
|  | --m_pShell->m_pShellData->nInitRepeats; | 
|  | m_eState = ePVRShellInitInstance; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | m_eState = ePVRShellQuitApp; | 
|  | return true; | 
|  |  | 
|  | case ePVRShellQuitApp: | 
|  | // Final app tidy-up | 
|  | m_pShell->QuitApplication(); | 
|  | m_eState = ePVRShellExit; | 
|  |  | 
|  | case ePVRShellExit: | 
|  | OsExit(); | 
|  | StringCopy(m_pShell->m_pShellData->pszAppName, 0); | 
|  | StringCopy(m_pShell->m_pShellData->pszExitMessage, 0); | 
|  | return false; | 
|  | } | 
|  |  | 
|  | m_eState = (EPVRShellState)(m_eState + 1); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /*!*********************************************************************** | 
|  | @brief	When prefOutputInfo is set to true this function outputs | 
|  | various pieces of non-API dependent information via | 
|  | PVRShellOutputDebug. | 
|  | *************************************************************************/ | 
|  | void PVRShellInit::OutputInfo() | 
|  | { | 
|  | if(m_pShell->PVRShellGet(prefOutputInfo)) | 
|  | { | 
|  | m_pShell->PVRShellOutputDebug("\n"); | 
|  | m_pShell->PVRShellOutputDebug("App name: %s\n"     , m_pShell->PVRShellGet(prefAppName)); | 
|  | m_pShell->PVRShellOutputDebug("SDK version: %s\n"  , m_pShell->PVRShellGet(prefVersion)); | 
|  | m_pShell->PVRShellOutputDebug("\n"); | 
|  | m_pShell->PVRShellOutputDebug("Read path:  %s\n"    , m_pShell->PVRShellGet(prefReadPath)); | 
|  | m_pShell->PVRShellOutputDebug("Write path: %s\n"   , m_pShell->PVRShellGet(prefWritePath)); | 
|  | m_pShell->PVRShellOutputDebug("\n"); | 
|  | m_pShell->PVRShellOutputDebug("Command-line: %s\n" , m_pShell->PVRShellGet(prefCommandLine)); | 
|  | m_pShell->PVRShellOutputDebug("\n"); | 
|  | m_pShell->PVRShellOutputDebug("Power saving: %s\n" , m_pShell->PVRShellGet(prefPowerSaving) ? "On" : "Off"); | 
|  | m_pShell->PVRShellOutputDebug("AA Samples requested: %i\n", m_pShell->PVRShellGet(prefAASamples)); | 
|  | m_pShell->PVRShellOutputDebug("Fullscreen: %s\n", m_pShell->PVRShellGet(prefFullScreen) ? "Yes" : "No"); | 
|  | m_pShell->PVRShellOutputDebug("PBuffer requested: %s\n", m_pShell->PVRShellGet(prefPBufferContext) ? "Yes" : "No"); | 
|  | m_pShell->PVRShellOutputDebug("ZBuffer requested: %s\n", m_pShell->PVRShellGet(prefZbufferContext) ? "Yes" : "No"); | 
|  | m_pShell->PVRShellOutputDebug("Stencil buffer requested: %s\n", m_pShell->PVRShellGet(prefStencilBufferContext) ? "Yes" : "No"); | 
|  |  | 
|  | if(m_pShell->PVRShellGet(prefColorBPP) > 0) | 
|  | m_pShell->PVRShellOutputDebug("Colour buffer size requested: %i\n", m_pShell->PVRShellGet(prefColorBPP)); | 
|  | if(m_pShell->PVRShellGet(prefDepthBPP) > 0) | 
|  | m_pShell->PVRShellOutputDebug("Depth buffer size requested: %i\n", m_pShell->PVRShellGet(prefDepthBPP)); | 
|  |  | 
|  | m_pShell->PVRShellOutputDebug("Software rendering requested: %s\n", m_pShell->PVRShellGet(prefSoftwareRendering) ? "Yes" : "No"); | 
|  | m_pShell->PVRShellOutputDebug("Swap Interval requested: %i\n", m_pShell->PVRShellGet(prefSwapInterval)); | 
|  |  | 
|  | if(m_pShell->PVRShellGet(prefInitRepeats) > 0) | 
|  | m_pShell->PVRShellOutputDebug("No of Init repeats: %i\n", m_pShell->PVRShellGet(prefInitRepeats)); | 
|  |  | 
|  | if(m_pShell->PVRShellGet(prefQuitAfterFrame) != -1) | 
|  | m_pShell->PVRShellOutputDebug("Quit after frame:   %i\n", m_pShell->PVRShellGet(prefQuitAfterFrame)); | 
|  |  | 
|  | if(m_pShell->PVRShellGet(prefQuitAfterTime)  != -1.0f) | 
|  | m_pShell->PVRShellOutputDebug("Quit after time:    %f\n", m_pShell->PVRShellGet(prefQuitAfterTime)); | 
|  | } | 
|  | } | 
|  |  | 
|  | /**************************************************************************** | 
|  | ** Local code | 
|  | ****************************************************************************/ | 
|  | /*!*********************************************************************** | 
|  | @brief	      This function copies pszSrc into pszStr. | 
|  | @param[out]  pszStr   The string to copy pszSrc into | 
|  | @param[in]	  pszSrc   The source string to copy | 
|  | *************************************************************************/ | 
|  | static bool StringCopy(char *&pszStr, const char * const pszSrc) | 
|  | { | 
|  | size_t len; | 
|  |  | 
|  | FREE(pszStr); | 
|  |  | 
|  | if(!pszSrc) | 
|  | return true; | 
|  |  | 
|  | len = strlen(pszSrc)+1; | 
|  | pszStr = (char*)malloc(len); | 
|  | if(!pszStr) | 
|  | return false; | 
|  |  | 
|  | strcpy(pszStr, pszSrc); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /// @endcond | 
|  | //NO_DOXYGEN | 
|  |  | 
|  | /***************************************************************************** | 
|  | End of file (PVRShell.cpp) | 
|  | *****************************************************************************/ | 
|  |  |