PageRenderTime 61ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/src/common/Gdc2/Alpha.cpp

#
C++ | 2385 lines | 2079 code | 281 blank | 25 comment | 350 complexity | 967b03b5e1dbae92c981bdc81051b958 MD5 | raw file
Possible License(s): LGPL-2.1, Unlicense
  1. /**
  2. \file
  3. \author Matthew Allen
  4. \date 4/3/1998
  5. \brief Draw mode effects
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <math.h>
  11. #include "Gdc2.h"
  12. // #define Div255(a) DivLut[a]
  13. #define Div255(a) ((a)/255)
  14. /// Alpha blending applicators
  15. class GAlphaApp : public GApplicator
  16. {
  17. protected:
  18. uchar alpha, oma;
  19. int Bits, Bytes;
  20. uchar *Ptr;
  21. uchar *APtr;
  22. void CreatePaletteLut(Pixel24 *c, GPalette *Pal, int Scale = 255)
  23. {
  24. if (Scale < 255)
  25. {
  26. uchar *DivLut = Div255Lut;
  27. for (int i=0; i<256; i++)
  28. {
  29. GdcRGB *p = (Pal) ? (*Pal)[i] : 0;
  30. if (p)
  31. {
  32. c[i].r = DivLut[p->R * Scale];
  33. c[i].g = DivLut[p->G * Scale];
  34. c[i].b = DivLut[p->B * Scale];
  35. }
  36. else
  37. {
  38. c[i].r = DivLut[i * Scale];
  39. c[i].g = c[i].r;
  40. c[i].b = c[i].r;
  41. }
  42. }
  43. }
  44. else if (Scale)
  45. {
  46. for (int i=0; i<256; i++)
  47. {
  48. GdcRGB *p = (Pal) ? (*Pal)[i] : 0;
  49. if (p)
  50. {
  51. c[i].r = p->R;
  52. c[i].g = p->G;
  53. c[i].b = p->B;
  54. }
  55. else
  56. {
  57. c[i].r = i;
  58. c[i].g = i;
  59. c[i].b = i;
  60. }
  61. }
  62. }
  63. else
  64. {
  65. memset(c, 0, sizeof(*c) * 256);
  66. }
  67. }
  68. public:
  69. GAlphaApp()
  70. {
  71. Op = GDC_ALPHA;
  72. alpha = 0xFF;
  73. oma = 0;
  74. Bits = 8;
  75. Bytes = 1;
  76. Ptr = 0;
  77. APtr = 0;
  78. }
  79. int GetVar(int Var)
  80. {
  81. switch (Var)
  82. {
  83. case GAPP_ALPHA_A: return alpha;
  84. }
  85. return 0;
  86. }
  87. int SetVar(int Var, NativeInt Value)
  88. {
  89. switch (Var)
  90. {
  91. case GAPP_ALPHA_A:
  92. {
  93. int Old = alpha;
  94. alpha = Value;
  95. oma = 0xFF - alpha;
  96. return Old;
  97. }
  98. case GAPP_ALPHA_PAL:
  99. {
  100. }
  101. }
  102. return 0;
  103. }
  104. bool SetSurface(GBmpMem *d, GPalette *p, GBmpMem *a)
  105. {
  106. if (d AND d->Bits == Bits)
  107. {
  108. Dest = d;
  109. Pal = p;
  110. Ptr = d->Base;
  111. Alpha = a;
  112. APtr = Alpha ? Alpha->Base : 0;
  113. return true;
  114. }
  115. return false;
  116. }
  117. void SetPtr(int x, int y)
  118. {
  119. LgiAssert(Dest AND Dest->Base);
  120. Ptr = Dest->Base + ((y * Dest->Line) + (x * Bytes));
  121. if (APtr)
  122. APtr = Alpha->Base + ((y * Alpha->Line) + x);
  123. }
  124. void IncX()
  125. {
  126. Ptr += Bytes;
  127. if (APtr)
  128. APtr++;
  129. }
  130. void IncY()
  131. {
  132. Ptr += Dest->Line;
  133. if (APtr)
  134. APtr += Alpha->Line;
  135. }
  136. void IncPtr(int X, int Y)
  137. {
  138. Ptr += (Y * Dest->Line) + (X * Bytes);
  139. if (APtr)
  140. APtr += (Y * Dest->Line) + X;
  141. }
  142. COLOUR Get()
  143. {
  144. switch (Bytes)
  145. {
  146. case 1:
  147. return *((uchar*)Ptr);
  148. case 2:
  149. return *((ushort*)Ptr);
  150. case 3:
  151. return Rgb24(Ptr[2], Ptr[1], Ptr[0]);
  152. case 4:
  153. return *((ulong*)Ptr);
  154. }
  155. return 0;
  156. }
  157. };
  158. class GdcApp8Alpha : public GAlphaApp
  159. {
  160. char Remap[256];
  161. uchar *DivLut;
  162. public:
  163. GdcApp8Alpha();
  164. int SetVar(int Var, NativeInt Value);
  165. void Set();
  166. void VLine(int height);
  167. void Rectangle(int x, int y);
  168. bool Blt(GBmpMem *Src, GPalette *SPal, GBmpMem *SrcAlpha);
  169. };
  170. class GdcApp15Alpha : public GAlphaApp
  171. {
  172. public:
  173. GdcApp15Alpha()
  174. {
  175. Bits = 15; Bytes = 2;
  176. }
  177. void Set();
  178. void VLine(int height);
  179. void Rectangle(int x, int y);
  180. bool Blt(GBmpMem *Src, GPalette *SPal, GBmpMem *SrcAlpha);
  181. };
  182. class GdcApp16Alpha : public GAlphaApp
  183. {
  184. public:
  185. GdcApp16Alpha()
  186. {
  187. Bits = 16; Bytes = 2;
  188. }
  189. void Set();
  190. void VLine(int height);
  191. void Rectangle(int x, int y);
  192. bool Blt(GBmpMem *Src, GPalette *SPal, GBmpMem *SrcAlpha);
  193. };
  194. class GdcApp24Alpha : public GAlphaApp
  195. {
  196. public:
  197. GdcApp24Alpha()
  198. {
  199. Bits = 24;
  200. Bytes = Pixel24::Size;
  201. }
  202. void Set();
  203. void VLine(int height);
  204. void Rectangle(int x, int y);
  205. bool Blt(GBmpMem *Src, GPalette *SPal, GBmpMem *SrcAlpha);
  206. };
  207. class GdcApp32Alpha : public GAlphaApp
  208. {
  209. public:
  210. GdcApp32Alpha()
  211. {
  212. Bits = 32; Bytes = sizeof(Pixel32);
  213. }
  214. void Set();
  215. void VLine(int height);
  216. void Rectangle(int x, int y);
  217. bool Blt(GBmpMem *Src, GPalette *SPal, GBmpMem *SrcAlpha);
  218. };
  219. GApplicator *GAlphaFactory::Create(int Bits, int Op)
  220. {
  221. if (Op == GDC_ALPHA)
  222. {
  223. switch (Bits)
  224. {
  225. case 8:
  226. return new GdcApp8Alpha;
  227. case 15:
  228. return new GdcApp15Alpha;
  229. case 16:
  230. return new GdcApp16Alpha;
  231. case 24:
  232. return new GdcApp24Alpha;
  233. case 32:
  234. return new GdcApp32Alpha;
  235. }
  236. }
  237. return 0;
  238. }
  239. GdcApp8Alpha::GdcApp8Alpha()
  240. {
  241. Bits = 8;
  242. Bytes = 1;
  243. Op = GDC_ALPHA;
  244. ZeroObj(Remap);
  245. DivLut = Div255Lut;
  246. }
  247. int GdcApp8Alpha::SetVar(int Var, NativeInt Value)
  248. {
  249. int Status = GAlphaApp::SetVar(Var, Value);
  250. switch (Var)
  251. {
  252. case GAPP_ALPHA_PAL:
  253. {
  254. GPalette *Pal = (GPalette*)Value;
  255. if (Pal AND alpha < 255)
  256. {
  257. GdcRGB *p = (*Pal)[0];
  258. GdcRGB *Col = (*Pal)[c&0xFF];
  259. for (int i=0; i<Pal->GetSize(); i++)
  260. {
  261. COLOUR Rgb = Rgb24( Div255((oma * p[i].R) + (alpha * Col->R)),
  262. Div255((oma * p[i].G) + (alpha * Col->G)),
  263. Div255((oma * p[i].B) + (alpha * Col->B)));
  264. Remap[i] = Pal->MatchRgb(Rgb);
  265. }
  266. }
  267. else
  268. {
  269. for (int i=0; i<256; i++)
  270. {
  271. Remap[i] = c;
  272. }
  273. }
  274. break;
  275. }
  276. }
  277. return Status;
  278. }
  279. void GdcApp8Alpha::Set()
  280. {
  281. *Ptr = Remap[*Ptr];
  282. if (APtr)
  283. {
  284. *APtr += DivLut[(255 - *APtr) * alpha];
  285. }
  286. }
  287. void GdcApp8Alpha::VLine(int y)
  288. {
  289. while (y--)
  290. {
  291. *Ptr = Remap[*Ptr];
  292. Ptr += Dest->Line;
  293. if (APtr)
  294. {
  295. *APtr += DivLut[(255 - *APtr) * alpha];
  296. APtr += Alpha->Line;
  297. }
  298. }
  299. }
  300. void GdcApp8Alpha::Rectangle(int x, int y)
  301. {
  302. while (y--)
  303. {
  304. uchar *p = Ptr;
  305. for (int X=0; X<x; X++)
  306. {
  307. *p++ = Remap[*p];
  308. }
  309. Ptr += Dest->Line;
  310. if (APtr)
  311. {
  312. uchar *a = APtr;
  313. for (int X=0; X<x; X++)
  314. {
  315. *a++ += DivLut[(255 - *a) * alpha];
  316. }
  317. APtr += Alpha->Line;
  318. }
  319. }
  320. }
  321. bool GdcApp8Alpha::Blt(GBmpMem *Src, GPalette *SPal, GBmpMem *SrcAlpha)
  322. {
  323. if (!Src OR !Pal) return false;
  324. if (!SPal) SPal = Pal;
  325. uchar *DivLut = Div255Lut;
  326. uchar *Lut = 0;
  327. uchar lookup[256];
  328. for (int i=0; i<256; i++)
  329. {
  330. lookup[i] = (i * (int)alpha) / 255;
  331. }
  332. if (SrcAlpha)
  333. {
  334. // Per pixel source alpha
  335. GdcRGB *SRgb = (*SPal)[0];
  336. GdcRGB *DRgb = (*Pal)[0];
  337. if (!SRgb OR !DRgb) return false;
  338. switch (Src->Bits)
  339. {
  340. case 8:
  341. {
  342. Pixel24 sc[256];
  343. CreatePaletteLut(sc, SPal);
  344. Pixel24 dc[256];
  345. CreatePaletteLut(dc, Pal);
  346. for (int y=0; y<Src->y; y++)
  347. {
  348. uchar *s = Src->Base + (y * Src->Line);
  349. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  350. uchar *d = Ptr;
  351. for (int x=0; x<Src->x; x++)
  352. {
  353. uchar a = lookup[*sa];
  354. if (a == 255)
  355. {
  356. *d = *s;
  357. }
  358. else if (a)
  359. {
  360. uchar o = 0xff - a;
  361. Pixel24 *src = sc + *s;
  362. Pixel24 *dst = dc + *d;
  363. int r = DivLut[(dst->r * o) + (src->r * a)];
  364. int g = DivLut[(dst->g * o) + (src->g * a)];
  365. int b = DivLut[(dst->b * o) + (src->b * a)];
  366. if (!Lut) Lut = Pal->MakeLut(15);
  367. *d = Lut[Rgb15(r, g, b)];
  368. }
  369. d++;
  370. sa++;
  371. s++;
  372. }
  373. Ptr += Dest->Line;
  374. }
  375. break;
  376. }
  377. case 15:
  378. {
  379. Pixel24 dc[256];
  380. CreatePaletteLut(dc, Pal);
  381. if (!Lut) Lut = Pal->MakeLut(15);
  382. for (int y=0; y<Src->y; y++)
  383. {
  384. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  385. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  386. uchar *d = Ptr;
  387. uchar *end = d + Src->x;
  388. while (d < end)
  389. {
  390. uchar a = lookup[*sa++];
  391. if (a == 255)
  392. {
  393. *d = Lut[*s];
  394. }
  395. else if (a)
  396. {
  397. uchar o = 255 - a;
  398. Pixel24 *dst = dc + *d;
  399. int r = DivLut[(dst->r * o) + (Rc15(*s) * a)];
  400. int g = DivLut[(dst->g * o) + (Gc15(*s) * a)];
  401. int b = DivLut[(dst->b * o) + (Bc15(*s) * a)];
  402. *d = Lut[Rgb15(r, g, b)];
  403. }
  404. d++;
  405. s++;
  406. }
  407. Ptr += Dest->Line;
  408. }
  409. break;
  410. }
  411. case 16:
  412. {
  413. Pixel24 dc[256];
  414. CreatePaletteLut(dc, Pal);
  415. if (!Lut) Lut = Pal->MakeLut(15);
  416. for (int y=0; y<Src->y; y++)
  417. {
  418. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  419. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  420. uchar *d = Ptr;
  421. uchar *end = d + Src->x;
  422. while (d < end)
  423. {
  424. uchar a = lookup[*sa++];
  425. if (a == 255)
  426. {
  427. *d = Lut[Rgb16To15(*s)];
  428. }
  429. else if (a)
  430. {
  431. uchar o = 255 - a;
  432. Pixel24 *dst = dc + *d;
  433. int r = DivLut[(dst->r * o) + (Rc16(*s) * a)];
  434. int g = DivLut[(dst->g * o) + (Gc16(*s) * a)];
  435. int b = DivLut[(dst->b * o) + (Bc16(*s) * a)];
  436. *d = Lut[Rgb15(r, g, b)];
  437. }
  438. d++;
  439. s++;
  440. }
  441. Ptr += Dest->Line;
  442. }
  443. break;
  444. }
  445. case 24:
  446. {
  447. Pixel24 dc[256];
  448. CreatePaletteLut(dc, Pal, 255);
  449. if (!Lut) Lut = Pal->MakeLut(15);
  450. for (int y=0; y<Src->y; y++)
  451. {
  452. Pixel24 *s = (Pixel24*) (Src->Base + (y * Src->Line));
  453. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  454. uchar *d = Ptr;
  455. for (int x=0; x<Src->x; x++)
  456. {
  457. uchar a = lookup[*sa++];
  458. if (a == 255)
  459. {
  460. *d = Lut[Rgb15(s->r, s->g, s->b)];
  461. }
  462. else if (a)
  463. {
  464. uchar o = 255 - a;
  465. Pixel24 *dst = dc + *d;
  466. int r = DivLut[(dst->r * o) + (s->r * a)];
  467. int g = DivLut[(dst->g * o) + (s->g * a)];
  468. int b = DivLut[(dst->b * o) + (s->b * a)];
  469. *d = Lut[Rgb15(r, g, b)];
  470. }
  471. d++;
  472. s = s->Next();
  473. }
  474. Ptr += Dest->Line;
  475. }
  476. break;
  477. }
  478. case 32:
  479. {
  480. Pixel24 dc[256];
  481. CreatePaletteLut(dc, Pal, 255);
  482. if (!Lut) Lut = Pal->MakeLut(15);
  483. for (int y=0; y<Src->y; y++)
  484. {
  485. Pixel32 *s = (Pixel32*) (Src->Base + (y * Src->Line));
  486. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  487. uchar *d = Ptr;
  488. for (int x=0; x<Src->x; x++)
  489. {
  490. uchar a = lookup[*sa++];
  491. if (a == 255)
  492. {
  493. *d = Lut[Rgb15(s->r, s->g, s->b)];
  494. }
  495. else if (a)
  496. {
  497. uchar o = 255 - a;
  498. Pixel24 *dst = dc + *d;
  499. int r = DivLut[(dst->r * o) + (s->r * a)];
  500. int g = DivLut[(dst->g * o) + (s->g * a)];
  501. int b = DivLut[(dst->b * o) + (s->b * a)];
  502. *d = Lut[Rgb15(r, g, b)];
  503. }
  504. d++;
  505. s++;
  506. }
  507. Ptr += Dest->Line;
  508. }
  509. break;
  510. }
  511. }
  512. }
  513. else
  514. {
  515. // Global alpha level
  516. GdcRGB *SRgb = (*SPal)[0];
  517. GdcRGB *DRgb = (*Pal)[0];
  518. if (!SRgb OR !DRgb) return false;
  519. switch (Src->Bits)
  520. {
  521. case 8:
  522. {
  523. if (alpha == 255)
  524. {
  525. // do a straight blt
  526. for (int y=0; y<Src->y; y++)
  527. {
  528. uchar *s = Src->Base + (y * Src->Line);
  529. uchar *d = Ptr;
  530. memcpy(d, s, Src->x);
  531. Ptr += Dest->Line;
  532. }
  533. }
  534. else if (alpha)
  535. {
  536. Pixel24 sc[256];
  537. CreatePaletteLut(sc, SPal, alpha);
  538. Pixel24 dc[256];
  539. CreatePaletteLut(dc, Pal, oma);
  540. if (!Lut) Lut = Pal->MakeLut(15);
  541. for (int y=0; y<Src->y; y++)
  542. {
  543. uchar *s = Src->Base + (y * Src->Line);
  544. uchar *d = Ptr;
  545. for (int x=0; x<Src->x; x++, s++, d++)
  546. {
  547. Pixel24 *src = sc + *s;
  548. Pixel24 *dst = dc + *d;
  549. int r = src->r + dst->r;
  550. int g = src->g + dst->g;
  551. int b = src->b + dst->b;
  552. *d = Lut[Rgb15(r, g, b)];
  553. }
  554. Ptr += Dest->Line;
  555. }
  556. }
  557. break;
  558. }
  559. case 15:
  560. {
  561. Pixel24 dc[256];
  562. CreatePaletteLut(dc, Pal, oma);
  563. if (!Lut) Lut = Pal->MakeLut(15);
  564. for (int y=0; y<Src->y; y++)
  565. {
  566. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  567. uchar *d = Ptr;
  568. uchar *e = d + Src->x;
  569. while (d < e)
  570. {
  571. Pixel24 *dst = dc + *d;
  572. int r = dst->r + DivLut[Rc15(*s) * alpha];
  573. int g = dst->g + DivLut[Gc15(*s) * alpha];
  574. int b = dst->b + DivLut[Bc15(*s) * alpha];
  575. *d++ = Lut[Rgb15(r, g, b)];
  576. s++;
  577. }
  578. Ptr += Dest->Line;
  579. }
  580. break;
  581. }
  582. case 16:
  583. {
  584. Pixel24 dc[256];
  585. CreatePaletteLut(dc, Pal, oma);
  586. if (!Lut) Lut = Pal->MakeLut(15);
  587. for (int y=0; y<Src->y; y++)
  588. {
  589. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  590. uchar *d = Ptr;
  591. for (int x=0; x<Src->x; x++, s++, d++)
  592. {
  593. Pixel24 *dst = dc + *d;
  594. int r = dst->r + DivLut[Rc16(*s) * alpha];
  595. int g = dst->g + DivLut[Gc16(*s) * alpha];
  596. int b = dst->b + DivLut[Bc16(*s) * alpha];
  597. *d = Lut[Rgb15(r, g, b)];
  598. }
  599. Ptr += Dest->Line;
  600. }
  601. break;
  602. }
  603. case 24:
  604. {
  605. Pixel24 dc[256];
  606. CreatePaletteLut(dc, Pal, oma);
  607. if (!Lut) Lut = Pal->MakeLut(15);
  608. for (int y=0; y<Src->y; y++)
  609. {
  610. Pixel24 *s = (Pixel24*) (Src->Base + (y * Src->Line));
  611. uchar *d = Ptr;
  612. uchar *e = Ptr + Src->x;
  613. while (d < e)
  614. {
  615. Pixel24 *dst = dc + *d;
  616. int r = dst->r + DivLut[s->r * alpha];
  617. int g = dst->g + DivLut[s->g * alpha];
  618. int b = dst->b + DivLut[s->b * alpha];
  619. s = s->Next();
  620. *d++ = Lut[Rgb15(r, g, b)];
  621. }
  622. Ptr += Dest->Line;
  623. }
  624. break;
  625. }
  626. case 32:
  627. {
  628. Pixel24 dc[256];
  629. CreatePaletteLut(dc, Pal);
  630. if (!Lut) Lut = Pal->MakeLut(15);
  631. for (int y=0; y<Src->y; y++)
  632. {
  633. Pixel32 *s = (Pixel32*) (Src->Base + (y * Src->Line));
  634. uchar *d = Ptr;
  635. uchar *end = d + Src->x;
  636. while (d < end)
  637. {
  638. uchar a = lookup[s->a];
  639. if (a)
  640. {
  641. Pixel24 *dst = dc + *d;
  642. uchar o = 255 - a;
  643. int r = lookup[s->r] + DivLut[dst->r * o];
  644. int g = lookup[s->g] + DivLut[dst->g * o];
  645. int b = lookup[s->b] + DivLut[dst->b * o];
  646. *d = Lut[Rgb15(r, g, b)];
  647. }
  648. s++;
  649. d++;
  650. }
  651. Ptr += Dest->Line;
  652. }
  653. break;
  654. }
  655. }
  656. }
  657. return false;
  658. }
  659. ///////////////////////////////////////////////////////////////////////////////////////////////////
  660. #define Setup15() \
  661. uchar *DivLut = Div255Lut; \
  662. int r = DivLut[Rc15(c)]; \
  663. int g = DivLut[Gc15(c)]; \
  664. int b = DivLut[Bc15(c)];
  665. #define Comp15() \
  666. *p = Rgb15( DivLut[r + (oma * Rc15(*p))], \
  667. DivLut[g + (oma * Gc15(*p))], \
  668. DivLut[b + (oma * Bc15(*p))] );
  669. void GdcApp15Alpha::Set()
  670. {
  671. ushort *p = (ushort*) Ptr;
  672. Setup15();
  673. Comp15();
  674. }
  675. void GdcApp15Alpha::VLine(int height)
  676. {
  677. ushort *p = (ushort*) Ptr;
  678. Setup15();
  679. while (height--)
  680. {
  681. Comp15();
  682. p = (ushort*)(Ptr += Dest->Line);
  683. }
  684. }
  685. void GdcApp15Alpha::Rectangle(int x, int y)
  686. {
  687. ushort *p = (ushort*) Ptr;
  688. Setup15();
  689. while (y--)
  690. {
  691. for (int n=0; n<x; n++, p++)
  692. {
  693. Comp15();
  694. }
  695. p = (ushort*)(Ptr += Dest->Line);
  696. }
  697. }
  698. bool GdcApp15Alpha::Blt(GBmpMem *Src, GPalette *SPal, GBmpMem *SrcAlpha)
  699. {
  700. if (!Src) return 0;
  701. uchar *DivLut = Div255Lut;
  702. if (SrcAlpha)
  703. {
  704. uchar lookup[256];
  705. for (int i=0; i<256; i++)
  706. {
  707. lookup[i] = (i * (int)alpha) / 255;
  708. }
  709. switch (Src->Bits)
  710. {
  711. case 8:
  712. {
  713. Pixel24 c[256];
  714. CreatePaletteLut(c, SPal, 255);
  715. for (int y=0; y<Src->y; y++)
  716. {
  717. uchar *s = Src->Base + (y * Src->Line);
  718. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  719. ushort *d = (ushort*) Ptr;
  720. ushort *e = d + Src->x;
  721. while (d < e)
  722. {
  723. uchar a = lookup[*sa++];
  724. if (a == 255)
  725. {
  726. Pixel24 *src = c + *s;
  727. *d = Rgb15(src->r, src->g, src->b);
  728. }
  729. else if (a)
  730. {
  731. Pixel24 *src = c + *s;
  732. uchar o = 255 - a;
  733. *d = Rgb15( DivLut[(o * Rc15(*d)) + (a * src->r)],
  734. DivLut[(o * Gc15(*d)) + (a * src->g)],
  735. DivLut[(o * Bc15(*d)) + (a * src->b)]);
  736. }
  737. d++;
  738. s++;
  739. }
  740. Ptr += Dest->Line;
  741. }
  742. break;
  743. }
  744. case 15:
  745. {
  746. for (int y=0; y<Src->y; y++)
  747. {
  748. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  749. uchar *src_a = SrcAlpha->Base + (y * SrcAlpha->Line);
  750. ushort *d = (ushort*) Ptr;
  751. ushort *e = d + Src->x;
  752. while (d < e)
  753. {
  754. uchar a = lookup[*src_a++];
  755. uchar oma = 255 - a;
  756. if (a == 255)
  757. {
  758. *d = *s;
  759. }
  760. else if (a)
  761. {
  762. *d = Rgb15
  763. (
  764. DivLut[(oma * Rc15(*d)) + (a * Rc15(*s))],
  765. DivLut[(oma * Gc15(*d)) + (a * Gc15(*s))],
  766. DivLut[(oma * Bc15(*d)) + (a * Bc15(*s))]
  767. );
  768. }
  769. d++;
  770. s++;
  771. }
  772. Ptr += Dest->Line;
  773. }
  774. break;
  775. }
  776. case 16:
  777. {
  778. for (int y=0; y<Src->y; y++)
  779. {
  780. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  781. uchar *src_a = SrcAlpha->Base + (y * SrcAlpha->Line);
  782. ushort *d = (ushort*) Ptr;
  783. for (int x=0; x<Src->x; x++)
  784. {
  785. uchar my_a = lookup[*src_a++];
  786. uchar my_oma = 255 - my_a;
  787. if (my_oma == 0)
  788. {
  789. *d = *s;
  790. }
  791. else if (my_oma < 255)
  792. {
  793. *d = Rgb15( Div255((my_oma * Rc15(*d)) + (my_a * Rc16(*s))),
  794. Div255((my_oma * Gc15(*d)) + (my_a * Gc16(*s))),
  795. Div255((my_oma * Bc15(*d)) + (my_a * Bc16(*s))));
  796. }
  797. d++;
  798. s++;
  799. }
  800. Ptr += Dest->Line;
  801. }
  802. break;
  803. }
  804. case 24:
  805. {
  806. for (int y=0; y<Src->y; y++)
  807. {
  808. Pixel24 *s = (Pixel24*) (Src->Base + (y * Src->Line));
  809. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  810. ushort *d = (ushort*) Ptr;
  811. ushort *e = d + Src->x;
  812. while (d < e)
  813. {
  814. uchar a = lookup[*sa++];
  815. uchar o = 255 - a;
  816. if (a == 255)
  817. {
  818. *d = Rgb15(s->r, s->g, s->b);
  819. }
  820. else if (a)
  821. {
  822. *d = Rgb15( Div255( (o * Rc15(*d)) + (a * s->r) ),
  823. Div255( (o * Gc15(*d)) + (a * s->g) ),
  824. Div255( (o * Bc15(*d)) + (a * s->b) ));
  825. }
  826. s = s->Next();
  827. d++;
  828. }
  829. Ptr += Dest->Line;
  830. }
  831. break;
  832. }
  833. case 32:
  834. {
  835. for (int y=0; y<Src->y; y++)
  836. {
  837. Pixel32 *s = (Pixel32*) (Src->Base + (y * Src->Line));
  838. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  839. ushort *d = (ushort*) Ptr;
  840. ushort *e = d + Src->x;
  841. while (d < e)
  842. {
  843. uchar a = lookup[*sa++];
  844. uchar o = 255 - a;
  845. if (a == 255)
  846. {
  847. *d = Rgb15(s->r, s->g, s->b);
  848. }
  849. else if (a)
  850. {
  851. *d = Rgb15( Div255( (o * Rc15(*d)) + (a * s->r) ),
  852. Div255( (o * Gc15(*d)) + (a * s->g) ),
  853. Div255( (o * Bc15(*d)) + (a * s->b) ));
  854. }
  855. d++;
  856. s++;
  857. }
  858. Ptr += Dest->Line;
  859. }
  860. break;
  861. }
  862. }
  863. }
  864. else
  865. {
  866. switch (Src->Bits)
  867. {
  868. case 8:
  869. {
  870. Pixel24 c[256];
  871. if (alpha) CreatePaletteLut(c, SPal, alpha);
  872. for (int y=0; y<Src->y; y++)
  873. {
  874. ushort *d = (ushort*) Ptr;
  875. ushort *e = d + Src->x;
  876. uchar *s = Src->Base + (Src->Line * y);
  877. Pixel24 *Src;
  878. if (alpha == 255)
  879. {
  880. // copy
  881. while (d < e)
  882. {
  883. Src = c + *s++;
  884. *d = Rgb15(Src->r, Src->g, Src->b);
  885. }
  886. }
  887. else if (alpha)
  888. {
  889. // blend
  890. while (d < e)
  891. {
  892. Src = c + *s++;
  893. *d++ = Rgb15
  894. (
  895. DivLut[oma * Rc15(*d)] + Src->r,
  896. DivLut[oma * Gc15(*d)] + Src->g,
  897. DivLut[oma * Bc15(*d)] + Src->b
  898. );
  899. }
  900. }
  901. Ptr += Dest->Line;
  902. }
  903. break;
  904. }
  905. case 15:
  906. {
  907. for (int y=0; y<Src->y; y++)
  908. {
  909. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  910. ushort *d = (ushort*) Ptr;
  911. ushort *e = d + Src->x;
  912. if (alpha == 255)
  913. {
  914. // copy
  915. while (d < e)
  916. {
  917. *d++ = *s++;
  918. }
  919. }
  920. else if (alpha)
  921. {
  922. // blend
  923. while (d < e)
  924. {
  925. *d = Rgb15
  926. (
  927. DivLut[(oma * Rc15(*d)) + (alpha * Rc15(*s))],
  928. DivLut[(oma * Gc15(*d)) + (alpha * Gc15(*s))],
  929. DivLut[(oma * Bc15(*d)) + (alpha * Bc15(*s))]
  930. );
  931. s++;
  932. d++;
  933. }
  934. }
  935. Ptr += Dest->Line;
  936. }
  937. break;
  938. }
  939. case 16:
  940. {
  941. // this code combines the colour bitmap with the destination
  942. // bitmap using the given alpha value
  943. for (int y=0; y<Src->y; y++)
  944. {
  945. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  946. ushort *d = (ushort*) Ptr;
  947. for (int x=0; x<Src->x; x++, d++, s++)
  948. {
  949. *d = Rgb15( Div255((oma * Rc15(*d)) + (alpha * Rc16(*s))),
  950. Div255((oma * Gc15(*d)) + (alpha * Gc16(*s))),
  951. Div255((oma * Bc15(*d)) + (alpha * Bc16(*s))));
  952. }
  953. Ptr += Dest->Line;
  954. }
  955. break;
  956. }
  957. case 24:
  958. {
  959. for (int y=0; y<Src->y; y++)
  960. {
  961. Pixel24 *s = (Pixel24*) (Src->Base + (y * Src->Line));
  962. ushort *d = (ushort*) Ptr;
  963. ushort *e = d + Src->x;
  964. while (d < e)
  965. {
  966. *d = Rgb15
  967. (
  968. DivLut[(oma * Rc15(*d)) + (alpha * s->r)],
  969. DivLut[(oma * Gc15(*d)) + (alpha * s->g)],
  970. DivLut[(oma * Bc15(*d)) + (alpha * s->b)]
  971. );
  972. s = s->Next();
  973. d++;
  974. }
  975. Ptr += Dest->Line;
  976. }
  977. break;
  978. }
  979. case 32:
  980. {
  981. for (int y=0; y<Src->y; y++)
  982. {
  983. Pixel32 *s = (Pixel32*) (Src->Base + (y * Src->Line));
  984. ushort *d = (ushort*) Ptr;
  985. ushort *e = d + Src->x;
  986. while (d < e)
  987. {
  988. *d = Rgb15
  989. (
  990. DivLut[(oma * Rc15(*d)) + (alpha * s->r)],
  991. DivLut[(oma * Gc15(*d)) + (alpha * s->g)],
  992. DivLut[(oma * Bc15(*d)) + (alpha * s->b)]
  993. );
  994. s++;
  995. d++;
  996. }
  997. Ptr += Dest->Line;
  998. }
  999. break;
  1000. }
  1001. }
  1002. }
  1003. return false;
  1004. }
  1005. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1006. #define Setup16() \
  1007. uchar *DivLut = Div255Lut; \
  1008. int r = Rc16(c) * alpha; \
  1009. int g = Gc16(c) * alpha; \
  1010. int b = Bc16(c) * alpha;
  1011. #define Comp16() \
  1012. *p = Rgb16( DivLut[r + (oma * Rc16(*p))], \
  1013. DivLut[g + (oma * Gc16(*p))], \
  1014. DivLut[b + (oma * Bc16(*p))]);
  1015. void GdcApp16Alpha::Set()
  1016. {
  1017. ushort *p = (ushort*) Ptr;
  1018. Setup16();
  1019. Comp16();
  1020. }
  1021. void GdcApp16Alpha::VLine(int height)
  1022. {
  1023. ushort *p = (ushort*) Ptr;
  1024. Setup16();
  1025. while (height--)
  1026. {
  1027. Comp16();
  1028. p = (ushort*) (Ptr += Dest->Line);
  1029. }
  1030. }
  1031. void GdcApp16Alpha::Rectangle(int x, int y)
  1032. {
  1033. ushort *p = (ushort*) Ptr;
  1034. Setup16();
  1035. while (y--)
  1036. {
  1037. for (int n=0; n<x; n++, p++)
  1038. {
  1039. Comp16();
  1040. }
  1041. p = (ushort*) (Ptr += Dest->Line);
  1042. }
  1043. }
  1044. bool GdcApp16Alpha::Blt(GBmpMem *Src, GPalette *SPal, GBmpMem *SrcAlpha)
  1045. {
  1046. if (!Src) return 0;
  1047. uchar *DivLut = Div255Lut;
  1048. uchar lookup[256];
  1049. for (int i=0; i<256; i++)
  1050. {
  1051. lookup[i] = (i * (int)alpha) / 255;
  1052. }
  1053. if (SrcAlpha)
  1054. {
  1055. switch (Src->Bits)
  1056. {
  1057. case 8:
  1058. {
  1059. Pixel24 c[256];
  1060. CreatePaletteLut(c, SPal, 255);
  1061. for (int y=0; y<Src->y; y++)
  1062. {
  1063. uchar *s = Src->Base + (y * Src->Line);
  1064. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1065. ushort *d = (ushort*) Ptr;
  1066. ushort *EndD = d + Src->x;
  1067. while (d < EndD)
  1068. {
  1069. uchar a = lookup[*sa++];
  1070. if (a == 255)
  1071. {
  1072. Pixel24 *src = c + *s;
  1073. *d = Rgb16(src->r, src->g, src->b);
  1074. }
  1075. else if (a)
  1076. {
  1077. Pixel24 *src = c + *s;
  1078. uchar o = 255 - a;
  1079. int r = DivLut[(Rc16(*d) * o) + (src->r * a)];
  1080. int g = DivLut[(Gc16(*d) * o) + (src->g * a)];
  1081. int b = DivLut[(Bc16(*d) * o) + (src->b * a)];
  1082. *d = Rgb16(r, g, b);
  1083. }
  1084. d++;
  1085. s++;
  1086. }
  1087. Ptr += Dest->Line;
  1088. }
  1089. break;
  1090. }
  1091. case 15:
  1092. {
  1093. for (int y=0; y<Src->y; y++)
  1094. {
  1095. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1096. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1097. ushort *d = (ushort*) Ptr;
  1098. ushort *e = d + Src->x;
  1099. while (d < e)
  1100. {
  1101. uchar a = lookup[*sa++];
  1102. uchar o = 255 - a;
  1103. if (a == 255)
  1104. {
  1105. *d = Rgb15To16(*s);
  1106. }
  1107. else if (a)
  1108. {
  1109. *d = Rgb16( Div255((o * Rc16(*d)) + (a * Rc15(*s))),
  1110. Div255((o * Gc16(*d)) + (a * Gc15(*s))),
  1111. Div255((o * Bc16(*d)) + (a * Bc15(*s))));
  1112. }
  1113. d++;
  1114. s++;
  1115. }
  1116. Ptr += Dest->Line;
  1117. }
  1118. break;
  1119. }
  1120. case 16:
  1121. {
  1122. for (int y=0; y<Src->y; y++)
  1123. {
  1124. ushort *s = (ushort*) ((uchar*)Src->Base + (y * Src->Line));
  1125. uchar *src_a = SrcAlpha->Base + (y * SrcAlpha->Line);
  1126. ushort *d = (ushort*) Ptr;
  1127. for (int x=0; x<Src->x; x++)
  1128. {
  1129. uchar my_a = lookup[*src_a++];
  1130. uchar my_oma = 255 - my_a;
  1131. if (my_oma == 0)
  1132. {
  1133. *d = *s;
  1134. }
  1135. else if (my_oma < 255)
  1136. {
  1137. *d = Rgb16( Div255((my_oma * Rc16(*d)) + (my_a * Rc16(*s))),
  1138. Div255((my_oma * Gc16(*d)) + (my_a * Gc16(*s))),
  1139. Div255((my_oma * Bc16(*d)) + (my_a * Bc16(*s))));
  1140. }
  1141. d++;
  1142. s++;
  1143. }
  1144. Ptr += Dest->Line;
  1145. }
  1146. break;
  1147. }
  1148. case 24:
  1149. #ifndef LINUX
  1150. {
  1151. for (int y=0; y<Src->y; y++)
  1152. {
  1153. Pixel24 *s = (Pixel24*) (Src->Base + (y * Src->Line));
  1154. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1155. ushort *d = (ushort*) Ptr;
  1156. ushort *end = d + Src->x;
  1157. while (d < end)
  1158. {
  1159. uchar a = lookup[*sa++];
  1160. if (a == 255)
  1161. {
  1162. *d = Rgb16(s->r, s->g, s->b);
  1163. }
  1164. else if (a)
  1165. {
  1166. uchar o = 255 - a;
  1167. int r = DivLut[(Rc16(*d) * o) + (s->r * a)];
  1168. int g = DivLut[(Gc16(*d) * o) + (s->g * a)];
  1169. int b = DivLut[(Bc16(*d) * o) + (s->b * a)];
  1170. *d = Rgb16(r, g, b);
  1171. }
  1172. s = s->Next();
  1173. d++;
  1174. }
  1175. Ptr += Dest->Line;
  1176. }
  1177. break;
  1178. }
  1179. #endif
  1180. case 32:
  1181. {
  1182. for (int y=0; y<Src->y; y++)
  1183. {
  1184. Pixel32 *s = (Pixel32*) (Src->Base + (y * Src->Line));
  1185. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1186. ushort *d = (ushort*) Ptr;
  1187. ushort *end = d + Src->x;
  1188. while (d < end)
  1189. {
  1190. uchar a = lookup[*sa++];
  1191. if (a == 255)
  1192. {
  1193. *d = Rgb16(s->r, s->g, s->b);
  1194. }
  1195. else if (a)
  1196. {
  1197. uchar o = 255 - a;
  1198. int r = DivLut[(Rc16(*d) * o) + (s->r * a)];
  1199. int g = DivLut[(Gc16(*d) * o) + (s->g * a)];
  1200. int b = DivLut[(Bc16(*d) * o) + (s->b * a)];
  1201. *d = Rgb16(r, g, b);
  1202. }
  1203. d++;
  1204. s++;
  1205. }
  1206. Ptr += Dest->Line;
  1207. }
  1208. break;
  1209. }
  1210. }
  1211. }
  1212. else
  1213. {
  1214. switch (Src->Bits)
  1215. {
  1216. case 8:
  1217. {
  1218. // this code uses the input bitmap as a mask to say where
  1219. // to draw the current colour at the given alpha value
  1220. Pixel24 c[256];
  1221. CreatePaletteLut(c, SPal, alpha);
  1222. for (int y=0; y<Src->y; y++)
  1223. {
  1224. ushort *d = (ushort*) Ptr;
  1225. uchar *s = Src->Base + (Src->Line * y);
  1226. for (int x=0; x<Src->x; x++, d++, s++)
  1227. {
  1228. Pixel24 *src = c + *s;
  1229. int r = src->r + DivLut[Rc16(*d) * oma];
  1230. int g = src->g + DivLut[Gc16(*d) * oma];
  1231. int b = src->b + DivLut[Bc16(*d) * oma];
  1232. *d = Rgb16(r, g, b);
  1233. }
  1234. Ptr += Dest->Line;
  1235. }
  1236. break;
  1237. }
  1238. case 15:
  1239. {
  1240. for (int y=0; y<Src->y; y++)
  1241. {
  1242. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1243. ushort *d = (ushort*) Ptr;
  1244. ushort *e = d + Src->x;
  1245. while (d < e)
  1246. {
  1247. *d = Rgb16
  1248. (
  1249. DivLut[(oma * Rc16(*d)) + (alpha * Rc15(*s))],
  1250. DivLut[(oma * Gc16(*d)) + (alpha * Gc15(*s))],
  1251. DivLut[(oma * Bc16(*d)) + (alpha * Bc15(*s))]
  1252. );
  1253. s++;
  1254. d++;
  1255. }
  1256. Ptr += Dest->Line;
  1257. }
  1258. break;
  1259. }
  1260. case 16:
  1261. {
  1262. for (int y=0; y<Src->y; y++)
  1263. {
  1264. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1265. ushort *d = (ushort*) Ptr;
  1266. for (int x=0; x<Src->x; x++, d++, s++)
  1267. {
  1268. *d = Rgb16( Div255((oma * Rc16(*d)) + (alpha * Rc16(*s))),
  1269. Div255((oma * Gc16(*d)) + (alpha * Gc16(*s))),
  1270. Div255((oma * Bc16(*d)) + (alpha * Bc16(*s))));
  1271. }
  1272. Ptr += Dest->Line;
  1273. }
  1274. break;
  1275. }
  1276. case 24:
  1277. {
  1278. for (int y=0; y<Src->y; y++)
  1279. {
  1280. Pixel24 *s = (Pixel24*) (Src->Base + (y * Src->Line));
  1281. ushort *d = (ushort*) Ptr;
  1282. ushort *e = d + Src->x;
  1283. while (d < e)
  1284. {
  1285. *d++ = Rgb16( Div255((oma * Rc16(*d)) + (alpha * s->r)),
  1286. Div255((oma * Gc16(*d)) + (alpha * s->g)),
  1287. Div255((oma * Bc16(*d)) + (alpha * s->b)));
  1288. s = s->Next();
  1289. }
  1290. Ptr += Dest->Line;
  1291. }
  1292. break;
  1293. }
  1294. case 32:
  1295. {
  1296. for (int y=0; y<Src->y; y++)
  1297. {
  1298. Pixel32 *s = (Pixel32*) (Src->Base + (y * Src->Line));
  1299. ushort *d = (ushort*) Ptr;
  1300. ushort *end = d + Src->x;
  1301. if (alpha == 255)
  1302. {
  1303. while (d < end)
  1304. {
  1305. if (s->a)
  1306. {
  1307. uchar o = 255 - s->a;
  1308. int r = DivLut[(Rc16(*d) * o) + (s->r * s->a)];
  1309. int g = DivLut[(Rc16(*d) * o) + (s->g * s->a)];
  1310. int b = DivLut[(Rc16(*d) * o) + (s->b * s->a)];
  1311. *d = Rgb16(r, g, b);
  1312. }
  1313. s++;
  1314. d++;
  1315. }
  1316. }
  1317. else if (alpha)
  1318. {
  1319. while (d < end)
  1320. {
  1321. uchar a = lookup[s->a];
  1322. if (a == 255)
  1323. {
  1324. *d = Rgb16(s->r, s->g, s->b);
  1325. }
  1326. else if (a)
  1327. {
  1328. uchar o = 255 - a;
  1329. int r = lookup[s->r] + DivLut[o * Rc16(*d)];
  1330. int g = lookup[s->g] + DivLut[o * Gc16(*d)];
  1331. int b = lookup[s->b] + DivLut[o * Bc16(*d)];
  1332. *d = Rgb16(r, g, b);
  1333. }
  1334. s++;
  1335. d++;
  1336. }
  1337. }
  1338. Ptr += Dest->Line;
  1339. }
  1340. break;
  1341. }
  1342. }
  1343. }
  1344. return false;
  1345. }
  1346. /////////////////////////////////////////////////////////////////////////////////////////////////////
  1347. #define Setup24() \
  1348. Pixel24 *p = (Pixel24*)Ptr; \
  1349. uchar *DivLut = Div255Lut; \
  1350. int r = R24(c) * alpha; \
  1351. int g = G24(c) * alpha; \
  1352. int b = B24(c) * alpha;
  1353. #define Comp24() \
  1354. p->r = DivLut[(oma * p->r) + r]; \
  1355. p->g = DivLut[(oma * p->g) + g]; \
  1356. p->b = DivLut[(oma * p->b) + b]; \
  1357. void GdcApp24Alpha::Set()
  1358. {
  1359. Setup24();
  1360. Comp24();
  1361. }
  1362. void GdcApp24Alpha::VLine(int height)
  1363. {
  1364. Setup24();
  1365. while (height--)
  1366. {
  1367. Comp24();
  1368. p = (Pixel24*) (Ptr += Dest->Line);
  1369. }
  1370. }
  1371. void GdcApp24Alpha::Rectangle(int x, int y)
  1372. {
  1373. Setup24();
  1374. while (y--)
  1375. {
  1376. for (int n=0; n<x; n++)
  1377. {
  1378. Comp24();
  1379. p = p->Next();
  1380. }
  1381. p = (Pixel24*) (Ptr += Dest->Line);
  1382. }
  1383. }
  1384. bool GdcApp24Alpha::Blt(GBmpMem *Src, GPalette *SPal, GBmpMem *SrcAlpha)
  1385. {
  1386. if (!Src) return false;
  1387. uchar *DivLut = Div255Lut;
  1388. uchar lookup[256];
  1389. for (int i=0; i<256; i++)
  1390. {
  1391. lookup[i] = (i * (int)alpha) / 255;
  1392. }
  1393. if (SrcAlpha)
  1394. {
  1395. switch (Src->Bits)
  1396. {
  1397. case 8:
  1398. {
  1399. Pixel24 c[256];
  1400. CreatePaletteLut(c, SPal, 255);
  1401. for (int y=0; y<Src->y; y++)
  1402. {
  1403. uchar *s = Src->Base + (y * Src->Line);
  1404. uchar *e = s + Src->x;
  1405. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1406. Pixel24 *d = (Pixel24*) Ptr;
  1407. while (s < e)
  1408. {
  1409. uchar a = lookup[*sa++];
  1410. uchar o = 255 - a;
  1411. if (a == 255)
  1412. {
  1413. Pixel24 *src = c + *s;
  1414. *d = *src;
  1415. }
  1416. else if (a)
  1417. {
  1418. Pixel24 *src = c + *s;
  1419. d->r = DivLut[(o * d->r) + (a * src->r)];
  1420. d->g = DivLut[(o * d->g) + (a * src->g)];
  1421. d->b = DivLut[(o * d->b) + (a * src->b)];
  1422. }
  1423. s++;
  1424. d = d->Next();
  1425. }
  1426. Ptr += Dest->Line;
  1427. }
  1428. break;
  1429. }
  1430. case 15:
  1431. {
  1432. for (int y=0; y<Src->y; y++)
  1433. {
  1434. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1435. ushort *e = s + Src->x;
  1436. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1437. Pixel24 *d = (Pixel24*) Ptr;
  1438. while (s < e)
  1439. {
  1440. uchar a = lookup[*sa++];
  1441. if (a == 255)
  1442. {
  1443. d->r = Bc15(*s);
  1444. d->g = Gc15(*s);
  1445. d->b = Rc15(*s);
  1446. }
  1447. else if (a)
  1448. {
  1449. uchar o = 255 - a;
  1450. d->r = Div255((o * d->r) + (a * Rc15(*s)));
  1451. d->g = Div255((o * d->g) + (a * Gc15(*s)));
  1452. d->b = Div255((o * d->b) + (a * Bc15(*s)));
  1453. }
  1454. s++;
  1455. d = d->Next();
  1456. }
  1457. Ptr += Dest->Line;
  1458. }
  1459. break;
  1460. }
  1461. case 16:
  1462. {
  1463. for (int y=0; y<Src->y; y++)
  1464. {
  1465. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1466. ushort *e = s + Src->x;
  1467. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1468. Pixel24 *d = (Pixel24*) Ptr;
  1469. while (s < e)
  1470. {
  1471. uchar a = lookup[*sa++];
  1472. if (a == 255)
  1473. {
  1474. d->r = Bc16(*s);
  1475. d->g = Gc16(*s);
  1476. d->b = Rc16(*s);
  1477. }
  1478. else if (a)
  1479. {
  1480. uchar o = 255 - a;
  1481. d->r = Div255((o * d->r) + (a * Rc16(*s)));
  1482. d->g = Div255((o * d->g) + (a * Gc16(*s)));
  1483. d->b = Div255((o * d->b) + (a * Bc16(*s)));
  1484. }
  1485. s++;
  1486. d = d->Next();
  1487. }
  1488. Ptr += Dest->Line;
  1489. }
  1490. break;
  1491. }
  1492. case 24:
  1493. {
  1494. for (int y=0; y<Src->y; y++)
  1495. {
  1496. uchar *s = Src->Base + (y * Src->Line);
  1497. uchar *src_a = SrcAlpha->Base + (y * SrcAlpha->Line);
  1498. uchar *d = Ptr;
  1499. for (int x=0; x<Src->x; x++)
  1500. {
  1501. uchar my_a = lookup[*src_a++];
  1502. uchar my_oma = 255 - my_a;
  1503. if (my_oma == 0)
  1504. {
  1505. d[0] = s[0];
  1506. d[1] = s[1];
  1507. d[2] = s[2];
  1508. }
  1509. else if (my_oma < 255)
  1510. {
  1511. d[0] = Div255( (my_oma * d[0]) + (my_a * s[0]) );
  1512. d[1] = Div255( (my_oma * d[1]) + (my_a * s[1]) );
  1513. d[2] = Div255( (my_oma * d[2]) + (my_a * s[2]) );
  1514. }
  1515. d += Bytes;
  1516. s += Bytes;
  1517. }
  1518. Ptr += Dest->Line;
  1519. }
  1520. break;
  1521. }
  1522. case 32:
  1523. {
  1524. for (int y=0; y<Src->y; y++)
  1525. {
  1526. Pixel32 *s = (Pixel32*) (Src->Base + (y * Src->Line));
  1527. Pixel32 *e = s + Src->x;
  1528. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1529. Pixel24 *d = (Pixel24*) Ptr;
  1530. while (s < e)
  1531. {
  1532. uchar a = lookup[*sa++];
  1533. if (a == 255)
  1534. {
  1535. d->r = s->r;
  1536. d->g = s->g;
  1537. d->b = s->b;
  1538. }
  1539. else if (a)
  1540. {
  1541. uchar o = 255 - a;
  1542. d->r = DivLut[(d->r * o) + (s->r * a)];
  1543. d->g = DivLut[(d->g * o) + (s->g * a)];
  1544. d->b = DivLut[(d->b * o) + (s->b * a)];
  1545. }
  1546. s++;
  1547. d = d->Next();
  1548. }
  1549. Ptr += Dest->Line;
  1550. }
  1551. break;
  1552. }
  1553. }
  1554. }
  1555. else
  1556. {
  1557. switch (Src->Bits)
  1558. {
  1559. case 8:
  1560. {
  1561. Pixel24 c[256];
  1562. CreatePaletteLut(c, SPal, alpha);
  1563. for (int y=0; y<Src->y; y++)
  1564. {
  1565. uchar *s = Src->Base + (y * Src->Line);
  1566. uchar *e = s + Src->x;
  1567. Pixel24 *d = (Pixel24*) Ptr;
  1568. while (s < e)
  1569. {
  1570. Pixel24 *src = c + *s++;
  1571. d->r = src->r + DivLut[d->r * oma];
  1572. d->g = src->g + DivLut[d->g * oma];
  1573. d->b = src->b + DivLut[d->b * oma];
  1574. d = d->Next();
  1575. }
  1576. Ptr += Dest->Line;
  1577. }
  1578. break;
  1579. }
  1580. case 15:
  1581. {
  1582. for (int y=0; y<Src->y; y++)
  1583. {
  1584. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1585. ushort *e = s + Src->x;
  1586. Pixel24 *d = (Pixel24*) Ptr;
  1587. while (s < e)
  1588. {
  1589. d->r = DivLut[(oma * d->r) + (alpha * Rc15(*s))];
  1590. d->g = DivLut[(oma * d->g) + (alpha * Gc15(*s))];
  1591. d->b = DivLut[(oma * d->b) + (alpha * Bc15(*s))];
  1592. s++;
  1593. d = d->Next();
  1594. }
  1595. Ptr += Dest->Line;
  1596. }
  1597. break;
  1598. }
  1599. case 16:
  1600. {
  1601. for (int y=0; y<Src->y; y++)
  1602. {
  1603. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1604. Pixel24 *d = (Pixel24*) Ptr;
  1605. if (alpha == 255)
  1606. {
  1607. for (int x=0; x<Src->x; x++)
  1608. {
  1609. d->r = Rc16(*s);
  1610. d->g = Gc16(*s);
  1611. d->b = Bc16(*s);
  1612. s++;
  1613. d = d->Next();
  1614. }
  1615. }
  1616. else if (alpha)
  1617. {
  1618. for (int x=0; x<Src->x; x++)
  1619. {
  1620. d->r = DivLut[(oma * d->r) + (alpha * Rc15(*s))];
  1621. d->g = DivLut[(oma * d->g) + (alpha * Gc16(*s))];
  1622. d->b = DivLut[(oma * d->b) + (alpha * Bc16(*s))];
  1623. s++;
  1624. d = d->Next();
  1625. }
  1626. }
  1627. Ptr += Dest->Line;
  1628. }
  1629. break;
  1630. }
  1631. case 24:
  1632. {
  1633. for (int y=0; y<Src->y; y++)
  1634. {
  1635. Pixel24 *s = (Pixel24*) (Src->Base + (y * Src->Line));
  1636. Pixel24 *d = (Pixel24*) Ptr;
  1637. if (alpha == 255)
  1638. {
  1639. memcpy(d, s, Src->x * Pixel24::Size);
  1640. }
  1641. else if (alpha)
  1642. {
  1643. for (int x=0; x<Src->x; x++)
  1644. {
  1645. d->r = DivLut[(oma * d->r) + (alpha * s->r)];
  1646. d->g = DivLut[(oma * d->g) + (alpha * s->g)];
  1647. d->b = DivLut[(oma * d->b) + (alpha * s->b)];
  1648. s = s->Next();
  1649. d = d->Next();
  1650. }
  1651. }
  1652. Ptr += Dest->Line;
  1653. }
  1654. break;
  1655. }
  1656. case 32:
  1657. {
  1658. for (int y=0; y<Src->y; y++)
  1659. {
  1660. Pixel32 *s = (Pixel32*) (Src->Base + (y * Src->Line));
  1661. Pixel24 *d = (Pixel24*) Ptr;
  1662. if (alpha == 255)
  1663. {
  1664. for (int x=0; x<Src->x; x++)
  1665. {
  1666. if (s->a)
  1667. {
  1668. uchar o = 255 - s->a;
  1669. d->r = DivLut[(s->r * s->a) + (d->r * o)];
  1670. d->g = DivLut[(s->g * s->a) + (d->g * o)];
  1671. d->b = DivLut[(s->b * s->a) + (d->b * o)];
  1672. }
  1673. s++;
  1674. d = d->Next();
  1675. }
  1676. }
  1677. else if (alpha)
  1678. {
  1679. for (int x=0; x<Src->x; x++)
  1680. {
  1681. uchar a = lookup[s->a];
  1682. if (a == 255)
  1683. {
  1684. d->r = s->r;
  1685. d->g = s->g;
  1686. d->b = s->b;
  1687. }
  1688. else if (a)
  1689. {
  1690. uchar o = 255 - a;
  1691. d->r = lookup[s->r] + DivLut[o * d->r];
  1692. d->g = lookup[s->g] + DivLut[o * d->g];
  1693. d->b = lookup[s->b] + DivLut[o * d->b];
  1694. }
  1695. s++;
  1696. d = d->Next();
  1697. }
  1698. }
  1699. Ptr += Dest->Line;
  1700. }
  1701. break;
  1702. }
  1703. }
  1704. }
  1705. return false;
  1706. }
  1707. /////////////////////////////////////////////////////////////////////////////////////////////////////
  1708. #define Setup32() \
  1709. uchar *DivLut = Div255Lut; \
  1710. int a = DivLut[A32(c) * alpha]; \
  1711. int oma = 255 - a; \
  1712. int r = R32(c) * a; \
  1713. int g = G32(c) * a; \
  1714. int b = B32(c) * a;
  1715. #define Comp32() \
  1716. p->r = DivLut[(oma * p->r) + r]; \
  1717. p->g = DivLut[(oma * p->g) + g]; \
  1718. p->b = DivLut[(oma * p->b) + b]; \
  1719. p->a = (p->a + a) - DivLut[p->a * a];
  1720. void GdcApp32Alpha::Set()
  1721. {
  1722. Pixel32 *p = (Pixel32*) Ptr;
  1723. Setup32();
  1724. Comp32();
  1725. }
  1726. void GdcApp32Alpha::VLine(int height)
  1727. {
  1728. Setup32();
  1729. while (height--)
  1730. {
  1731. Pixel32 *p = (Pixel32*) Ptr;
  1732. Comp32();
  1733. Ptr = (((uchar*) Ptr) + Dest->Line);
  1734. }
  1735. }
  1736. void GdcApp32Alpha::Rectangle(int x, int y)
  1737. {
  1738. Setup32();
  1739. while (y--)
  1740. {
  1741. Pixel32 *p = (Pixel32*) Ptr;
  1742. for (int n=0; n<x; n++, p++)
  1743. {
  1744. Comp32();
  1745. }
  1746. Ptr = (((uchar*) Ptr) + Dest->Line);
  1747. }
  1748. }
  1749. bool GdcApp32Alpha::Blt(GBmpMem *Src, GPalette *SPal, GBmpMem *SrcAlpha)
  1750. {
  1751. if (!Src) return 0;
  1752. uchar *DivLut = Div255Lut;
  1753. uchar lookup[256];
  1754. for (int i=0; i<256; i++)
  1755. {
  1756. lookup[i] = DivLut[i * alpha];
  1757. }
  1758. if (SrcAlpha)
  1759. {
  1760. switch (Src->Bits)
  1761. {
  1762. case 8:
  1763. {
  1764. Pixel24 c[256];
  1765. CreatePaletteLut(c, SPal);
  1766. for (int y=0; y<Src->y; y++)
  1767. {
  1768. uchar *s = (uchar*) (Src->Base + (y * Src->Line));
  1769. uchar *sa = (uchar*) (SrcAlpha->Base + (y * SrcAlpha->Line));
  1770. Pixel24 *sc;
  1771. Pixel32 *d = (Pixel32*) Ptr;
  1772. uchar a, o;
  1773. for (int x=0; x<Src->x; x++)
  1774. {
  1775. a = lookup[*sa++];
  1776. if (a == 255)
  1777. {
  1778. sc = c + *s;
  1779. d->r = sc->r;
  1780. d->g = sc->g;
  1781. d->b = sc->b;
  1782. d->a = 255;
  1783. }
  1784. else if (a)
  1785. {
  1786. sc = c + *s;
  1787. o = 0xff - a;
  1788. d->r = DivLut[(d->r * o) + (sc->r * a)];
  1789. d->g = DivLut[(d->g * o) + (sc->g * a)];
  1790. d->b = DivLut[(d->b * o) + (sc->b * a)];
  1791. d->a = (a + d->a) - DivLut[a * d->a];
  1792. }
  1793. s++;
  1794. d++;
  1795. }
  1796. Ptr = (((uchar*) Ptr) + Dest->Line);
  1797. }
  1798. break;
  1799. }
  1800. case 15:
  1801. {
  1802. for (int y=0; y<Src->y; y++)
  1803. {
  1804. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1805. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1806. Pixel32 *d = (Pixel32*) Ptr;
  1807. for (int x=0; x<Src->x; x++)
  1808. {
  1809. uchar a = lookup[*sa++];
  1810. if (a == 255)
  1811. {
  1812. d->r = Rc15(*s);
  1813. d->g = Gc15(*s);
  1814. d->b = Bc15(*s);
  1815. }
  1816. else if (a)
  1817. {
  1818. uchar o = 255 - a;
  1819. d->r = DivLut[(a * Rc15(*s)) + (o * d->r)];
  1820. d->g = DivLut[(a * Gc15(*s)) + (o * d->g)];
  1821. d->b = DivLut[(a * Bc15(*s)) + (o * d->b)];
  1822. }
  1823. s++;
  1824. d++;
  1825. }
  1826. Ptr += Dest->Line;
  1827. }
  1828. break;
  1829. }
  1830. case 16:
  1831. {
  1832. for (int y=0; y<Src->y; y++)
  1833. {
  1834. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1835. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1836. Pixel32 *d = (Pixel32*) Ptr;
  1837. for (int x=0; x<Src->x; x++)
  1838. {
  1839. uchar a = lookup[*sa++];
  1840. if (a == 255)
  1841. {
  1842. d->r = Rc16(*s);
  1843. d->g = Gc16(*s);
  1844. d->b = Bc16(*s);
  1845. }
  1846. else if (a)
  1847. {
  1848. uchar o = 255 - a;
  1849. d->r = DivLut[(a * Rc16(*s)) + (o * d->r)];
  1850. d->g = DivLut[(a * Gc16(*s)) + (o * d->g)];
  1851. d->b = DivLut[(a * Bc16(*s)) + (o * d->b)];
  1852. }
  1853. s++;
  1854. d++;
  1855. }
  1856. Ptr += Dest->Line;
  1857. }
  1858. break;
  1859. }
  1860. case 24:
  1861. {
  1862. for (int y=0; y<Src->y; y++)
  1863. {
  1864. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1865. Pixel32 *d = (Pixel32*) Ptr;
  1866. Pixel24 *s = (Pixel24*) (Src->Base + (y * Src->Line));
  1867. for (int x=0; x<Src->x; x++)
  1868. {
  1869. uchar a = lookup[*sa++];
  1870. if (a == 255)
  1871. {
  1872. d->r = s->r;
  1873. d->g = s->g;
  1874. d->b = s->b;
  1875. }
  1876. else if (a)
  1877. {
  1878. uchar o = 255 - a;
  1879. d->r = DivLut[(a * s->r) + (o * d->r)];
  1880. d->g = DivLut[(a * s->g) + (o * d->g)];
  1881. d->b = DivLut[(a * s->b) + (o * d->b)];
  1882. }
  1883. d++;
  1884. s = s->Next();
  1885. }
  1886. Ptr += Dest->Line;
  1887. }
  1888. break;
  1889. }
  1890. case 32:
  1891. {
  1892. for (int y=0; y<Src->y; y++)
  1893. {
  1894. Pixel32 *d = (Pixel32*) Ptr;
  1895. Pixel32 *s = (Pixel32*) (Src->Base + (y * Src->Line));
  1896. uchar *sa = SrcAlpha->Base + (y * SrcAlpha->Line);
  1897. for (int x=0; x<Src->x; x++)
  1898. {
  1899. uchar a = lookup[*sa++];
  1900. if (a == 255)
  1901. {
  1902. d->r = s->r;
  1903. d->g = s->g;
  1904. d->b = s->b;
  1905. d->a = 255;
  1906. }
  1907. else if (a)
  1908. {
  1909. uchar o = 255 - a;
  1910. d->r = DivLut[(a * s->r) + (o * d->r)];
  1911. d->g = DivLut[(a * s->g) + (o * d->g)];
  1912. d->b = DivLut[(a * s->b) + (o * d->b)];
  1913. d->a = (s->a + d->a) - DivLut[s->a * d->a];
  1914. }
  1915. d++;
  1916. s++;
  1917. }
  1918. Ptr += Dest->Line;
  1919. }
  1920. break;
  1921. }
  1922. }
  1923. }
  1924. else
  1925. {
  1926. switch (Src->Bits)
  1927. {
  1928. case 8:
  1929. {
  1930. Pixel24 c[256];
  1931. CreatePaletteLut(c, SPal, alpha);
  1932. for (int y=0; y<Src->y; y++)
  1933. {
  1934. uchar *s = (uchar*) (Src->Base + (y * Src->Line));
  1935. Pixel24 *sc;
  1936. Pixel32 *d = (Pixel32*) Ptr;
  1937. if (alpha == 255)
  1938. {
  1939. for (int x=0; x<Src->x; x++)
  1940. {
  1941. sc = c + *s++;
  1942. d->r = sc->r;
  1943. d->g = sc->g;
  1944. d->b = sc->b;
  1945. d->a = 255;
  1946. d++;
  1947. }
  1948. }
  1949. else if (alpha)
  1950. {
  1951. for (int x=0; x<Src->x; x++)
  1952. {
  1953. sc = c + *s++;
  1954. d->r = sc->r + DivLut[d->r * oma];
  1955. d->g = sc->g + DivLut[d->g * oma];
  1956. d->b = sc->b + DivLut[d->b * oma];
  1957. d->a = (alpha + d->a) - DivLut[alpha * d->a];
  1958. d++;
  1959. }
  1960. }
  1961. Ptr = (((uchar*) Ptr) + Dest->Line);
  1962. }
  1963. break;
  1964. }
  1965. case 15:
  1966. {
  1967. for (int y=0; y<Src->y; y++)
  1968. {
  1969. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1970. ushort *e = s + Src->x;
  1971. Pixel32 *d = (Pixel32*) Ptr;
  1972. while (s < e)
  1973. {
  1974. d->r = DivLut[(oma * d->r) + (alpha * Rc15(*s))];
  1975. d->g = DivLut[(oma * d->g) + (alpha * Gc15(*s))];
  1976. d->b = DivLut[(oma * d->b) + (alpha * Bc15(*s))];
  1977. s++;
  1978. d++;
  1979. }
  1980. Ptr += Dest->Line;
  1981. }
  1982. break;
  1983. }
  1984. case 16:
  1985. {
  1986. for (int y=0; y<Src->y; y++)
  1987. {
  1988. ushort *s = (ushort*) (Src->Base + (y * Src->Line));
  1989. Pixel32 *d = (Pixel32*) Ptr;
  1990. if (alpha == 255)
  1991. {
  1992. for (int x=0; x<Src->x; x++)
  1993. {
  1994. d->r = Rc16(*s);
  1995. d->g = Gc16(*s);
  1996. d->b = Bc16(*s);
  1997. d->a = 255;
  1998. d++;
  1999. s++;
  2000. }
  2001. }
  2002. else if (alpha)
  2003. {
  2004. for (int x=0; x<Src->x; x++)
  2005. {
  2006. d->r = DivLut[(d->r * oma) + (Rc16(*s) * alpha)];
  2007. d->g = DivLut[(d->g * oma) + (Gc16(*s) * alpha)];
  2008. d->b = DivLut[(d->b * oma) + (Bc16(*s) * alpha)];
  2009. d->a = (alpha + d->a) - DivLut[alpha * d->a];
  2010. d++;
  2011. s++;
  2012. }
  2013. }
  2014. Ptr = (((uchar*) Ptr) + Dest->Line);
  2015. }
  2016. break;
  2017. }
  2018. case 24:
  2019. {
  2020. for (int y=0; y<Src->y; y++)
  2021. {
  2022. Pixel24 *s = (Pixel24*) (Src->Base + (y * Src->Line));
  2023. Pixel32 *d = (Pixel32*) Ptr;
  2024. if (alpha == 255)
  2025. {
  2026. for (int x=0; x<Src->x; x++)
  2027. {
  2028. d->r = s->r;
  2029. d->g = s->g;
  2030. d->b = s->b;
  2031. d->a = 255;
  2032. d++;
  2033. s = s->Next();
  2034. }
  2035. }
  2036. else if (alpha)
  2037. {
  2038. for (int x=0; x<Src->x; x++)
  2039. {
  2040. d->r = DivLut[(d->r * oma) + (s->r * alpha)];
  2041. d->g = DivLut[(d->g * oma) + (s->g * alpha)];
  2042. d->b = DivLut[(d->b * oma) + (s->b * alpha)];
  2043. d->a = (d->a * alpha) - DivLut[d->a * alpha];
  2044. d++;
  2045. s = s->Next();
  2046. }
  2047. }
  2048. Ptr = (((uchar*) Ptr) + Dest->Line);
  2049. }
  2050. break;
  2051. }
  2052. case 32:
  2053. {
  2054. for (int y=0; y<Src->y; y++)
  2055. {
  2056. Pixel32 *s = (Pixel32*) (Src->Base + (y * Src->Line));
  2057. Pixel32 *d = (Pixel32*) Ptr;
  2058. if (alpha == 255)
  2059. {
  2060. // 32bit alpha channel blt
  2061. for (int x=0; x<Src->x; x++)
  2062. {
  2063. if (s->a == 255)
  2064. {
  2065. *d = *s;
  2066. }
  2067. else if (s->a)
  2068. {
  2069. uchar o = 255 - s->a;
  2070. int ra = (d->a + s->a) - DivLut[d->a * s->a];
  2071. #define rop(c) d->c = (DivLut[DivLut[d->c * d->a] * o] + DivLut[s->c * s->a]) * 255 / ra;
  2072. rop(r);
  2073. rop(g);
  2074. rop(b);
  2075. #undef rop
  2076. d->a = ra;
  2077. }
  2078. d++;
  2079. s++;
  2080. }
  2081. }
  2082. else if (alpha)
  2083. {
  2084. // Const alpha + 32bit alpha channel blt
  2085. for (int x=0; x<Src->x; x++)
  2086. {
  2087. uchar a = lookup[s->a];
  2088. uchar o = 255 - a;
  2089. d->r = lookup[s->r] + DivLut[d->r * o];
  2090. d->g = lookup[s->g] + DivLut[d->g * o];
  2091. d->b = lookup[s->b] + DivLut[d->b * o];
  2092. d->a = (d->a + a) - DivLut[d->a * a];
  2093. d++;
  2094. s++;
  2095. }
  2096. }
  2097. Ptr = (((uchar*) Ptr) + Dest->Line);
  2098. }
  2099. break;
  2100. }
  2101. }
  2102. }
  2103. return false;
  2104. }