Advertisement
Guest User

Untitled

a guest
Mar 18th, 2013
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.17 KB | None | 0 0
  1. //
  2. // Copyright (C) 2003-2008 Martin Freij
  3. //
  4. // This file is part of Nestopia.
  5. //
  6. // Nestopia 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. // Nestopia 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 Nestopia; if not, write to the Free Software
  18. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. //
  20. ////////////////////////////////////////////////////////////////////////////////////////
  21.  
  22. #include "NstAssert.hpp"
  23. #include "NstVideoRenderer.hpp"
  24. #include "NstVideoFilterNtsc.hpp"
  25. #include "NstFpuPrecision.hpp"
  26.  
  27. namespace Nes
  28. {
  29. namespace Core
  30. {
  31. namespace Video
  32. {
  33. void Renderer::FilterNtsc::Blit(const Input& input,const Output& output,uint phase)
  34. {
  35. (*this.*path)( input, output, phase );
  36. }
  37.  
  38. template<typename Pixel,uint BITS>
  39. void Renderer::FilterNtsc::BlitType(const Input& input,const Output& output,uint phase) const
  40. {
  41. NST_ASSERT( phase < 3 );
  42.  
  43. const uint bgcolor = this->bgColor;
  44. const Input::Pixel* NST_RESTRICT src = input.pixels;
  45. Pixel* NST_RESTRICT dst = static_cast<Pixel*>(output.pixels);
  46. const long pitch = output.pitch;
  47. const long pad = 2*output.pitch - (NTSC_WIDTH-7) * sizeof(Pixel);
  48.  
  49. phase &= lut.noFieldMerging;
  50.  
  51. for (uint y=HEIGHT; y; --y)
  52. {
  53. NES_NTSC_BEGIN_ROW( &lut, phase, bgcolor, bgcolor, *src++ );
  54.  
  55. Pixel temp;
  56. // 0%
  57. #define PIXEL_OUT( i ) \
  58. NES_NTSC_RGB_OUT( i, dst[i], BITS );\
  59. reinterpret_cast<Pixel*>(reinterpret_cast<char*>(dst)+pitch)[i] = 0;
  60.  
  61. for (const Input::Pixel* const end=src+(NTSC_WIDTH/7*3-3); src != end; src += 3, dst +=7)
  62. {
  63. NES_NTSC_COLOR_IN( 0, src[0] );
  64. NES_NTSC_RGB_OUT( 0, dst[0], BITS );
  65. NES_NTSC_RGB_OUT( 1, dst[1], BITS );
  66.  
  67.  
  68. NES_NTSC_COLOR_IN( 1, src[1] );
  69. PIXEL_OUT( 2 );
  70. PIXEL_OUT( 3 );
  71.  
  72. NES_NTSC_COLOR_IN( 2, src[2] );
  73. NES_NTSC_RGB_OUT( 4, dst[4], BITS );
  74. NES_NTSC_RGB_OUT( 5, dst[5], BITS );
  75. NES_NTSC_RGB_OUT( 6, dst[6], BITS );
  76.  
  77. }
  78.  
  79. NES_NTSC_COLOR_IN( 0, lut.black );
  80. NES_NTSC_RGB_OUT( 0, dst[0], BITS );
  81. NES_NTSC_RGB_OUT( 1, dst[1], BITS );
  82.  
  83.  
  84. NES_NTSC_COLOR_IN( 1, lut.black );
  85. NES_NTSC_RGB_OUT( 2, dst[2], BITS );
  86. NES_NTSC_RGB_OUT( 3, dst[3], BITS );
  87.  
  88.  
  89. NES_NTSC_COLOR_IN( 2, lut.black );
  90. NES_NTSC_RGB_OUT( 4, dst[4], BITS );
  91. NES_NTSC_RGB_OUT( 5, dst[5], BITS );
  92. NES_NTSC_RGB_OUT( 6, dst[6], BITS );
  93.  
  94. }
  95.  
  96.  
  97. NES_NTSC_COLOR_IN( 0, bgcolor );
  98. NES_NTSC_RGB_OUT( 0, dst[0], BITS );
  99. NES_NTSC_RGB_OUT( 1, dst[1], BITS );
  100.  
  101. NES_NTSC_COLOR_IN( 1, bgcolor );
  102. NES_NTSC_RGB_OUT( 2, dst[2], BITS );
  103. NES_NTSC_RGB_OUT( 3, dst[3], BITS );
  104.  
  105. ! NES_NTSC_COLOR_IN( 2, bgcolor );
  106. NES_NTSC_RGB_OUT( 4, dst[4], BITS );
  107. NES_NTSC_RGB_OUT( 5, dst[5], BITS );
  108. NES_NTSC_RGB_OUT( 6, dst[6], BITS );
  109.  
  110. dst = reinterpret_cast<Pixel*>(reinterpret_cast<byte*>(dst) + pad);
  111.  
  112. phase = (phase + 1) % 3;
  113. }
  114. }
  115.  
  116. #ifdef NST_MSVC_OPTIMIZE
  117. #pragma optimize("s", on)
  118. #endif
  119.  
  120. bool Renderer::FilterNtsc::Check(const RenderState& state)
  121. {
  122. return (state.width == NTSC_WIDTH && state.height == HEIGHT*2) &&
  123. (
  124. (state.bits.count == 16 && state.bits.mask.b == 0x001F && ((state.bits.mask.g == 0x07E0 && state.bits.mask.r == 0xF800) || (state.bits.mask.g == 0x03E0 && state.bits.mask.r == 0x7C00))) ||
  125. (state.bits.count == 32 && state.bits.mask.r == 0xFF0000 && state.bits.mask.g == 0x00FF00 && state.bits.mask.b == 0x0000FF)
  126. );
  127. }
  128.  
  129. Renderer::FilterNtsc::Path Renderer::FilterNtsc::GetPath(const RenderState& state,const Lut& lut)
  130. {
  131. if (state.bits.count == 32)
  132. {
  133. return &FilterNtsc::BlitType<dword,32>;
  134. }
  135. else if (state.bits.mask.g == 0x07E0)
  136. {
  137. return &FilterNtsc::BlitType<word,16>;
  138. }
  139. else
  140. {
  141. return &FilterNtsc::BlitType<word,15>;
  142. }
  143. }
  144.  
  145. inline uint Renderer::FilterNtsc::Lut::GetBlack(const byte (&p)[PALETTE][3])
  146. {
  147. uint index = DEF_BLACK;
  148.  
  149. for (uint i=0, intensity = 0xFF * 100; i < 64; ++i)
  150. {
  151. const uint v = p[i][0] * 30 + p[i][1] * 59 + p[i][2] * 11;
  152.  
  153. if (intensity > v)
  154. {
  155. intensity = v;
  156. index = i;
  157. }
  158. }
  159.  
  160. return index;
  161. }
  162.  
  163. Renderer::FilterNtsc::Lut::Lut
  164. (
  165. const byte (&palette)[PALETTE][3],
  166. const schar sharpness,
  167. const schar resolution,
  168. const schar bleed,
  169. const schar artifacts,
  170. const schar fringing,
  171. const bool fieldMerging
  172. )
  173. :
  174. noFieldMerging (fieldMerging ? 0U : ~0U),
  175. black (GetBlack(palette))
  176. {
  177. FpuPrecision precision;
  178.  
  179. nes_ntsc_setup_t setup;
  180.  
  181. setup.hue = 0;
  182. setup.saturation = 0;
  183. setup.contrast = 0;
  184. setup.brightness = 0;
  185. setup.sharpness = sharpness / 100.0;
  186. setup.gamma = 0;
  187. setup.resolution = resolution / 100.0;
  188. setup.artifacts = artifacts / 100.0;
  189. setup.fringing = fringing / 100.0;
  190. setup.bleed = bleed / 100.0;
  191. setup.merge_fields = fieldMerging;
  192. setup.decoder_matrix = NULL;
  193. setup.palette_out = NULL;
  194. setup.palette = *palette;
  195. setup.base_palette = NULL;
  196.  
  197. ::nes_ntsc_init( this, &setup );
  198. }
  199.  
  200. Renderer::FilterNtsc::FilterNtsc
  201. (
  202. const RenderState& state,
  203. const byte (&palette)[PALETTE][3],
  204. schar sharpness,
  205. schar resolution,
  206. schar bleed,
  207. schar artifacts,
  208. schar fringing,
  209. bool fieldMerging
  210. )
  211. :
  212. Filter (state),
  213. path (GetPath(state,lut)),
  214. lut (palette,sharpness,resolution,bleed,artifacts,fringing,fieldMerging)
  215. {
  216. }
  217.  
  218. #ifdef NST_MSVC_OPTIMIZE
  219. #pragma optimize("", on)
  220. #endif
  221. }
  222. }
  223. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement