r_filter.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* Emacs style mode select -*- C++ -*-
  2. *-----------------------------------------------------------------------------
  3. *
  4. *
  5. * PrBoom: a Doom port merged with LxDoom and LSDLDoom
  6. * based on BOOM, a modified and improved DOOM engine
  7. * Copyright (C) 1999 by
  8. * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
  9. * Copyright (C) 1999-2000 by
  10. * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
  11. * Copyright 2005, 2006 by
  12. * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. *
  29. *-----------------------------------------------------------------------------*/
  30. #include "doomtype.h"
  31. #include "r_filter.h"
  32. #define DMR 16
  33. byte filter_ditherMatrix[DITHER_DIM][DITHER_DIM] = {
  34. {0*DMR, 14*DMR, 3*DMR, 13*DMR}, {11*DMR, 5*DMR, 8*DMR, 6*DMR},
  35. {12*DMR, 2*DMR, 15*DMR, 1*DMR}, {7*DMR, 9*DMR, 4*DMR, 10*DMR}
  36. };
  37. byte filter_roundedUVMap[FILTER_UVDIM*FILTER_UVDIM];
  38. byte filter_roundedRowMap[4*16];
  39. void R_FilterInit(void) {
  40. int i,j,s,t;
  41. // scale2x takes the following source:
  42. // A B C
  43. // D E F
  44. // G H I
  45. //
  46. // and doubles the size of E to produce:
  47. // E0 E1
  48. // E2 E3
  49. //
  50. // E0 = D == B && B != F && D != H ? D : E;
  51. // E1 = B == F && B != D && F != H ? F : E;
  52. // E2 = D == H && D != B && H != F ? D : E;
  53. // E3 = H == F && D != H && B != F ? F : E;
  54. //
  55. // to make this comparison regimen faster, we encode source color
  56. // equivalency into a single byte with the getCode() macro
  57. //
  58. // #define getCode(b,f,h,d) ( (b == f)<<0 | (f == h)<<1 | (h == d)<<2 | (d == b)<<3 )
  59. // encode the scale2x conditionals into a lookup code
  60. for (i=0; i<16; i++) {
  61. // E0 = D == B && B != F && D != H ? D : E; // 10-0 => 1000 or 1010 => 8 or A
  62. filter_roundedRowMap[0*16+i] = (i == 0x8 || i == 0xA) ? 0 : 1;
  63. // E1 = B == F && B != D && F != H ? F : E; // 0-01 => 0101 or 0001 => 5 or 1
  64. filter_roundedRowMap[1*16+i] = (i == 0x5 || i == 0x1) ? 2 : 1;
  65. // E2 = D == H && D != B && H != F ? D : E; // 010- => 0101 or 0100 => 5 or 4
  66. filter_roundedRowMap[2*16+i] = (i == 0x4 || i == 0x5) ? 0 : 1;
  67. // E3 = H == F && D != H && B != F ? F : E; // -010 => 1010 or 0010 => A or 2
  68. filter_roundedRowMap[3*16+i] = (i == 0xA || i == 0x2) ? 2 : 1;
  69. }
  70. // fill the uvMap. this will return:
  71. // 0/\1
  72. // /4 \
  73. // \ /
  74. // 2\/3
  75. // .. based on the uv coordinates
  76. for (i=0; i<FILTER_UVDIM; i++) {
  77. for (j=0; j<FILTER_UVDIM; j++) {
  78. s = (FILTER_UVDIM/2) - i;
  79. t = (FILTER_UVDIM/2) - j;
  80. if (s>=0 && t>=0) filter_roundedUVMap[i*FILTER_UVDIM+j] = (s+t > FILTER_UVDIM/2) ? 0 : 4;
  81. else if (s>=0 && t<=0) filter_roundedUVMap[i*FILTER_UVDIM+j] = (s-t > FILTER_UVDIM/2) ? 2 : 4;
  82. else if (s<=0 && t>=0) filter_roundedUVMap[i*FILTER_UVDIM+j] = (-s+t > FILTER_UVDIM/2) ? 1 : 4;
  83. else if (s<=0 && t<=0) filter_roundedUVMap[i*FILTER_UVDIM+j] = (-s-t > FILTER_UVDIM/2) ? 3 : 4;
  84. else filter_roundedUVMap[i*FILTER_UVDIM+j] = 4;
  85. }
  86. }
  87. }
  88. byte *filter_getScale2xQuadColors(byte e, byte b, byte f, byte h, byte d) {
  89. // A B C
  90. // D E F
  91. // G H I
  92. // perform the Scale2x algorithm (quickly) to get the new quad to represent E
  93. static byte quad[5];
  94. static byte rowColors[3];
  95. int code;
  96. rowColors[0] = d;
  97. rowColors[1] = e;
  98. rowColors[2] = f;
  99. #define getCode(b,f,h,d) ( (b == f)<<0 | (f == h)<<1 | (h == d)<<2 | (d == b)<<3 )
  100. code = getCode(b,f,h,d);
  101. quad[0] = rowColors[filter_roundedRowMap[0*16+code]];
  102. quad[1] = rowColors[filter_roundedRowMap[1*16+code]];
  103. quad[2] = rowColors[filter_roundedRowMap[2*16+code]];
  104. quad[3] = rowColors[filter_roundedRowMap[3*16+code]];
  105. quad[4] = e;
  106. return quad;
  107. }