PVRShell.cpp 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679
  1. /******************************************************************************
  2. @File PVRShell.cpp
  3. @Title PVRShell
  4. @Version
  5. @Copyright Copyright (C) Imagination Technologies Limited.
  6. @Platform Independent
  7. @Description Makes programming for 3D APIs easier by wrapping surface
  8. initialization, Texture allocation and other functions for use by a demo.
  9. ******************************************************************************/
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <stdarg.h>
  14. #include "PVRShell.h"
  15. #include "PVRShellOS.h"
  16. #include "PVRShellAPI.h"
  17. #include "PVRShellImpl.h"
  18. /*! This file simply defines a version string. It can be commented out. */
  19. #include "../Builds/sdkver.h"
  20. #ifndef PVRSDK_VERSION
  21. #define PVRSDK_VERSION "n.nn.nn.nnnn"
  22. #endif
  23. /*! Define to automatically stop the app after x frames. If negative, run forever. */
  24. #ifndef PVRSHELL_QUIT_AFTER_FRAME
  25. #define PVRSHELL_QUIT_AFTER_FRAME -1
  26. #endif
  27. /*! Define to automatically stop the app after x amount of seconds. If negative, run forever. */
  28. #ifndef PVRSHELL_QUIT_AFTER_TIME
  29. #define PVRSHELL_QUIT_AFTER_TIME -1
  30. #endif
  31. /*! Define for the screen shot file name. */
  32. #define PVRSHELL_SCREENSHOT_NAME "PVRShell"
  33. #if defined(_WIN32) && !defined(__BADA__)
  34. #define snprintf _snprintf
  35. #endif
  36. /*****************************************************************************
  37. ** Prototypes
  38. *****************************************************************************/
  39. static bool StringCopy(char *&pszStr, const char * const pszSrc);
  40. /****************************************************************************
  41. ** Class: PVRShell
  42. ****************************************************************************/
  43. /*!***********************************************************************
  44. @Function PVRShell
  45. @Description Constructor
  46. *************************************************************************/
  47. PVRShell::PVRShell()
  48. {
  49. m_pShellInit = NULL;
  50. m_pShellData = new PVRShellData;
  51. m_pShellData->nShellPosX=0;
  52. m_pShellData->nShellPosY=0;
  53. m_pShellData->bFullScreen=false; // note this may be overriden by some OS versions of PVRShell
  54. m_pShellData->nFSAAMode=0;
  55. m_pShellData->nColorBPP = 0;
  56. m_pShellData->nDepthBPP = 0;
  57. m_pShellData->nDieAfterFrames=PVRSHELL_QUIT_AFTER_FRAME;
  58. m_pShellData->fDieAfterTime=PVRSHELL_QUIT_AFTER_TIME;
  59. m_pShellData->bNeedPbuffer = false;
  60. m_pShellData->bNeedPixmap = false;
  61. m_pShellData->bNeedPixmapDisableCopy = false;
  62. m_pShellData->bNeedZbuffer = true;
  63. m_pShellData->bLockableBackBuffer = false;
  64. m_pShellData->bSoftwareRender = false;
  65. m_pShellData->bNeedStencilBuffer = false;
  66. m_pShellData->bNeedOpenVG = false;
  67. m_pShellData->bNeedAlphaFormatPre = false;
  68. m_pShellData->bUsingPowerSaving = true;
  69. m_pShellData->bOutputInfo = false;
  70. m_pShellData->bNoShellSwapBuffer = false;
  71. m_pShellData->pszAppName = 0;
  72. m_pShellData->pszExitMessage = 0;
  73. m_pShellData->nSwapInterval = 1;
  74. m_pShellData->nInitRepeats = 0;
  75. m_pShellData->nCaptureFrameStart = -1;
  76. m_pShellData->nCaptureFrameStop = -1;
  77. m_pShellData->nPriority = 2;
  78. // Internal Data
  79. m_pShellData->bShellPosWasDefault = true;
  80. m_pShellData->nShellCurFrameNum = 0;
  81. #ifdef PVRSHELL_FPS_OUTPUT
  82. m_pShellData->bOutputFPS = false;
  83. #endif
  84. }
  85. /*!***********************************************************************
  86. @Function ~PVRShell
  87. @Description Destructor
  88. *************************************************************************/
  89. PVRShell::~PVRShell()
  90. {
  91. delete m_pShellData;
  92. m_pShellData = NULL;
  93. }
  94. // Allow user to set preferences from within InitApplication
  95. /*!***********************************************************************
  96. @Function PVRShellSet
  97. @Input prefName Name of preference to set to value
  98. @Input value Value
  99. @Return true for success
  100. @Description This function is used to pass preferences to the PVRShell.
  101. If used, it must be called from InitApplication().
  102. *************************************************************************/
  103. bool PVRShell::PVRShellSet(const prefNameBoolEnum prefName, const bool value)
  104. {
  105. switch(prefName)
  106. {
  107. case prefFullScreen:
  108. m_pShellData->bFullScreen = value;
  109. return true;
  110. case prefPBufferContext:
  111. m_pShellData->bNeedPbuffer = value;
  112. return true;
  113. case prefPixmapContext:
  114. m_pShellData->bNeedPixmap = value;
  115. return true;
  116. case prefPixmapDisableCopy:
  117. m_pShellData->bNeedPixmapDisableCopy = value;
  118. return true;
  119. case prefZbufferContext:
  120. m_pShellData->bNeedZbuffer = value;
  121. return true;
  122. case prefLockableBackBuffer:
  123. m_pShellData->bLockableBackBuffer = value;
  124. return true;
  125. case prefSoftwareRendering:
  126. m_pShellData->bSoftwareRender = value;
  127. return true;
  128. case prefStencilBufferContext:
  129. m_pShellData->bNeedStencilBuffer = value;
  130. return true;
  131. case prefOpenVGContext:
  132. m_pShellData->bNeedOpenVG = value;
  133. return true;
  134. case prefAlphaFormatPre:
  135. m_pShellData->bNeedAlphaFormatPre = value;
  136. return true;
  137. case prefPowerSaving:
  138. m_pShellData->bUsingPowerSaving = value;
  139. return true;
  140. case prefOutputInfo:
  141. m_pShellData->bOutputInfo = value;
  142. return true;
  143. case prefNoShellSwapBuffer:
  144. m_pShellData->bNoShellSwapBuffer = value;
  145. return true;
  146. #ifdef PVRSHELL_FPS_OUTPUT
  147. case prefOutputFPS:
  148. m_pShellData->bOutputFPS = value;
  149. return true;
  150. #endif
  151. default:
  152. break;
  153. }
  154. return false;
  155. }
  156. /*!***********************************************************************
  157. @Function PVRShellGet
  158. @Input prefName Name of preference to set to value
  159. @Return Value asked for.
  160. @Description This function is used to get parameters from the PVRShell
  161. It can be called from any where in the program.
  162. *************************************************************************/
  163. bool PVRShell::PVRShellGet(const prefNameBoolEnum prefName) const
  164. {
  165. switch(prefName)
  166. {
  167. case prefFullScreen: return m_pShellData->bFullScreen;
  168. case prefIsRotated: return (m_pShellData->nShellDimY > m_pShellData->nShellDimX);
  169. case prefPBufferContext: return m_pShellData->bNeedPbuffer;
  170. case prefPixmapContext: return m_pShellData->bNeedPixmap;
  171. case prefPixmapDisableCopy: return m_pShellData->bNeedPixmapDisableCopy;
  172. case prefZbufferContext: return m_pShellData->bNeedZbuffer;
  173. case prefLockableBackBuffer: return m_pShellData->bLockableBackBuffer;
  174. case prefSoftwareRendering: return m_pShellData->bSoftwareRender;
  175. case prefNoShellSwapBuffer: return m_pShellData->bNoShellSwapBuffer;
  176. case prefStencilBufferContext: return m_pShellData->bNeedStencilBuffer;
  177. case prefOpenVGContext: return m_pShellData->bNeedOpenVG;
  178. case prefAlphaFormatPre: return m_pShellData->bNeedAlphaFormatPre;
  179. case prefPowerSaving: return m_pShellData->bUsingPowerSaving;
  180. case prefOutputInfo: return m_pShellData->bOutputInfo;
  181. #ifdef PVRSHELL_FPS_OUTPUT
  182. case prefOutputFPS: return m_pShellData->bOutputFPS;
  183. #endif
  184. default: return false;
  185. }
  186. }
  187. /*!***********************************************************************
  188. @Function PVRShellSet
  189. @Input prefName Name of preference to set to value
  190. @Input value Value
  191. @Return true for success
  192. @Description This function is used to pass preferences to the PVRShell.
  193. If used, it must be called from InitApplication().
  194. *************************************************************************/
  195. bool PVRShell::PVRShellSet(const prefNameFloatEnum prefName, const float value)
  196. {
  197. switch(prefName)
  198. {
  199. case prefQuitAfterTime:
  200. m_pShellData->fDieAfterTime = value;
  201. return true;
  202. default:
  203. break;
  204. }
  205. return false;
  206. }
  207. /*!***********************************************************************
  208. @Function PVRShellGet
  209. @Input prefName Name of preference to set to value
  210. @Return Value asked for.
  211. @Description This function is used to get parameters from the PVRShell
  212. It can be called from any where in the program.
  213. *************************************************************************/
  214. float PVRShell::PVRShellGet(const prefNameFloatEnum prefName) const
  215. {
  216. switch(prefName)
  217. {
  218. case prefQuitAfterTime: return m_pShellData->fDieAfterTime;
  219. default: return -1;
  220. }
  221. }
  222. /*!***********************************************************************
  223. @Function PVRShellSet
  224. @Input prefName Name of preference to set to value
  225. @Input value Value
  226. @Return true for success
  227. @Description This function is used to pass preferences to the PVRShell.
  228. If used, it must be called from InitApplication().
  229. *************************************************************************/
  230. bool PVRShell::PVRShellSet(const prefNameIntEnum prefName, const int value)
  231. {
  232. switch(prefName)
  233. {
  234. case prefWidth:
  235. if(value > 0)
  236. {
  237. m_pShellData->nShellDimX = value;
  238. return true;
  239. }
  240. return false;
  241. case prefHeight:
  242. if(value > 0)
  243. {
  244. m_pShellData->nShellDimY = value;
  245. return true;
  246. }
  247. return false;
  248. case prefPositionX:
  249. m_pShellData->bShellPosWasDefault = false;
  250. m_pShellData->nShellPosX = value;
  251. return true;
  252. case prefPositionY:
  253. m_pShellData->bShellPosWasDefault = false;
  254. m_pShellData->nShellPosY = value;
  255. return true;
  256. case prefQuitAfterFrame:
  257. m_pShellData->nDieAfterFrames = value;
  258. return true;
  259. case prefInitRepeats:
  260. m_pShellData->nInitRepeats = value;
  261. return true;
  262. case prefFSAAMode:
  263. if(value >= 0 && value <= 2)
  264. {
  265. m_pShellData->nFSAAMode = value;
  266. return true;
  267. }
  268. return false;
  269. case prefColorBPP:
  270. if(value >= 0)
  271. {
  272. m_pShellData->nColorBPP = value;
  273. return true;
  274. }
  275. return false;
  276. case prefDepthBPP:
  277. if(value >= 0)
  278. {
  279. m_pShellData->nDepthBPP = value;
  280. return true;
  281. }
  282. return false;
  283. case prefRotateKeys:
  284. {
  285. switch((PVRShellKeyRotate)value)
  286. {
  287. case PVRShellKeyRotateNone:
  288. m_pShellInit->m_eKeyMapUP = PVRShellKeyNameUP;
  289. m_pShellInit->m_eKeyMapLEFT = PVRShellKeyNameLEFT;
  290. m_pShellInit->m_eKeyMapDOWN = PVRShellKeyNameDOWN;
  291. m_pShellInit->m_eKeyMapRIGHT = PVRShellKeyNameRIGHT;
  292. break;
  293. case PVRShellKeyRotate90:
  294. m_pShellInit->m_eKeyMapUP = PVRShellKeyNameLEFT;
  295. m_pShellInit->m_eKeyMapLEFT = PVRShellKeyNameDOWN;
  296. m_pShellInit->m_eKeyMapDOWN = PVRShellKeyNameRIGHT;
  297. m_pShellInit->m_eKeyMapRIGHT = PVRShellKeyNameUP;
  298. break;
  299. case PVRShellKeyRotate180:
  300. m_pShellInit->m_eKeyMapUP = PVRShellKeyNameDOWN;
  301. m_pShellInit->m_eKeyMapLEFT = PVRShellKeyNameRIGHT;
  302. m_pShellInit->m_eKeyMapDOWN = PVRShellKeyNameUP;
  303. m_pShellInit->m_eKeyMapRIGHT = PVRShellKeyNameLEFT;
  304. break;
  305. case PVRShellKeyRotate270:
  306. m_pShellInit->m_eKeyMapUP = PVRShellKeyNameRIGHT;
  307. m_pShellInit->m_eKeyMapLEFT = PVRShellKeyNameUP;
  308. m_pShellInit->m_eKeyMapDOWN = PVRShellKeyNameLEFT;
  309. m_pShellInit->m_eKeyMapRIGHT = PVRShellKeyNameDOWN;
  310. break;
  311. default:
  312. return false;
  313. }
  314. }
  315. return true;
  316. case prefCaptureFrameStart:
  317. m_pShellData->nCaptureFrameStart = value;
  318. return true;
  319. case prefCaptureFrameStop:
  320. m_pShellData->nCaptureFrameStop = value;
  321. return true;
  322. default:
  323. {
  324. if(m_pShellInit->ApiSet(prefName, value))
  325. return true;
  326. return m_pShellInit->OsSet(prefName, value);
  327. }
  328. }
  329. }
  330. /*!***********************************************************************
  331. @Function PVRShellGet
  332. @Input prefName Name of preference to return the value of
  333. @Return Value asked for.
  334. @Description This function is used to get parameters from the PVRShell
  335. It can be called from any where in the program.
  336. *************************************************************************/
  337. int PVRShell::PVRShellGet(const prefNameIntEnum prefName) const
  338. {
  339. switch(prefName)
  340. {
  341. case prefWidth: return m_pShellData->nShellDimX;
  342. case prefHeight: return m_pShellData->nShellDimY;
  343. case prefPositionX: return m_pShellData->nShellPosX;
  344. case prefPositionY: return m_pShellData->nShellPosY;
  345. case prefQuitAfterFrame: return m_pShellData->nDieAfterFrames;
  346. case prefSwapInterval: return m_pShellData->nSwapInterval;
  347. case prefInitRepeats: return m_pShellData->nInitRepeats;
  348. case prefFSAAMode: return m_pShellData->nFSAAMode;
  349. case prefCommandLineOptNum: return m_pShellInit->m_CommandLine.m_nOptLen;
  350. case prefColorBPP: return m_pShellData->nColorBPP;
  351. case prefDepthBPP: return m_pShellData->nDepthBPP;
  352. case prefCaptureFrameStart: return m_pShellData->nCaptureFrameStart;
  353. case prefCaptureFrameStop: return m_pShellData->nCaptureFrameStop;
  354. case prefPriority: return m_pShellData->nPriority;
  355. default:
  356. {
  357. int n;
  358. if(m_pShellInit->ApiGet(prefName, &n))
  359. return n;
  360. if(m_pShellInit->OsGet(prefName, &n))
  361. return n;
  362. return -1;
  363. }
  364. }
  365. }
  366. /*!***********************************************************************
  367. @Function PVRShellSet
  368. @Input prefName Name of preference to set to value
  369. @Input ptrValue Value
  370. @Return true for success
  371. @Description This function is used to pass preferences to the PVRShell.
  372. If used, it must be called from InitApplication().
  373. *************************************************************************/
  374. bool PVRShell::PVRShellSet(const prefNamePtrEnum prefName, const void * const ptrValue)
  375. {
  376. PVRSHELL_UNREFERENCED_PARAMETER(prefName);
  377. PVRSHELL_UNREFERENCED_PARAMETER(ptrValue);
  378. return false;
  379. }
  380. /*!***********************************************************************
  381. @Function PVRShellGet
  382. @Input prefName Name of preference to set to value
  383. @Return Value asked for.
  384. @Description This function is used to get parameters from the PVRShell
  385. It can be called from any where in the program.
  386. *************************************************************************/
  387. void *PVRShell::PVRShellGet(const prefNamePtrEnum prefName) const
  388. {
  389. switch(prefName)
  390. {
  391. case prefNativeWindowType: return m_pShellInit->OsGetNativeWindowType();
  392. default:
  393. {
  394. void *p;
  395. if(m_pShellInit->ApiGet(prefName, &p))
  396. return p;
  397. if(m_pShellInit->OsGet(prefName, &p))
  398. return p;
  399. return NULL;
  400. }
  401. }
  402. }
  403. /*!***********************************************************************
  404. @Function PVRShellSet
  405. @Input prefName Name of preference to set to value
  406. @Input ptrValue Value
  407. @Return true for success
  408. @Description This function is used to pass preferences to the PVRShell.
  409. If used, it must be called from InitApplication().
  410. *************************************************************************/
  411. bool PVRShell::PVRShellSet(const prefNameConstPtrEnum prefName, const void * const ptrValue)
  412. {
  413. switch(prefName)
  414. {
  415. case prefAppName:
  416. StringCopy(m_pShellData->pszAppName, (char*)ptrValue);
  417. return true;
  418. case prefExitMessage:
  419. StringCopy(m_pShellData->pszExitMessage, (char*)ptrValue);
  420. PVRShellOutputDebug("Exit message has been set to: \"%s\".\n", ptrValue);
  421. return true;
  422. default:
  423. break;
  424. }
  425. return false;
  426. }
  427. /*!***********************************************************************
  428. @Function PVRShellGet
  429. @Input prefName Name of preference to set to value
  430. @Return Value asked for.
  431. @Description This function is used to get parameters from the PVRShell
  432. It can be called from any where in the program.
  433. *************************************************************************/
  434. const void *PVRShell::PVRShellGet(const prefNameConstPtrEnum prefName) const
  435. {
  436. switch(prefName)
  437. {
  438. case prefAppName:
  439. return m_pShellData->pszAppName;
  440. case prefExitMessage:
  441. return m_pShellData->pszExitMessage;
  442. case prefReadPath:
  443. return m_pShellInit->GetReadPath();
  444. case prefWritePath:
  445. return m_pShellInit->GetWritePath();
  446. case prefCommandLine:
  447. return m_pShellInit->m_CommandLine.m_psOrig;
  448. case prefCommandLineOpts:
  449. return m_pShellInit->m_CommandLine.m_pOpt;
  450. case prefVersion:
  451. return PVRSDK_VERSION;
  452. default:
  453. return 0;
  454. }
  455. }
  456. /*!***********************************************************************
  457. @Function PVRShellScreenCaptureBuffer
  458. @Input Width size of image to capture (relative to 0,0)
  459. @Input Height size of image to capture (relative to 0,0)
  460. @Modified pLines receives a pointer to an area of memory containing the screen buffer.
  461. @Return true for success
  462. @Description It will be stored as 24-bit per pixel, 8-bit per chanel RGB. The
  463. memory should be freed with free() when no longer needed.
  464. *************************************************************************/
  465. bool PVRShell::PVRShellScreenCaptureBuffer(const int Width, const int Height, unsigned char **pLines)
  466. {
  467. int Pitch;
  468. /* Compute line pitch */
  469. Pitch = 3*Width;
  470. if ( ((3*Width)%4)!=0 )
  471. {
  472. Pitch += 4-((3*Width)%4);
  473. }
  474. /* Allocate memory for line */
  475. *pLines=(unsigned char *)calloc(Pitch*Height, sizeof(unsigned char));
  476. if (!(*pLines)) return false;
  477. return m_pShellInit->ApiScreenCaptureBuffer(Width, Height, *pLines);
  478. }
  479. /*!***********************************************************************
  480. @Function PVRShellScreenSave
  481. @Input fname base of file to save screen to
  482. @Output ofname If non-NULL, receives the filename actually used
  483. @Modified pLines image data to write out (24bpp, 8-bit per channel RGB)
  484. @Return true for success
  485. @Description Writes out the image data to a BMP file with basename
  486. fname. The file written will be fname suffixed with a
  487. number to make the file unique.
  488. For example, if fname is "abc", this function will attempt
  489. to save to "abc0000.bmp"; if that file already exists, it
  490. will try "abc0001.bmp", repeating until a new filename is
  491. found. The final filename used is returned in ofname.
  492. *************************************************************************/
  493. int PVRShell::PVRShellScreenSave(
  494. const char * const fname,
  495. const unsigned char * const pLines,
  496. char * const ofname)
  497. {
  498. FILE *file = 0;
  499. const char *pszWritePath;
  500. char *pszFileName;
  501. int nScreenshotCount;
  502. int dwWidth = m_pShellData->nShellDimX;
  503. int dwHeight= m_pShellData->nShellDimY;
  504. int error;
  505. pszWritePath = (const char*)PVRShellGet(prefWritePath);
  506. int nFileNameSize = strlen(pszWritePath) + 200;
  507. pszFileName = (char*)malloc(nFileNameSize);
  508. /* Look for the first file name that doesn't already exist */
  509. for(nScreenshotCount = 0; nScreenshotCount < 10000; ++nScreenshotCount)
  510. {
  511. #if defined(__SYMBIAN32__) || defined(UITRON) || defined(_UITRON_)
  512. sprintf(pszFileName, "%s%s%04d.bmp", pszWritePath, fname, nScreenshotCount);
  513. #else
  514. snprintf(pszFileName, nFileNameSize, "%s%s%04d.bmp", pszWritePath, fname, nScreenshotCount);
  515. #endif
  516. file = fopen(pszFileName,"r");
  517. if(!file)
  518. break;
  519. fclose(file);
  520. }
  521. /* If all files already exist, replace the first one */
  522. if (nScreenshotCount==10000)
  523. {
  524. #if defined(__SYMBIAN32__) || defined(UITRON) || defined(_UITRON_)
  525. sprintf(pszFileName, "%s%s0000.bmp", pszWritePath, fname);
  526. #else
  527. snprintf(pszFileName, nFileNameSize, "%s%s0000.bmp", pszWritePath, fname);
  528. #endif
  529. PVRShellOutputDebug("PVRShell: *WARNING* : Overwriting %s\n", pszFileName);
  530. }
  531. if(ofname) // requested the output file name
  532. {
  533. strcpy(ofname, pszFileName);
  534. }
  535. error = PVRShellWriteBMPFile(pszFileName, dwWidth, dwHeight, pLines);
  536. FREE(pszFileName);
  537. if (error)
  538. {
  539. return 10*error+1;
  540. }
  541. else
  542. {
  543. // No problem occured
  544. return 0;
  545. }
  546. }
  547. /*!***********************************************************************
  548. @Function PVRShellByteSwap
  549. @Input pBytes The bytes to swap
  550. @Input i32ByteNo The number of bytes to swap
  551. @Description Swaps the bytes in pBytes from little to big endian (or vice versa)
  552. *************************************************************************/
  553. inline void PVRShellByteSwap(unsigned char* pBytes, int i32ByteNo)
  554. {
  555. int i = 0, j = i32ByteNo - 1;
  556. while(i < j)
  557. {
  558. unsigned char cTmp = pBytes[i];
  559. pBytes[i] = pBytes[j];
  560. pBytes[j] = cTmp;
  561. ++i;
  562. --j;
  563. }
  564. }
  565. /*!***********************************************************************
  566. @Function PVRShellWriteBMPFile
  567. @Input pszFilename file to save screen to
  568. @Input uWidth the width of the data
  569. @Input uHeight the height of the data
  570. @Input pImageData image data to write out (24bpp, 8-bit per channel RGB)
  571. @Return 0 on success
  572. @Description Writes out the image data to a BMP file with name fname.
  573. *************************************************************************/
  574. const int g_i32BMPHeaderSize = 14; /*!< The size of a BMP header */
  575. const int g_i32BMPInfoSize = 40; /*!< The size of a BMP info header */
  576. int PVRShell::PVRShellWriteBMPFile(
  577. const char * const pszFilename,
  578. const unsigned long uWidth,
  579. const unsigned long uHeight,
  580. const void * const pImageData)
  581. {
  582. #define ByteSwap(x) PVRShellByteSwap((unsigned char*) &x, sizeof(x))
  583. int Result = 1;
  584. unsigned int i,j;
  585. FILE* fpDumpfile = 0;
  586. fpDumpfile = fopen(pszFilename, "wb");
  587. if (fpDumpfile != 0)
  588. {
  589. short int word = 0x0001;
  590. char *byte = (char*) &word;
  591. bool bLittleEndian = byte[0] ? true : false;
  592. int i32Line = uWidth * 3;
  593. int i32BytesPerLine = i32Line;
  594. unsigned int i32Align = 0;
  595. // round up to a dword boundary
  596. if(i32BytesPerLine & 3)
  597. {
  598. i32BytesPerLine |= 3;
  599. ++i32BytesPerLine;
  600. i32Align = i32BytesPerLine - i32Line;
  601. }
  602. int i32RealSize = i32BytesPerLine *uHeight;
  603. // BMP Header
  604. unsigned short bfType = 0x4D42;
  605. unsigned long bfSize = g_i32BMPHeaderSize + g_i32BMPInfoSize + i32RealSize;
  606. unsigned short bfReserved1 = 0;
  607. unsigned short bfReserved2 = 0;
  608. unsigned long bfOffBits = g_i32BMPHeaderSize + g_i32BMPInfoSize;
  609. // BMP Info Header
  610. unsigned long biSize = g_i32BMPInfoSize;
  611. unsigned long biWidth = uWidth;
  612. unsigned long biHeight = uHeight;
  613. unsigned short biPlanes = 1;
  614. unsigned short biBitCount = 24;
  615. unsigned long biCompression = 0L;
  616. unsigned long biSizeImage = i32RealSize;
  617. unsigned long biXPelsPerMeter = 0;
  618. unsigned long biYPelsPerMeter = 0;
  619. unsigned long biClrUsed = 0;
  620. unsigned long biClrImportant = 0;
  621. unsigned char *pData = (unsigned char*) pImageData;
  622. if(!bLittleEndian)
  623. {
  624. for(i = 0; i < uWidth * uHeight; ++i)
  625. PVRShellByteSwap(pData + (3 * i), 3);
  626. ByteSwap(bfType);
  627. ByteSwap(bfSize);
  628. ByteSwap(bfOffBits);
  629. ByteSwap(biSize);
  630. ByteSwap(biWidth);
  631. ByteSwap(biHeight);
  632. ByteSwap(biPlanes);
  633. ByteSwap(biBitCount);
  634. ByteSwap(biCompression);
  635. ByteSwap(biSizeImage);
  636. }
  637. // Write Header.
  638. fwrite(&bfType , 1, sizeof(bfType) , fpDumpfile);
  639. fwrite(&bfSize , 1, sizeof(bfSize) , fpDumpfile);
  640. fwrite(&bfReserved1 , 1, sizeof(bfReserved1), fpDumpfile);
  641. fwrite(&bfReserved2 , 1, sizeof(bfReserved2), fpDumpfile);
  642. fwrite(&bfOffBits , 1, sizeof(bfOffBits) , fpDumpfile);
  643. // Write info header.
  644. fwrite(&biSize , 1, sizeof(biSize) , fpDumpfile);
  645. fwrite(&biWidth , 1, sizeof(biWidth) , fpDumpfile);
  646. fwrite(&biHeight , 1, sizeof(biHeight) , fpDumpfile);
  647. fwrite(&biPlanes , 1, sizeof(biPlanes) , fpDumpfile);
  648. fwrite(&biBitCount , 1, sizeof(biBitCount) , fpDumpfile);
  649. fwrite(&biCompression , 1, sizeof(biCompression) , fpDumpfile);
  650. fwrite(&biSizeImage , 1, sizeof(biSizeImage) , fpDumpfile);
  651. fwrite(&biXPelsPerMeter , 1, sizeof(biXPelsPerMeter), fpDumpfile);
  652. fwrite(&biYPelsPerMeter , 1, sizeof(biYPelsPerMeter), fpDumpfile);
  653. fwrite(&biClrUsed , 1, sizeof(biClrUsed) , fpDumpfile);
  654. fwrite(&biClrImportant , 1, sizeof(biClrImportant) , fpDumpfile);
  655. unsigned char align = 0x00;
  656. // Write image.
  657. if(i32Align == 0)
  658. {
  659. fwrite(pData, 1, i32RealSize, fpDumpfile);
  660. }
  661. else
  662. {
  663. for(i = 0; i < uHeight; i++)
  664. {
  665. pData += fwrite(pData, 1, i32Line, fpDumpfile);
  666. for(j = 0; j < i32Align; ++j)
  667. fwrite(&align, 1, 1, fpDumpfile);
  668. }
  669. }
  670. // Last but not least close the file.
  671. fclose(fpDumpfile);
  672. Result = 0;
  673. }
  674. else
  675. {
  676. PVRShellOutputDebug("PVRShell: Failed to open \"%s\" for writing screen dump.\n", pszFilename);
  677. }
  678. return Result;
  679. }
  680. /*!***********************************************************************
  681. @Function PVRShellGetTime
  682. @Returns A value which increments once per millisecond.
  683. @Description The number itself should be considered meaningless; an
  684. application should use this function to determine how much
  685. time has passed between two points (e.g. between each
  686. frame).
  687. *************************************************************************/
  688. unsigned long PVRShell::PVRShellGetTime()
  689. {
  690. // Read timer from a platform dependant function
  691. return m_pShellInit->OsGetTime()-m_pShellInit->m_u32ShellStartTime;
  692. }
  693. /*!***********************************************************************
  694. @Function PVRShellIsKeyPressed
  695. @Input key Code of the key to test
  696. @Return true if key was pressed
  697. @Description Check if a key was pressed. The keys on various devices
  698. are mapped to the PVRShell-supported keys (listed in @a PVRShellKeyName) in
  699. a platform-dependent manner, since most platforms have different input
  700. devices. Check the SDK release notes for details on how the enum values
  701. map to your device's input device.
  702. *************************************************************************/
  703. bool PVRShell::PVRShellIsKeyPressed(const PVRShellKeyName key)
  704. {
  705. if(!m_pShellInit)
  706. return false;
  707. return m_pShellInit->DoIsKeyPressed(key);
  708. }
  709. /*!****************************************************************************
  710. * @Class PVRShellCommandLine
  711. *****************************************************************************/
  712. /*!***********************************************************************
  713. @Function PVRShellCommandLine
  714. @Description Constructor
  715. *************************************************************************/
  716. PVRShellCommandLine::PVRShellCommandLine()
  717. {
  718. memset(this, 0, sizeof(*this));
  719. }
  720. /*!***********************************************************************
  721. @Function PVRShellCommandLine
  722. @Description Destructor
  723. *************************************************************************/
  724. PVRShellCommandLine::~PVRShellCommandLine()
  725. {
  726. delete [] m_psOrig;
  727. delete [] m_psSplit;
  728. FREE(m_pOpt);
  729. }
  730. /*!***********************************************************************
  731. @Function Set
  732. @Input pStr Input string
  733. @Description Set command-line options to pStr
  734. *************************************************************************/
  735. void PVRShellCommandLine::Set(const char *pStr)
  736. {
  737. delete [] m_psOrig;
  738. m_psOrig = 0;
  739. if(pStr)
  740. {
  741. size_t len = strlen(pStr)+1;
  742. m_psOrig = new char[len];
  743. strcpy(m_psOrig, pStr);
  744. }
  745. }
  746. /*!***********************************************************************
  747. @Function Prefix
  748. @Input pStr Input string
  749. @Description Prepend command-line options to m_psOrig
  750. *************************************************************************/
  751. void PVRShellCommandLine::Prefix(const char *pStr)
  752. {
  753. if(!m_psOrig)
  754. Set(pStr);
  755. else if(!pStr)
  756. return;
  757. else
  758. {
  759. char *pstmp = m_psOrig;
  760. size_t lenA = strlen(pStr);
  761. size_t TotalLen = lenA + 1 + strlen(m_psOrig);
  762. m_psOrig = new char[TotalLen + 1];
  763. strcpy(m_psOrig, pStr);
  764. m_psOrig[lenA] = ' ';
  765. strcpy(m_psOrig + lenA + 1, pstmp);
  766. m_psOrig[TotalLen] = '\0';
  767. delete[] pstmp;
  768. }
  769. }
  770. /*!***********************************************************************
  771. @Function PrefixFromFile
  772. @Input pFileName Input string
  773. @Description Prepend command-line options to m_psOrig from a file
  774. *************************************************************************/
  775. bool PVRShellCommandLine::PrefixFromFile(const char *pFileName)
  776. {
  777. char* nl;
  778. FILE *pFile = fopen(pFileName, "rb");
  779. if(pFile)
  780. {
  781. // Get the file size
  782. fseek(pFile, 0, SEEK_END);
  783. long m_Size = ftell(pFile) + 2;
  784. fseek(pFile, 0, SEEK_SET);
  785. char *pFullFile = new char[m_Size];
  786. if(pFullFile)
  787. {
  788. size_t offset = 0;
  789. while(fgets(pFullFile + offset, (int) (m_Size - offset), pFile))
  790. {
  791. offset = strlen(pFullFile);
  792. // Replace new lines with spaces
  793. nl = strrchr(pFullFile, '\r');
  794. if(nl) *nl = ' ';
  795. nl = strrchr(pFullFile, '\n');
  796. if(nl) *nl = ' ';
  797. }
  798. pFullFile[offset] = '\0';
  799. Prefix(pFullFile);
  800. delete[] pFullFile;
  801. fclose(pFile);
  802. return true;
  803. }
  804. fclose(pFile);
  805. }
  806. return false;
  807. }
  808. /*!***********************************************************************
  809. @Function Parse
  810. @Description Parse m_psOrig for command-line options and store them in m_pOpt
  811. *************************************************************************/
  812. void PVRShellCommandLine::Parse()
  813. {
  814. size_t len;
  815. int nIn, nOut;
  816. bool bInQuotes;
  817. SCmdLineOpt opt;
  818. if(!m_psOrig)
  819. return;
  820. // Tidy up any options we have already parsed
  821. delete [] m_psSplit;
  822. FREE(m_pOpt);
  823. // Take a copy to be edited
  824. len = strlen(m_psOrig) + 1;
  825. m_psSplit = new char[len];
  826. // Break the command line into options
  827. bInQuotes = false;
  828. opt.pArg = NULL;
  829. opt.pVal = NULL;
  830. nIn = -1;
  831. nOut = 0;
  832. do
  833. {
  834. ++nIn;
  835. if(m_psOrig[nIn] == '"')
  836. {
  837. bInQuotes = !bInQuotes;
  838. }
  839. else
  840. {
  841. if(bInQuotes && m_psOrig[nIn] != 0)
  842. {
  843. if(!opt.pArg)
  844. opt.pArg = &m_psSplit[nOut];
  845. m_psSplit[nOut++] = m_psOrig[nIn];
  846. }
  847. else
  848. {
  849. switch(m_psOrig[nIn])
  850. {
  851. case '=':
  852. m_psSplit[nOut++] = 0;
  853. opt.pVal = &m_psSplit[nOut];
  854. break;
  855. case ' ':
  856. case '\t':
  857. case '\0':
  858. m_psSplit[nOut++] = 0;
  859. if(opt.pArg || opt.pVal)
  860. {
  861. // Increase list length if necessary
  862. if(m_nOptLen == m_nOptMax)
  863. m_nOptMax = m_nOptMax * 2 + 1;
  864. m_pOpt = (SCmdLineOpt*)realloc(m_pOpt, m_nOptMax * sizeof(*m_pOpt));
  865. if(!m_pOpt)
  866. return;
  867. // Add option to list
  868. m_pOpt[m_nOptLen++] = opt;
  869. opt.pArg = NULL;
  870. opt.pVal = NULL;
  871. }
  872. break;
  873. default:
  874. if(!opt.pArg)
  875. opt.pArg = &m_psSplit[nOut];
  876. m_psSplit[nOut++] = m_psOrig[nIn];
  877. break;
  878. }
  879. }
  880. }
  881. } while(m_psOrig[nIn]);
  882. }
  883. /*!***********************************************************************
  884. @Function Apply
  885. @Input shell
  886. @Description Apply the command-line options to shell
  887. *************************************************************************/
  888. void PVRShellCommandLine::Apply(PVRShell &shell)
  889. {
  890. int i;
  891. const char *arg, *val;
  892. for(i = 0; i < m_nOptLen; ++i)
  893. {
  894. arg = m_pOpt[i].pArg;
  895. val = m_pOpt[i].pVal;
  896. if(!arg)
  897. continue;
  898. if(val)
  899. {
  900. if(_stricmp(arg, "-width") == 0)
  901. {
  902. shell.PVRShellSet(prefWidth, atoi(val));
  903. }
  904. else if(_stricmp(arg, "-height") == 0)
  905. {
  906. shell.PVRShellSet(prefHeight, atoi(val));
  907. }
  908. else if(_stricmp(arg, "-FSAAMode") == 0 || _stricmp(arg, "-aa") == 0)
  909. {
  910. shell.PVRShellSet(prefFSAAMode, atoi(val));
  911. }
  912. else if(_stricmp(arg, "-fullscreen") == 0)
  913. {
  914. shell.PVRShellSet(prefFullScreen, (atoi(val) != 0));
  915. }
  916. else if(_stricmp(arg, "-sw") == 0)
  917. {
  918. shell.PVRShellSet(prefSoftwareRendering, (atoi(val) != 0));
  919. }
  920. else if(_stricmp(arg, "-quitafterframe") == 0 || _stricmp(arg, "-qaf") == 0)
  921. {
  922. shell.PVRShellSet(prefQuitAfterFrame, atoi(val));
  923. }
  924. else if(_stricmp(arg, "-quitaftertime") == 0 || _stricmp(arg, "-qat") == 0)
  925. {
  926. shell.PVRShellSet(prefQuitAfterTime, (float)atof(val));
  927. }
  928. else if(_stricmp(arg, "-posx") == 0)
  929. {
  930. shell.PVRShellSet(prefPositionX, atoi(val));
  931. }
  932. else if(_stricmp(arg, "-posy") == 0)
  933. {
  934. shell.PVRShellSet(prefPositionY, atoi(val));
  935. }
  936. else if(_stricmp(arg, "-vsync") == 0)
  937. {
  938. shell.PVRShellSet(prefSwapInterval, atoi(val));
  939. }
  940. else if(_stricmp(arg, "-powersaving") == 0 || _stricmp(arg, "-ps") == 0)
  941. {
  942. shell.PVRShellSet(prefPowerSaving, (atoi(val) != 0));
  943. }
  944. else if(_stricmp(arg, "-colourbpp") == 0 || _stricmp(arg, "-colorbpp") == 0 ||_stricmp(arg, "-cbpp") == 0)
  945. {
  946. shell.PVRShellSet(prefColorBPP, atoi(val));
  947. }
  948. else if(_stricmp(arg, "-depthbpp") == 0 || _stricmp(arg, "-dbpp") == 0)
  949. {
  950. shell.PVRShellSet(prefDepthBPP, atoi(val));
  951. }
  952. else if(_stricmp(arg, "-rotatekeys") == 0)
  953. {
  954. shell.PVRShellSet(prefRotateKeys, atoi(val));
  955. }
  956. else if(_stricmp(arg, "-c") == 0)
  957. {
  958. const char* pDash = strchr(val, '-');
  959. shell.PVRShellSet(prefCaptureFrameStart, atoi(val));
  960. if(!pDash)
  961. shell.PVRShellSet(prefCaptureFrameStop, atoi(val));
  962. else
  963. shell.PVRShellSet(prefCaptureFrameStop, atoi(pDash + 1));
  964. }
  965. else if(_stricmp(arg, "-priority") == 0)
  966. {
  967. shell.PVRShellSet(prefPriority, atoi(val));
  968. }
  969. else if(_stricmp(arg, "-config") == 0)
  970. {
  971. shell.PVRShellSet(prefRequestedConfig, atoi(val));
  972. }
  973. else if(_stricmp(arg, "-display") == 0)
  974. {
  975. shell.PVRShellSet(prefNativeDisplay, atoi(val));
  976. }
  977. }
  978. else
  979. {
  980. if(_stricmp(arg, "-version") == 0)
  981. {
  982. shell.PVRShellOutputDebug("Version: \"%s\"\n", shell.PVRShellGet(prefVersion));
  983. }
  984. #ifdef PVRSHELL_FPS_OUTPUT
  985. else if(_stricmp(arg, "-fps") == 0)
  986. {
  987. shell.PVRShellSet(prefOutputFPS, true);
  988. }
  989. #endif
  990. else if(_stricmp(arg, "-info") == 0)
  991. {
  992. shell.PVRShellSet(prefOutputInfo, true);
  993. }
  994. }
  995. }
  996. }
  997. /*!***************************************************************************
  998. * @Class PVRShellInit
  999. ****************************************************************************/
  1000. /*!***********************************************************************
  1001. @Function PVRShellInit
  1002. @Description Constructor
  1003. *************************************************************************/
  1004. PVRShellInit::PVRShellInit()
  1005. {
  1006. memset(this, 0, sizeof(*this));
  1007. }
  1008. /*!***********************************************************************
  1009. @Function ~PVRShellInit
  1010. @Description Destructor
  1011. *************************************************************************/
  1012. PVRShellInit::~PVRShellInit()
  1013. {
  1014. Deinit();
  1015. delete [] m_pReadPath;
  1016. m_pReadPath = NULL;
  1017. delete [] m_pWritePath;
  1018. m_pWritePath = NULL;
  1019. }
  1020. /*!***********************************************************************
  1021. @Function Deinit
  1022. @Input Shell
  1023. @Description PVRShell deinitialisation.
  1024. *************************************************************************/
  1025. void PVRShellInit::Deinit()
  1026. {
  1027. if(m_pShell)
  1028. {
  1029. // Is the App currently running?
  1030. if(m_eState > ePVRShellInitApp && m_eState < ePVRShellExit)
  1031. {
  1032. // If so force it to go through the exit procedure
  1033. if(m_eState < ePVRShellReleaseView)
  1034. m_eState = ePVRShellReleaseView;
  1035. // Class the App as done
  1036. gShellDone = true;
  1037. // Run through the exiting states
  1038. while(Run()){};
  1039. }
  1040. delete m_pShell;
  1041. m_pShell = 0;
  1042. }
  1043. }
  1044. /*!***********************************************************************
  1045. @Function Init
  1046. @Input Shell
  1047. @Returns True on success and false on failure
  1048. @description PVRShell Initialisation.
  1049. *************************************************************************/
  1050. bool PVRShellInit::Init()
  1051. {
  1052. Deinit();
  1053. m_pShell = NewDemo();
  1054. if(!m_pShell)
  1055. return false;
  1056. m_pShell->m_pShellInit = this;
  1057. m_u32ShellStartTime = OsGetTime();
  1058. // set default direction key mappings
  1059. m_eKeyMapDOWN = PVRShellKeyNameDOWN;
  1060. m_eKeyMapLEFT = PVRShellKeyNameLEFT;
  1061. m_eKeyMapUP = PVRShellKeyNameUP;
  1062. m_eKeyMapRIGHT = PVRShellKeyNameRIGHT;
  1063. nLastKeyPressed = PVRShellKeyNameNull;
  1064. OsInit();
  1065. gShellDone = false;
  1066. m_eState = ePVRShellInitApp;
  1067. return true;
  1068. }
  1069. /*!***********************************************************************
  1070. @Function CommandLine
  1071. @Input str A string containing the command-line
  1072. @Description Receives the command-line from the application.
  1073. *************************************************************************/
  1074. void PVRShellInit::CommandLine(char *str)
  1075. {
  1076. m_CommandLine.Set(str);
  1077. }
  1078. /*!***********************************************************************
  1079. @Function CommandLine
  1080. @Input argc Number of strings in argv
  1081. @Input argv An array of strings
  1082. @Description Receives the command-line from the application.
  1083. *************************************************************************/
  1084. void PVRShellInit::CommandLine(int argc, char **argv)
  1085. {
  1086. size_t tot, len;
  1087. char *buf;
  1088. int i;
  1089. tot = 0;
  1090. for(i = 0; i < argc; ++i)
  1091. tot += strlen(argv[i]);
  1092. if(!tot)
  1093. {
  1094. CommandLine((char*) "");
  1095. return;
  1096. }
  1097. // Add room for spaces and the \0
  1098. tot += argc;
  1099. buf = new char[tot];
  1100. tot = 0;
  1101. for(i = 0; i < argc; ++i)
  1102. {
  1103. len = strlen(argv[i]);
  1104. strncpy(&buf[tot], argv[i], len);
  1105. tot += len;
  1106. buf[tot++] = ' ';
  1107. }
  1108. buf[tot-1] = 0;
  1109. CommandLine(buf);
  1110. delete [] buf;
  1111. }
  1112. /*!***********************************************************************
  1113. @Function DoIsKeyPressed
  1114. @Input key The key we're querying for
  1115. @description Return 'true' if the specific key has been pressed.
  1116. *************************************************************************/
  1117. bool PVRShellInit::DoIsKeyPressed(const PVRShellKeyName key)
  1118. {
  1119. if(key == nLastKeyPressed)
  1120. {
  1121. nLastKeyPressed = PVRShellKeyNameNull;
  1122. return true;
  1123. }
  1124. else
  1125. {
  1126. return false;
  1127. }
  1128. }
  1129. /*!***********************************************************************
  1130. @Function KeyPressed
  1131. @Input nkey The key that has been pressed
  1132. @description Used by the OS-specific code to tell the Shell that a key has been pressed.
  1133. *************************************************************************/
  1134. void PVRShellInit::KeyPressed(PVRShellKeyName nKey)
  1135. {
  1136. nLastKeyPressed = nKey;
  1137. }
  1138. /*!***********************************************************************
  1139. @Function GetReadPath
  1140. @Returns A path the application is capable of reading from
  1141. @description Used by the OS-specific code to tell the Shell where to read external files from
  1142. *************************************************************************/
  1143. const char* PVRShellInit::GetReadPath() const
  1144. {
  1145. return m_pReadPath;
  1146. }
  1147. /*!***********************************************************************
  1148. @Function GetWritePath
  1149. @Returns A path the applications is capable of writing to
  1150. @description Used by the OS-specific code to tell the Shell where to write to
  1151. *************************************************************************/
  1152. const char* PVRShellInit::GetWritePath() const
  1153. {
  1154. return m_pWritePath;
  1155. }
  1156. /*!****************************************************************************
  1157. @Function SetAppName
  1158. @Input str The application name
  1159. @Description Sets the default app name (to be displayed by the OS)
  1160. *******************************************************************************/
  1161. void PVRShellInit::SetAppName(const char * const str)
  1162. {
  1163. const char *pName = strrchr(str, PVRSHELL_DIR_SYM);
  1164. if(pName)
  1165. {
  1166. ++pName;
  1167. }
  1168. else
  1169. {
  1170. pName = str;
  1171. }
  1172. m_pShell->PVRShellSet(prefAppName, pName);
  1173. }
  1174. /*!***********************************************************************
  1175. @Function SetReadPath
  1176. @Input str The read path
  1177. @description Set the path to where the application expects to read from.
  1178. *************************************************************************/
  1179. void PVRShellInit::SetReadPath(const char * const str)
  1180. {
  1181. m_pReadPath = new char[strlen(str)+1];
  1182. if(m_pReadPath)
  1183. {
  1184. strcpy(m_pReadPath, str);
  1185. char* lastSlash = strrchr(m_pReadPath, PVRSHELL_DIR_SYM);
  1186. if(lastSlash)
  1187. lastSlash[1] = 0;
  1188. }
  1189. }
  1190. /*!***********************************************************************
  1191. @Function SetWritePath
  1192. @Input str The write path
  1193. @description Set the path to where the application expects to write to.
  1194. *************************************************************************/
  1195. void PVRShellInit::SetWritePath(const char * const str)
  1196. {
  1197. m_pWritePath = new char[strlen(str)+1];
  1198. if(m_pWritePath)
  1199. {
  1200. strcpy(m_pWritePath, str);
  1201. char* lastSlash = strrchr(m_pWritePath, PVRSHELL_DIR_SYM);
  1202. if(lastSlash)
  1203. lastSlash[1] = 0;
  1204. }
  1205. }
  1206. #ifdef PVRSHELL_FPS_OUTPUT
  1207. /*****************************************************************************
  1208. * Function Name : FpsUpdate
  1209. * Description : Calculates a value for frames-per-second (FPS).
  1210. *****************************************************************************/
  1211. void PVRShellInit::FpsUpdate()
  1212. {
  1213. unsigned int ui32TimeDelta, ui32Time;
  1214. ui32Time = m_pShell->PVRShellGetTime();
  1215. ++m_i32FpsFrameCnt;
  1216. ui32TimeDelta = ui32Time - m_i32FpsTimePrev;
  1217. if(ui32TimeDelta >= 1000)
  1218. {
  1219. float fFPS = 1000.0f * (float) m_i32FpsFrameCnt / (float) ui32TimeDelta;
  1220. m_pShell->PVRShellOutputDebug("PVRShell: frame %d, FPS %.1f.\n",
  1221. m_pShell->m_pShellData->nShellCurFrameNum, fFPS);
  1222. m_i32FpsFrameCnt = 0;
  1223. m_i32FpsTimePrev = ui32Time;
  1224. }
  1225. }
  1226. #endif
  1227. /*****************************************************************************
  1228. * Function Name : Run
  1229. * Returns : false when the app should quit
  1230. * Description : Main message loop / render loop
  1231. *****************************************************************************/
  1232. bool PVRShellInit::Run()
  1233. {
  1234. static unsigned long StartTime = 0;
  1235. switch(m_eState)
  1236. {
  1237. case ePVRShellInitApp:
  1238. {
  1239. // Prepend command-line options from PVRShellCL.txt
  1240. const char * const pCL = "PVRShellCL.txt";
  1241. const char *pPath = (const char*) m_pShell->PVRShellGet(prefReadPath);
  1242. int nSize = strlen(pPath) + strlen(pCL) + 1;
  1243. char *pString = new char[nSize];
  1244. if(pString)
  1245. {
  1246. #if defined(__SYMBIAN32__) || defined(UITRON) || defined(_UITRON_)
  1247. sprintf(pString, "%s%s", pPath, pCL);
  1248. #else
  1249. snprintf(pString, nSize, "%s%s", pPath, pCL);
  1250. #endif
  1251. if(!m_CommandLine.PrefixFromFile(pString))
  1252. {
  1253. delete[] pString;
  1254. pPath = (const char*) m_pShell->PVRShellGet(prefWritePath);
  1255. nSize = strlen(pPath) + strlen(pCL) + 1;
  1256. pString = new char[nSize];
  1257. #if defined(__SYMBIAN32__) || defined(UITRON) || defined(_UITRON_)
  1258. sprintf(pString, "%s%s", pPath, pCL);
  1259. #else
  1260. snprintf(pString, nSize, "%s%s", pPath, pCL);
  1261. #endif
  1262. if(m_CommandLine.PrefixFromFile(pString))
  1263. m_pShell->PVRShellOutputDebug("Loaded command-line options from %s.\n", pString);
  1264. }
  1265. else
  1266. m_pShell->PVRShellOutputDebug("Loaded command-line options from %s.\n", pString);
  1267. delete[] pString;
  1268. }
  1269. // Parse the command-line
  1270. m_CommandLine.Parse();
  1271. #if defined(_DEBUG)
  1272. m_pShell->PVRShellOutputDebug("PVRShell command line: %d/%d\n", m_CommandLine.m_nOptLen, m_CommandLine.m_nOptMax);
  1273. for(int i = 0; i < m_CommandLine.m_nOptLen; ++i)
  1274. {
  1275. m_pShell->PVRShellOutputDebug("CL %d: \"%s\"\t= \"%s\".\n", i,
  1276. m_CommandLine.m_pOpt[i].pArg ? m_CommandLine.m_pOpt[i].pArg : "",
  1277. m_CommandLine.m_pOpt[i].pVal ? m_CommandLine.m_pOpt[i].pVal : "");
  1278. }
  1279. #endif
  1280. // Call InitApplication
  1281. if(!m_pShell->InitApplication())
  1282. {
  1283. m_eState = ePVRShellExit;
  1284. return true;
  1285. }
  1286. m_eState = ePVRShellInitInstance;
  1287. return true;
  1288. }
  1289. case ePVRShellInitInstance:
  1290. {
  1291. m_CommandLine.Apply(*m_pShell);
  1292. // Output non-api specific data if required
  1293. OutputInfo();
  1294. // Perform OS initialisation
  1295. if(!OsInitOS())
  1296. {
  1297. m_pShell->PVRShellOutputDebug("InitOS failed!\n");
  1298. m_eState = ePVRShellQuitApp;
  1299. return true;
  1300. }
  1301. // Initialize the 3D API
  1302. if(!OsDoInitAPI())
  1303. {
  1304. m_pShell->PVRShellOutputDebug("InitAPI failed!\n");
  1305. m_eState = ePVRShellReleaseOS;
  1306. gShellDone = true;
  1307. return true;
  1308. }
  1309. // Output api specific data if required
  1310. OutputAPIInfo();
  1311. // Initialise the app
  1312. if(!m_pShell->InitView())
  1313. {
  1314. m_pShell->PVRShellOutputDebug("InitView failed!\n");
  1315. m_eState = ePVRShellReleaseAPI;
  1316. gShellDone = true;
  1317. return true;
  1318. }
  1319. if(StartTime==0)
  1320. {
  1321. StartTime = OsGetTime();
  1322. }
  1323. m_eState = ePVRShellRender;
  1324. return true;
  1325. }
  1326. case ePVRShellRender:
  1327. {
  1328. // Main message loop:
  1329. if(!m_pShell->RenderScene())
  1330. break;
  1331. ApiRenderComplete();
  1332. OsRenderComplete();
  1333. #ifdef PVRSHELL_FPS_OUTPUT
  1334. if(m_pShell->m_pShellData->bOutputFPS)
  1335. FpsUpdate();
  1336. #endif
  1337. int nCurrentFrame = m_pShell->m_pShellData->nShellCurFrameNum;
  1338. if(DoIsKeyPressed(PVRShellKeyNameScreenshot) || (nCurrentFrame >= m_pShell->m_pShellData->nCaptureFrameStart && nCurrentFrame <= m_pShell->m_pShellData->nCaptureFrameStop))
  1339. {
  1340. unsigned char *pBuf;
  1341. if(m_pShell->PVRShellScreenCaptureBuffer(m_pShell->PVRShellGet(prefWidth), m_pShell->PVRShellGet(prefHeight), &pBuf))
  1342. {
  1343. if(m_pShell->PVRShellScreenSave(PVRSHELL_SCREENSHOT_NAME, pBuf) != 0)
  1344. {
  1345. m_pShell->PVRShellSet(prefExitMessage, "Screen-shot save failed.\n");
  1346. }
  1347. }
  1348. else
  1349. {
  1350. m_pShell->PVRShellSet(prefExitMessage, "Screen capture failed.\n");
  1351. }
  1352. FREE(pBuf);
  1353. }
  1354. if(DoIsKeyPressed(PVRShellKeyNameQUIT))
  1355. gShellDone = true;
  1356. if(gShellDone)
  1357. break;
  1358. /* Quit if maximum number of allowed frames is reached */
  1359. if((m_pShell->m_pShellData->nDieAfterFrames>=0) && (nCurrentFrame >= m_pShell->m_pShellData->nDieAfterFrames))
  1360. break;
  1361. /* Quit if maximum time is reached */
  1362. if((m_pShell->m_pShellData->fDieAfterTime>=0.0f) && (((OsGetTime()-StartTime)*0.001f) >= m_pShell->m_pShellData->fDieAfterTime))
  1363. break;
  1364. m_pShell->m_pShellData->nShellCurFrameNum++;
  1365. return true;
  1366. }
  1367. case ePVRShellReleaseView:
  1368. m_pShell->ReleaseView();
  1369. case ePVRShellReleaseAPI:
  1370. OsDoReleaseAPI();
  1371. case ePVRShellReleaseOS:
  1372. OsReleaseOS();
  1373. if(!gShellDone && m_pShell->m_pShellData->nInitRepeats)
  1374. {
  1375. --m_pShell->m_pShellData->nInitRepeats;
  1376. m_eState = ePVRShellInitInstance;
  1377. return true;
  1378. }
  1379. m_eState = ePVRShellQuitApp;
  1380. return true;
  1381. case ePVRShellQuitApp:
  1382. // Final app tidy-up
  1383. m_pShell->QuitApplication();
  1384. m_eState = ePVRShellExit;
  1385. case ePVRShellExit:
  1386. OsExit();
  1387. StringCopy(m_pShell->m_pShellData->pszAppName, 0);
  1388. StringCopy(m_pShell->m_pShellData->pszExitMessage, 0);
  1389. return false;
  1390. }
  1391. m_eState = (EPVRShellState)(m_eState + 1);
  1392. return true;
  1393. }
  1394. /*!***********************************************************************
  1395. @Function OutputInfo
  1396. @description When prefOutputInfo is set to true this function outputs
  1397. various pieces of non-API dependent information via
  1398. PVRShellOutputDebug.
  1399. *************************************************************************/
  1400. void PVRShellInit::OutputInfo()
  1401. {
  1402. if(m_pShell->PVRShellGet(prefOutputInfo))
  1403. {
  1404. m_pShell->PVRShellOutputDebug("\n");
  1405. m_pShell->PVRShellOutputDebug("App name: %s\n" , m_pShell->PVRShellGet(prefAppName));
  1406. m_pShell->PVRShellOutputDebug("SDK version: %s\n" , m_pShell->PVRShellGet(prefVersion));
  1407. m_pShell->PVRShellOutputDebug("\n");
  1408. m_pShell->PVRShellOutputDebug("Read path: %s\n" , m_pShell->PVRShellGet(prefReadPath));
  1409. m_pShell->PVRShellOutputDebug("Write path: %s\n" , m_pShell->PVRShellGet(prefWritePath));
  1410. m_pShell->PVRShellOutputDebug("\n");
  1411. m_pShell->PVRShellOutputDebug("Command-line: %s\n" , m_pShell->PVRShellGet(prefCommandLine));
  1412. m_pShell->PVRShellOutputDebug("\n");
  1413. m_pShell->PVRShellOutputDebug("Power saving: %s\n" , m_pShell->PVRShellGet(prefPowerSaving) ? "On" : "Off");
  1414. m_pShell->PVRShellOutputDebug("FSAAMode requested: %i\n", m_pShell->PVRShellGet(prefFSAAMode));
  1415. m_pShell->PVRShellOutputDebug("Fullscreen: %s\n", m_pShell->PVRShellGet(prefFullScreen) ? "Yes" : "No");
  1416. m_pShell->PVRShellOutputDebug("PBuffer requested: %s\n", m_pShell->PVRShellGet(prefPBufferContext) ? "Yes" : "No");
  1417. m_pShell->PVRShellOutputDebug("ZBuffer requested: %s\n", m_pShell->PVRShellGet(prefZbufferContext) ? "Yes" : "No");
  1418. m_pShell->PVRShellOutputDebug("Stencil buffer requested: %s\n", m_pShell->PVRShellGet(prefStencilBufferContext) ? "Yes" : "No");
  1419. if(m_pShell->PVRShellGet(prefColorBPP) > 0)
  1420. m_pShell->PVRShellOutputDebug("Colour buffer size requested: %i\n", m_pShell->PVRShellGet(prefColorBPP));
  1421. if(m_pShell->PVRShellGet(prefDepthBPP) > 0)
  1422. m_pShell->PVRShellOutputDebug("Depth buffer size requested: %i\n", m_pShell->PVRShellGet(prefDepthBPP));
  1423. m_pShell->PVRShellOutputDebug("Software rendering requested: %s\n", m_pShell->PVRShellGet(prefSoftwareRendering) ? "Yes" : "No");
  1424. m_pShell->PVRShellOutputDebug("OpenVG requested: %s\n", m_pShell->PVRShellGet(prefOpenVGContext) ? "Yes" : "No");
  1425. m_pShell->PVRShellOutputDebug("Swap Interval requested: %i\n", m_pShell->PVRShellGet(prefSwapInterval));
  1426. if(m_pShell->PVRShellGet(prefInitRepeats) > 0)
  1427. m_pShell->PVRShellOutputDebug("No of Init repeats: %i\n", m_pShell->PVRShellGet(prefInitRepeats));
  1428. if(m_pShell->PVRShellGet(prefQuitAfterFrame) != -1)
  1429. m_pShell->PVRShellOutputDebug("Quit after frame: %i\n", m_pShell->PVRShellGet(prefQuitAfterFrame));
  1430. if(m_pShell->PVRShellGet(prefQuitAfterTime) != -1.0f)
  1431. m_pShell->PVRShellOutputDebug("Quit after time: %f\n", m_pShell->PVRShellGet(prefQuitAfterTime));
  1432. }
  1433. }
  1434. /****************************************************************************
  1435. ** Local code
  1436. ****************************************************************************/
  1437. /*!***********************************************************************
  1438. @Function StringCopy
  1439. @Modified pszStr The string to copy pszSrc into
  1440. @Input pszSrc The source string to copy
  1441. @description This function copies pszSrc into pszStr.
  1442. *************************************************************************/
  1443. static bool StringCopy(char *&pszStr, const char * const pszSrc)
  1444. {
  1445. size_t len;
  1446. FREE(pszStr);
  1447. if(!pszSrc)
  1448. return true;
  1449. len = strlen(pszSrc)+1;
  1450. pszStr = (char*)malloc(len);
  1451. if(!pszStr)
  1452. return false;
  1453. strcpy(pszStr, pszSrc);
  1454. return true;
  1455. }
  1456. /*****************************************************************************
  1457. End of file (PVRShell.cpp)
  1458. *****************************************************************************/