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