| /****************************************************************************** | 
 |  | 
 |  @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) | 
 | *****************************************************************************/ | 
 |  |