mono.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  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. #ifdef PATHS_IN_INCLUDES
  19. #include "GREEN/BLiT/BLIT.H"
  20. #else
  21. #include "BLIT.H"
  22. #endif
  23. #ifdef PATHS_IN_INCLUDES
  24. #include "GREEN/BLiT/_BlitInt.H"
  25. #else
  26. #include "_BlitInt.H"
  27. #endif
  28. #ifdef PATHS_IN_INCLUDES
  29. #include "ORANGE/QuickMath/Fractions.h"
  30. #else
  31. #include "Fractions.h"
  32. #endif
  33. // Now, 1 bit scaled BLiTting into an BMP1 from an FSPR1
  34. // NO CLIPPING, no colro info!
  35. //
  36. short rspBlitToMono(
  37. RImage* pimSrc,
  38. RImage* pimDst,
  39. short sDstX,
  40. short sDstY,
  41. short sDstW,
  42. short sDstH
  43. )
  44. {
  45. #ifdef _DEBUG
  46. if ((pimSrc == NULL) || (pimDst == NULL))
  47. {
  48. TRACE("BLiT: null CImage* passed\n");
  49. return -1;
  50. }
  51. if (pimSrc->m_type != RImage::FSPR1)
  52. {
  53. TRACE("BLiT: This form of BLiT is designed for FSPR1 type images!\n");
  54. return -1;
  55. }
  56. if (pimDst->m_type != RImage::BMP1)
  57. {
  58. TRACE("BLiT: This functions only BLiTs to BMP1 images.\n");
  59. return -1;
  60. }
  61. #endif
  62. if ( (sDstW < 1) || (sDstH < 1))
  63. {
  64. TRACE("BLiT: Zero or negative area passed.\n");
  65. return -1;
  66. }
  67. long lDstP = pimDst->m_lPitch;
  68. if ( (sDstX < 0) || (sDstY < 0) ||
  69. ( (sDstX + sDstW) > pimDst->m_sWidth) ||
  70. ( (sDstY + sDstH) > pimDst->m_sHeight) )
  71. {
  72. TRACE("BLiT: This BLiT does not yet clip!\n");
  73. return -1;
  74. }
  75. UCHAR *pDst,*pDstLine,*pCode,ucCount;
  76. pDstLine = pimDst->m_pData + lDstP * sDstY + (sDstX>>3);
  77. RSpecialFSPR1* pHead = (RSpecialFSPR1*)(pimSrc->m_pSpecial);
  78. pCode = pHead->m_pCode;
  79. const UCHAR FF = (UCHAR)255;
  80. // Let's scale it, baby! (pre-clipping)
  81. short sDenX = pimSrc->m_sWidth;
  82. short sDenY = pimSrc->m_sHeight;
  83. RFracU16 frX = {0};
  84. RFracU16 frInitX = {0};
  85. RFracU16 frOldX = {0};
  86. RFracU16 frOldY = {0},frY = {0};
  87. RFracU16 *afrSkipX=NULL,*afrSkipY=NULL;
  88. afrSkipX = rspfrU16Strafe256(sDstW,sDenX);
  89. afrSkipY = rspfrU16Strafe256(sDstH,sDenY);
  90. // Make magnification possible:
  91. short i;
  92. long *alDstSkip = (long*)calloc(sizeof(long),afrSkipY[1].mod + 2);
  93. for (i=1;i<(afrSkipY[1].mod + 2);i++)
  94. alDstSkip[i] = alDstSkip[i-1] + lDstP;
  95. UCHAR bits[] = {128,64,32,16,8,4,2,1};
  96. short sBit;
  97. frInitX.mod = (sDstX & 7);
  98. //***********************************************************
  99. //***************** AT LAST! CODE! **********************
  100. //***********************************************************
  101. while (TRUE)
  102. {
  103. if ((*pCode) == FF) // vertical run
  104. { // end of sprite?
  105. if ( (ucCount = *(++pCode)) == FF) break;
  106. rspfrAdd(frY,afrSkipY[ucCount],sDenY);
  107. pDstLine += lDstP * (frY.mod - frOldY.mod);
  108. pCode++; // open stack
  109. continue; // next line
  110. }
  111. if (frOldY.mod == frY.mod) // do a quick skip of a line:
  112. {
  113. while ( (*(pCode++)) != FF) ; // skip line!
  114. rspfrAdd(frY,afrSkipY[1],sDenY);
  115. pDstLine += alDstSkip[frY.mod - frOldY.mod];
  116. }
  117. else // actually draw it!
  118. {
  119. frOldY = frY;
  120. pDst = pDstLine;
  121. frX.set = frInitX.set; // start of line!
  122. while ( (ucCount = *(pCode++)) != FF) // EOL
  123. {
  124. frOldX = frX;
  125. rspfrAdd(frX,afrSkipX[ucCount],sDenX);
  126. //pDst += (frX.mod - frOldX.mod); // skip
  127. ucCount = *(pCode++);
  128. frOldX = frX;
  129. rspfrAdd(frX,afrSkipX[ucCount],sDenX);
  130. ucCount = UCHAR(frX.mod - frOldX.mod);
  131. // Modify this to a rect for solid VMagnification.
  132. pDst = pDstLine + ((frOldX.mod)>>3);
  133. sBit = frOldX.mod & 7;
  134. while (ucCount--)
  135. {
  136. (*pDst) |= bits[sBit]; // watch this!
  137. sBit++;
  138. if (sBit > 7)
  139. {
  140. sBit = 0;
  141. pDst++;
  142. }
  143. }
  144. }
  145. rspfrAdd(frY,afrSkipY[1],sDenY);
  146. pDstLine += alDstSkip[frY.mod - frOldY.mod];
  147. }
  148. }
  149. free(alDstSkip);
  150. free(afrSkipX);
  151. free(afrSkipY);
  152. //======================= for debugging only:
  153. /*
  154. CImage* pimScreen,*pimBuffer;
  155. rspNameBuffers(&pimBuffer,&pimScreen);
  156. pimDst->Convert(BMP8);
  157. // copy safebuf to screen:
  158. rspBlit(pimDst,pimScreen,0,0,0,0,(short)pimDst->lWidth,
  159. (short)pimDst->lHeight);
  160. pimDst->Convert(BMP1);
  161. rspWaitForClick();
  162. */
  163. return 0;
  164. }
  165. // mono rect ....
  166. //
  167. short rspRectToMono(ULONG ulColor,RImage* pimDst,short sX,short sY,
  168. short sW,short sH)
  169. {
  170. #ifdef _DEBUG
  171. if (pimDst->m_type != RImage::BMP1)
  172. {
  173. TRACE("rspRectMono: Only BMP1 images supported.\n");
  174. return -1;
  175. }
  176. if ( (sW < 1) || (sH < 1) )
  177. {
  178. TRACE("rspRectMono: Zero or negative area passed.\n");
  179. return -1;
  180. }
  181. #endif
  182. if ( (sX < 0) || (sY < 0) || ( (sX + sW) > pimDst->m_sWidth) ||
  183. ( (sY + sH) > pimDst->m_sHeight) )
  184. {
  185. TRACE("rspRectMono:Clipping not yet supported.\n");
  186. return -1;
  187. }
  188. long lP = pimDst->m_lPitch;
  189. UCHAR ucStart = 0,ucEnd = 0;
  190. UCHAR *pDst,*pDstLine;
  191. short sMidCount,sStart,sEnd,i,j;
  192. UCHAR ucBits[] = { 128,64,32,16,8,4,2,1 };
  193. UCHAR ucStartBits[] = { 255,127,63,31,15,7,3,1 };
  194. UCHAR ucEndBits[] = { 128,192,224,240,248,252,254,255 };
  195. sStart = (sX >> 3);
  196. sEnd = (sX + sW - 1);
  197. short sEndB = (sEnd >> 3);
  198. sMidCount = sEndB - sStart - 1;
  199. if (sMidCount < 1) sMidCount = 0;
  200. if (sStart == sEndB) // very thin:
  201. for (i= (sX&7);i<=(sEnd&7);i++) ucStart += ucBits[i];
  202. else // more normal run:
  203. {
  204. ucStart = ucStartBits[sX&7];
  205. ucEnd = ucEndBits[ sEnd & 7 ];
  206. }
  207. pDstLine = pimDst->m_pData + lP * sY + sStart;
  208. if (ulColor) // copy a rect of 1 bits:
  209. {
  210. for (j=sH;j!=0;j--)
  211. {
  212. pDst = pDstLine;
  213. (*pDst++) |= ucStart;
  214. for (i=sMidCount;i!=0;i--) *(pDst++) = 255;
  215. (*pDst++) |= ucEnd;
  216. pDstLine += lP;
  217. }
  218. }
  219. else // copy color 0 rect of bits:
  220. {
  221. ucStart = ~ucStart;
  222. ucEnd = ~ucEnd;
  223. for (j=sH;j!=0;j--)
  224. {
  225. pDst = pDstLine;
  226. (*pDst++) &= ucStart;
  227. for (i=sMidCount;i!=0;i--) *(pDst++) = 0;
  228. (*pDst++) &= ucEnd;
  229. pDstLine += lP;
  230. }
  231. }
  232. return 0;
  233. }