offscr8bpp.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. //*****************************************************************************
  2. //
  3. // offscr8bpp.c - 8 BPP off-screen display buffer driver.
  4. //
  5. // Copyright (c) 2008-2010 Texas Instruments Incorporated. All rights reserved.
  6. // Software License Agreement
  7. //
  8. // Texas Instruments (TI) is supplying this software for use solely and
  9. // exclusively on TI's microcontroller products. The software is owned by
  10. // TI and/or its suppliers, and is protected under applicable copyright
  11. // laws. You may not combine this software with "viral" open-source
  12. // software in order to form a larger program.
  13. //
  14. // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
  15. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
  16. // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
  18. // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
  19. // DAMAGES, FOR ANY REASON WHATSOEVER.
  20. //
  21. // This is part of revision 6288 of the Stellaris Graphics Library.
  22. //
  23. //*****************************************************************************
  24. #include "debug.h"
  25. #include "grlib.h"
  26. //*****************************************************************************
  27. //
  28. //! \addtogroup primitives_api
  29. //! @{
  30. //
  31. //*****************************************************************************
  32. //*****************************************************************************
  33. //
  34. //! Translates a 24-bit RGB color to a display driver-specific color.
  35. //!
  36. //! \param pvDisplayData is a pointer to the driver-specific data for this
  37. //! display driver.
  38. //! \param ulValue is the 24-bit RGB color. The least-significant byte is the
  39. //! blue channel, the next byte is the green channel, and the third byte is the
  40. //! red channel.
  41. //!
  42. //! This function translates a 24-bit RGB color into a value that can be
  43. //! written into the display's frame buffer in order to reproduce that color,
  44. //! or the closest possible approximation of that color.
  45. //!
  46. //! \return Returns the display-driver specific color.
  47. //
  48. //*****************************************************************************
  49. static unsigned int
  50. GrOffScreen8BPPColorTranslate(void *pvDisplayData, unsigned int ulValue)
  51. {
  52. unsigned int ulIdx, ulDiff, ulMatchIdx, ulMatchDiff, ulR, ulG, ulB;
  53. unsigned char *pucPalette;
  54. //
  55. // Check the arguments.
  56. //
  57. ASSERT(pvDisplayData);
  58. //
  59. // Get a pointer to the palette for the off-screen buffer.
  60. //
  61. pucPalette = (unsigned char *)pvDisplayData + 6;
  62. //
  63. // Extract the red, green, and blue component from the input color.
  64. //
  65. ulR = (ulValue >> ClrRedShift) & 0xff;
  66. ulG = (ulValue >> ClrGreenShift) & 0xff;
  67. ulB = (ulValue >> ClrBlueShift) & 0xff;
  68. //
  69. // Set the match such that the first palette entry will be a better match.
  70. //
  71. ulMatchIdx = 0;
  72. ulMatchDiff = 0xffffffff;
  73. //
  74. // Loop through the colors in the palette.
  75. //
  76. for(ulIdx = 0; ulIdx < 256; ulIdx++, pucPalette += 3)
  77. {
  78. //
  79. // Compute the Cartesian distance between these two colors.
  80. //
  81. ulDiff = (((pucPalette[2] - ulR) * (pucPalette[2] - ulR)) +
  82. ((pucPalette[1] - ulG) * (pucPalette[1] - ulG)) +
  83. ((pucPalette[0] - ulB) * (pucPalette[0] - ulB)));
  84. //
  85. // See if this color is a closer match than any of the previous colors.
  86. //
  87. if(ulDiff < ulMatchDiff)
  88. {
  89. //
  90. // Save this color as the new best match.
  91. //
  92. ulMatchDiff = ulDiff;
  93. ulMatchIdx = ulIdx;
  94. }
  95. //
  96. // Stop looking if an exact match was found.
  97. //
  98. if(ulDiff == 0)
  99. {
  100. break;
  101. }
  102. }
  103. //
  104. // Return the index of the best match.
  105. //
  106. return(ulMatchIdx);
  107. }
  108. //*****************************************************************************
  109. //
  110. //! Draws a pixel on the screen.
  111. //!
  112. //! \param pvDisplayData is a pointer to the driver-specific data for this
  113. //! display driver.
  114. //! \param lX is the X coordinate of the pixel.
  115. //! \param lY is the Y coordinate of the pixel.
  116. //! \param ulValue is the color of the pixel.
  117. //!
  118. //! This function sets the given pixel to a particular color. The coordinates
  119. //! of the pixel are assumed to be within the extents of the display.
  120. //!
  121. //! \return None.
  122. //
  123. //*****************************************************************************
  124. static void
  125. GrOffScreen8BPPPixelDraw(void *pvDisplayData, int lX, int lY,
  126. unsigned int ulValue)
  127. {
  128. unsigned char *pucData;
  129. //
  130. // Check the arguments.
  131. //
  132. ASSERT(pvDisplayData);
  133. //
  134. // Create a character pointer for the display-specific data (which points
  135. // to the image buffer).
  136. //
  137. pucData = (unsigned char *)pvDisplayData;
  138. //
  139. // Get the offset to the byte of the image buffer that contains the pixel
  140. // in question.
  141. //
  142. pucData += (*(unsigned short *)(pucData + 1) * lY) + lX + 6 + (256 * 3);
  143. //
  144. // Write this pixel into the image buffer.
  145. //
  146. *pucData = ulValue;
  147. }
  148. //*****************************************************************************
  149. //
  150. //! Draws a horizontal sequence of pixels on the screen.
  151. //!
  152. //! \param pvDisplayData is a pointer to the driver-specific data for this
  153. //! display driver.
  154. //! \param lX is the X coordinate of the first pixel.
  155. //! \param lY is the Y coordinate of the first pixel.
  156. //! \param lX0 is sub-pixel offset within the pixel data, which is valid for 1
  157. //! or 4 bit per pixel formats.
  158. //! \param lCount is the number of pixels to draw.
  159. //! \param lBPP is the number of bits per pixel; must be 1, 4, or 8.
  160. //! \param pucData is a pointer to the pixel data. For 1 and 4 bit per pixel
  161. //! formats, the most significant bit(s) represent the left-most pixel.
  162. //! \param pucPalette is a pointer to the palette used to draw the pixels.
  163. //!
  164. //! This function draws a horizontal sequence of pixels on the screen, using
  165. //! the supplied palette. For 1 bit per pixel format, the palette contains
  166. //! pre-translated colors; for 4 and 8 bit per pixel formats, the palette
  167. //! contains 24-bit RGB values that must be translated before being written to
  168. //! the display.
  169. //!
  170. //! \return None.
  171. //
  172. //*****************************************************************************
  173. static void
  174. GrOffScreen8BPPPixelDrawMultiple(void *pvDisplayData, int lX, int lY,
  175. int lX0, int lCount, int lBPP,
  176. const unsigned char *pucData,
  177. const unsigned char *pucPalette)
  178. {
  179. unsigned char *pucPtr;
  180. unsigned int ulByte;
  181. //
  182. // Check the arguments.
  183. //
  184. ASSERT(pvDisplayData);
  185. ASSERT(pucData);
  186. ASSERT(pucPalette);
  187. //
  188. // Create a character pointer for the display-specific data (which points
  189. // to the image buffer).
  190. //
  191. pucPtr = (unsigned char *)pvDisplayData;
  192. //
  193. // Get the offset to the byte of the image buffer that contains the
  194. // starting pixel.
  195. //
  196. pucPtr += (*(unsigned short *)(pucPtr + 1) * lY) + lX + 6 + (256 * 3);
  197. //
  198. // Determine how to interpret the pixel data based on the number of bits
  199. // per pixel.
  200. //
  201. switch(lBPP)
  202. {
  203. //
  204. // The pixel data is in 1 bit per pixel format.
  205. //
  206. case 1:
  207. {
  208. //
  209. // Loop while there are more pixels to draw.
  210. //
  211. while(lCount)
  212. {
  213. //
  214. // Get the next byte of image data.
  215. //
  216. ulByte = *pucData++;
  217. //
  218. // Loop through the pixels in this byte of image data.
  219. //
  220. for(; (lX0 < 8) && lCount; lX0++, lCount--)
  221. {
  222. //
  223. // Draw this pixel in the appropriate color.
  224. //
  225. *pucPtr++ = (((unsigned int *)pucPalette)[(ulByte >>
  226. (7 - lX0)) &
  227. 1]);
  228. }
  229. //
  230. // Start at the beginning of the next byte of image data.
  231. //
  232. lX0 = 0;
  233. }
  234. //
  235. // The image data has been drawn.
  236. //
  237. break;
  238. }
  239. //
  240. // The pixel data is in 4 bit per pixel format.
  241. //
  242. case 4:
  243. {
  244. //
  245. // Loop while there are more pixels to draw. "Duff's device" is
  246. // used to jump into the middle of the loop if the first nibble of
  247. // the pixel data should not be used. Duff's device makes use of
  248. // the fact that a case statement is legal anywhere within a
  249. // sub-block of a switch statement. See
  250. // http://en.wikipedia.org/wiki/Duff's_device for detailed
  251. // information about Duff's device.
  252. //
  253. switch(lX0 & 1)
  254. {
  255. case 0:
  256. while(lCount)
  257. {
  258. //
  259. // Get the upper nibble of the next byte of pixel data
  260. // and extract the corresponding entry from the
  261. // palette.
  262. //
  263. ulByte = (*pucData >> 4) * 3;
  264. ulByte = (*(unsigned int *)(pucPalette + ulByte) &
  265. 0x00ffffff);
  266. //
  267. // Translate this palette entry and write it to the
  268. // screen.
  269. //
  270. *pucPtr++ =
  271. GrOffScreen8BPPColorTranslate(pvDisplayData,
  272. ulByte);
  273. //
  274. // Decrement the count of pixels to draw.
  275. //
  276. lCount--;
  277. //
  278. // See if there is another pixel to draw.
  279. //
  280. if(lCount)
  281. {
  282. case 1:
  283. //
  284. // Get the lower nibble of the next byte of pixel
  285. // data and extract the corresponding entry from
  286. // the palette.
  287. //
  288. ulByte = (*pucData++ & 15) * 3;
  289. ulByte = (*(unsigned int *)(pucPalette + ulByte) &
  290. 0x00ffffff);
  291. //
  292. // Translate this palette entry and write it to the
  293. // screen.
  294. //
  295. *pucPtr++ =
  296. GrOffScreen8BPPColorTranslate(pvDisplayData,
  297. ulByte);
  298. //
  299. // Decrement the count of pixels to draw.
  300. //
  301. lCount--;
  302. }
  303. }
  304. }
  305. //
  306. // The image data has been drawn.
  307. //
  308. break;
  309. }
  310. //
  311. // The pixel data is in 8 bit per pixel format.
  312. //
  313. case 8:
  314. {
  315. //
  316. // Loop while there are more pixels to draw.
  317. //
  318. while(lCount--)
  319. {
  320. //
  321. // Get the next byte of pixel data and extract the
  322. // corresponding entry from the palette.
  323. //
  324. ulByte = *pucData++ * 3;
  325. ulByte = *(unsigned int *)(pucPalette + ulByte) & 0x00ffffff;
  326. //
  327. // Translate this palette entry and write it to the screen.
  328. //
  329. *pucPtr++ = GrOffScreen8BPPColorTranslate(pvDisplayData,
  330. ulByte);
  331. }
  332. //
  333. // The image data has been drawn.
  334. //
  335. break;
  336. }
  337. }
  338. }
  339. //*****************************************************************************
  340. //
  341. //! Draws a horizontal line.
  342. //!
  343. //! \param pvDisplayData is a pointer to the driver-specific data for this
  344. //! display driver.
  345. //! \param lX1 is the X coordinate of the start of the line.
  346. //! \param lX2 is the X coordinate of the end of the line.
  347. //! \param lY is the Y coordinate of the line.
  348. //! \param ulValue is the color of the line.
  349. //!
  350. //! This function draws a horizontal line on the display. The coordinates of
  351. //! the line are assumed to be within the extents of the display.
  352. //!
  353. //! \return None.
  354. //
  355. //*****************************************************************************
  356. static void
  357. GrOffScreen8BPPLineDrawH(void *pvDisplayData, int lX1, int lX2, int lY,
  358. unsigned int ulValue)
  359. {
  360. unsigned char *pucData;
  361. //
  362. // Check the arguments.
  363. //
  364. ASSERT(pvDisplayData);
  365. //
  366. // Create a character pointer for the display-specific data (which points
  367. // to the image buffer).
  368. //
  369. pucData = (unsigned char *)pvDisplayData;
  370. //
  371. // Get the offset to the byte of the image buffer that contains the
  372. // starting pixel.
  373. //
  374. pucData += (*(unsigned short *)(pucData + 1) * lY) + lX1 + 6 + (256 * 3);
  375. //
  376. // Copy the pixel value into all 4 pixels of the unsigned int. This will
  377. // be used later to write multiple pixels into memory (as opposed to one at
  378. // a time).
  379. //
  380. ulValue = (ulValue << 24) | (ulValue << 16) | (ulValue << 8) | ulValue;
  381. //
  382. // See if the buffer pointer is not half-word aligned.
  383. //
  384. if(((unsigned int)pucData) & 1)
  385. {
  386. //
  387. // Draw one pixel to half-word align the buffer pointer.
  388. //
  389. *pucData++ = ulValue & 0xff;
  390. lX1++;
  391. }
  392. //
  393. // See if the buffer pointer is not word aligned and there are at least two
  394. // pixels left to draw.
  395. //
  396. if(((unsigned int)pucData & 2) && ((lX2 - lX1) > 0))
  397. {
  398. //
  399. // Draw two pixels to word align the buffer pointer.
  400. //
  401. *(unsigned short *)pucData = ulValue & 0xffff;
  402. pucData += 2;
  403. lX1 += 2;
  404. }
  405. //
  406. // Loop while there are at least four pixels left to draw.
  407. //
  408. while((lX1 + 3) <= lX2)
  409. {
  410. //
  411. // Draw four pixels.
  412. //
  413. *(unsigned int *)pucData = ulValue;
  414. pucData += 4;
  415. lX1 += 4;
  416. }
  417. //
  418. // See if there are at least two pixels left to draw.
  419. //
  420. if((lX1 + 1) <= lX2)
  421. {
  422. //
  423. // Draw two pixels, leaving the buffer pointer half-word aligned.
  424. //
  425. *(unsigned short *)pucData = ulValue & 0xffff;
  426. pucData += 2;
  427. lX1 += 2;
  428. }
  429. //
  430. // See if there is one pixel left to draw.
  431. //
  432. if(lX1 == lX2)
  433. {
  434. //
  435. // Draw the final pixel.
  436. //
  437. *pucData = ulValue & 0xff;
  438. }
  439. }
  440. //*****************************************************************************
  441. //
  442. //! Draws a vertical line.
  443. //!
  444. //! \param pvDisplayData is a pointer to the driver-specific data for this
  445. //! display driver.
  446. //! \param lX is the X coordinate of the line.
  447. //! \param lY1 is the Y coordinate of the start of the line.
  448. //! \param lY2 is the Y coordinate of the end of the line.
  449. //! \param ulValue is the color of the line.
  450. //!
  451. //! This function draws a vertical line on the display. The coordinates of the
  452. //! line are assumed to be within the extents of the display.
  453. //!
  454. //! \return None.
  455. //
  456. //*****************************************************************************
  457. static void
  458. GrOffScreen8BPPLineDrawV(void *pvDisplayData, int lX, int lY1, int lY2,
  459. unsigned int ulValue)
  460. {
  461. unsigned char *pucData;
  462. int lBytesPerRow;
  463. //
  464. // Check the arguments.
  465. //
  466. ASSERT(pvDisplayData);
  467. //
  468. // Create a character pointer for the display-specific data (which points
  469. // to the image buffer).
  470. //
  471. pucData = (unsigned char *)pvDisplayData;
  472. //
  473. // Compute the number of bytes per row in the image buffer.
  474. //
  475. lBytesPerRow = *(unsigned short *)(pucData + 1);
  476. //
  477. // Get the offset to the byte of the image buffer that contains the
  478. // starting pixel.
  479. //
  480. pucData += (lBytesPerRow * lY1) + lX + 6 + (256 * 3);
  481. //
  482. // Loop over the rows of the line.
  483. //
  484. for(; lY1 <= lY2; lY1++)
  485. {
  486. *pucData = ulValue;
  487. pucData += lBytesPerRow;
  488. }
  489. }
  490. //*****************************************************************************
  491. //
  492. //! Fills a rectangle.
  493. //!
  494. //! \param pvDisplayData is a pointer to the driver-specific data for this
  495. //! display driver.
  496. //! \param pRect is a pointer to the structure describing the rectangle.
  497. //! \param ulValue is the color of the rectangle.
  498. //!
  499. //! This function fills a rectangle on the display. The coordinates of the
  500. //! rectangle are assumed to be within the extents of the display, and the
  501. //! rectangle specification is fully inclusive (in other words, both sXMin and
  502. //! sXMax are drawn, along with sYMin and sYMax).
  503. //!
  504. //! \return None.
  505. //
  506. //*****************************************************************************
  507. static void
  508. GrOffScreen8BPPRectFill(void *pvDisplayData, const tRectangle *pRect,
  509. unsigned int ulValue)
  510. {
  511. unsigned char *pucData, *pucPtr;
  512. int lBytesPerRow, lX, lY;
  513. //
  514. // Check the arguments.
  515. //
  516. ASSERT(pvDisplayData);
  517. ASSERT(pRect);
  518. //
  519. // Create a character pointer for the display-specific data (which points
  520. // to the image buffer).
  521. //
  522. pucData = (unsigned char *)pvDisplayData;
  523. //
  524. // Compute the number of bytes per row in the image buffer.
  525. //
  526. lBytesPerRow = *(unsigned short *)(pucData + 1);
  527. //
  528. // Get the offset to the byte of the image buffer that contains the
  529. // starting pixel.
  530. //
  531. pucData += (lBytesPerRow * pRect->sYMin) + pRect->sXMin + 6 + (256 * 3);
  532. //
  533. // Copy the pixel value into all 4 pixels of the unsigned int. This will
  534. // be used later to write multiple pixels into memory (as opposed to one at
  535. // a time).
  536. //
  537. ulValue = (ulValue << 24) | (ulValue << 16) | (ulValue << 8) | ulValue;
  538. //
  539. // Get the starting X coordinate.
  540. //
  541. lX = pRect->sXMin;
  542. //
  543. // See if the buffer pointer is not half-word aligned.
  544. //
  545. if(((unsigned int)pucData) & 1)
  546. {
  547. //
  548. // Draw one pixel column to half-word align the buffer pointer.
  549. //
  550. for(lY = pRect->sYMin, pucPtr = pucData; lY <= pRect->sYMax;
  551. lY++, pucPtr += lBytesPerRow)
  552. {
  553. *pucPtr = ulValue & 0xff;
  554. }
  555. pucData++;
  556. lX++;
  557. }
  558. //
  559. // See if the buffer pointer is not word aligned and there are at least two
  560. // pixel columns left to draw.
  561. //
  562. if(((unsigned int)pucData & 2) && ((pRect->sXMax - lX) > 0))
  563. {
  564. //
  565. // Draw two pixel columns to word align the buffer pointer.
  566. //
  567. for(lY = pRect->sYMin, pucPtr = pucData; lY <= pRect->sYMax;
  568. lY++, pucPtr += lBytesPerRow)
  569. {
  570. *(unsigned short *)pucPtr = ulValue & 0xffff;
  571. }
  572. pucData += 2;
  573. lX += 2;
  574. }
  575. //
  576. // Loop while there are at least four pixel columns left to draw.
  577. //
  578. while((lX + 3) <= pRect->sXMax)
  579. {
  580. //
  581. // Draw four pixel columns.
  582. //
  583. for(lY = pRect->sYMin, pucPtr = pucData; lY <= pRect->sYMax;
  584. lY++, pucPtr += lBytesPerRow)
  585. {
  586. *(unsigned int *)pucPtr = ulValue;
  587. }
  588. pucData += 4;
  589. lX += 4;
  590. }
  591. //
  592. // See if ther are at least two pixel columns left to draw.
  593. //
  594. if((lX + 1) <= pRect->sXMax)
  595. {
  596. //
  597. // Draw two pixel columns, leaving the buffer pointer half-word
  598. // aligned.
  599. //
  600. ulValue &= 0xffff;
  601. for(lY = pRect->sYMin, pucPtr = pucData; lY <= pRect->sYMax;
  602. lY++, pucPtr += lBytesPerRow)
  603. {
  604. *(unsigned short *)pucPtr = ulValue;
  605. }
  606. pucData += 2;
  607. lX += 2;
  608. }
  609. //
  610. // See if there is one pixel column left to draw.
  611. //
  612. if(lX == pRect->sXMax)
  613. {
  614. //
  615. // Draw the final pixel column.
  616. //
  617. ulValue &= 0xff;
  618. for(lY = pRect->sYMin; lY <= pRect->sYMax;
  619. lY++, pucData += lBytesPerRow)
  620. {
  621. *pucData = ulValue;
  622. }
  623. }
  624. }
  625. //*****************************************************************************
  626. //
  627. //! Flushes any cached drawing operations.
  628. //!
  629. //! \param pvDisplayData is a pointer to the driver-specific data for this
  630. //! display driver.
  631. //!
  632. //! This functions flushes any cached drawing operations to the display. This
  633. //! is useful when a local frame buffer is used for drawing operations, and the
  634. //! flush would copy the local frame buffer to the display. For the off-screen
  635. //! display buffer driver, the flush is a no operation.
  636. //!
  637. //! \return None.
  638. //
  639. //*****************************************************************************
  640. static void
  641. GrOffScreen8BPPFlush(void *pvDisplayData)
  642. {
  643. //
  644. // Check the arguments.
  645. //
  646. ASSERT(pvDisplayData);
  647. }
  648. //*****************************************************************************
  649. //
  650. //! Initializes an 8 BPP off-screen buffer.
  651. //!
  652. //! \param pDisplay is a pointer to the display structure to be configured for
  653. //! the 4 BPP off-screen buffer.
  654. //! \param pucImage is a pointer to the image buffer to be used for the
  655. //! off-screen buffer.
  656. //! \param lWidth is the width of the image buffer in pixels.
  657. //! \param lHeight is the height of the image buffer in pixels.
  658. //!
  659. //! This function initializes a display structure, preparing it to draw into
  660. //! the supplied image buffer. The image buffer is assumed to be large enough
  661. //! to hold an image of the specified geometry.
  662. //!
  663. //! \return None.
  664. //
  665. //*****************************************************************************
  666. void
  667. GrOffScreen8BPPInit(tDisplay *pDisplay, unsigned char *pucImage, int lWidth,
  668. int lHeight)
  669. {
  670. //
  671. // Check the arguments.
  672. //
  673. ASSERT(pDisplay);
  674. ASSERT(pucImage);
  675. //
  676. // Initialize the display structure.
  677. //
  678. pDisplay->lSize = sizeof(tDisplay);
  679. pDisplay->pvDisplayData = pucImage;
  680. pDisplay->usWidth = lWidth;
  681. pDisplay->usHeight = lHeight;
  682. pDisplay->pfnPixelDraw = GrOffScreen8BPPPixelDraw;
  683. pDisplay->pfnPixelDrawMultiple = GrOffScreen8BPPPixelDrawMultiple;
  684. pDisplay->pfnLineDrawH = GrOffScreen8BPPLineDrawH;
  685. pDisplay->pfnLineDrawV = GrOffScreen8BPPLineDrawV;
  686. pDisplay->pfnRectFill = GrOffScreen8BPPRectFill;
  687. pDisplay->pfnColorTranslate = GrOffScreen8BPPColorTranslate;
  688. pDisplay->pfnFlush = GrOffScreen8BPPFlush;
  689. //
  690. // Initialize the image buffer.
  691. //
  692. pucImage[0] = IMAGE_FMT_8BPP_UNCOMP;
  693. *(unsigned short *)(pucImage + 1) = lWidth;
  694. *(unsigned short *)(pucImage + 3) = lHeight;
  695. pucImage[5] = 255;
  696. }
  697. //*****************************************************************************
  698. //
  699. //! Sets the palette of an 8 BPP off-screen buffer.
  700. //!
  701. //! \param pDisplay is a pointer to the display structure for the 4 BPP
  702. //! off-screen buffer.
  703. //! \param pulPalette is a pointer to the array of 24-bit RGB values to be
  704. //! placed into the palette.
  705. //! \param ulOffset is the starting offset into the image palette.
  706. //! \param ulCount is the number of palette entries to set.
  707. //!
  708. //! This function sets the entries of the palette used by the 8 BPP off-screen
  709. //! buffer. The palette is used to select colors for drawing via
  710. //! GrOffScreen4BPPColorTranslate(), and for the final rendering of the image
  711. //! to a real display via GrImageDraw().
  712. //!
  713. //! \return None.
  714. //
  715. //*****************************************************************************
  716. void
  717. GrOffScreen8BPPPaletteSet(tDisplay *pDisplay, unsigned int *pulPalette,
  718. unsigned int ulOffset, unsigned int ulCount)
  719. {
  720. unsigned char *pucData;
  721. //
  722. // Check the arguments.
  723. //
  724. ASSERT(pDisplay);
  725. ASSERT(pulPalette);
  726. ASSERT(ulOffset < 256);
  727. ASSERT((ulOffset + ulCount) <= 256);
  728. //
  729. // Get a pointer to the start of the image buffer's palette.
  730. //
  731. pucData = (unsigned char *)pDisplay->pvDisplayData + 6;
  732. //
  733. // Skip to the specified offset in the palette.
  734. //
  735. pucData += ulOffset * 3;
  736. //
  737. // Loop while there are more palette entries to add.
  738. //
  739. while(ulCount--)
  740. {
  741. //
  742. // Copy this palette entry to the image buffer's palette.
  743. //
  744. *pucData++ = (*pulPalette >> ClrBlueShift) & 0xff;
  745. *pucData++ = (*pulPalette >> ClrGreenShift) & 0xff;
  746. *pucData++ = (*pulPalette++ >> ClrRedShift) & 0xff;
  747. }
  748. }
  749. //*****************************************************************************
  750. //
  751. // Close the Doxygen group.
  752. //! @}
  753. //
  754. //*****************************************************************************