home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / interp.h < prev    next >
Encoding:
C/C++ Source or Header  |  2003-11-19  |  9.7 KB  |  295 lines

  1. /*
  2.  * This file is part of the Advance project.
  3.  *
  4.  * Copyright (C) 2003 Andrea Mazzoleni
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * In addition, as a special exception, Andrea Mazzoleni
  21.  * gives permission to link the code of this program with
  22.  * the MAME library (or with modified versions of MAME that use the
  23.  * same license as MAME), and distribute linked combinations including
  24.  * the two.  You must obey the GNU General Public License in all
  25.  * respects for all of the code used other than MAME.  If you modify
  26.  * this file, you may extend this exception to your version of the
  27.  * file, but you are not obligated to do so.  If you do not wish to
  28.  * do so, delete this exception statement from your version.
  29.  */
  30.  
  31. #ifndef __INTERP_H
  32. #define __INTERP_H
  33.  
  34. /***************************************************************************/
  35. /* Basic types */
  36.  
  37. /***************************************************************************/
  38. /* interpolation */
  39.  
  40. static unsigned interp_mask[2];
  41. static unsigned interp_bits_per_pixel;
  42.  
  43. #define INTERP_16_MASK_1(v) (v & interp_mask[0])
  44. #define INTERP_16_MASK_2(v) (v & interp_mask[1])
  45.  
  46. static inline u16 interp_16_521(u16 p1, u16 p2, u16 p3)
  47. {
  48.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*2 + INTERP_16_MASK_1(p3)*1) / 8)
  49.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*2 + INTERP_16_MASK_2(p3)*1) / 8);
  50. }
  51.  
  52. static inline u16 interp_16_332(u16 p1, u16 p2, u16 p3)
  53. {
  54.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)*2) / 8)
  55.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)*2) / 8);
  56. }
  57.  
  58. static inline u16 interp_16_611(u16 p1, u16 p2, u16 p3)
  59. {
  60.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*6 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 8)
  61.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*6 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 8);
  62. }
  63.  
  64. static inline u16 interp_16_71(u16 p1, u16 p2)
  65. {
  66.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*7 + INTERP_16_MASK_1(p2)) / 8)
  67.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*7 + INTERP_16_MASK_2(p2)) / 8);
  68. }
  69.  
  70. static inline u16 interp_16_211(u16 p1, u16 p2, u16 p3)
  71. {
  72.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*2 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 4)
  73.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*2 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 4);
  74. }
  75.  
  76. static inline u16 interp_16_772(u16 p1, u16 p2, u16 p3)
  77. {
  78.   return INTERP_16_MASK_1(((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2))*7 + INTERP_16_MASK_1(p3)*2) / 16)
  79.     | INTERP_16_MASK_2(((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2))*7 + INTERP_16_MASK_2(p3)*2) / 16);
  80. }
  81.  
  82. static inline u16 interp_16_11(u16 p1, u16 p2)
  83. {
  84.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1) + INTERP_16_MASK_1(p2)) / 2)
  85.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1) + INTERP_16_MASK_2(p2)) / 2);
  86. }
  87.  
  88. static inline u16 interp_16_31(u16 p1, u16 p2)
  89. {
  90.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*3 + INTERP_16_MASK_1(p2)) / 4)
  91.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*3 + INTERP_16_MASK_2(p2)) / 4);
  92. }
  93.  
  94. static inline u16 interp_16_1411(u16 p1, u16 p2, u16 p3)
  95. {
  96.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*14 + INTERP_16_MASK_1(p2) + INTERP_16_MASK_1(p3)) / 16)
  97.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*14 + INTERP_16_MASK_2(p2) + INTERP_16_MASK_2(p3)) / 16);
  98. }
  99.  
  100. static inline u16 interp_16_431(u16 p1, u16 p2, u16 p3)
  101. {
  102.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*4 + INTERP_16_MASK_1(p2)*3 + INTERP_16_MASK_1(p3)) / 8)
  103.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*4 + INTERP_16_MASK_2(p2)*3 + INTERP_16_MASK_2(p3)) / 8);
  104. }
  105.  
  106. static inline u16 interp_16_53(u16 p1, u16 p2)
  107. {
  108.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*5 + INTERP_16_MASK_1(p2)*3) / 8)
  109.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*5 + INTERP_16_MASK_2(p2)*3) / 8);
  110. }
  111.  
  112. static inline u16 interp_16_151(u16 p1, u16 p2)
  113. {
  114.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*15 + INTERP_16_MASK_1(p2)) / 16)
  115.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*15 + INTERP_16_MASK_2(p2)) / 16);
  116. }
  117.  
  118. static inline u16 interp_16_97(u16 p1, u16 p2)
  119. {
  120.   return INTERP_16_MASK_1((INTERP_16_MASK_1(p1)*9 + INTERP_16_MASK_1(p2)*7) / 16)
  121.     | INTERP_16_MASK_2((INTERP_16_MASK_2(p1)*9 + INTERP_16_MASK_2(p2)*7) / 16);
  122. }
  123.  
  124. #define INTERP_32_MASK_1(v) (v & 0xFF00FF)
  125. #define INTERP_32_MASK_2(v) (v & 0x00FF00)
  126.  
  127. static inline u32 interp_32_521(u32 p1, u32 p2, u32 p3)
  128. {
  129.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*2 + INTERP_32_MASK_1(p3)*1) / 8)
  130.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*2 + INTERP_32_MASK_2(p3)*1) / 8);
  131. }
  132.  
  133. static inline u32 interp_32_332(u32 p1, u32 p2, u32 p3)
  134. {
  135.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)*2) / 8)
  136.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)*2) / 8);
  137. }
  138.  
  139. static inline u32 interp_32_211(u32 p1, u32 p2, u32 p3)
  140. {
  141.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*2 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 4)
  142.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*2 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 4);
  143. }
  144.  
  145. static inline u32 interp_32_611(u32 p1, u32 p2, u32 p3)
  146. {
  147.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*6 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 8)
  148.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*6 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 8);
  149. }
  150.  
  151. static inline u32 interp_32_71(u32 p1, u32 p2)
  152. {
  153.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*7 + INTERP_32_MASK_1(p2)) / 8)
  154.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*7 + INTERP_32_MASK_2(p2)) / 8);
  155. }
  156.  
  157. static inline u32 interp_32_772(u32 p1, u32 p2, u32 p3)
  158. {
  159.   return INTERP_32_MASK_1(((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2))*7 + INTERP_32_MASK_1(p3)*2) / 16)
  160.     | INTERP_32_MASK_2(((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2))*7 + INTERP_32_MASK_2(p3)*2) / 16);
  161. }
  162.  
  163. static inline u32 interp_32_11(u32 p1, u32 p2)
  164. {
  165.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1) + INTERP_32_MASK_1(p2)) / 2)
  166.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1) + INTERP_32_MASK_2(p2)) / 2);
  167. }
  168.  
  169. static inline u32 interp_32_31(u32 p1, u32 p2)
  170. {
  171.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*3 + INTERP_32_MASK_1(p2)) / 4)
  172.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*3 + INTERP_32_MASK_2(p2)) / 4);
  173. }
  174.  
  175. static inline u32 interp_32_1411(u32 p1, u32 p2, u32 p3)
  176. {
  177.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*14 + INTERP_32_MASK_1(p2) + INTERP_32_MASK_1(p3)) / 16)
  178.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*14 + INTERP_32_MASK_2(p2) + INTERP_32_MASK_2(p3)) / 16);
  179. }
  180.  
  181. static inline u32 interp_32_431(u32 p1, u32 p2, u32 p3)
  182. {
  183.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*4 + INTERP_32_MASK_1(p2)*3 + INTERP_32_MASK_1(p3)) / 8)
  184.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*4 + INTERP_32_MASK_2(p2)*3 + INTERP_32_MASK_2(p3)) / 8);
  185. }
  186.  
  187. static inline u32 interp_32_53(u32 p1, u32 p2)
  188. {
  189.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*5 + INTERP_32_MASK_1(p2)*3) / 8)
  190.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*5 + INTERP_32_MASK_2(p2)*3) / 8);
  191. }
  192.  
  193. static inline u32 interp_32_151(u32 p1, u32 p2)
  194. {
  195.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*15 + INTERP_32_MASK_1(p2)) / 16)
  196.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*15 + INTERP_32_MASK_2(p2)) / 16);
  197. }
  198.  
  199. static inline u32 interp_32_97(u32 p1, u32 p2)
  200. {
  201.   return INTERP_32_MASK_1((INTERP_32_MASK_1(p1)*9 + INTERP_32_MASK_1(p2)*7) / 16)
  202.     | INTERP_32_MASK_2((INTERP_32_MASK_2(p1)*9 + INTERP_32_MASK_2(p2)*7) / 16);
  203. }
  204.  
  205. /***************************************************************************/
  206. /* diff */
  207.  
  208. #define INTERP_Y_LIMIT (0x30*4)
  209. #define INTERP_U_LIMIT (0x07*4)
  210. #define INTERP_V_LIMIT (0x06*8)
  211.  
  212. static int interp_16_diff(u16 p1, u16 p2)
  213. {
  214.   int r, g, b;
  215.   int y, u, v;
  216.  
  217.   if (p1 == p2)
  218.     return 0;
  219.  
  220.   if (interp_bits_per_pixel == 16) {
  221.     b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
  222.     g = (int)((p1 & 0x7E0) - (p2 & 0x7E0)) >> 3;
  223.     r = (int)((p1 & 0xF800) - (p2 & 0xF800)) >> 8;
  224.   } else {
  225.     b = (int)((p1 & 0x1F) - (p2 & 0x1F)) << 3;
  226.     g = (int)((p1 & 0x3E0) - (p2 & 0x3E0)) >> 2;
  227.     r = (int)((p1 & 0x7C00) - (p2 & 0x7C00)) >> 7;
  228.   }
  229.  
  230.   y = r + g + b;
  231.   u = r - b;
  232.   v = -r + 2*g - b;
  233.  
  234.   if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
  235.     return 1;
  236.  
  237.   if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
  238.     return 1;
  239.  
  240.   if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
  241.     return 1;
  242.  
  243.   return 0;
  244. }
  245.  
  246. static int interp_32_diff(u32 p1, u32 p2)
  247. {
  248.   int r, g, b;
  249.   int y, u, v;
  250.  
  251.   if ((p1 & 0xF8F8F8) == (p2 & 0xF8F8F8))
  252.     return 0;
  253.  
  254.   b = (int)((p1 & 0xFF) - (p2 & 0xFF));
  255.   g = (int)((p1 & 0xFF00) - (p2 & 0xFF00)) >> 8;
  256.   r = (int)((p1 & 0xFF0000) - (p2 & 0xFF0000)) >> 16;
  257.  
  258.   y = r + g + b;
  259.   u = r - b;
  260.   v = -r + 2*g - b;
  261.  
  262.   if (y < -INTERP_Y_LIMIT || y > INTERP_Y_LIMIT)
  263.     return 1;
  264.  
  265.   if (u < -INTERP_U_LIMIT || u > INTERP_U_LIMIT)
  266.     return 1;
  267.  
  268.   if (v < -INTERP_V_LIMIT || v > INTERP_V_LIMIT)
  269.     return 1;
  270.  
  271.   return 0;
  272. }
  273.  
  274. static void interp_set(unsigned bits_per_pixel)
  275. {
  276.   interp_bits_per_pixel = bits_per_pixel;
  277.  
  278.   switch (bits_per_pixel) {
  279.   case 15 :
  280.     interp_mask[0] = 0x7C1F;
  281.     interp_mask[1] = 0x03E0;
  282.     break;
  283.   case 16 :
  284.     interp_mask[0] = 0xF81F;
  285.     interp_mask[1] = 0x07E0;
  286.     break;
  287.   case 32 :
  288.     interp_mask[0] = 0xFF00FF;
  289.     interp_mask[1] = 0x00FF00;
  290.     break;
  291.   }
  292. }
  293.  
  294. #endif
  295.