alphablit.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. // The USER version of this will be moved to BLit.h eventually.
  19. #ifndef ALPHA_BLIT_H
  20. #define ALPHA_BLIT_H
  21. //===========================================================================
  22. #include "GREEN/BLiT/BLIT.H"
  23. #include "ORANGE/color/colormatch.h"
  24. //===========================================================================
  25. //////////////////////////////////////////////////////////////////////
  26. //
  27. // ALPHABLIT.H
  28. //
  29. // Created in 1996 JRD
  30. // Implemented throughout 1996 and 1997 - JRD
  31. //
  32. // 07/10/97 JRD Finally documented this file and added history section.
  33. //
  34. //////////////////////////////////////////////////////////////////////
  35. // Here is a comand summary which hopefully is descriptive:
  36. //********************************************************************
  37. //--------------------- CONVENTIONAL ALPHA BLiTs ---------------------
  38. //********************************************************************
  39. //
  40. // All alpha blits need a MultiAlpha table set for the current palette
  41. // in order to translate true color transparency effects into 8-bit color
  42. //
  43. // All alpha objects and classes are part of Orange/Color/colormatch.cpp
  44. // This is only the set of related blits.
  45. //
  46. // An "alpha table" descibes how colors map at a SET, SINGLE transparency
  47. // level, such as 128 (50%). It is a memory efficient way to do fixed,
  48. // homogeneous level alpha blending.
  49. //
  50. // A "multialpha table" has a set of alpha tables for different alpha
  51. // levels, so that blits can be used which involve many different alpha
  52. // levels on one image or varying alpha levels. Multialphas are memory
  53. // intensive and tend to blow caching, so they are slower. But they
  54. // allow the fullest alpha effects.
  55. //
  56. // A "fast multialpha table" is an optimized data structure which
  57. // compresses memory by only including data for colors likely to
  58. // be found in the source and destination. Once you KNOW your
  59. // assets, this can be a useful memory saver.
  60. //
  61. // An "alpha channel value" ranges from 255 = opaque source,
  62. // to 0 = invisible source
  63. //
  64. // Homogeneous alpha blits let you specify one alpha level for an
  65. // entire sprite. Masked alpha blits let you specify a second BMP
  66. // in which every pixel represents the alpha level for each corresponding
  67. // pixel in the source sprite.
  68. //
  69. // Alpha "BlitT" functions allow you to specify source index 0 as
  70. // fully transparent, even if the alpha level is not zero. It is
  71. // normally better to set the alpha mask to zero if possible.
  72. //
  73. // EFFICIENCY NOTE: All alpha blits AUTOMATICALLY switch to normal
  74. // blits in the fully opaque case, and do nothing in the fully transparent
  75. // case, so the app need not worry about such things.
  76. //---------------------------------------------------------------------
  77. // DOCUMENTATION SECTIONS:
  78. //
  79. // 1) Alpha BLiTs -> use RAlphas and RMultiAlphas
  80. // 2) Fast Alpha Blits -> use Fast MultiAlphas
  81. // 3) General Color functions (inlines) for your pleasure
  82. // 4) special blits designed to dynamically alter and create alpha masks!
  83. //====================================================================
  84. // rspAlphaBlit - "opaque blit" which uses a single RAlpha table
  85. // Note that in this BLiT, a
  86. // source color of ZERO will be interpreted
  87. // by it's COLOR - sheet of glass effect.
  88. // THIS IS NOT A MULTIALPHA BLIT. It creates the effect of a single,
  89. // fixed alpha level - the alpha level is IMPLIED in the creation of
  90. // the given alpha table and cannot be varied. (fixed homogeneous)
  91. // This is the fastest and most memory efficient alpha blit. It is
  92. // also the most limited.
  93. //====================================================================
  94. extern void rspAlphaBlit(
  95. RAlpha* pX, // Set for current palette and alpha level
  96. RImage* pimSrc, // BMP8 source
  97. RImage* pimDst, // BMP8 destination
  98. short sDstX,short sDstY);
  99. //====================================================================
  100. // rspAlphaBlitT - "transparent blit" which uses a single RAlpha
  101. // Note that in this BLiT, a
  102. // source color of ZERO will be interpreted
  103. // as fully transparent. (useful)
  104. //
  105. // THIS IS NOT A MULTIALPHA BLIT. It creates the effect of a single,
  106. // fixed alpha level - the alpha level is IMPLIED in the creation of
  107. // the given alpha table and cannot be varied. (fixed homogeneous)
  108. // This is the fastest and most memory efficient alpha blit. It is
  109. // also the most limited.
  110. //====================================================================
  111. extern void rspAlphaBlitT(
  112. RAlpha* pX, // Set for current palette and alpha level
  113. RImage* pimSrc, // BMP8 source
  114. RImage* pimDst, // BMP8 destination
  115. short sDstX,short sDstY);
  116. //====================================================================
  117. // rspAlphaBlitT - "transparent blit" which uses a single alpha level
  118. // In this BLiT, a source color of ZERO will be
  119. // interpreted as fully transparent, REGARDLESS of
  120. // the alpha level (which could be useful)
  121. // This is a homogeneous blit - NO ALPHA MASK is used. Rather, the
  122. // entire sprite is blit at the alphalevel specified, except for 0
  123. // source pixels, which are taken as 100% transparent.
  124. //
  125. // This is the only case of a BlitT function that MUST be used, since
  126. // there's no alpha mask to describe the sprite shape with.
  127. //
  128. //====================================================================
  129. extern void rspAlphaBlitT(
  130. short sAlphaLevel, // 255 = opaque
  131. RMultiAlpha* pMultiX, // For current palette
  132. RImage* pimSrc, // BMP8 source image
  133. RImage* pimDst, // BMP8 destination
  134. short sDstX,short sDstY,
  135. RRect* prDst = NULL);
  136. //====================================================================
  137. // rspGeneralAlphaBlit - "opaque blit" which uses a BMP8 per pixel
  138. // alpha mask. Note that in this BLiT, a
  139. // source color of ZERO will be interpreted
  140. // by it's COLOR - sheet of glass effect.
  141. //====================================================================
  142. extern void rspGeneralAlphaBlit(
  143. RMultiAlpha* pX, // For current palette
  144. RImage* pimMask, // BMP8 alpha channel mask
  145. RImage* pimSrc, // BMP8 source image
  146. RImage* pimDst, // BMP8 destination
  147. short sDstX,
  148. short sDstY,
  149. RRect &rDstClip);
  150. //====================================================================
  151. // rspGeneralAlphaBlit - "opaque blit" which uses a BMP8 per pixel
  152. // alpha mask. Note that in this BLiT, a
  153. // source color of ZERO will be interpreted
  154. // by it's COLOR - sheet of glass effect.
  155. //
  156. // This variation allows real time "dimming" of the curent mask.
  157. // If sLevel = 255, the mask will BLiT normally, but less than 255
  158. // and the image will fade away.
  159. //
  160. //====================================================================
  161. extern void rspGeneralAlphaBlit(
  162. short sLevel, // 0-255, 255 = unchanged
  163. RMultiAlpha* pX, // for current palette
  164. RImage* pimMask, // BMP8 alpha channel mask
  165. RImage* pimSrc, // BMP8 source
  166. RImage* pimDst, // BMP8 destination
  167. short sDstX,
  168. short sDstY,
  169. RRect &rDstClip);
  170. //====================================================================
  171. // rspGeneralAlphaBlitT - "transparent blit" which uses a BMP8 per pixel
  172. // alpha mask.
  173. // In this BLiT, a source color of ZERO will be
  174. // interpreted as fully transparent, REGARDLESS of
  175. // the alpha mask (which could be useful)
  176. //
  177. // This variation allows real time "dimming" of the curent mask.
  178. // If sLevel = 255, the mask will BLiT normally, but less than 255
  179. // and the image will fade away.
  180. //
  181. // NOTE: It is better to use rspGeneralAlphaBlit and put the transparency
  182. // in the alpha mask!
  183. //
  184. //====================================================================
  185. extern void rspGeneralAlphaBlitT(
  186. short sLevel, // 0-255, 255 = unchanged
  187. RMultiAlpha* pX, // for current palette
  188. RImage* pimMask, // BMP8 alpha channel mask
  189. RImage* pimSrc, // BMP8 source
  190. RImage* pimDst, // BMP8 destination
  191. short sDstX,
  192. short sDstY,
  193. RRect &rDstClip);
  194. //********************************************************************
  195. //------------------------- FAST ALPHA BLiTs -------------------------
  196. //********************************************************************
  197. // Fast Multi Alphas are initially created from normal Multi Alphas.
  198. // They are touchy, because they only apply to a subset of source and
  199. // destination colors, and if these ranges are not met, these
  200. // blits can crash. But, they can be FAR more memory efficient.
  201. //
  202. // Not all of the regular alpha blits have been ported over to the fast format
  203. //====================================================================
  204. // rspFastAlphaBlitT - "transparent blit"
  205. // In this BLiT, a source color of ZERO will be
  206. // interpreted as fully transparent, REGARDLESS of
  207. // the alpha level (which could be useful)
  208. // This is a homogeneous blit - NO ALPHA MASK is used. Rather, the
  209. // entire sprite is blit at the alphalevel specified, except for 0
  210. // source pixels, which are taken as 100% transparent.
  211. //
  212. // This is the only case of a BlitT function that MUST be used, since
  213. // there's no alpha mask to describe the sprite shape with.
  214. //
  215. //====================================================================
  216. extern void rspFastAlphaBlitT(
  217. short sAlphaLevel, // 0-255, 255 = unchanged
  218. UCHAR*** pMultiX, // A fast multialpha table
  219. RImage* pimSrc, // BMP8 source
  220. RImage* pimDst, // BMP8 destination
  221. short sDstX,short sDstY,
  222. RRect* prDst = NULL);
  223. //====================================================================
  224. // rspFastMaskAlphaBlit - "opaque blit" which uses a BMP8 per pixel
  225. // alpha mask. Note that in this BLiT, a
  226. // source color of ZERO will be interpreted
  227. // by it's COLOR - sheet of glass effect.
  228. //====================================================================
  229. extern void rspFastMaskAlphaBlit(
  230. UCHAR*** pfaX, // A fast multialpha table
  231. RImage* pimMask, // BMP8 source alpha channel mask
  232. RImage* pimSrc, // BMP8 source
  233. RImage* pimDst, // BMP8 destination
  234. short sDstX,
  235. short sDstY,
  236. RRect &rDstClip);
  237. //====================================================================
  238. // rspFastMaskAlphaBlitT - "transparent blit" which uses a BMP8 per pixel
  239. // alpha mask.
  240. // In this BLiT, a source color of ZERO will be
  241. // interpreted as fully transparent, REGARDLESS of
  242. // the alpha mask (which could be useful)
  243. //====================================================================
  244. extern void rspFastMaskAlphaBlitT(
  245. UCHAR*** pfaX, // A fast multialpha table
  246. RImage* pimMask, // BMP8 source alpha channel mask
  247. RImage* pimSrc, // BMP8 source
  248. RImage* pimDst, // BMP8 destination
  249. short sDstX,short sDstY,
  250. RRect &rDstClip);
  251. //********************************************************************
  252. //-------------- Color Blending Tools for Custom Functions ---------
  253. //********************************************************************
  254. // THIS SHOULD MOVE TO OFFICIAL BLIT STATUS and not staty in alpha
  255. //
  256. inline short rspSimpleClip(short &sSrcX,short &sSrcY,short &sDstX,short &sDstY,
  257. short &sDstW,short &sDstH,
  258. short sClipX,short sClipY,short sClipW,short sClipH)
  259. {
  260. short sClipL,sClipR,sClipT,sClipB;
  261. //-------- Do the clipping:
  262. sClipL = sClipX - sDstX; if (sClipL < 0) sClipL = 0;
  263. sClipT = sClipY - sDstY; if (sClipT < 0) sClipT = 0;
  264. sClipR = (sDstX + sDstW - sClipX - sClipW); if (sClipR < 0) sClipR = 0;
  265. sClipB = (sDstY + sDstH - sClipY - sClipH); if (sClipB < 0) sClipB = 0;
  266. if ( ((sClipL + sClipR) >= sDstW) || ((sClipT + sClipB) >= sDstH) )
  267. {
  268. return -1; // fully clipped out
  269. }
  270. sSrcX += sClipL; sDstX += sClipL;
  271. sSrcY += sClipT; sDstY += sClipT;
  272. sDstW -= (sClipL + sClipR);
  273. sDstH -= (sClipT + sClipB);
  274. return 0;
  275. }
  276. //====================================================================
  277. // rspScaleAlphaMask - you can adjust an existing alpha mask
  278. //--------------------------------------------------------------------
  279. // if dScale < 1.0, you will make the mask more transparent
  280. // if dScale > 1.0, the maskwill be more opaque and will saturate
  281. // at 255.
  282. //
  283. // NOTE: This process is lossy, and if done repeatedly should use the
  284. // original source mask each time.
  285. //====================================================================
  286. extern void rspScaleAlphaMask(RImage* pimSrcMask, // BMP8 alpha mask
  287. double dScale, // 1.0 = no change
  288. RImage* pimDstMask);// BMP8 alpha mask
  289. //===========================================================================
  290. // Here are some low level access functions to the alpha stuff so you can
  291. // build alpha graphics primatives: There is a random access once, but for
  292. // sequential speed you should track your own pointers:
  293. //===========================================================================
  294. //
  295. // rspBlendColor
  296. //
  297. // RETURN the new color index based on a source and destination index:
  298. // WARNING: will not bounds check so be careful:
  299. // sLeve will range from 255 (solid) to 0 (transparent)
  300. //===========================================================================
  301. inline UCHAR rspBlendColor(short sLevel,RMultiAlpha* pX,UCHAR ucSrc,UCHAR ucDst)
  302. {
  303. ASSERT(pX);
  304. if (sLevel > *(pX->m_pLevelOpacity))
  305. {
  306. UCHAR** ppucAlpha = pX->m_pGeneralAlpha[sLevel];
  307. if (ppucAlpha) return ppucAlpha[ucSrc][ucDst]; // alpha'ed
  308. return ucSrc; // opaque
  309. }
  310. return ucDst; // transparent
  311. }
  312. //===========================================================================
  313. //
  314. // rspBlendColor
  315. //
  316. // UINPUT: sLevel -> the alpha level (0-255) you wish to work with
  317. // OUTPUT: psOpaque -> a special case flag, is TRUE if FULLY opaque (normal BLiT)
  318. // RETURN: ppuc, a short cut to the fast blend function, or NULL if you hit the
  319. // extreme cases of fully opaque of fully transparent.
  320. //===========================================================================
  321. inline UCHAR** rspFindBlend(short sLevel,RMultiAlpha* pX,short* psOpaque)
  322. {
  323. ASSERT(pX);
  324. ASSERT(psOpaque);
  325. *psOpaque = FALSE;
  326. if (sLevel <= *(pX->m_pLevelOpacity)) return NULL; // fully transparent
  327. UCHAR** ppucAlpha = pX->m_pGeneralAlpha[sLevel];
  328. if (ppucAlpha) return ppucAlpha;
  329. *psOpaque = TRUE;
  330. return NULL;
  331. }
  332. // A fast way to do repeated blits of the same alpha level, once you've used rspFindBlend:
  333. inline UCHAR rspBlendColor(UCHAR** ppucAlpha,RMultiAlpha* pX,UCHAR ucSrc,UCHAR ucDst)
  334. {
  335. ASSERT(ppucAlpha);
  336. ASSERT(pX);
  337. return ppucAlpha[ucSrc][ucDst];
  338. }
  339. //********************************************************************
  340. //----------- SPECIAL BLITs used in creation of X-RAY effect -------
  341. //********************************************************************
  342. //====================================================================
  343. // rspMaskBlit - a blit used to dynamically create an alpha mask
  344. //--------------------------------------------------------------------
  345. // The OPPOSITE of a sprite blit, this is a blit that draws only
  346. // where the DESTINATION is not zero! It was useful to draw a
  347. // transparent "hole" in an existing alpha mask, but keep the hole
  348. // from going off the edge of the mask.
  349. //
  350. // NOTE: THIS BLiT Will clip to the destination
  351. //====================================================================
  352. extern void rspMaskBlit(
  353. RImage* pimSrc, // BMP8
  354. RImage* pimDst,
  355. short sDstX,short sDstY);
  356. //====================================================================
  357. // rspMakeMask - a blit used to dynamically create an alpha mask
  358. //--------------------------------------------------------------------
  359. // This takes a given sprite, and reduces it's colors to 0 and
  360. // ucVal. This is useful for giving a given sprite a matching
  361. // alpha mask of a set homogeneous opacity level.
  362. //====================================================================
  363. extern void rspMakeMask(RImage* pimSrc, // SOURCE AND DESTINATION
  364. UCHAR ucVal);
  365. //====================================================================
  366. // rspCopyAsMask - a blit used to dynamically create an alpha mask
  367. //--------------------------------------------------------------------
  368. // This takes a given sprite, and reduces it's colors to 0 and
  369. // ucVal. This is useful for giving a given sprite a matching
  370. // alpha mask of a set homogeneous opacity level.
  371. //
  372. // This does the same as rspMakeMask, but does not alter the original
  373. //====================================================================
  374. extern void rspCopyAsMask(
  375. RImage* pimSrc,
  376. RImage* pimDst,
  377. UCHAR ucVal);
  378. //===========================================================================
  379. #endif