PVRTPrint3D.cpp 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634
  1. /******************************************************************************
  2. @File PVRTPrint3D.cpp
  3. @Title PVRTPrint3D
  4. @Version
  5. @Copyright Copyright (C) Imagination Technologies Limited.
  6. @Platform ANSI compatible
  7. @Description Displays a text string using 3D polygons. Can be done in two ways:
  8. using a window defined by the user or writing straight on the
  9. screen.
  10. ******************************************************************************/
  11. /****************************************************************************
  12. ** Includes
  13. ****************************************************************************/
  14. #include <stdarg.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include "PVRTGlobal.h"
  19. #include "PVRTFixedPoint.h"
  20. #include "PVRTMatrix.h"
  21. #include "PVRTPrint3D.h"
  22. /* Print3D texture data */
  23. #include "PVRTPrint3DIMGLogo.h"
  24. #include "PVRTPrint3DPVRLogo.h"
  25. #include "PVRTPrint3Ddat.h"
  26. /****************************************************************************
  27. ** Defines
  28. ****************************************************************************/
  29. #define MAX_LETTERS (5120)
  30. #define MIN_CACHED_VTX (0x1000)
  31. #define MAX_CACHED_VTX (0x00100000)
  32. #define LINES_SPACING (29.0f)
  33. #define Print3D_WIN_EXIST 1
  34. #define Print3D_WIN_ACTIVE 2
  35. #define Print3D_WIN_TITLE 4
  36. #define Print3D_WIN_STATIC 8
  37. #define Print3D_FULL_OPAQUE 16
  38. #define Print3D_FULL_TRANS 32
  39. #define Print3D_ADJUST_SIZE 64
  40. #define Print3D_NO_BORDER 128
  41. #if defined(_WIN32) && !defined(__BADA__)
  42. #define vsnprintf _vsnprintf
  43. #endif
  44. /****************************************************************************
  45. ** Class: CPVRTPrint3D
  46. ****************************************************************************/
  47. /*****************************************************************************
  48. @Function CPVRTPrint3D
  49. @Description Init some values.
  50. *****************************************************************************/
  51. CPVRTPrint3D::CPVRTPrint3D()
  52. {
  53. #if !defined(DISABLE_PRINT3D)
  54. // Initialise all variables
  55. memset(this, 0, sizeof(*this));
  56. #endif
  57. }
  58. /*****************************************************************************
  59. @Function ~CPVRTPrint3D
  60. @Description De-allocate the working memory
  61. *****************************************************************************/
  62. CPVRTPrint3D::~CPVRTPrint3D()
  63. {
  64. #if !defined (DISABLE_PRINT3D)
  65. #endif
  66. }
  67. /*!***************************************************************************
  68. @Function PVRTPrint3DSetTextures
  69. @Input pContext Context
  70. @Input dwScreenX Screen resolution along X
  71. @Input dwScreenY Screen resolution along Y
  72. @Input bRotate Rotate print3D by 90 degrees
  73. @Return PVR_SUCCESS or PVR_FAIL
  74. @Description Initialization and texture upload. Should be called only once
  75. for a given context.
  76. *****************************************************************************/
  77. EPVRTError CPVRTPrint3D::SetTextures(
  78. const SPVRTContext * const pContext,
  79. const unsigned int dwScreenX,
  80. const unsigned int dwScreenY,
  81. const bool bRotate)
  82. {
  83. #if !defined (DISABLE_PRINT3D)
  84. unsigned short i;
  85. bool bStatus;
  86. /* Set the aspect ratio, so we can chage it without updating textures or anything else */
  87. float fX, fY;
  88. m_bRotate = bRotate;
  89. m_ui32ScreenDim[0] = bRotate ? dwScreenY : dwScreenX;
  90. m_ui32ScreenDim[1] = bRotate ? dwScreenX : dwScreenY;
  91. // Alter the X, Y resolutions if the screen isn't portrait.
  92. if(dwScreenX > dwScreenY)
  93. {
  94. fX = (float) dwScreenX;
  95. fY = (float) dwScreenY;
  96. }
  97. else
  98. {
  99. fX = (float) dwScreenY;
  100. fY = (float) dwScreenX;
  101. }
  102. m_fScreenScale[0] = (bRotate ? fY : fX) /640.0f;
  103. m_fScreenScale[1] = (bRotate ? fX : fY) /480.0f;
  104. /* Check whether textures are already set up just in case */
  105. if (m_bTexturesSet)
  106. return PVR_SUCCESS;
  107. if(!APIInit(pContext))
  108. return PVR_FAIL;
  109. /*
  110. This is the window background texture
  111. Type 0 because the data comes in TexTool rectangular format.
  112. */
  113. bStatus = APIUpLoad4444(1, (unsigned char *)WindowBackground, 16, 0);
  114. if (!bStatus) return PVR_FAIL;
  115. bStatus = APIUpLoad4444(2, (unsigned char *)WindowPlainBackground, 16, 0);
  116. if (!bStatus) return PVR_FAIL;
  117. bStatus = APIUpLoad4444(3, (unsigned char *)WindowBackgroundOp, 16, 0);
  118. if (!bStatus) return PVR_FAIL;
  119. bStatus = APIUpLoad4444(4, (unsigned char *)WindowPlainBackgroundOp, 16, 0);
  120. if (!bStatus) return PVR_FAIL;
  121. /*
  122. This is the texture with the fonts.
  123. Type 1 because there is only alpha component (RGB are white).
  124. */
  125. bStatus = APIUpLoad4444(0, (unsigned char *)PVRTPrint3DABC_Pixels, 256, 1);
  126. if (!bStatus) return PVR_FAIL;
  127. /* INDEX BUFFERS */
  128. m_pwFacesFont = (unsigned short*)malloc(PVRTPRINT3D_MAX_RENDERABLE_LETTERS*2*3*sizeof(unsigned short));
  129. if(!m_pwFacesFont)
  130. return PVR_FAIL;
  131. bStatus = APIUpLoadIcons((const PVRTuint32 *)PVRTPrint3DPVRLogo, (const PVRTuint32 *)PVRTPrint3DIMGLogo);
  132. if (!bStatus) return PVR_FAIL;
  133. /* Vertex indices for letters */
  134. for (i=0; i < PVRTPRINT3D_MAX_RENDERABLE_LETTERS; i++)
  135. {
  136. m_pwFacesFont[i*6+0] = 0+i*4;
  137. m_pwFacesFont[i*6+1] = 3+i*4;
  138. m_pwFacesFont[i*6+2] = 1+i*4;
  139. m_pwFacesFont[i*6+3] = 3+i*4;
  140. m_pwFacesFont[i*6+4] = 0+i*4;
  141. m_pwFacesFont[i*6+5] = 2+i*4;
  142. }
  143. m_nVtxCacheMax = MIN_CACHED_VTX;
  144. m_pVtxCache = (SPVRTPrint3DAPIVertex*)malloc(m_nVtxCacheMax * sizeof(*m_pVtxCache));
  145. m_nVtxCache = 0;
  146. if(!m_pVtxCache)
  147. {
  148. return PVR_FAIL;
  149. }
  150. /* Everything is OK */
  151. m_bTexturesSet = true;
  152. /* set all windows for an update */
  153. for (i=0; i<PVRTPRINT3D_MAX_WINDOWS; i++)
  154. m_pWin[i].bNeedUpdated = true;
  155. /* Return OK */
  156. return PVR_SUCCESS;
  157. #else
  158. return PVR_SUCCESS;
  159. #endif
  160. }
  161. /*!***************************************************************************
  162. @Function PVRTPrint3D
  163. @Input fPosX Position of the text along X
  164. @Input fPosY Position of the text along Y
  165. @Input fScale Scale of the text
  166. @Input Colour Colour of the text
  167. @Input pszFormat Format string for the text
  168. @Return PVR_SUCCESS or PVR_FAIL
  169. @Description Display 3D text on screen.
  170. No window needs to be allocated to use this function.
  171. However, PVRTPrint3DSetTextures(...) must have been called
  172. beforehand.
  173. This function accepts formatting in the printf way.
  174. *****************************************************************************/
  175. EPVRTError CPVRTPrint3D::Print3D(float fPosX, float fPosY, const float fScale, unsigned int Colour, const char * const pszFormat, ...)
  176. {
  177. #if !defined (DISABLE_PRINT3D)
  178. va_list args;
  179. static char Text[MAX_LETTERS+1], sPreviousString[MAX_LETTERS+1];
  180. static float XPosPrev, YPosPrev, fScalePrev;
  181. static unsigned int ColourPrev;
  182. static unsigned int nVertices;
  183. /* No textures! so... no window */
  184. if (!m_bTexturesSet)
  185. {
  186. PVRTErrorOutputDebug("DisplayWindow : You must call PVRTPrint3DSetTextures()\nbefore using this function!!!\n");
  187. return PVR_FAIL;
  188. }
  189. /* Reading the arguments to create our Text string */
  190. va_start(args, pszFormat);
  191. #if defined(__SYMBIAN32__) || defined(UITRON) || defined(_UITRON_)
  192. vsprintf(Text, pszFormat, args);
  193. #else
  194. vsnprintf(Text, MAX_LETTERS+1, pszFormat, args);
  195. #endif
  196. va_end(args);
  197. /* nothing to be drawn */
  198. if(*Text == 0)
  199. return PVR_FAIL;
  200. /* Adjust input parameters */
  201. fPosX *= 640.0f/100.0f;
  202. fPosY *= 480.0f/100.0f;
  203. /* We check if the string has been changed since last time */
  204. if(
  205. strcmp (sPreviousString, Text) != 0 ||
  206. fPosX != XPosPrev ||
  207. fPosY != YPosPrev ||
  208. fScale != fScalePrev ||
  209. Colour != ColourPrev ||
  210. m_pPrint3dVtx == NULL)
  211. {
  212. /* copy strings */
  213. strcpy (sPreviousString, Text);
  214. XPosPrev = fPosX;
  215. YPosPrev = fPosY;
  216. fScalePrev = fScale;
  217. ColourPrev = Colour;
  218. /* Create Vertex Buffer (only if it doesn't exist) */
  219. if(m_pPrint3dVtx == 0)
  220. {
  221. m_pPrint3dVtx = (SPVRTPrint3DAPIVertex*)malloc(MAX_LETTERS*4*sizeof(SPVRTPrint3DAPIVertex));
  222. if(!m_pPrint3dVtx)
  223. return PVR_FAIL;
  224. }
  225. /* Fill up our buffer */
  226. nVertices = UpdateLine(0, 0.0f, fPosX, fPosY, fScale, Colour, Text, m_pPrint3dVtx);
  227. }
  228. // Draw the text
  229. DrawLineUP(m_pPrint3dVtx, nVertices);
  230. #endif
  231. return PVR_SUCCESS;
  232. }
  233. /*!***************************************************************************
  234. @Function DisplayDefaultTitle
  235. @Input sTitle Title to display
  236. @Input sDescription Description to display
  237. @Input uDisplayLogo 1 = Display the logo
  238. @Return PVR_SUCCESS or PVR_FAIL
  239. @Description Creates a default title with predefined position and colours.
  240. It displays as well company logos when requested:
  241. 0 = No logo
  242. 1 = PowerVR logo
  243. 2 = Img Tech logo
  244. *****************************************************************************/
  245. EPVRTError CPVRTPrint3D::DisplayDefaultTitle(const char * const pszTitle, const char * const pszDescription, const unsigned int uDisplayLogo)
  246. {
  247. EPVRTError eRet = PVR_SUCCESS;
  248. #if !defined (DISABLE_PRINT3D)
  249. /* Display Title
  250. */
  251. if(pszTitle)
  252. {
  253. if(Print3D(0.0f, 1.0f, 1.2f, PVRTRGBA(255, 255, 0, 255), pszTitle) != PVR_SUCCESS)
  254. eRet = PVR_FAIL;
  255. }
  256. /* Display Description
  257. */
  258. if(pszDescription)
  259. {
  260. if(Print3D(0.0f, 8.0f, 0.9f, PVRTRGBA(255, 255, 255, 255), pszDescription) != PVR_SUCCESS)
  261. eRet = PVR_FAIL;
  262. }
  263. m_uLogoToDisplay = uDisplayLogo;
  264. #endif
  265. return eRet;
  266. }
  267. /*!***************************************************************************
  268. @Function CreateDefaultWindow
  269. @Input fPosX Position X for the new window
  270. @Input fPosY Position Y for the new window
  271. @Input nXSize_LettersPerLine
  272. @Input sTitle Title of the window
  273. @Input sBody Body text of the window
  274. @Return Window handle
  275. @Description Creates a default window.
  276. If Title is NULL the main body will have just one line
  277. (for InfoWin).
  278. *****************************************************************************/
  279. unsigned int CPVRTPrint3D::CreateDefaultWindow(float fPosX, float fPosY, int nXSize_LettersPerLine, char *sTitle, char *sBody)
  280. {
  281. #if !defined (DISABLE_PRINT3D)
  282. unsigned int dwActualWin;
  283. unsigned int dwFlags = ePVRTPrint3D_ADJUST_SIZE_ALWAYS;
  284. unsigned int dwBodyTextColor, dwBodyBackgroundColor;
  285. /* If no text is specified, return an error */
  286. if(!sBody && !sTitle) return 0xFFFFFFFF;
  287. /* If no title is specified, body text colours are different */
  288. if(!sTitle)
  289. {
  290. dwBodyTextColor = PVRTRGBA(0xFF, 0xFF, 0x30, 0xFF);
  291. dwBodyBackgroundColor = PVRTRGBA(0x20, 0x20, 0xB0, 0xE0);
  292. }
  293. else
  294. {
  295. dwBodyTextColor = PVRTRGBA(0xFF, 0xFF, 0xFF, 0xFF);
  296. dwBodyBackgroundColor = PVRTRGBA(0x20, 0x30, 0xFF, 0xE0);
  297. }
  298. /* Set window flags depending on title and body text were specified */
  299. if(!sBody) dwFlags |= ePVRTPrint3D_DEACTIVATE_WIN;
  300. if(!sTitle) dwFlags |= ePVRTPrint3D_DEACTIVATE_TITLE;
  301. /* Create window */
  302. dwActualWin = InitWindow(nXSize_LettersPerLine, (sTitle==NULL) ? 1:50);
  303. /* Set window properties */
  304. SetWindow(dwActualWin, dwBodyBackgroundColor, dwBodyTextColor, 0.5f, fPosX, fPosY, 20.0f, 20.0f);
  305. /* Set title */
  306. if (sTitle)
  307. SetTitle(dwActualWin, PVRTRGBA(0x20, 0x20, 0xB0, 0xE0), 0.6f, PVRTRGBA(0xFF, 0xFF, 0x30, 0xFF), sTitle, PVRTRGBA(0xFF, 0xFF, 0x30, 0xFF), (char*)"");
  308. /* Set window text */
  309. if (sBody)
  310. SetText(dwActualWin, sBody);
  311. /* Set window flags */
  312. SetWindowFlags(dwActualWin, dwFlags);
  313. m_pWin[dwActualWin].bNeedUpdated = true;
  314. /* Return window handle */
  315. return dwActualWin;
  316. #else
  317. return 0;
  318. #endif
  319. }
  320. /*!***************************************************************************
  321. @Function InitWindow
  322. @Input dwBufferSizeX Buffer width
  323. @Input dwBufferSizeY Buffer height
  324. @Return Window handle
  325. @Description Allocate a buffer for a newly-created window and return its
  326. handle.
  327. *****************************************************************************/
  328. unsigned int CPVRTPrint3D::InitWindow(unsigned int dwBufferSizeX, unsigned int dwBufferSizeY)
  329. {
  330. #if !defined (DISABLE_PRINT3D)
  331. unsigned int dwCurrentWin;
  332. /* Find the first available window */
  333. for (dwCurrentWin=1; dwCurrentWin<PVRTPRINT3D_MAX_WINDOWS; dwCurrentWin++)
  334. {
  335. /* If this window available? */
  336. if (!(m_pWin[dwCurrentWin].dwFlags & Print3D_WIN_EXIST))
  337. {
  338. /* Window available, exit loop */
  339. break;
  340. }
  341. }
  342. /* No more windows available? */
  343. if (dwCurrentWin == PVRTPRINT3D_MAX_WINDOWS)
  344. {
  345. _RPT0(_CRT_WARN,"\nPVRTPrint3DCreateWindow WARNING: PVRTPRINT3D_MAX_WINDOWS overflow.\n");
  346. return 0;
  347. }
  348. /* Set flags */
  349. m_pWin[dwCurrentWin].dwFlags = Print3D_WIN_TITLE | Print3D_WIN_EXIST | Print3D_WIN_ACTIVE;
  350. /* Text Buffer */
  351. m_pWin[dwCurrentWin].dwBufferSizeX = dwBufferSizeX + 1;
  352. m_pWin[dwCurrentWin].dwBufferSizeY = dwBufferSizeY;
  353. m_pWin[dwCurrentWin].pTextBuffer = (char *)calloc((dwBufferSizeX+2)*(dwBufferSizeY+2), sizeof(char));
  354. m_pWin[dwCurrentWin].bTitleTextL = (char *)calloc(MAX_LETTERS, sizeof(char));
  355. m_pWin[dwCurrentWin].bTitleTextR = (char *)calloc(MAX_LETTERS, sizeof(char));
  356. /* Memory allocation failed */
  357. if (!m_pWin[dwCurrentWin].pTextBuffer || !m_pWin[dwCurrentWin].bTitleTextL || !m_pWin[dwCurrentWin].bTitleTextR)
  358. {
  359. _RPT0(_CRT_WARN,"\nPVRTPrint3DCreateWindow : No memory enough for Text Buffer.\n");
  360. return 0;
  361. }
  362. /* Title */
  363. m_pWin[dwCurrentWin].fTitleFontSize = 1.0f;
  364. m_pWin[dwCurrentWin].dwTitleFontColorL = PVRTRGBA(0xFF, 0xFF, 0x00, 0xFF);
  365. m_pWin[dwCurrentWin].dwTitleFontColorR = PVRTRGBA(0xFF, 0xFF, 0x00, 0xFF);
  366. m_pWin[dwCurrentWin].dwTitleBaseColor = PVRTRGBA(0x30, 0x30, 0xFF, 0xFF); /* Dark Blue */
  367. /* Window */
  368. m_pWin[dwCurrentWin].fWinFontSize = 0.5f;
  369. m_pWin[dwCurrentWin].dwWinFontColor = PVRTRGBA(0xFF, 0xFF, 0xFF, 0xFF);
  370. m_pWin[dwCurrentWin].dwWinBaseColor = PVRTRGBA(0x80, 0x80, 0xFF, 0xFF); /* Light Blue */
  371. m_pWin[dwCurrentWin].fWinPos[0] = 0.0f;
  372. m_pWin[dwCurrentWin].fWinPos[1] = 0.0f;
  373. m_pWin[dwCurrentWin].fWinSize[0] = 20.0f;
  374. m_pWin[dwCurrentWin].fWinSize[1] = 20.0f;
  375. m_pWin[dwCurrentWin].fZPos = 0.0f;
  376. m_pWin[dwCurrentWin].dwSort = 0;
  377. m_pWin[dwCurrentWin].bNeedUpdated = true;
  378. dwCurrentWin++;
  379. /* Returning the handle */
  380. return (dwCurrentWin-1);
  381. #else
  382. return 0;
  383. #endif
  384. }
  385. /*!***************************************************************************
  386. @Function DeleteWindow
  387. @Input dwWin Window handle
  388. @Description Delete the window referenced by dwWin.
  389. *****************************************************************************/
  390. void CPVRTPrint3D::DeleteWindow(unsigned int dwWin)
  391. {
  392. #if !defined (DISABLE_PRINT3D)
  393. int i;
  394. /* Release VertexBuffer */
  395. FREE(m_pWin[dwWin].pTitleVtxL);
  396. FREE(m_pWin[dwWin].pTitleVtxR);
  397. FREE(m_pWin[dwWin].pWindowVtxTitle);
  398. FREE(m_pWin[dwWin].pWindowVtxText);
  399. for(i=0; i<255; i++)
  400. FREE(m_pWin[dwWin].pLineVtx[i]);
  401. /* Only delete window if it exists */
  402. if(m_pWin[dwWin].dwFlags & Print3D_WIN_EXIST)
  403. {
  404. FREE(m_pWin[dwWin].pTextBuffer);
  405. FREE(m_pWin[dwWin].bTitleTextL);
  406. FREE(m_pWin[dwWin].bTitleTextR);
  407. }
  408. /* Reset flags */
  409. m_pWin[dwWin].dwFlags = 0;
  410. #endif
  411. }
  412. /*!***************************************************************************
  413. @Function DeleteAllWindows
  414. @Description Delete all windows.
  415. *****************************************************************************/
  416. void CPVRTPrint3D::DeleteAllWindows()
  417. {
  418. #if !defined (DISABLE_PRINT3D)
  419. int unsigned i;
  420. for (i=0; i<PVRTPRINT3D_MAX_WINDOWS; i++)
  421. DeleteWindow (i);
  422. #endif
  423. }
  424. /*!***************************************************************************
  425. @Function DisplayWindow
  426. @Input dwWin
  427. @Return PVR_SUCCESS or PVR_FAIL
  428. @Description Display window.
  429. This function MUST be called between a BeginScene/EndScene
  430. pair as it uses D3D render primitive calls.
  431. PVRTPrint3DSetTextures(...) must have been called beforehand.
  432. *****************************************************************************/
  433. EPVRTError CPVRTPrint3D::DisplayWindow(unsigned int dwWin)
  434. {
  435. #if !defined (DISABLE_PRINT3D)
  436. unsigned int i;
  437. float fTitleSize = 0.0f;
  438. /* No textures! so... no window */
  439. if (!m_bTexturesSet)
  440. {
  441. _RPT0(_CRT_WARN,"DisplayWindow : You must call PVRTPrint3DSetTextures()\nbefore using this function!!!\n");
  442. return PVR_FAIL;
  443. }
  444. /* Update Vertex data only when needed */
  445. if(m_pWin[dwWin].bNeedUpdated)
  446. {
  447. /* TITLE */
  448. if(m_pWin[dwWin].dwFlags & Print3D_WIN_TITLE)
  449. {
  450. /* Set title size */
  451. if(m_pWin[dwWin].fTitleFontSize < 0.0f)
  452. fTitleSize = 8.0f + 16.0f;
  453. else
  454. fTitleSize = m_pWin[dwWin].fTitleFontSize * 23.5f + 16.0f;
  455. /* Title */
  456. UpdateTitleVertexBuffer(dwWin);
  457. /* Background */
  458. if (!(m_pWin[dwWin].dwFlags & Print3D_FULL_TRANS))
  459. {
  460. /* Draw title background */
  461. UpdateBackgroundWindow(
  462. dwWin, m_pWin[dwWin].dwTitleBaseColor,
  463. 0.0f,
  464. m_pWin[dwWin].fWinPos[0],
  465. m_pWin[dwWin].fWinPos[1],
  466. m_pWin[dwWin].fWinSize[0],
  467. fTitleSize, &m_pWin[dwWin].pWindowVtxTitle);
  468. }
  469. }
  470. /* Main text */
  471. UpdateMainTextVertexBuffer(dwWin);
  472. UpdateBackgroundWindow(
  473. dwWin, m_pWin[dwWin].dwWinBaseColor,
  474. 0.0f,
  475. m_pWin[dwWin].fWinPos[0],
  476. (m_pWin[dwWin].fWinPos[1] + fTitleSize),
  477. m_pWin[dwWin].fWinSize[0],
  478. m_pWin[dwWin].fWinSize[1], &m_pWin[dwWin].pWindowVtxText);
  479. /* Don't update until next change makes it needed */
  480. m_pWin[dwWin].bNeedUpdated = false;
  481. }
  482. // Ensure any previously drawn text has been submitted before drawing the window.
  483. Flush();
  484. /* Save current render states */
  485. APIRenderStates(0);
  486. /*
  487. DRAW TITLE
  488. */
  489. if(m_pWin[dwWin].dwFlags & Print3D_WIN_TITLE)
  490. {
  491. if (!(m_pWin[dwWin].dwFlags & Print3D_FULL_TRANS))
  492. {
  493. DrawBackgroundWindowUP(m_pWin[dwWin].pWindowVtxTitle, (m_pWin[dwWin].dwFlags & Print3D_FULL_OPAQUE) ? true : false, (m_pWin[dwWin].dwFlags & Print3D_NO_BORDER) ? false : true);
  494. }
  495. /* Left and Right text */
  496. DrawLineUP(m_pWin[dwWin].pTitleVtxL, m_pWin[dwWin].nTitleVerticesL);
  497. DrawLineUP(m_pWin[dwWin].pTitleVtxR, m_pWin[dwWin].nTitleVerticesR);
  498. }
  499. /*
  500. DRAW WINDOW
  501. */
  502. if (m_pWin[dwWin].dwFlags & Print3D_WIN_ACTIVE)
  503. {
  504. /* Background */
  505. if (!(m_pWin[dwWin].dwFlags & Print3D_FULL_TRANS))
  506. {
  507. DrawBackgroundWindowUP(m_pWin[dwWin].pWindowVtxText, (m_pWin[dwWin].dwFlags & Print3D_FULL_OPAQUE) ? true : false, (m_pWin[dwWin].dwFlags & Print3D_NO_BORDER) ? false : true);
  508. }
  509. /* Text, line by line */
  510. for (i=0; i<m_pWin[dwWin].dwBufferSizeY; i++)
  511. {
  512. DrawLineUP(m_pWin[dwWin].pLineVtx[i], m_pWin[dwWin].nLineVertices[i]);
  513. }
  514. }
  515. /* Restore render states */
  516. APIRenderStates(1);
  517. #endif
  518. return PVR_SUCCESS;
  519. }
  520. /*!***************************************************************************
  521. @Function SetText
  522. @Input dwWin Window handle
  523. @Input Format Format string
  524. @Return PVR_SUCCESS or PVR_FAIL
  525. @Description Feed the text buffer of window referenced by dwWin.
  526. This function accepts formatting in the printf way.
  527. *****************************************************************************/
  528. EPVRTError CPVRTPrint3D::SetText(unsigned int dwWin, const char *Format, ...)
  529. {
  530. #if !defined (DISABLE_PRINT3D)
  531. va_list args;
  532. unsigned int i;
  533. unsigned int dwBufferSize, dwTotalLength = 0;
  534. unsigned int dwPosBx, dwPosBy, dwSpcPos;
  535. char bChar;
  536. unsigned int dwCursorPos;
  537. static char sText[MAX_LETTERS+1];
  538. /* If window doesn't exist then return from function straight away */
  539. if (!(m_pWin[dwWin].dwFlags & Print3D_WIN_EXIST))
  540. return PVR_FAIL;
  541. // Empty the window buffer
  542. memset(m_pWin[dwWin].pTextBuffer, 0, m_pWin[dwWin].dwBufferSizeX * m_pWin[dwWin].dwBufferSizeY * sizeof(char));
  543. /* Reading the arguments to create our Text string */
  544. va_start(args,Format);
  545. #if defined(__SYMBIAN32__) || defined(UITRON) || defined(_UITRON_)
  546. vsprintf(sText, Format, args);
  547. #else
  548. vsnprintf(sText, MAX_LETTERS+1, Format, args);
  549. #endif
  550. va_end(args);
  551. dwCursorPos = 0;
  552. m_pWin[dwWin].bNeedUpdated = true;
  553. /* Compute buffer size */
  554. dwBufferSize = (m_pWin[dwWin].dwBufferSizeX+1) * (m_pWin[dwWin].dwBufferSizeY+1);
  555. /* Compute length */
  556. while(dwTotalLength < dwBufferSize && sText[dwTotalLength] != 0)
  557. dwTotalLength++;
  558. /* X and Y pointer position */
  559. dwPosBx = 0;
  560. dwPosBy = 0;
  561. /* Process each character */
  562. for (i=0; i<dwTotalLength; i++)
  563. {
  564. /* Get current character in string */
  565. bChar = sText[i];
  566. /* Space (for word wrap only) */
  567. if (bChar == ' ')
  568. {
  569. /* Looking for the next space (or return or end) */
  570. dwSpcPos = 1;
  571. do
  572. {
  573. bChar = sText[i + dwSpcPos++];
  574. }
  575. while (bChar==' ' || bChar==0x0A || bChar==0);
  576. bChar = ' ';
  577. /*
  578. Humm, if this word is longer than the buffer don't move it.
  579. Otherwise check if it is at the end and create a return.
  580. */
  581. if (dwSpcPos<m_pWin[dwWin].dwBufferSizeX && (dwPosBx+dwSpcPos)>m_pWin[dwWin].dwBufferSizeX)
  582. {
  583. /* Set NULL character */
  584. m_pWin[dwWin].pTextBuffer[dwCursorPos++] = 0;
  585. dwPosBx = 0;
  586. dwPosBy++;
  587. /* Set new cursor position */
  588. dwCursorPos = dwPosBy * m_pWin[dwWin].dwBufferSizeX;
  589. /* Don't go any further */
  590. continue;
  591. }
  592. }
  593. /* End of line */
  594. if (dwPosBx == (m_pWin[dwWin].dwBufferSizeX-1))
  595. {
  596. m_pWin[dwWin].pTextBuffer[dwCursorPos++] = 0;
  597. dwPosBx = 0;
  598. dwPosBy++;
  599. }
  600. /* Vertical Scroll */
  601. if (dwPosBy >= m_pWin[dwWin].dwBufferSizeY)
  602. {
  603. memcpy(m_pWin[dwWin].pTextBuffer,
  604. m_pWin[dwWin].pTextBuffer + m_pWin[dwWin].dwBufferSizeX,
  605. (m_pWin[dwWin].dwBufferSizeX-1) * m_pWin[dwWin].dwBufferSizeY);
  606. dwCursorPos -= m_pWin[dwWin].dwBufferSizeX;
  607. dwPosBx = 0;
  608. dwPosBy--;
  609. }
  610. /* Return */
  611. if (bChar == 0x0A)
  612. {
  613. /* Set NULL character */
  614. m_pWin[dwWin].pTextBuffer[dwCursorPos++] = 0;
  615. dwPosBx = 0;
  616. dwPosBy++;
  617. dwCursorPos = dwPosBy * m_pWin[dwWin].dwBufferSizeX;
  618. /* Don't go any further */
  619. continue;
  620. }
  621. /* Storing our character */
  622. if (dwCursorPos<dwBufferSize)
  623. {
  624. m_pWin[dwWin].pTextBuffer[dwCursorPos++] = bChar;
  625. }
  626. /* Increase position */
  627. dwPosBx++;
  628. }
  629. /* Automatic adjust of the window size */
  630. if (m_pWin[dwWin].dwFlags & Print3D_ADJUST_SIZE)
  631. {
  632. AdjustWindowSize(dwWin, 0);
  633. }
  634. #endif
  635. return PVR_SUCCESS;
  636. }
  637. /*!***************************************************************************
  638. @Function SetWindow
  639. @Input dwWin Window handle
  640. @Input dwWinColor Window colour
  641. @Input dwFontColor Font colour
  642. @Input fFontSize Font size
  643. @Input fPosX Window position X
  644. @Input fPosY Window position Y
  645. @Input fSizeX Window size X
  646. @Input fSizeY Window size Y
  647. @Description Set attributes of window.
  648. Windows position and size are referred to a virtual screen
  649. of 100x100. (0,0) is the top-left corner and (100,100) the
  650. bottom-right corner.
  651. These values are the same for all resolutions.
  652. *****************************************************************************/
  653. void CPVRTPrint3D::SetWindow(unsigned int dwWin, unsigned int dwWinColor, unsigned int dwFontColor, float fFontSize,
  654. float fPosX, float fPosY, float fSizeX, float fSizeY)
  655. {
  656. #if !defined (DISABLE_PRINT3D)
  657. /* Check if there is a real change */
  658. if( m_pWin[dwWin].fWinFontSize != fFontSize ||
  659. m_pWin[dwWin].dwWinFontColor != dwFontColor ||
  660. m_pWin[dwWin].dwWinBaseColor != dwWinColor ||
  661. m_pWin[dwWin].fWinPos[0] != fPosX * 640.0f/100.0f ||
  662. m_pWin[dwWin].fWinPos[1] != fPosY * 480.0f/100.0f ||
  663. m_pWin[dwWin].fWinSize[0] != fSizeX * 640.0f/100.0f ||
  664. m_pWin[dwWin].fWinSize[1] != fSizeY * 480.0f/100.0f)
  665. {
  666. /* Set window properties */
  667. m_pWin[dwWin].fWinFontSize = fFontSize;
  668. m_pWin[dwWin].dwWinFontColor = dwFontColor;
  669. m_pWin[dwWin].dwWinBaseColor = dwWinColor;
  670. m_pWin[dwWin].fWinPos[0] = fPosX * 640.0f/100.0f;
  671. m_pWin[dwWin].fWinPos[1] = fPosY * 480.0f/100.0f;
  672. m_pWin[dwWin].fWinSize[0] = fSizeX * 640.0f/100.0f;
  673. m_pWin[dwWin].fWinSize[1] = fSizeY * 480.0f/100.0f;
  674. m_pWin[dwWin].bNeedUpdated = true;
  675. }
  676. #endif
  677. }
  678. /*!***************************************************************************
  679. @Function SetTitle
  680. @Input dwWin Window handle
  681. @Input dwBackgroundColor Background color
  682. @Input fFontSize Font size
  683. @Input dwFontColorLeft
  684. @Input sTitleLeft
  685. @Input dwFontColorRight
  686. @Input sTitleRight
  687. @Description Set window title.
  688. *****************************************************************************/
  689. void CPVRTPrint3D::SetTitle(unsigned int dwWin, unsigned int dwBackgroundColor, float fFontSize,
  690. unsigned int dwFontColorLeft, char *sTitleLeft,
  691. unsigned int dwFontColorRight, char *sTitleRight)
  692. {
  693. #if !defined (DISABLE_PRINT3D)
  694. FREE(m_pWin[dwWin].pTitleVtxL);
  695. FREE(m_pWin[dwWin].pTitleVtxR);
  696. if(sTitleLeft) memcpy(m_pWin[dwWin].bTitleTextL, sTitleLeft , PVRT_MIN((size_t)(MAX_LETTERS-1), strlen(sTitleLeft )+1));
  697. if(sTitleRight) memcpy(m_pWin[dwWin].bTitleTextR, sTitleRight, PVRT_MIN((size_t)(MAX_LETTERS-1), strlen(sTitleRight)+1));
  698. /* Set title properties */
  699. m_pWin[dwWin].fTitleFontSize = fFontSize;
  700. m_pWin[dwWin].dwTitleFontColorL = dwFontColorLeft;
  701. m_pWin[dwWin].dwTitleFontColorR = dwFontColorRight;
  702. m_pWin[dwWin].dwTitleBaseColor = dwBackgroundColor;
  703. m_pWin[dwWin].fTextRMinPos = GetLength(m_pWin[dwWin].fTitleFontSize, m_pWin[dwWin].bTitleTextL) + 10.0f;
  704. m_pWin[dwWin].bNeedUpdated = true;
  705. #endif
  706. }
  707. /*!***************************************************************************
  708. @Function SetWindowFlags
  709. @Input dwWin Window handle
  710. @Input dwFlags Flags
  711. @Description Set flags for window referenced by dwWin.
  712. A list of flag can be found at the top of this header.
  713. *****************************************************************************/
  714. void CPVRTPrint3D::SetWindowFlags(unsigned int dwWin, unsigned int dwFlags)
  715. {
  716. #if !defined (DISABLE_PRINT3D)
  717. /* Check if there is need of updating vertex buffers */
  718. if( dwFlags & ePVRTPrint3D_ACTIVATE_TITLE ||
  719. dwFlags & ePVRTPrint3D_DEACTIVATE_TITLE ||
  720. dwFlags & ePVRTPrint3D_ADJUST_SIZE_ALWAYS)
  721. m_pWin[dwWin].bNeedUpdated = true;
  722. /* Set window flags */
  723. if (dwFlags & ePVRTPrint3D_ACTIVATE_WIN) m_pWin[dwWin].dwFlags |= Print3D_WIN_ACTIVE;
  724. if (dwFlags & ePVRTPrint3D_DEACTIVATE_WIN) m_pWin[dwWin].dwFlags &= ~Print3D_WIN_ACTIVE;
  725. if (dwFlags & ePVRTPrint3D_ACTIVATE_TITLE) m_pWin[dwWin].dwFlags |= Print3D_WIN_TITLE;
  726. if (dwFlags & ePVRTPrint3D_DEACTIVATE_TITLE) m_pWin[dwWin].dwFlags &= ~Print3D_WIN_TITLE;
  727. if (dwFlags & ePVRTPrint3D_FULL_OPAQUE) m_pWin[dwWin].dwFlags |= Print3D_FULL_OPAQUE;
  728. if (dwFlags & ePVRTPrint3D_FULL_TRANS) m_pWin[dwWin].dwFlags |= Print3D_FULL_TRANS;
  729. if (dwFlags & ePVRTPrint3D_ADJUST_SIZE_ALWAYS)
  730. {
  731. m_pWin[dwWin].dwFlags |= Print3D_ADJUST_SIZE;
  732. AdjustWindowSize(dwWin, 0);
  733. }
  734. if (dwFlags & ePVRTPrint3D_NO_BORDER) m_pWin[dwWin].dwFlags |= Print3D_NO_BORDER;
  735. #endif
  736. }
  737. /*!***************************************************************************
  738. @Function AdjustWindowSize
  739. @Input dwWin Window handle
  740. @Input dwMode dwMode 0 = Both, dwMode 1 = X only, dwMode 2 = Y only
  741. @Description Calculates window size so that all text fits in the window.
  742. *****************************************************************************/
  743. void CPVRTPrint3D::AdjustWindowSize(unsigned int dwWin, unsigned int dwMode)
  744. {
  745. #if !defined (DISABLE_PRINT3D)
  746. int unsigned i;
  747. unsigned int dwPointer = 0;
  748. float fMax = 0.0f, fLength;
  749. if (dwMode==1 || dwMode==0)
  750. {
  751. /* Title horizontal Size */
  752. if(m_pWin[dwWin].dwFlags & Print3D_WIN_TITLE)
  753. {
  754. fMax = GetLength(m_pWin[dwWin].fTitleFontSize, m_pWin[dwWin].bTitleTextL);
  755. if (m_pWin[dwWin].bTitleTextR)
  756. {
  757. fMax += GetLength(m_pWin[dwWin].fTitleFontSize, m_pWin[dwWin].bTitleTextR) + 12.0f;
  758. }
  759. }
  760. /* Body horizontal size (line by line) */
  761. for (i=0; i<m_pWin[dwWin].dwBufferSizeY; i++)
  762. {
  763. fLength = GetLength(m_pWin[dwWin].fWinFontSize, (m_pWin[dwWin].pTextBuffer + dwPointer));
  764. if (fLength > fMax) fMax = fLength;
  765. dwPointer += m_pWin[dwWin].dwBufferSizeX;
  766. }
  767. m_pWin[dwWin].fWinSize[0] = fMax - 2.0f + 16.0f;
  768. }
  769. /* Vertical Size */
  770. if(dwMode==0 || dwMode==2)
  771. {
  772. if(m_pWin[dwWin].dwBufferSizeY < 2)
  773. {
  774. i = 0;
  775. }
  776. else
  777. {
  778. /* Looking for the last line */
  779. i=m_pWin[dwWin].dwBufferSizeY;
  780. while(i)
  781. {
  782. --i;
  783. if (m_pWin[dwWin].pTextBuffer[m_pWin[dwWin].dwBufferSizeX * i])
  784. break;
  785. }
  786. }
  787. if (m_pWin[dwWin].fWinFontSize>0)
  788. m_pWin[dwWin].fWinSize[1] = (float)(i+1) * LINES_SPACING * m_pWin[dwWin].fWinFontSize + 16.0f;
  789. else
  790. m_pWin[dwWin].fWinSize[1] = ((float)(i+1) * 12.0f) + 16.0f;
  791. }
  792. m_pWin[dwWin].bNeedUpdated = true;
  793. #endif
  794. }
  795. /*!***************************************************************************
  796. @Function GetSize
  797. @Output pfWidth Width of the string in pixels
  798. @Output pfHeight Height of the string in pixels
  799. @Input fFontSize Font size
  800. @Input sString String to take the size of
  801. @Description Returns the size of a string in pixels.
  802. *****************************************************************************/
  803. void CPVRTPrint3D::GetSize(
  804. float * const pfWidth,
  805. float * const pfHeight,
  806. const float fFontSize,
  807. const char * sString)
  808. {
  809. #if !defined (DISABLE_PRINT3D)
  810. unsigned char Val;
  811. float fScale, fSize;
  812. if(sString == NULL) {
  813. if(pfWidth)
  814. *pfWidth = 0;
  815. if(pfHeight)
  816. *pfHeight = 0;
  817. return;
  818. }
  819. if(fFontSize > 0.0f) /* Arial font */
  820. {
  821. fScale = fFontSize;
  822. fSize = 0.0f;
  823. Val = *sString++;
  824. while(Val)
  825. {
  826. if(Val==' ')
  827. Val = '_';
  828. else if(Val>='0' && Val <= '9')
  829. Val = '0'; /* That's for fixing the number width */
  830. fSize += PVRTPrint3DSize_Bold[Val] * 40.0f * fScale ;
  831. /* these letters are too narrow due to a bug in the table */
  832. if(Val=='i' || Val == 'l' || Val == 'j')
  833. fSize += 0.4f* fScale;
  834. Val = *sString++;
  835. }
  836. if(pfHeight)
  837. *pfHeight = m_fScreenScale[1] * fScale * 27.0f * (100.0f / 640.0f);
  838. }
  839. else /* System font */
  840. {
  841. fScale = 255.0f;
  842. fSize = 0.0f;
  843. Val = *sString++;
  844. while (Val)
  845. {
  846. if(Val == ' ') {
  847. fSize += 5.0f;
  848. continue;
  849. }
  850. if(Val>='0' && Val <= '9')
  851. Val = '0'; /* That's for fixing the number width */
  852. fSize += PVRTPrint3DSize_System[Val] * fScale * (100.0f / 640.0f);
  853. Val = *sString++;
  854. }
  855. if(pfHeight)
  856. *pfHeight = m_fScreenScale[1] * 12.0f;
  857. }
  858. if(pfWidth)
  859. *pfWidth = fSize;
  860. #endif
  861. }
  862. /*!***************************************************************************
  863. @Function GetAspectRatio
  864. @Output dwScreenX Screen resolution X
  865. @Output dwScreenY Screen resolution Y
  866. @Description Returns the current resolution used by Print3D
  867. *****************************************************************************/
  868. void CPVRTPrint3D::GetAspectRatio(unsigned int *dwScreenX, unsigned int *dwScreenY)
  869. {
  870. #if !defined (DISABLE_PRINT3D)
  871. *dwScreenX = (int)(640.0f * m_fScreenScale[0]);
  872. *dwScreenY = (int)(480.0f * m_fScreenScale[1]);
  873. #endif
  874. }
  875. /*************************************************************
  876. * PRIVATE FUNCTIONS *
  877. **************************************************************/
  878. /*!***************************************************************************
  879. @Function UpdateBackgroundWindow
  880. @Return true if succesful, false otherwise.
  881. @Description Draw a generic rectangle (with or without border).
  882. *****************************************************************************/
  883. bool CPVRTPrint3D::UpdateBackgroundWindow(unsigned int /*dwWin*/, unsigned int Color, float fZPos, float fPosX, float fPosY, float fSizeX, float fSizeY, SPVRTPrint3DAPIVertex **ppVtx)
  884. {
  885. int i;
  886. SPVRTPrint3DAPIVertex *vBox;
  887. float fU[] = { 0.0f, 0.0f, 6.0f, 6.0f, 10.0f,10.0f, 16.0f,16.0f,10.0f,16.0f,10.0f,16.0f,6.0f,6.0f,0.0f,0.0f};
  888. float fV[] = { 0.0f, 6.0f, 0.0f, 6.0f, 0.0f, 6.0f, 0.0f, 6.0f, 10.0f, 10.0f, 16.0f,16.0f, 16.0f, 10.0f, 16.0f, 10.0f};
  889. /* Create our vertex buffers */
  890. if(*ppVtx==0)
  891. {
  892. *ppVtx = (SPVRTPrint3DAPIVertex*)malloc(16*sizeof(SPVRTPrint3DAPIVertex));
  893. if(!*ppVtx)
  894. return false;
  895. }
  896. vBox = *ppVtx;
  897. /* Removing the border */
  898. fSizeX -= 16.0f ;
  899. fSizeY -= 16.0f ;
  900. /* Set Z position, color and texture coordinates in array */
  901. for (i=0; i<16; i++)
  902. {
  903. vBox[i].sz = f2vt(fZPos);
  904. vBox[i].rhw = f2vt(1.0f);
  905. vBox[i].color = Color;
  906. vBox[i].tu = f2vt(fU[i]/16.0f);
  907. vBox[i].tv = f2vt(1.0f - fV[i]/16.0f);
  908. }
  909. /* Set coordinates in array */
  910. vBox[0].sx = f2vt((fPosX + fU[0]) * m_fScreenScale[0]);
  911. vBox[0].sy = f2vt((fPosY + fV[0]) * m_fScreenScale[1]);
  912. vBox[1].sx = f2vt((fPosX + fU[1]) * m_fScreenScale[0]);
  913. vBox[1].sy = f2vt((fPosY + fV[1]) * m_fScreenScale[1]);
  914. vBox[2].sx = f2vt((fPosX + fU[2]) * m_fScreenScale[0]);
  915. vBox[2].sy = f2vt((fPosY + fV[2]) * m_fScreenScale[1]);
  916. vBox[3].sx = f2vt((fPosX + fU[3]) * m_fScreenScale[0]);
  917. vBox[3].sy = f2vt((fPosY + fV[3]) * m_fScreenScale[1]);
  918. vBox[4].sx = f2vt((fPosX + fU[4] + fSizeX) * m_fScreenScale[0]);
  919. vBox[4].sy = f2vt((fPosY + fV[4]) * m_fScreenScale[1]);
  920. vBox[5].sx = f2vt((fPosX + fU[5] + fSizeX) * m_fScreenScale[0]);
  921. vBox[5].sy = f2vt((fPosY + fV[5]) * m_fScreenScale[1]);
  922. vBox[6].sx = f2vt((fPosX + fU[6] + fSizeX) * m_fScreenScale[0]);
  923. vBox[6].sy = f2vt((fPosY + fV[6]) * m_fScreenScale[1]);
  924. vBox[7].sx = f2vt((fPosX + fU[7] + fSizeX) * m_fScreenScale[0]);
  925. vBox[7].sy = f2vt((fPosY + fV[7]) * m_fScreenScale[1]);
  926. vBox[8].sx = f2vt((fPosX + fU[8] + fSizeX) * m_fScreenScale[0]);
  927. vBox[8].sy = f2vt((fPosY + fV[8] + fSizeY) * m_fScreenScale[1]);
  928. vBox[9].sx = f2vt((fPosX + fU[9] + fSizeX) * m_fScreenScale[0]);
  929. vBox[9].sy = f2vt((fPosY + fV[9] + fSizeY) * m_fScreenScale[1]);
  930. vBox[10].sx = f2vt((fPosX + fU[10] + fSizeX) * m_fScreenScale[0]);
  931. vBox[10].sy = f2vt((fPosY + fV[10] + fSizeY) * m_fScreenScale[1]);
  932. vBox[11].sx = f2vt((fPosX + fU[11] + fSizeX) * m_fScreenScale[0]);
  933. vBox[11].sy = f2vt((fPosY + fV[11] + fSizeY) * m_fScreenScale[1]);
  934. vBox[12].sx = f2vt((fPosX + fU[12]) * m_fScreenScale[0]);
  935. vBox[12].sy = f2vt((fPosY + fV[12] + fSizeY) * m_fScreenScale[1]);
  936. vBox[13].sx = f2vt((fPosX + fU[13]) * m_fScreenScale[0]);
  937. vBox[13].sy = f2vt((fPosY + fV[13] + fSizeY) * m_fScreenScale[1]);
  938. vBox[14].sx = f2vt((fPosX + fU[14]) * m_fScreenScale[0]);
  939. vBox[14].sy = f2vt((fPosY + fV[14] + fSizeY) * m_fScreenScale[1]);
  940. vBox[15].sx = f2vt((fPosX + fU[15]) * m_fScreenScale[0]);
  941. vBox[15].sy = f2vt((fPosY + fV[15] + fSizeY) * m_fScreenScale[1]);
  942. if(m_bRotate)
  943. Rotate(vBox, 16);
  944. /* No problem occured */
  945. return true;
  946. }
  947. /*!***************************************************************************
  948. @Function UpdateLine
  949. @Description
  950. *****************************************************************************/
  951. unsigned int CPVRTPrint3D::UpdateLine(const unsigned int dwWin, const float fZPos, float XPos, float YPos, const float fScale, const unsigned int Colour, const char * const Text, SPVRTPrint3DAPIVertex * const pVertices)
  952. {
  953. unsigned i=0, VertexCount=0;
  954. unsigned Val;
  955. float XSize = 0.0f, XFixBug, YSize = 0;
  956. float UPos, VPos;
  957. float USize, VSize;
  958. #if 0
  959. float fWinClipX[2],fWinClipY[2];
  960. #endif
  961. float fScaleX, fScaleY, fPreXPos;
  962. /* Nothing to update */
  963. if (Text==NULL) return 0;
  964. _ASSERT(m_pWin[dwWin].dwFlags & Print3D_WIN_EXIST || !dwWin);
  965. if (fScale>0)
  966. {
  967. fScaleX = m_fScreenScale[0] * fScale * 255.0f;
  968. fScaleY = m_fScreenScale[1] * fScale * 27.0f;
  969. }
  970. else
  971. {
  972. fScaleX = m_fScreenScale[0] * 255.0f;
  973. fScaleY = m_fScreenScale[1] * 12.0f;
  974. }
  975. XPos *= m_fScreenScale[0];
  976. YPos *= m_fScreenScale[1];
  977. fPreXPos = XPos;
  978. #if 0
  979. /*
  980. Calculating our margins
  981. */
  982. if (dwWin)
  983. {
  984. fWinClipX[0] = (m_pWin[dwWin].fWinPos[0] + 6.0f) * m_fScreenScale[0];
  985. fWinClipX[1] = (m_pWin[dwWin].fWinPos[0] + m_pWin[dwWin].fWinSize[0] - 6.0f) * m_fScreenScale[0];
  986. fWinClipY[0] = (m_pWin[dwWin].fWinPos[1] + 6.0f) * m_fScreenScale[1];
  987. fWinClipY[1] = (m_pWin[dwWin].fWinPos[1] + m_pWin[dwWin].fWinSize[1] + 9.0f) * m_fScreenScale[1];
  988. if(m_pWin[dwWin].dwFlags & Print3D_WIN_TITLE)
  989. {
  990. if (m_pWin[dwWin].fTitleFontSize>0)
  991. {
  992. fWinClipY[0] += m_pWin[dwWin].fTitleFontSize * 25.0f * m_fScreenScale[1];
  993. fWinClipY[1] += m_pWin[dwWin].fTitleFontSize * 25.0f * m_fScreenScale[1];
  994. }
  995. else
  996. {
  997. fWinClipY[0] += 10.0f * m_fScreenScale[1];
  998. fWinClipY[1] += 8.0f * m_fScreenScale[1];
  999. }
  1000. }
  1001. }
  1002. #endif
  1003. for(;;)
  1004. {
  1005. Val = (int)Text[i++];
  1006. /* End of the string */
  1007. if (Val==0 || i>MAX_LETTERS) break;
  1008. /* It is SPACE so don't draw and carry on... */
  1009. if (Val==' ')
  1010. {
  1011. if (fScale>0) XPos += 10.0f/255.0f * fScaleX;
  1012. else XPos += 5.0f * m_fScreenScale[0];
  1013. continue;
  1014. }
  1015. /* It is HASH so don't draw and carry on... */
  1016. if (Val=='#')
  1017. {
  1018. if (fScale>0) XPos += 1.0f/255.0f * fScaleX;
  1019. else XPos += 5.0f * m_fScreenScale[0];
  1020. continue;
  1021. }
  1022. /* It is RETURN so jump a line */
  1023. if (Val==0x0A)
  1024. {
  1025. XPos = fPreXPos - XSize;
  1026. YPos += YSize;
  1027. continue;
  1028. }
  1029. /* If fScale is negative then select the small set of letters (System) */
  1030. if (fScale < 0.0f)
  1031. {
  1032. XPos += XSize;
  1033. UPos = PVRTPrint3DU_System[Val];
  1034. VPos = PVRTPrint3DV_System[Val] - 0.0001f; /* Some cards need this little bit */
  1035. YSize = fScaleY;
  1036. XSize = PVRTPrint3DSize_System[Val] * fScaleX;
  1037. USize = PVRTPrint3DSize_System[Val];
  1038. VSize = 12.0f/255.0f;
  1039. }
  1040. else /* Big set of letters (Bold) */
  1041. {
  1042. XPos += XSize;
  1043. UPos = PVRTPrint3DU_Bold[Val];
  1044. VPos = PVRTPrint3DV_Bold[Val] - 1.0f/230.0f;
  1045. YSize = fScaleY;
  1046. XSize = PVRTPrint3DSize_Bold[Val] * fScaleX;
  1047. USize = PVRTPrint3DSize_Bold[Val];
  1048. VSize = 29.0f/255.0f;
  1049. }
  1050. /*
  1051. CLIPPING
  1052. */
  1053. XFixBug = XSize;
  1054. #if 0
  1055. if(dwWin) /* for dwWin==0 (screen) no clipping */
  1056. {
  1057. float TempSize;
  1058. /* Outside */
  1059. if (XPos>fWinClipX[1] || (YPos)>fWinClipY[1])
  1060. {
  1061. continue;
  1062. }
  1063. /* Clip X */
  1064. if (XPos<fWinClipX[1] && XPos+XSize > fWinClipX[1])
  1065. {
  1066. TempSize = XSize;
  1067. XSize = fWinClipX[1] - XPos;
  1068. if (fScale < 0.0f)
  1069. USize = PVRTPrint3DSize_System[Val] * (XSize/TempSize);
  1070. else
  1071. USize = PVRTPrint3DSize_Bold[Val] * (XSize/TempSize);
  1072. }
  1073. /*
  1074. Clip Y
  1075. */
  1076. if (YPos<fWinClipY[1] && YPos+YSize > fWinClipY[1])
  1077. {
  1078. TempSize = YSize;
  1079. YSize = fWinClipY[1] - YPos;
  1080. if(fScale < 0.0f)
  1081. VSize = (YSize/TempSize)*12.0f/255.0f;
  1082. else
  1083. VSize = (YSize/TempSize)*28.0f/255.0f;
  1084. }
  1085. }
  1086. #endif
  1087. /* Filling vertex data */
  1088. pVertices[VertexCount+0].sx = f2vt(XPos);
  1089. pVertices[VertexCount+0].sy = f2vt(YPos);
  1090. pVertices[VertexCount+0].sz = f2vt(fZPos);
  1091. pVertices[VertexCount+0].rhw = f2vt(1.0f);
  1092. pVertices[VertexCount+0].tu = f2vt(UPos);
  1093. pVertices[VertexCount+0].tv = f2vt(VPos);
  1094. pVertices[VertexCount+1].sx = f2vt(XPos+XSize);
  1095. pVertices[VertexCount+1].sy = f2vt(YPos);
  1096. pVertices[VertexCount+1].sz = f2vt(fZPos);
  1097. pVertices[VertexCount+1].rhw = f2vt(1.0f);
  1098. pVertices[VertexCount+1].tu = f2vt(UPos+USize);
  1099. pVertices[VertexCount+1].tv = f2vt(VPos);
  1100. pVertices[VertexCount+2].sx = f2vt(XPos);
  1101. pVertices[VertexCount+2].sy = f2vt(YPos+YSize);
  1102. pVertices[VertexCount+2].sz = f2vt(fZPos);
  1103. pVertices[VertexCount+2].rhw = f2vt(1.0f);
  1104. pVertices[VertexCount+2].tu = f2vt(UPos);
  1105. pVertices[VertexCount+2].tv = f2vt(VPos-VSize);
  1106. pVertices[VertexCount+3].sx = f2vt(XPos+XSize);
  1107. pVertices[VertexCount+3].sy = f2vt(YPos+YSize);
  1108. pVertices[VertexCount+3].sz = f2vt(fZPos);
  1109. pVertices[VertexCount+3].rhw = f2vt(1.0f);
  1110. pVertices[VertexCount+3].tu = f2vt(UPos+USize);
  1111. pVertices[VertexCount+3].tv = f2vt(VPos-VSize);
  1112. pVertices[VertexCount+0].color = Colour;
  1113. pVertices[VertexCount+1].color = Colour;
  1114. pVertices[VertexCount+2].color = Colour;
  1115. pVertices[VertexCount+3].color = Colour;
  1116. VertexCount += 4;
  1117. XSize = XFixBug;
  1118. /* Fix number width */
  1119. if (Val >='0' && Val <='9')
  1120. {
  1121. if (fScale < 0.0f)
  1122. XSize = PVRTPrint3DSize_System[(int)'0'] * fScaleX;
  1123. else
  1124. XSize = PVRTPrint3DSize_Bold[(int)'0'] * fScaleX;
  1125. }
  1126. }
  1127. if(m_bRotate)
  1128. Rotate(pVertices, VertexCount);
  1129. return VertexCount;
  1130. }
  1131. /*!***************************************************************************
  1132. @Function DrawLineUP
  1133. @Return true or false
  1134. @Description Draw a single line of text.
  1135. *****************************************************************************/
  1136. bool CPVRTPrint3D::DrawLineUP(SPVRTPrint3DAPIVertex *pVtx, unsigned int nVertices)
  1137. {
  1138. if(!nVertices)
  1139. return true;
  1140. _ASSERT((nVertices % 4) == 0);
  1141. _ASSERT((nVertices/4) < MAX_LETTERS);
  1142. while(m_nVtxCache + (int)nVertices > m_nVtxCacheMax) {
  1143. if(m_nVtxCache + nVertices > MAX_CACHED_VTX) {
  1144. _RPT1(_CRT_WARN, "Print3D: Out of space to cache text! (More than %d vertices!)\n", MAX_CACHED_VTX);
  1145. return false;
  1146. }
  1147. m_nVtxCacheMax = PVRT_MIN(m_nVtxCacheMax * 2, MAX_CACHED_VTX);
  1148. m_pVtxCache = (SPVRTPrint3DAPIVertex*)realloc(m_pVtxCache, m_nVtxCacheMax * sizeof(*m_pVtxCache));
  1149. _ASSERT(m_pVtxCache);
  1150. _RPT1(_CRT_WARN, "Print3D: TextCache increased to %d vertices.\n", m_nVtxCacheMax);
  1151. }
  1152. memcpy(&m_pVtxCache[m_nVtxCache], pVtx, nVertices * sizeof(*pVtx));
  1153. m_nVtxCache += nVertices;
  1154. return true;
  1155. }
  1156. /*!***************************************************************************
  1157. @Function UpdateTitleVertexBuffer
  1158. @Return true or false
  1159. @Description
  1160. *****************************************************************************/
  1161. bool CPVRTPrint3D::UpdateTitleVertexBuffer(unsigned int dwWin)
  1162. {
  1163. float fRPos;
  1164. unsigned int dwLenL = 0, dwLenR = 0;
  1165. /* Doesn't exist */
  1166. if (!(m_pWin[dwWin].dwFlags & Print3D_WIN_EXIST) && dwWin)
  1167. return false;
  1168. /* Allocate our buffers if needed */
  1169. if(m_pWin[dwWin].pTitleVtxL==0 || m_pWin[dwWin].pTitleVtxR==0)
  1170. {
  1171. dwLenL = (unsigned int)strlen(m_pWin[dwWin].bTitleTextL);
  1172. FREE(m_pWin[dwWin].pTitleVtxL);
  1173. if(dwLenL)
  1174. m_pWin[dwWin].pTitleVtxL = (SPVRTPrint3DAPIVertex*)malloc(dwLenL*4*sizeof(SPVRTPrint3DAPIVertex));
  1175. dwLenR = m_pWin[dwWin].bTitleTextR ? (unsigned int)strlen(m_pWin[dwWin].bTitleTextR) : 0;
  1176. FREE(m_pWin[dwWin].pTitleVtxR);
  1177. if(dwLenR)
  1178. m_pWin[dwWin].pTitleVtxR = (SPVRTPrint3DAPIVertex*)malloc(dwLenR*4*sizeof(SPVRTPrint3DAPIVertex));
  1179. }
  1180. /* Left title */
  1181. if (dwLenL)
  1182. {
  1183. m_pWin[dwWin].nTitleVerticesL = UpdateLine(dwWin, 0.0f,
  1184. (m_pWin[dwWin].fWinPos[0] + 6.0f),
  1185. (m_pWin[dwWin].fWinPos[1] + 7.0f),
  1186. m_pWin[dwWin].fTitleFontSize,
  1187. m_pWin[dwWin].dwTitleFontColorL,
  1188. m_pWin[dwWin].bTitleTextL,
  1189. m_pWin[dwWin].pTitleVtxL);
  1190. }
  1191. else
  1192. {
  1193. m_pWin[dwWin].nTitleVerticesL = 0;
  1194. m_pWin[dwWin].pTitleVtxL = NULL;
  1195. }
  1196. /* Right title */
  1197. if (dwLenR)
  1198. {
  1199. /* Compute position */
  1200. fRPos = GetLength(m_pWin[dwWin].fTitleFontSize,m_pWin[dwWin].bTitleTextR);
  1201. fRPos = m_pWin[dwWin].fWinSize[0] - fRPos - 6.0f;
  1202. /* Check that we're not under minimum position */
  1203. if(fRPos<m_pWin[dwWin].fTextRMinPos)
  1204. fRPos = m_pWin[dwWin].fTextRMinPos;
  1205. /* Add window position */
  1206. fRPos += m_pWin[dwWin].fWinPos[0];
  1207. /* Print text */
  1208. m_pWin[dwWin].nTitleVerticesR = UpdateLine(dwWin, 0.0f,
  1209. fRPos,
  1210. m_pWin[dwWin].fWinPos[1] + 7.0f,
  1211. m_pWin[dwWin].fTitleFontSize,
  1212. m_pWin[dwWin].dwTitleFontColorR,
  1213. m_pWin[dwWin].bTitleTextR,
  1214. m_pWin[dwWin].pTitleVtxR);
  1215. }
  1216. else
  1217. {
  1218. m_pWin[dwWin].nTitleVerticesR = 0;
  1219. m_pWin[dwWin].pTitleVtxR = NULL;
  1220. }
  1221. return true;
  1222. }
  1223. /*!***************************************************************************
  1224. @Function UpdateMainTextVertexBuffer
  1225. @Return true or false
  1226. @Description
  1227. *****************************************************************************/
  1228. bool CPVRTPrint3D::UpdateMainTextVertexBuffer(unsigned int dwWin)
  1229. {
  1230. int i;
  1231. float fNewPos, fTitleSize;
  1232. unsigned int dwPointer = 0, dwLen;
  1233. /* Doesn't exist */
  1234. if (!(m_pWin[dwWin].dwFlags & Print3D_WIN_EXIST) && dwWin) return false;
  1235. /* No text to update vertices */
  1236. if(m_pWin[dwWin].pTextBuffer==NULL) return true;
  1237. /* Well, once we've got our text, allocate it to draw it later */
  1238. /* Text, line by line */
  1239. for (i = 0; i < (int) m_pWin[dwWin].dwBufferSizeY; i++)
  1240. {
  1241. /* line length */
  1242. dwLen = (unsigned int)strlen(&m_pWin[dwWin].pTextBuffer[dwPointer]);
  1243. if(dwLen==0)
  1244. {
  1245. m_pWin[dwWin].nLineVertices[i] = 0;
  1246. m_pWin[dwWin].pLineVtx[i] = NULL;
  1247. }
  1248. else
  1249. {
  1250. /* Create Vertex Buffer (one per line) */
  1251. if (m_pWin[dwWin].pLineVtx[i]==0)
  1252. {
  1253. m_pWin[dwWin].pLineVtx[i] = (SPVRTPrint3DAPIVertex*)malloc(m_pWin[dwWin].dwBufferSizeX *4*sizeof(SPVRTPrint3DAPIVertex));
  1254. if(!m_pWin[dwWin].pLineVtx[i])
  1255. return false;
  1256. }
  1257. /* Compute new text position */
  1258. fTitleSize = 0.0f;
  1259. if(m_pWin[dwWin].fTitleFontSize < 0.0f)
  1260. {
  1261. /* New position for alternate font */
  1262. if(m_pWin[dwWin].dwFlags & Print3D_WIN_TITLE)
  1263. fTitleSize = 8.0f +16;
  1264. fNewPos = fTitleSize + (float)(i * 12.0f);
  1265. }
  1266. else
  1267. {
  1268. /* New position for normal font */
  1269. if(m_pWin[dwWin].dwFlags & Print3D_WIN_TITLE)
  1270. fTitleSize = m_pWin[dwWin].fTitleFontSize * 23.5f + 16.0f;
  1271. fNewPos = fTitleSize + (float)(i * m_pWin[dwWin].fWinFontSize) * LINES_SPACING;
  1272. }
  1273. /* Print window text */
  1274. m_pWin[dwWin].nLineVertices[i] = UpdateLine(dwWin, 0.0f,
  1275. (m_pWin[dwWin].fWinPos[0] + 6.0f),
  1276. (m_pWin[dwWin].fWinPos[1] + 6.0f + fNewPos),
  1277. m_pWin[dwWin].fWinFontSize, m_pWin[dwWin].dwWinFontColor,
  1278. &m_pWin[dwWin].pTextBuffer[dwPointer],
  1279. m_pWin[dwWin].pLineVtx[i]);
  1280. }
  1281. /* Increase pointer */
  1282. dwPointer += m_pWin[dwWin].dwBufferSizeX;
  1283. }
  1284. return true;
  1285. }
  1286. /*!***************************************************************************
  1287. @Function GetLength
  1288. @Description calculates the size in pixels.
  1289. *****************************************************************************/
  1290. float CPVRTPrint3D::GetLength(float fFontSize, char *sString)
  1291. {
  1292. unsigned char Val;
  1293. float fScale, fSize;
  1294. if(sString == NULL)
  1295. return 0.0f;
  1296. if (fFontSize>=0) /* Arial font */
  1297. {
  1298. fScale = fFontSize * 255.0f;
  1299. fSize = 0.0f;
  1300. Val = *sString++;
  1301. while (Val)
  1302. {
  1303. if(Val==' ')
  1304. {
  1305. fSize += 10.0f * fFontSize;
  1306. }
  1307. else
  1308. {
  1309. if(Val>='0' && Val <= '9') Val = '0'; /* That's for fixing the number width */
  1310. fSize += PVRTPrint3DSize_Bold[Val] * fScale ;
  1311. }
  1312. Val = *sString++;
  1313. }
  1314. }
  1315. else /* System font */
  1316. {
  1317. fScale = 255.0f;
  1318. fSize = 0.0f;
  1319. Val = *sString++;
  1320. while (Val)
  1321. {
  1322. if (Val==' ')
  1323. {
  1324. fSize += 5.0f;
  1325. }
  1326. else
  1327. {
  1328. if(Val>='0' && Val <= '9') Val = '0'; /* That's for fixing the number width */
  1329. fSize += PVRTPrint3DSize_System[Val] * fScale;
  1330. }
  1331. Val = *sString++;
  1332. }
  1333. }
  1334. return (fSize);
  1335. }
  1336. void CPVRTPrint3D::Rotate(SPVRTPrint3DAPIVertex * const pv, const unsigned int nCnt)
  1337. {
  1338. unsigned int i;
  1339. VERTTYPE x, y;
  1340. for(i = 0; i < nCnt; ++i)
  1341. {
  1342. x = VERTTYPEDIV((VERTTYPE&)pv[i].sx, f2vt(640.0f * m_fScreenScale[0]));
  1343. y = VERTTYPEDIV((VERTTYPE&)pv[i].sy, f2vt(480.0f * m_fScreenScale[1]));
  1344. (VERTTYPE&)pv[i].sx = VERTTYPEMUL(y, f2vt(640.0f * m_fScreenScale[0]));
  1345. (VERTTYPE&)pv[i].sy = VERTTYPEMUL(f2vt(1.0f) - x, f2vt(480.0f * m_fScreenScale[1]));
  1346. }
  1347. }
  1348. /****************************************************************************
  1349. ** Local code
  1350. ****************************************************************************/
  1351. /*****************************************************************************
  1352. End of file (PVRTPrint3D.cpp)
  1353. *****************************************************************************/