Advertisement
Guest User

Untitled

a guest
Aug 19th, 2017
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 161.69 KB | None | 0 0
  1. //============================================================
  2. //
  3. // drawd3d.c - Win32 Direct3D implementation
  4. //
  5. //============================================================
  6. //
  7. // Copyright Aaron Giles
  8. // All rights reserved.
  9. //
  10. // Redistribution and use in source and binary forms, with or
  11. // without modification, are permitted provided that the
  12. // following conditions are met:
  13. //
  14. // * Redistributions of source code must retain the above
  15. // copyright notice, this list of conditions and the
  16. // following disclaimer.
  17. // * Redistributions in binary form must reproduce the
  18. // above copyright notice, this list of conditions and
  19. // the following disclaimer in the documentation and/or
  20. // other materials provided with the distribution.
  21. // * Neither the name 'MAME' nor the names of its
  22. // contributors may be used to endorse or promote
  23. // products derived from this software without specific
  24. // prior written permission.
  25. //
  26. // THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND
  27. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  29. // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
  30. // EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
  31. // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32. // DAMAGE (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  33. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  34. // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35. // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  37. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  38. // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39. //
  40. //============================================================
  41.  
  42. // Useful info:
  43. // Windows XP/2003 shipped with DirectX 8.1
  44. // Windows 2000 shipped with DirectX 7a
  45. // Windows 98SE shipped with DirectX 6.1a
  46. // Windows 98 shipped with DirectX 5
  47. // Windows NT shipped with DirectX 3.0a
  48. // Windows 95 shipped with DirectX 2
  49.  
  50. // standard windows headers
  51. #define WIN32_LEAN_AND_MEAN
  52. #include <windows.h>
  53. #include <tchar.h>
  54. #include <mmsystem.h>
  55. #include <d3d9.h>
  56. #include <d3dx9.h>
  57. #undef interface
  58.  
  59. // MAME headers
  60. #include "emu.h"
  61. #include "render.h"
  62. #include "ui.h"
  63. #include "rendutil.h"
  64. #include "options.h"
  65. #include "emuopts.h"
  66.  
  67. // MAMEOS headers
  68. #include "d3dintf.h"
  69. #include "winmain.h"
  70. #include "window.h"
  71. #include "config.h"
  72. #include "strconv.h"
  73.  
  74.  
  75.  
  76. //============================================================
  77. // DEBUGGING
  78. //============================================================
  79.  
  80. extern void mtlog_add(const char *event);
  81.  
  82.  
  83.  
  84. //============================================================
  85. // CONSTANTS
  86. //============================================================
  87.  
  88. #define ENABLE_BORDER_PIX (1)
  89.  
  90. #define VERTEX_BASE_FORMAT (D3DFVF_DIFFUSE | D3DFVF_TEX1)
  91. #define VERTEX_BUFFER_SIZE (2048*4+4)
  92.  
  93. enum
  94. {
  95. TEXTURE_TYPE_PLAIN,
  96. TEXTURE_TYPE_DYNAMIC,
  97. TEXTURE_TYPE_SURFACE
  98. };
  99.  
  100.  
  101.  
  102. //============================================================
  103. // MACROS
  104. //============================================================
  105.  
  106. #define FSWAP(var1, var2) do { float temp = var1; var1 = var2; var2 = temp; } while (0)
  107.  
  108.  
  109.  
  110. //============================================================
  111. // TYPE DEFINITIONS
  112. //============================================================
  113.  
  114. /* texture_info holds information about a texture */
  115. typedef struct _texture_info texture_info;
  116. struct _texture_info
  117. {
  118. texture_info * next; // next texture in the list
  119. UINT32 hash; // hash value for the texture
  120. UINT32 flags; // rendering flags
  121. render_texinfo texinfo; // copy of the texture info
  122. float ustart, ustop; // beginning/ending U coordinates
  123. float vstart, vstop; // beginning/ending V coordinates
  124. int rawwidth, rawheight; // raw width/height of the texture
  125. int type; // what type of texture are we?
  126. int xborderpix; // number of border pixels in X
  127. int yborderpix; // number of border pixels in Y
  128. int xprescale; // what is our X prescale factor?
  129. int yprescale; // what is our Y prescale factor?
  130. int cur_frame; // what is our current frame?
  131. d3d_texture * d3dtex; // Direct3D texture pointer
  132. d3d_surface * d3dsurface; // Direct3D offscreen plain surface pointer
  133. d3d_surface * d3dtarget0; // Direct3D render target surface pointer (pass 0, if necessary)
  134. d3d_surface * d3dtarget1; // Direct3D render target surface pointer (pass 1, if necessary)
  135. d3d_surface * d3dtarget2; // Direct3D render target surface pointer (pass 2, if necessary)
  136. d3d_surface * d3dtarget3; // Direct3D render target surface pointer (pass 3, if necessary)
  137. d3d_surface * d3dtarget4; // Direct3D render target surface pointer (pass 4, if necessary)
  138. d3d_surface * d3dsmalltarget0; // Direct3D render target surface pointer (small pass 0, if necessary)
  139. d3d_texture * d3dtexture0; // Direct3D render target texture pointer (pass 0, if necessary)
  140. d3d_texture * d3dtexture1; // Direct3D render target texture pointer (pass 1, if necessary)
  141. d3d_texture * d3dtexture2; // Direct3D render target texture pointer (pass 2, if necessary)
  142. d3d_texture * d3dtexture3; // Direct3D render target texture pointer (pass 3, if necessary)
  143. d3d_texture * d3dtexture4; // Direct3D render target texture pointer (pass 4, if necessary)
  144. d3d_texture * d3dsmalltexture0; // Direct3D render target texture pointer (small pass 0, if necessary)
  145. d3d_texture * d3dfinaltex; // Direct3D final (post-scaled) texture
  146. };
  147.  
  148.  
  149. /* poly_info holds information about a single polygon/d3d primitive */
  150. typedef struct _poly_info poly_info;
  151. struct _poly_info
  152. {
  153. D3DPRIMITIVETYPE type; // type of primitive
  154. UINT32 count; // total number of primitives
  155. UINT32 numverts; // total number of vertices
  156. UINT32 flags; // rendering flags
  157. DWORD modmode; // texture modulation mode
  158. texture_info * texture; // pointer to texture info
  159. };
  160.  
  161.  
  162. /* d3d_vertex describes a single vertex */
  163. typedef struct _d3d_vertex d3d_vertex;
  164. struct _d3d_vertex
  165. {
  166. float x, y, z; // X,Y,Z coordinates
  167. float rhw; // RHW when no HLSL, padding when HLSL
  168. D3DCOLOR color; // diffuse color
  169. float u0, v0; // texture stage 0 coordinates
  170. };
  171.  
  172.  
  173. /* d3d_options is the information about runtime-mutable Direct3D options */
  174. typedef struct _d3d_options d3d_options;
  175. struct _d3d_options
  176. {
  177. float screen_shadow_mask_alpha;
  178. int screen_shadow_mask_count_x;
  179. int screen_shadow_mask_count_y;
  180. float screen_shadow_mask_u_size;
  181. float screen_shadow_mask_v_size;
  182. float screen_curvature;
  183. float screen_pincushion;
  184. float screen_scanline_alpha;
  185. float screen_scanline_scale;
  186. float screen_scanline_bright_scale;
  187. float screen_scanline_bright_offset;
  188. float screen_scanline_offset;
  189. float screen_defocus_x;
  190. float screen_defocus_y;
  191. float screen_red_converge_x;
  192. float screen_red_converge_y;
  193. float screen_green_converge_x;
  194. float screen_green_converge_y;
  195. float screen_blue_converge_x;
  196. float screen_blue_converge_y;
  197. float screen_red_radial_converge_x;
  198. float screen_red_radial_converge_y;
  199. float screen_green_radial_converge_x;
  200. float screen_green_radial_converge_y;
  201. float screen_blue_radial_converge_x;
  202. float screen_blue_radial_converge_y;
  203. float screen_red_from_red;
  204. float screen_red_from_green;
  205. float screen_red_from_blue;
  206. float screen_green_from_red;
  207. float screen_green_from_green;
  208. float screen_green_from_blue;
  209. float screen_blue_from_red;
  210. float screen_blue_from_green;
  211. float screen_blue_from_blue;
  212. float screen_red_offset;
  213. float screen_green_offset;
  214. float screen_blue_offset;
  215. float screen_red_scale;
  216. float screen_green_scale;
  217. float screen_blue_scale;
  218. float screen_red_power;
  219. float screen_green_power;
  220. float screen_blue_power;
  221. float screen_red_floor;
  222. float screen_green_floor;
  223. float screen_blue_floor;
  224. float screen_red_phosphor_life;
  225. float screen_green_phosphor_life;
  226. float screen_blue_phosphor_life;
  227. float screen_saturation;
  228. };
  229.  
  230. /* d3d_info is the information about Direct3D for the current screen */
  231. typedef struct _d3d_info d3d_info;
  232. struct _d3d_info
  233. {
  234. int adapter; // ordinal adapter number
  235. int width, height; // current width, height
  236. int refresh; // current refresh rate
  237. int create_error_count; // number of consecutive create errors
  238.  
  239. win_window_info * window; // current window info
  240.  
  241. d3d_device * device; // pointer to the Direct3DDevice object
  242. int gamma_supported; // is full screen gamma supported?
  243. d3d_present_parameters presentation; // set of presentation parameters
  244. D3DDISPLAYMODE origmode; // original display mode for the adapter
  245. D3DFORMAT pixformat; // pixel format we are using
  246.  
  247. d3d_vertex_buffer * vertexbuf; // pointer to the vertex buffer object
  248. d3d_vertex * lockedbuf; // pointer to the locked vertex buffer
  249. int numverts; // number of accumulated vertices
  250.  
  251. d3d_effect * effect; // pointer to the current effect object
  252. d3d_effect * post_effect; // pointer to the current post-effect object
  253. d3d_effect * pincushion_effect; // pointer to the current pincushion-effect object
  254. d3d_effect * focus_effect; // pointer to the current focus-effect object
  255. d3d_effect * phosphor_effect; // pointer to the current phosphor-effect object
  256. d3d_effect * deconverge_effect; // pointer to the current deconvergence-effect object
  257. d3d_effect * color_effect; // pointer to the current color-effect object
  258. d3d_effect * yiq_encode_effect; // pointer to the current YIQ encoder effect object
  259. d3d_effect * yiq_decode_effect; // pointer to the current YIQ decoder effect object
  260. d3d_vertex * fsfx_vertices; // pointer to our full-screen-quad object
  261.  
  262. poly_info poly[VERTEX_BUFFER_SIZE / 3];// array to hold polygons as they are created
  263. int numpolys; // number of accumulated polygons
  264.  
  265. texture_info * texlist; // list of active textures
  266. int dynamic_supported; // are dynamic textures supported?
  267. int stretch_supported; // is StretchRect with point filtering supported?
  268. int mod2x_supported; // is D3DTOP_MODULATE2X supported?
  269. int mod4x_supported; // is D3DTOP_MODULATE4X supported?
  270. D3DFORMAT screen_format; // format to use for screen textures
  271. D3DFORMAT yuv_format; // format to use for YUV textures
  272.  
  273. DWORD texture_caps; // textureCaps field
  274. DWORD texture_max_aspect; // texture maximum aspect ratio
  275. DWORD texture_max_width; // texture maximum width
  276. DWORD texture_max_height; // texture maximum height
  277.  
  278. texture_info * last_texture; // previous texture
  279. UINT32 last_texture_flags; // previous texture flags
  280. int last_blendenable; // previous blendmode
  281. int last_blendop; // previous blendmode
  282. int last_blendsrc; // previous blendmode
  283. int last_blenddst; // previous blendmode
  284. int last_filter; // previous texture filter
  285. int last_wrap; // previous wrap state
  286. DWORD last_modmode; // previous texture modulation
  287.  
  288. bitmap_t * vector_bitmap; // experimental: bitmap for vectors
  289. texture_info * vector_texture; // experimental: texture for vectors
  290.  
  291. bitmap_t * default_bitmap; // experimental: default bitmap
  292. texture_info * default_texture; // experimental: default texture
  293.  
  294. bool hlsl_enable; // experimental: HLSL enable flag
  295. bool yiq_enable; // experimental: HLSL YIQ-convolution flag
  296. d3d_surface * last_d3dtarget[9]; // Direct3D render target surface pointer for each screen's previous frame
  297. d3d_texture * last_d3dtexture[9]; // Direct3D render target texture pointer for each screen's previous frame
  298. float oversample_x; // experimental: render target oversampling factor (width) for shader prettification
  299. float oversample_y; // experimental: render target oversampling factor (height) for shader prettification
  300. bitmap_t * shadow_bitmap; // experimental: shadow mask bitmap for post-processing shader
  301. texture_info * shadow_texture; // experimental: shadow mask texture for post-processing shader
  302. int registered_targets; // Number of registered HLSL targets (i.e., screens)
  303. d3d_options * hlsl_options; // HLSL uniforms
  304. };
  305.  
  306.  
  307. /* line_aa_step is used for drawing antialiased lines */
  308. typedef struct _line_aa_step line_aa_step;
  309. struct _line_aa_step
  310. {
  311. float xoffs, yoffs; // X/Y deltas
  312. float weight; // weight contribution
  313. };
  314.  
  315.  
  316.  
  317. //============================================================
  318. // GLOBALS
  319. //============================================================
  320.  
  321. static d3d * d3dintf;
  322.  
  323. static const line_aa_step line_aa_1step[] =
  324. {
  325. { 0.00f, 0.00f, 1.00f },
  326. { 0 }
  327. };
  328.  
  329. static const line_aa_step line_aa_4step[] =
  330. {
  331. { -0.25f, 0.00f, 0.25f },
  332. { 0.25f, 0.00f, 0.25f },
  333. { 0.00f, -0.25f, 0.25f },
  334. { 0.00f, 0.25f, 0.25f },
  335. { 0 }
  336. };
  337.  
  338. /*-------------------------------------------------
  339. slider_alloc - allocate a new slider entry
  340. currently duplicated from ui.c, this could
  341. be done in a more ideal way.
  342. -------------------------------------------------*/
  343.  
  344. static slider_state *slider_alloc(running_machine &machine, const char *title, INT32 minval, INT32 defval, INT32 maxval, INT32 incval, slider_update update, void *arg)
  345. {
  346. int size = sizeof(slider_state) + strlen(title);
  347. slider_state *state = (slider_state *)auto_alloc_array_clear(machine, UINT8, size);
  348.  
  349. state->minval = minval;
  350. state->defval = defval;
  351. state->maxval = maxval;
  352. state->incval = incval;
  353. state->update = update;
  354. state->arg = arg;
  355. strcpy(state->description, title);
  356.  
  357. return state;
  358. }
  359.  
  360.  
  361. //============================================================
  362. // assorted slider accessors
  363. //============================================================
  364.  
  365. static slider_state *slider_list;
  366.  
  367. static INT32 slider_set(float *option, float scale, const char *fmt, astring *string, INT32 newval)
  368. {
  369. if (option != NULL && newval != SLIDER_NOCHANGE) *option = (float)newval * scale;
  370. if (string != NULL) string->printf(fmt, *option);
  371. return floor(*option / scale + 0.5f);
  372. }
  373.  
  374. static INT32 slider_shadow_mask_alpha(running_machine &machine, void *arg, astring *string, INT32 newval)
  375. {
  376. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_shadow_mask_alpha), 0.01f, "%2.2f", string, newval);
  377. }
  378.  
  379. static INT32 slider_shadow_mask_x_count(running_machine &machine, void *arg, astring *string, INT32 newval)
  380. {
  381. d3d_options *options = ((d3d_info*)arg)->hlsl_options;
  382. if (newval != SLIDER_NOCHANGE) options->screen_shadow_mask_count_x = newval;
  383. if (string != NULL) string->printf("%d", options->screen_shadow_mask_count_x);
  384. return options->screen_shadow_mask_count_x;
  385. }
  386.  
  387. static INT32 slider_shadow_mask_y_count(running_machine &machine, void *arg, astring *string, INT32 newval)
  388. {
  389. d3d_options *options = ((d3d_info*)arg)->hlsl_options;
  390. if (newval != SLIDER_NOCHANGE) options->screen_shadow_mask_count_y = newval;
  391. if (string != NULL) string->printf("%d", options->screen_shadow_mask_count_y);
  392. return options->screen_shadow_mask_count_y;
  393. }
  394.  
  395. static INT32 slider_shadow_mask_usize(running_machine &machine, void *arg, astring *string, INT32 newval)
  396. {
  397. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_shadow_mask_u_size), 1.0f / 32.0f, "%2.5f", string, newval);
  398. }
  399.  
  400. static INT32 slider_shadow_mask_vsize(running_machine &machine, void *arg, astring *string, INT32 newval)
  401. {
  402. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_shadow_mask_v_size), 1.0f / 32.0f, "%2.5f", string, newval);
  403. }
  404.  
  405. static INT32 slider_curvature(running_machine &machine, void *arg, astring *string, INT32 newval)
  406. {
  407. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_curvature), 0.01f, "%2.2f", string, newval);
  408. }
  409.  
  410. static INT32 slider_pincushion(running_machine &machine, void *arg, astring *string, INT32 newval)
  411. {
  412. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_pincushion), 0.01f, "%2.2f", string, newval);
  413. }
  414.  
  415. static INT32 slider_scanline_alpha(running_machine &machine, void *arg, astring *string, INT32 newval)
  416. {
  417. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_scanline_alpha), 0.01f, "%2.2f", string, newval);
  418. }
  419.  
  420. static INT32 slider_scanline_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
  421. {
  422. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_scanline_scale), 0.05f, "%2.2f", string, newval);
  423. }
  424.  
  425. static INT32 slider_scanline_bright_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
  426. {
  427. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_scanline_bright_scale), 0.05f, "%2.2f", string, newval);
  428. }
  429.  
  430. static INT32 slider_scanline_bright_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
  431. {
  432. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_scanline_bright_offset), 0.05f, "%2.2f", string, newval);
  433. }
  434.  
  435. static INT32 slider_scanline_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
  436. {
  437. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_scanline_offset), 0.05f, "%2.2f", string, newval);
  438. }
  439.  
  440. static INT32 slider_defocus_x(running_machine &machine, void *arg, astring *string, INT32 newval)
  441. {
  442. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_defocus_x), 0.5f, "%2.1f", string, newval);
  443. }
  444.  
  445. static INT32 slider_defocus_y(running_machine &machine, void *arg, astring *string, INT32 newval)
  446. {
  447. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_defocus_y), 0.5f, "%2.1f", string, newval);
  448. }
  449.  
  450. static INT32 slider_red_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
  451. {
  452. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_converge_x), 0.1f, "%3.1f", string, newval);
  453. }
  454.  
  455. static INT32 slider_red_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
  456. {
  457. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_converge_y), 0.1f, "%3.1f", string, newval);
  458. }
  459.  
  460. static INT32 slider_green_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
  461. {
  462. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_converge_x), 0.1f, "%3.1f", string, newval);
  463. }
  464.  
  465. static INT32 slider_green_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
  466. {
  467. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_converge_y), 0.1f, "%3.1f", string, newval);
  468. }
  469.  
  470. static INT32 slider_blue_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
  471. {
  472. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_converge_x), 0.1f, "%3.1f", string, newval);
  473. }
  474.  
  475. static INT32 slider_blue_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
  476. {
  477. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_converge_y), 0.1f, "%3.1f", string, newval);
  478. }
  479.  
  480. static INT32 slider_red_radial_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
  481. {
  482. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_radial_converge_x), 0.1f, "%3.1f", string, newval);
  483. }
  484.  
  485. static INT32 slider_red_radial_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
  486. {
  487. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_radial_converge_y), 0.1f, "%3.1f", string, newval);
  488. }
  489.  
  490. static INT32 slider_green_radial_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
  491. {
  492. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_radial_converge_x), 0.1f, "%3.1f", string, newval);
  493. }
  494.  
  495. static INT32 slider_green_radial_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
  496. {
  497. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_radial_converge_y), 0.1f, "%3.1f", string, newval);
  498. }
  499.  
  500. static INT32 slider_blue_radial_converge_x(running_machine &machine, void *arg, astring *string, INT32 newval)
  501. {
  502. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_radial_converge_x), 0.1f, "%3.1f", string, newval);
  503. }
  504.  
  505. static INT32 slider_blue_radial_converge_y(running_machine &machine, void *arg, astring *string, INT32 newval)
  506. {
  507. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_radial_converge_y), 0.1f, "%3.1f", string, newval);
  508. }
  509.  
  510. static INT32 slider_red_from_r(running_machine &machine, void *arg, astring *string, INT32 newval)
  511. {
  512. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_from_red), 0.005f, "%2.3f", string, newval);
  513. }
  514.  
  515. static INT32 slider_red_from_g(running_machine &machine, void *arg, astring *string, INT32 newval)
  516. {
  517. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_from_green), 0.005f, "%2.3f", string, newval);
  518. }
  519.  
  520. static INT32 slider_red_from_b(running_machine &machine, void *arg, astring *string, INT32 newval)
  521. {
  522. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_from_blue), 0.005f, "%2.3f", string, newval);
  523. }
  524.  
  525. static INT32 slider_green_from_r(running_machine &machine, void *arg, astring *string, INT32 newval)
  526. {
  527. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_from_red), 0.005f, "%2.3f", string, newval);
  528. }
  529.  
  530. static INT32 slider_green_from_g(running_machine &machine, void *arg, astring *string, INT32 newval)
  531. {
  532. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_from_green), 0.005f, "%2.3f", string, newval);
  533. }
  534.  
  535. static INT32 slider_green_from_b(running_machine &machine, void *arg, astring *string, INT32 newval)
  536. {
  537. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_from_blue), 0.005f, "%2.3f", string, newval);
  538. }
  539.  
  540. static INT32 slider_blue_from_r(running_machine &machine, void *arg, astring *string, INT32 newval)
  541. {
  542. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_from_red), 0.005f, "%2.3f", string, newval);
  543. }
  544.  
  545. static INT32 slider_blue_from_g(running_machine &machine, void *arg, astring *string, INT32 newval)
  546. {
  547. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_from_green), 0.005f, "%2.3f", string, newval);
  548. }
  549.  
  550. static INT32 slider_blue_from_b(running_machine &machine, void *arg, astring *string, INT32 newval)
  551. {
  552. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_from_blue), 0.005f, "%2.3f", string, newval);
  553. }
  554.  
  555. static INT32 slider_red_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
  556. {
  557. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_offset), 0.01f, "%2.2f", string, newval);
  558. }
  559.  
  560. static INT32 slider_green_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
  561. {
  562. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_offset), 0.01f, "%2.2f", string, newval);
  563. }
  564.  
  565. static INT32 slider_blue_offset(running_machine &machine, void *arg, astring *string, INT32 newval)
  566. {
  567. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_offset), 0.01f, "%2.2f", string, newval);
  568. }
  569.  
  570. static INT32 slider_red_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
  571. {
  572. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_scale), 0.01f, "%2.2f", string, newval);
  573. }
  574.  
  575. static INT32 slider_green_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
  576. {
  577. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_scale), 0.01f, "%2.2f", string, newval);
  578. }
  579.  
  580. static INT32 slider_blue_scale(running_machine &machine, void *arg, astring *string, INT32 newval)
  581. {
  582. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_scale), 0.01f, "%2.2f", string, newval);
  583. }
  584.  
  585. static INT32 slider_red_power(running_machine &machine, void *arg, astring *string, INT32 newval)
  586. {
  587. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_power), 0.05f, "%2.2f", string, newval);
  588. }
  589.  
  590. static INT32 slider_green_power(running_machine &machine, void *arg, astring *string, INT32 newval)
  591. {
  592. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_power), 0.05f, "%2.2f", string, newval);
  593. }
  594.  
  595. static INT32 slider_blue_power(running_machine &machine, void *arg, astring *string, INT32 newval)
  596. {
  597. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_power), 0.05f, "%2.2f", string, newval);
  598. }
  599.  
  600. static INT32 slider_red_floor(running_machine &machine, void *arg, astring *string, INT32 newval)
  601. {
  602. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_floor), 0.01f, "%2.2f", string, newval);
  603. }
  604.  
  605. static INT32 slider_green_floor(running_machine &machine, void *arg, astring *string, INT32 newval)
  606. {
  607. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_floor), 0.01f, "%2.2f", string, newval);
  608. }
  609.  
  610. static INT32 slider_blue_floor(running_machine &machine, void *arg, astring *string, INT32 newval)
  611. {
  612. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_floor), 0.01f, "%2.2f", string, newval);
  613. }
  614.  
  615. static INT32 slider_red_phosphor_life(running_machine &machine, void *arg, astring *string, INT32 newval)
  616. {
  617. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_red_phosphor_life), 0.01f, "%2.2f", string, newval);
  618. }
  619.  
  620. static INT32 slider_green_phosphor_life(running_machine &machine, void *arg, astring *string, INT32 newval)
  621. {
  622. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_green_phosphor_life), 0.01f, "%2.2f", string, newval);
  623. }
  624.  
  625. static INT32 slider_blue_phosphor_life(running_machine &machine, void *arg, astring *string, INT32 newval)
  626. {
  627. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_blue_phosphor_life), 0.01f, "%2.2f", string, newval);
  628. }
  629.  
  630. static INT32 slider_saturation(running_machine &machine, void *arg, astring *string, INT32 newval)
  631. {
  632. return slider_set(&(((d3d_info*)arg)->hlsl_options->screen_saturation), 0.01f, "%2.2f", string, newval);
  633. }
  634.  
  635. //============================================================
  636. // init_slider_list
  637. //============================================================
  638.  
  639. static slider_state *init_slider_list(d3d_info *d3d)
  640. {
  641. slider_state *listhead = NULL;
  642. slider_state **tailptr = &listhead;
  643. astring string;
  644.  
  645. if(!d3d->hlsl_enable || !d3dintf->post_fx_available)
  646. {
  647. slider_list = NULL;
  648. return NULL;
  649. }
  650.  
  651. *tailptr = slider_alloc(d3d->window->machine(), "Shadow Mask Darkness", 0, 0, 100, 1, slider_shadow_mask_alpha, (void*)d3d); tailptr = &(*tailptr)->next;
  652. *tailptr = slider_alloc(d3d->window->machine(), "Shadow Mask X Count", 1, 640, 1024, 1, slider_shadow_mask_x_count, (void*)d3d); tailptr = &(*tailptr)->next;
  653. *tailptr = slider_alloc(d3d->window->machine(), "Shadow Mask Y Count", 1, 480, 1024, 1, slider_shadow_mask_y_count, (void*)d3d); tailptr = &(*tailptr)->next;
  654. *tailptr = slider_alloc(d3d->window->machine(), "Shadow Mask Pixel Count X", 1, 3, 32, 1, slider_shadow_mask_usize, (void*)d3d); tailptr = &(*tailptr)->next;
  655. *tailptr = slider_alloc(d3d->window->machine(), "Shadow Mask Pixel Count Y", 1, 3, 32, 1, slider_shadow_mask_vsize, (void*)d3d); tailptr = &(*tailptr)->next;
  656. *tailptr = slider_alloc(d3d->window->machine(), "Screen Curvature", 0, 0, 100, 1, slider_curvature, (void*)d3d); tailptr = &(*tailptr)->next;
  657. *tailptr = slider_alloc(d3d->window->machine(), "Image Pincushion", 0, 0, 100, 1, slider_pincushion, (void*)d3d); tailptr = &(*tailptr)->next;
  658. *tailptr = slider_alloc(d3d->window->machine(), "Scanline Darkness", 0, 0, 100, 1, slider_scanline_alpha, (void*)d3d); tailptr = &(*tailptr)->next;
  659. *tailptr = slider_alloc(d3d->window->machine(), "Scanline Size", 1, 20, 80, 1, slider_scanline_scale, (void*)d3d); tailptr = &(*tailptr)->next;
  660. *tailptr = slider_alloc(d3d->window->machine(), "Scanline Brightness", 0, 20, 40, 1, slider_scanline_bright_scale, (void*)d3d); tailptr = &(*tailptr)->next;
  661. *tailptr = slider_alloc(d3d->window->machine(), "Scanline Brightness Overdrive", 0, 12, 20, 1, slider_scanline_bright_offset, (void*)d3d); tailptr = &(*tailptr)->next;
  662. *tailptr = slider_alloc(d3d->window->machine(), "Scanline Jitter", 0, 0, 40, 1, slider_scanline_offset, (void*)d3d); tailptr = &(*tailptr)->next;
  663. *tailptr = slider_alloc(d3d->window->machine(), "Defocus X", 0, 0, 64, 1, slider_defocus_x, (void*)d3d); tailptr = &(*tailptr)->next;
  664. *tailptr = slider_alloc(d3d->window->machine(), "Defocus Y", 0, 0, 64, 1, slider_defocus_y, (void*)d3d); tailptr = &(*tailptr)->next;
  665. *tailptr = slider_alloc(d3d->window->machine(), "Red Position Offset X", -1500, 0, 1500, 1, slider_red_converge_x, (void*)d3d); tailptr = &(*tailptr)->next;
  666. *tailptr = slider_alloc(d3d->window->machine(), "Red Position Offset Y", -1500, 0, 1500, 1, slider_red_converge_y, (void*)d3d); tailptr = &(*tailptr)->next;
  667. *tailptr = slider_alloc(d3d->window->machine(), "Green Position Offset X", -1500, 0, 1500, 1, slider_green_converge_x, (void*)d3d); tailptr = &(*tailptr)->next;
  668. *tailptr = slider_alloc(d3d->window->machine(), "Green Position Offset Y", -1500, 0, 1500, 1, slider_green_converge_y, (void*)d3d); tailptr = &(*tailptr)->next;
  669. *tailptr = slider_alloc(d3d->window->machine(), "Blue Position Offset X", -1500, 0, 1500, 1, slider_blue_converge_x, (void*)d3d); tailptr = &(*tailptr)->next;
  670. *tailptr = slider_alloc(d3d->window->machine(), "Blue Position Offset Y", -1500, 0, 1500, 1, slider_blue_converge_y, (void*)d3d); tailptr = &(*tailptr)->next;
  671. *tailptr = slider_alloc(d3d->window->machine(), "Red Convergence X", -1500, 0, 1500, 1, slider_red_radial_converge_x, (void*)d3d); tailptr = &(*tailptr)->next;
  672. *tailptr = slider_alloc(d3d->window->machine(), "Red Convergence Y", -1500, 0, 1500, 1, slider_red_radial_converge_y, (void*)d3d); tailptr = &(*tailptr)->next;
  673. *tailptr = slider_alloc(d3d->window->machine(), "Green Convergence X", -1500, 0, 1500, 1, slider_green_radial_converge_x, (void*)d3d); tailptr = &(*tailptr)->next;
  674. *tailptr = slider_alloc(d3d->window->machine(), "Green Convergence Y", -1500, 0, 1500, 1, slider_green_radial_converge_y, (void*)d3d); tailptr = &(*tailptr)->next;
  675. *tailptr = slider_alloc(d3d->window->machine(), "Blue Convergence X", -1500, 0, 1500, 1, slider_blue_radial_converge_x, (void*)d3d); tailptr = &(*tailptr)->next;
  676. *tailptr = slider_alloc(d3d->window->machine(), "Blue Convergence Y", -1500, 0, 1500, 1, slider_blue_radial_converge_y, (void*)d3d); tailptr = &(*tailptr)->next;
  677. *tailptr = slider_alloc(d3d->window->machine(), "Red Output from Red Input", -400, 0, 400, 5, slider_red_from_r, (void*)d3d); tailptr = &(*tailptr)->next;
  678. *tailptr = slider_alloc(d3d->window->machine(), "Red Output from Green Input", -400, 0, 400, 5, slider_red_from_g, (void*)d3d); tailptr = &(*tailptr)->next;
  679. *tailptr = slider_alloc(d3d->window->machine(), "Red Output from Blue Input", -400, 0, 400, 5, slider_red_from_b, (void*)d3d); tailptr = &(*tailptr)->next;
  680. *tailptr = slider_alloc(d3d->window->machine(), "Green Output from Red Input", -400, 0, 400, 5, slider_green_from_r, (void*)d3d); tailptr = &(*tailptr)->next;
  681. *tailptr = slider_alloc(d3d->window->machine(), "Green Output from Green Input", -400, 0, 400, 5, slider_green_from_g, (void*)d3d); tailptr = &(*tailptr)->next;
  682. *tailptr = slider_alloc(d3d->window->machine(), "Green Output from Blue Input", -400, 0, 400, 5, slider_green_from_b, (void*)d3d); tailptr = &(*tailptr)->next;
  683. *tailptr = slider_alloc(d3d->window->machine(), "Blue Output from Red Input", -400, 0, 400, 5, slider_blue_from_r, (void*)d3d); tailptr = &(*tailptr)->next;
  684. *tailptr = slider_alloc(d3d->window->machine(), "Blue Output from Green Input", -400, 0, 400, 5, slider_blue_from_g, (void*)d3d); tailptr = &(*tailptr)->next;
  685. *tailptr = slider_alloc(d3d->window->machine(), "Blue Output from Blue Input", -400, 0, 400, 5, slider_blue_from_b, (void*)d3d); tailptr = &(*tailptr)->next;
  686. *tailptr = slider_alloc(d3d->window->machine(), "Red DC Offset", -100, 0, 100, 1, slider_red_offset, (void*)d3d); tailptr = &(*tailptr)->next;
  687. *tailptr = slider_alloc(d3d->window->machine(), "Green DC Offset", -100, 0, 100, 1, slider_green_offset, (void*)d3d); tailptr = &(*tailptr)->next;
  688. *tailptr = slider_alloc(d3d->window->machine(), "Blue DC Offset", -100, 0, 100, 1, slider_blue_offset, (void*)d3d); tailptr = &(*tailptr)->next;
  689. *tailptr = slider_alloc(d3d->window->machine(), "Red Scale", -200, 100, 200, 1, slider_red_scale, (void*)d3d); tailptr = &(*tailptr)->next;
  690. *tailptr = slider_alloc(d3d->window->machine(), "Green Scale", -200, 100, 200, 1, slider_green_scale, (void*)d3d); tailptr = &(*tailptr)->next;
  691. *tailptr = slider_alloc(d3d->window->machine(), "Blue Scale", -200, 100, 200, 1, slider_blue_scale, (void*)d3d); tailptr = &(*tailptr)->next;
  692. *tailptr = slider_alloc(d3d->window->machine(), "Red Power", -80, 20, 80, 1, slider_red_power, (void*)d3d); tailptr = &(*tailptr)->next;
  693. *tailptr = slider_alloc(d3d->window->machine(), "Green Power", -80, 20, 80, 1, slider_green_power, (void*)d3d); tailptr = &(*tailptr)->next;
  694. *tailptr = slider_alloc(d3d->window->machine(), "Blue Power", -80, 20, 80, 1, slider_blue_power, (void*)d3d); tailptr = &(*tailptr)->next;
  695. *tailptr = slider_alloc(d3d->window->machine(), "Red Floor", 0, 0, 100, 1, slider_red_floor, (void*)d3d); tailptr = &(*tailptr)->next;
  696. *tailptr = slider_alloc(d3d->window->machine(), "Green Floor", 0, 0, 100, 1, slider_green_floor, (void*)d3d); tailptr = &(*tailptr)->next;
  697. *tailptr = slider_alloc(d3d->window->machine(), "Blue Floor", 0, 0, 100, 1, slider_blue_floor, (void*)d3d); tailptr = &(*tailptr)->next;
  698. *tailptr = slider_alloc(d3d->window->machine(), "Red Phosphor Life", 0, 0, 100, 1, slider_red_phosphor_life, (void*)d3d); tailptr = &(*tailptr)->next;
  699. *tailptr = slider_alloc(d3d->window->machine(), "Green Phosphor Life", 0, 0, 100, 1, slider_green_phosphor_life, (void*)d3d); tailptr = &(*tailptr)->next;
  700. *tailptr = slider_alloc(d3d->window->machine(), "Blue Phosphor Life", 0, 0, 100, 1, slider_blue_phosphor_life, (void*)d3d); tailptr = &(*tailptr)->next;
  701. *tailptr = slider_alloc(d3d->window->machine(), "Saturation", 0, 100, 400, 1, slider_saturation, (void*)d3d); tailptr = &(*tailptr)->next;
  702.  
  703. return listhead;
  704. }
  705.  
  706. //============================================================
  707. // get_slider_list
  708. //============================================================
  709.  
  710. void *windows_osd_interface::get_slider_list()
  711. {
  712. return (void*)slider_list;
  713. }
  714.  
  715. //============================================================
  716. // INLINES
  717. //============================================================
  718.  
  719. INLINE BOOL GetClientRectExceptMenu(HWND hWnd, PRECT pRect, BOOL fullscreen)
  720. {
  721. static HMENU last_menu;
  722. static RECT last_rect;
  723. static RECT cached_rect;
  724. HMENU menu = GetMenu(hWnd);
  725. BOOL result = GetClientRect(hWnd, pRect);
  726.  
  727. if (!fullscreen || !menu)
  728. return result;
  729.  
  730. // to avoid flicker use cache if we can use
  731. if (last_menu != menu || memcmp(&last_rect, pRect, sizeof *pRect) != 0)
  732. {
  733. last_menu = menu;
  734. last_rect = *pRect;
  735.  
  736. SetMenu(hWnd, NULL);
  737. result = GetClientRect(hWnd, &cached_rect);
  738. SetMenu(hWnd, menu);
  739. }
  740.  
  741. *pRect = cached_rect;
  742. return result;
  743. }
  744.  
  745.  
  746. INLINE UINT32 ycc_to_rgb(UINT8 y, UINT8 cb, UINT8 cr)
  747. {
  748. /* original equations:
  749.  
  750. C = Y - 16
  751. D = Cb - 128
  752. E = Cr - 128
  753.  
  754. R = clip(( 298 * C + 409 * E + 128) >> 8)
  755. G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8)
  756. B = clip(( 298 * C + 516 * D + 128) >> 8)
  757.  
  758. R = clip(( 298 * (Y - 16) + 409 * (Cr - 128) + 128) >> 8)
  759. G = clip(( 298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8)
  760. B = clip(( 298 * (Y - 16) + 516 * (Cb - 128) + 128) >> 8)
  761.  
  762. R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8)
  763. G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
  764. B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8)
  765.  
  766. R = clip(( 298 * Y - 298 * 16 + 409 * Cr - 409 * 128 + 128) >> 8)
  767. G = clip(( 298 * Y - 298 * 16 - 100 * Cb + 100 * 128 - 208 * Cr + 208 * 128 + 128) >> 8)
  768. B = clip(( 298 * Y - 298 * 16 + 516 * Cb - 516 * 128 + 128) >> 8)
  769. */
  770. int r, g, b, common;
  771.  
  772. common = 298 * y - 298 * 16;
  773. r = (common + 409 * cr - 409 * 128 + 128) >> 8;
  774. g = (common - 100 * cb + 100 * 128 - 208 * cr + 208 * 128 + 128) >> 8;
  775. b = (common + 516 * cb - 516 * 128 + 128) >> 8;
  776.  
  777. if (r < 0) r = 0;
  778. else if (r > 255) r = 255;
  779. if (g < 0) g = 0;
  780. else if (g > 255) g = 255;
  781. if (b < 0) b = 0;
  782. else if (b > 255) b = 255;
  783.  
  784. return MAKE_ARGB(0xff, r, g, b);
  785. }
  786.  
  787.  
  788. INLINE UINT32 texture_compute_hash(const render_texinfo *texture, UINT32 flags)
  789. {
  790. return (FPTR)texture->base ^ (flags & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK));
  791. }
  792.  
  793.  
  794. INLINE void set_texture(d3d_info *d3d, texture_info *texture)
  795. {
  796. HRESULT result;
  797. if (texture != d3d->last_texture)
  798. {
  799. d3d->last_texture = texture;
  800. d3d->last_texture_flags = (texture == NULL ? 0 : texture->flags);
  801. result = (*d3dintf->device.set_texture)(d3d->device, 0, (texture == NULL) ? NULL : texture->d3dfinaltex);
  802. if(d3d->hlsl_enable && d3d->effect != NULL)
  803. {
  804. (*d3dintf->effect.set_texture)(d3d->effect, "Diffuse", (texture == NULL) ? NULL : texture->d3dfinaltex);
  805. if(d3d->yiq_enable)
  806. {
  807. (*d3dintf->effect.set_texture)(d3d->yiq_encode_effect, "Diffuse", (texture == NULL) ? NULL : texture->d3dfinaltex);
  808. }
  809. else
  810. {
  811. (*d3dintf->effect.set_texture)(d3d->color_effect, "Diffuse", (texture == NULL) ? NULL : texture->d3dfinaltex);
  812. }
  813. (*d3dintf->effect.set_texture)(d3d->pincushion_effect, "Diffuse", (texture == NULL) ? NULL : texture->d3dfinaltex);
  814. }
  815. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture call\n", (int)result);
  816. }
  817. }
  818.  
  819.  
  820. INLINE void set_filter(d3d_info *d3d, int filter)
  821. {
  822. HRESULT result;
  823. if (filter != d3d->last_filter)
  824. {
  825. d3d->last_filter = filter;
  826. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
  827. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
  828. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
  829. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
  830. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
  831. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
  832. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
  833. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
  834. }
  835. }
  836.  
  837.  
  838. INLINE void set_wrap(d3d_info *d3d, int wrap)
  839. {
  840. HRESULT result;
  841. if (wrap != d3d->last_wrap)
  842. {
  843. d3d->last_wrap = wrap;
  844. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSU, wrap ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
  845. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
  846. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 0, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSV, wrap ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
  847. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
  848. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSU, wrap ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
  849. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
  850. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 1, (D3DTEXTURESTAGESTATETYPE)D3DTSS_ADDRESSV, wrap ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP);
  851. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
  852. }
  853. }
  854.  
  855.  
  856. INLINE void set_modmode(d3d_info *d3d, DWORD modmode)
  857. {
  858. HRESULT result;
  859. if (modmode != d3d->last_modmode)
  860. {
  861. d3d->last_modmode = modmode;
  862. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 0, D3DTSS_COLOROP, modmode);
  863. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
  864. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 1, D3DTSS_COLOROP, modmode);
  865. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture_stage_state call\n", (int)result);
  866. }
  867. }
  868.  
  869.  
  870. INLINE void set_blendmode(d3d_info *d3d, int blendmode)
  871. {
  872. HRESULT result;
  873. int blendenable;
  874. int blendop;
  875. int blendsrc;
  876. int blenddst;
  877.  
  878. // choose the parameters
  879. switch (blendmode)
  880. {
  881. default:
  882. case BLENDMODE_NONE: blendenable = FALSE; blendop = D3DBLENDOP_ADD; blendsrc = D3DBLEND_SRCALPHA; blenddst = D3DBLEND_INVSRCALPHA; break;
  883. case BLENDMODE_ALPHA: blendenable = TRUE; blendop = D3DBLENDOP_ADD; blendsrc = D3DBLEND_SRCALPHA; blenddst = D3DBLEND_INVSRCALPHA; break;
  884. case BLENDMODE_RGB_MULTIPLY: blendenable = TRUE; blendop = D3DBLENDOP_ADD; blendsrc = D3DBLEND_DESTCOLOR; blenddst = D3DBLEND_ZERO; break;
  885. case BLENDMODE_ADD: blendenable = TRUE; blendop = D3DBLENDOP_ADD; blendsrc = D3DBLEND_SRCALPHA; blenddst = D3DBLEND_ONE; break;
  886. }
  887.  
  888. // adjust the bits that changed
  889. if (blendenable != d3d->last_blendenable)
  890. {
  891. d3d->last_blendenable = blendenable;
  892. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_ALPHABLENDENABLE, blendenable);
  893. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
  894. }
  895.  
  896. if (blendop != d3d->last_blendop)
  897. {
  898. d3d->last_blendop = blendop;
  899. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_BLENDOP, blendop);
  900. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
  901. }
  902.  
  903. if (blendsrc != d3d->last_blendsrc)
  904. {
  905. d3d->last_blendsrc = blendsrc;
  906. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_SRCBLEND, blendsrc);
  907. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
  908. }
  909.  
  910. if (blenddst != d3d->last_blenddst)
  911. {
  912. d3d->last_blenddst = blenddst;
  913. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_DESTBLEND, blenddst);
  914. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_state call\n", (int)result);
  915. }
  916. }
  917.  
  918.  
  919. INLINE void reset_render_states(d3d_info *d3d)
  920. {
  921. // this ensures subsequent calls to the above setters will force-update the data
  922. d3d->last_texture = (texture_info *)~0;
  923. d3d->last_filter = -1;
  924. d3d->last_blendenable = -1;
  925. d3d->last_blendop = -1;
  926. d3d->last_blendsrc = -1;
  927. d3d->last_blenddst = -1;
  928. d3d->last_wrap = -1;
  929. }
  930.  
  931.  
  932.  
  933. //============================================================
  934. // PROTOTYPES
  935. //============================================================
  936.  
  937. // core functions
  938. static void drawd3d_exit(void);
  939. static int drawd3d_window_init(win_window_info *window);
  940. static void drawd3d_window_destroy(win_window_info *window);
  941. static render_primitive_list *drawd3d_window_get_primitives(win_window_info *window);
  942. static int drawd3d_window_draw(win_window_info *window, HDC dc, int update);
  943.  
  944. // devices
  945. static int device_create(win_window_info *window);
  946. static int device_create_resources(d3d_info *d3d);
  947. static void device_delete(d3d_info *d3d);
  948. static void device_delete_resources(d3d_info *d3d);
  949. static int device_verify_caps(d3d_info *d3d, win_window_info *window);
  950. static int device_test_cooperative(d3d_info *d3d);
  951.  
  952. // video modes
  953. static int config_adapter_mode(win_window_info *window);
  954. static int get_adapter_for_monitor(d3d_info *d3d, win_monitor_info *monitor);
  955. static void pick_best_mode(win_window_info *window);
  956. static int update_window_size(win_window_info *window);
  957.  
  958. // drawing
  959. static void draw_line(d3d_info *d3d, const render_primitive *prim);
  960. static void draw_quad(d3d_info *d3d, const render_primitive *prim);
  961. static void init_fsfx_quad(d3d_info *d3d);
  962.  
  963. // primitives
  964. static d3d_vertex *primitive_alloc(d3d_info *d3d, int numverts);
  965. static void primitive_flush_pending(d3d_info *d3d);
  966.  
  967. // textures
  968. static texture_info *texture_create(d3d_info *d3d, const render_texinfo *texsource, UINT32 flags);
  969. static void texture_compute_size(d3d_info *d3d, int texwidth, int texheight, texture_info *texture);
  970. static void texture_set_data(d3d_info *d3d, texture_info *texture, const render_texinfo *texsource, UINT32 flags);
  971. static void texture_prescale(d3d_info *d3d, texture_info *texture);
  972. static texture_info *texture_find(d3d_info *d3d, const render_primitive *prim);
  973. static void texture_update(d3d_info *d3d, const render_primitive *prim);
  974.  
  975.  
  976.  
  977. //============================================================
  978. // drawd3d_init
  979. //============================================================
  980.  
  981. int drawd3d_init(running_machine &machine, win_draw_callbacks *callbacks)
  982. {
  983. int version = downcast<windows_options &>(machine.options()).d3d_version();
  984. d3dintf = NULL;
  985.  
  986. // try Direct3D 9 if requested
  987. if (version >= 9)
  988. d3dintf = drawd3d9_init();
  989.  
  990. #if DIRECT3D_VERSION < 0x0900
  991. // if that didn't work, try Direct3D 8
  992. if (d3dintf == NULL && version >= 8)
  993. d3dintf = drawd3d8_init();
  994. #endif
  995.  
  996. // if we failed, note the error
  997. if (d3dintf == NULL)
  998. {
  999. mame_printf_error("Unable to initialize Direct3D.\n");
  1000. return 1;
  1001. }
  1002.  
  1003. // fill in the callbacks
  1004. callbacks->exit = drawd3d_exit;
  1005. callbacks->window_init = drawd3d_window_init;
  1006. callbacks->window_get_primitives = drawd3d_window_get_primitives;
  1007. callbacks->window_draw = drawd3d_window_draw;
  1008. callbacks->window_destroy = drawd3d_window_destroy;
  1009. return 0;
  1010. }
  1011.  
  1012.  
  1013.  
  1014. //============================================================
  1015. // drawd3d_exit
  1016. //============================================================
  1017.  
  1018. static void drawd3d_exit(void)
  1019. {
  1020. if (d3dintf != NULL)
  1021. (*d3dintf->d3d.release)(d3dintf);
  1022. }
  1023.  
  1024.  
  1025.  
  1026. //============================================================
  1027. // drawd3d_window_init
  1028. //============================================================
  1029.  
  1030. static int drawd3d_window_init(win_window_info *window)
  1031. {
  1032. d3d_info *d3d;
  1033.  
  1034. // allocate memory for our structures
  1035. d3d = global_alloc_clear(d3d_info);
  1036. window->drawdata = d3d;
  1037. d3d->window = window;
  1038.  
  1039. // experimental: load a PNG to use for vector rendering; it is treated
  1040. // as a brightness map
  1041. emu_file file(window->machine().options().art_path(), OPEN_FLAG_READ);
  1042. d3d->vector_bitmap = render_load_png(file, NULL, "vector.png", NULL, NULL);
  1043. if (d3d->vector_bitmap != NULL)
  1044. {
  1045. bitmap_fill(d3d->vector_bitmap, NULL, MAKE_ARGB(0xff,0xff,0xff,0xff));
  1046. d3d->vector_bitmap = render_load_png(file, NULL, "vector.png", d3d->vector_bitmap, NULL);
  1047. }
  1048.  
  1049. d3d->shadow_texture = NULL;
  1050.  
  1051. d3d->default_bitmap = auto_bitmap_alloc(window->machine(), 8, 8, BITMAP_FORMAT_RGB32);
  1052. bitmap_fill(d3d->default_bitmap, NULL, MAKE_ARGB(0xff,0xff,0xff,0xff));
  1053.  
  1054. // configure the adapter for the mode we want
  1055. if (config_adapter_mode(window))
  1056. goto error;
  1057.  
  1058. // create the device immediately for the full screen case (defer for window mode)
  1059. if (window->fullscreen && device_create(window))
  1060. goto error;
  1061.  
  1062. return 0;
  1063.  
  1064. error:
  1065. drawd3d_window_destroy(window);
  1066. mame_printf_error("Unable to initialize Direct3D.\n");
  1067. return 1;
  1068. }
  1069.  
  1070.  
  1071.  
  1072. //============================================================
  1073. // drawd3d_window_destroy
  1074. //============================================================
  1075.  
  1076. static void drawd3d_window_destroy(win_window_info *window)
  1077. {
  1078. d3d_info *d3d = (d3d_info *)window->drawdata;
  1079.  
  1080. // skip if nothing
  1081. if (d3d == NULL)
  1082. return;
  1083.  
  1084. // delete the device
  1085. device_delete(d3d);
  1086.  
  1087. // experimental: free the vector PNG
  1088. global_free(d3d->vector_bitmap);
  1089. d3d->vector_bitmap = NULL;
  1090.  
  1091. // experimental: free the shadow PNG
  1092. if(d3d->hlsl_enable && d3d->shadow_bitmap != NULL)
  1093. {
  1094. global_free(d3d->shadow_bitmap);
  1095. d3d->shadow_bitmap = NULL;
  1096. }
  1097.  
  1098. // free the memory in the window
  1099. global_free(d3d);
  1100. window->drawdata = NULL;
  1101. }
  1102.  
  1103.  
  1104.  
  1105. //============================================================
  1106. // drawd3d_window_get_primitives
  1107. //============================================================
  1108.  
  1109. static render_primitive_list *drawd3d_window_get_primitives(win_window_info *window)
  1110. {
  1111. d3d_info *d3d = (d3d_info *)window->drawdata;
  1112. RECT client;
  1113.  
  1114. GetClientRectExceptMenu(window->hwnd, &client, window->fullscreen);
  1115. if (rect_width(&client) > 0 && rect_height(&client) > 0)
  1116. {
  1117. window->target->set_bounds(rect_width(&client), rect_height(&client), winvideo_monitor_get_aspect(window->monitor));
  1118. window->target->set_max_update_rate((d3d->refresh == 0) ? d3d->origmode.RefreshRate : d3d->refresh);
  1119. }
  1120. return &window->target->get_primitives();
  1121. }
  1122.  
  1123.  
  1124.  
  1125. //============================================================
  1126. // drawd3d_window_draw
  1127. //============================================================
  1128.  
  1129. static int drawd3d_window_draw(win_window_info *window, HDC dc, int update)
  1130. {
  1131. d3d_info *d3d = (d3d_info *)window->drawdata;
  1132. render_primitive *prim;
  1133. HRESULT result;
  1134.  
  1135. // if we're in the middle of resizing, leave things alone
  1136. if (window->resize_state == RESIZE_STATE_RESIZING)
  1137. return 0;
  1138.  
  1139. // if we haven't been created, just punt
  1140. if (d3d == NULL)
  1141. return 1;
  1142.  
  1143. // if we have a device, check the cooperative level
  1144. if (d3d->device != NULL)
  1145. {
  1146. int error = device_test_cooperative(d3d);
  1147. if (error)
  1148. return 1;
  1149. }
  1150.  
  1151. // in window mode, we need to track the window size
  1152. if (!window->fullscreen || d3d->device == NULL)
  1153. {
  1154. // if the size changes, skip this update since the render target will be out of date
  1155. if (update_window_size(window))
  1156. return 0;
  1157.  
  1158. // if we have no device, after updating the size, return an error so GDI can try
  1159. if (d3d->device == NULL)
  1160. return 1;
  1161. }
  1162.  
  1163. mtlog_add("drawd3d_window_draw: begin");
  1164.  
  1165. // first update any textures
  1166. window->primlist->acquire_lock();
  1167. for (prim = window->primlist->first(); prim != NULL; prim = prim->next())
  1168. if (prim->texture.base != NULL)
  1169. texture_update(d3d, prim);
  1170.  
  1171. // begin the scene
  1172. mtlog_add("drawd3d_window_draw: begin_scene");
  1173. result = (*d3dintf->device.begin_scene)(d3d->device);
  1174. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result);
  1175.  
  1176. d3d->lockedbuf = NULL;
  1177.  
  1178. // loop over primitives
  1179. if(d3d->hlsl_enable && d3dintf->post_fx_available)
  1180. {
  1181. init_fsfx_quad(d3d);
  1182. }
  1183.  
  1184. mtlog_add("drawd3d_window_draw: primitive loop begin");
  1185. for (prim = window->primlist->first(); prim != NULL; prim = prim->next())
  1186. switch (prim->type)
  1187. {
  1188. case render_primitive::LINE:
  1189. draw_line(d3d, prim);
  1190. break;
  1191.  
  1192. case render_primitive::QUAD:
  1193. draw_quad(d3d, prim);
  1194. break;
  1195.  
  1196. default:
  1197. throw emu_fatalerror("Unexpected render_primitive type");
  1198. }
  1199. mtlog_add("drawd3d_window_draw: primitive loop end");
  1200. window->primlist->release_lock();
  1201.  
  1202. // flush any pending polygons
  1203. mtlog_add("drawd3d_window_draw: flush_pending begin");
  1204. primitive_flush_pending(d3d);
  1205. mtlog_add("drawd3d_window_draw: flush_pending end");
  1206.  
  1207. // finish the scene
  1208. mtlog_add("drawd3d_window_draw: end_scene begin");
  1209. result = (*d3dintf->device.end_scene)(d3d->device);
  1210. mtlog_add("drawd3d_window_draw: end_scene end");
  1211. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device end_scene call\n", (int)result);
  1212.  
  1213. // present the current buffers
  1214. mtlog_add("drawd3d_window_draw: present begin");
  1215. result = (*d3dintf->device.present)(d3d->device, NULL, NULL, NULL, NULL, 0);
  1216. mtlog_add("drawd3d_window_draw: present end");
  1217. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device present call\n", (int)result);
  1218.  
  1219. return 0;
  1220. }
  1221.  
  1222.  
  1223.  
  1224. //============================================================
  1225. // device_create
  1226. //============================================================
  1227.  
  1228. static int device_create(win_window_info *window)
  1229. {
  1230. d3d_info *d3d = (d3d_info *)window->drawdata;
  1231. HRESULT result;
  1232. int verify;
  1233.  
  1234. // if a device exists, free it
  1235. if (d3d->device != NULL)
  1236. device_delete(d3d);
  1237.  
  1238. // verify the caps
  1239. verify = device_verify_caps(d3d, window);
  1240. if (verify == 2)
  1241. {
  1242. mame_printf_error("Error: Device does not meet minimum requirements for Direct3D rendering\n");
  1243. return 1;
  1244. }
  1245. if (verify == 1)
  1246. mame_printf_warning("Warning: Device may not perform well for Direct3D rendering\n");
  1247.  
  1248. // verify texture formats
  1249. result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, d3d->pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
  1250. if (result != D3D_OK)
  1251. {
  1252. mame_printf_error("Error: A8R8G8B8 format textures not supported\n");
  1253. return 1;
  1254. }
  1255.  
  1256. // pick a YUV texture format
  1257. d3d->yuv_format = D3DFMT_UYVY;
  1258. result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, d3d->pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_UYVY);
  1259. if (result != D3D_OK)
  1260. {
  1261. d3d->yuv_format = D3DFMT_YUY2;
  1262. result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, d3d->pixformat, 0, D3DRTYPE_TEXTURE, D3DFMT_YUY2);
  1263. if (result != D3D_OK)
  1264. d3d->yuv_format = D3DFMT_A8R8G8B8;
  1265. }
  1266. mame_printf_verbose("Direct3D: YUV format = %s\n", (d3d->yuv_format == D3DFMT_YUY2) ? "YUY2" : (d3d->yuv_format == D3DFMT_UYVY) ? "UYVY" : "RGB");
  1267.  
  1268. try_again:
  1269. // try for XRGB first
  1270. d3d->screen_format = D3DFMT_X8R8G8B8;
  1271. result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, d3d->pixformat, d3d->dynamic_supported ? D3DUSAGE_DYNAMIC : 0, D3DRTYPE_TEXTURE, d3d->screen_format);
  1272. if (result != D3D_OK)
  1273. {
  1274. // if not, try for ARGB
  1275. d3d->screen_format = D3DFMT_A8R8G8B8;
  1276. result = (*d3dintf->d3d.check_device_format)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, d3d->pixformat, d3d->dynamic_supported ? D3DUSAGE_DYNAMIC : 0, D3DRTYPE_TEXTURE, d3d->screen_format);
  1277. if (result != D3D_OK && d3d->dynamic_supported)
  1278. {
  1279. d3d->dynamic_supported = FALSE;
  1280. goto try_again;
  1281. }
  1282. if (result != D3D_OK)
  1283. {
  1284. mame_printf_error("Error: unable to configure a screen texture format\n");
  1285. return 1;
  1286. }
  1287. }
  1288.  
  1289. // initialize the D3D presentation parameters
  1290. memset(&d3d->presentation, 0, sizeof(d3d->presentation));
  1291. d3d->presentation.BackBufferWidth = d3d->width;
  1292. d3d->presentation.BackBufferHeight = d3d->height;
  1293. d3d->presentation.BackBufferFormat = d3d->pixformat;
  1294. d3d->presentation.BackBufferCount = video_config.triplebuf ? 2 : 1;
  1295. d3d->presentation.MultiSampleType = D3DMULTISAMPLE_NONE;
  1296. d3d->presentation.SwapEffect = D3DSWAPEFFECT_DISCARD;
  1297. d3d->presentation.hDeviceWindow = window->hwnd;
  1298. d3d->presentation.Windowed = !window->fullscreen || win_has_menu(window);
  1299. d3d->presentation.EnableAutoDepthStencil = FALSE;
  1300. d3d->presentation.AutoDepthStencilFormat = D3DFMT_D16;
  1301. d3d->presentation.Flags = 0;
  1302. d3d->presentation.FullScreen_RefreshRateInHz = d3d->refresh;
  1303. d3d->presentation.PresentationInterval = ((video_config.triplebuf && window->fullscreen) || video_config.waitvsync || video_config.syncrefresh) ?
  1304. D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
  1305.  
  1306. // create the D3D device
  1307. result = (*d3dintf->d3d.create_device)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, win_window_list->hwnd,
  1308. D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_FPU_PRESERVE, &d3d->presentation, &d3d->device);
  1309. if (result != D3D_OK)
  1310. {
  1311. // if we got a "DEVICELOST" error, it may be transitory; count it and only fail if
  1312. // we exceed a threshold
  1313. if (result == D3DERR_DEVICELOST)
  1314. {
  1315. d3d->create_error_count++;
  1316. if (d3d->create_error_count < 10)
  1317. return 0;
  1318. }
  1319.  
  1320. // fatal error if we just can't do it
  1321. mame_printf_error("Unable to create the Direct3D device (%08X)\n", (UINT32)result);
  1322. return 1;
  1323. }
  1324. d3d->create_error_count = 0;
  1325. mame_printf_verbose("Direct3D: Device created at %dx%d\n", d3d->width, d3d->height);
  1326.  
  1327. // set the max texture size
  1328. window->target->set_max_texture_size(d3d->texture_max_width, d3d->texture_max_height);
  1329. mame_printf_verbose("Direct3D: Max texture size = %dx%d\n", (int)d3d->texture_max_width, (int)d3d->texture_max_height);
  1330.  
  1331. // set the gamma if we need to
  1332. if (window->fullscreen)
  1333. {
  1334. // only set the gamma if it's not 1.0f
  1335. windows_options &options = downcast<windows_options &>(window->machine().options());
  1336. float brightness = options.full_screen_brightness();
  1337. float contrast = options.full_screen_contrast();
  1338. float gamma = options.full_screen_gamma();
  1339. if (brightness != 1.0f || contrast != 1.0f || gamma != 1.0f)
  1340. {
  1341. // warn if we can't do it
  1342. if (!d3d->gamma_supported)
  1343. mame_printf_warning("Direct3D: Warning - device does not support full screen gamma correction.\n");
  1344. else
  1345. {
  1346. D3DGAMMARAMP ramp;
  1347. int i;
  1348.  
  1349. // create a standard ramp and set it
  1350. for (i = 0; i < 256; i++)
  1351. ramp.red[i] = ramp.green[i] = ramp.blue[i] = apply_brightness_contrast_gamma(i, brightness, contrast, gamma) << 8;
  1352. (*d3dintf->device.set_gamma_ramp)(d3d->device, 0, &ramp);
  1353. }
  1354. }
  1355. }
  1356.  
  1357. // experimental: initialize some more things if we're using HLSL
  1358. if(d3d->hlsl_enable && d3dintf->post_fx_available)
  1359. {
  1360. const char *fx_dir = downcast<windows_options &>(window->machine().options()).screen_post_fx_dir();
  1361. char primary_name_cstr[1024];
  1362. char post_name_cstr[1024];
  1363. char pincushion_name_cstr[1024];
  1364. char phosphor_name_cstr[1024];
  1365. char focus_name_cstr[1024];
  1366. char deconverge_name_cstr[1024];
  1367. char color_name_cstr[1024];
  1368. char yiq_encode_name_cstr[1024];
  1369. char yiq_decode_name_cstr[1024];
  1370.  
  1371. sprintf(primary_name_cstr, "%s\\primary.fx", fx_dir);
  1372. TCHAR *primary_name = tstring_from_utf8(primary_name_cstr);
  1373.  
  1374. sprintf(post_name_cstr, "%s\\post.fx", fx_dir);
  1375. TCHAR *post_name = tstring_from_utf8(post_name_cstr);
  1376.  
  1377. sprintf(pincushion_name_cstr, "%s\\pincushion.fx", fx_dir);
  1378. TCHAR *pincushion_name = tstring_from_utf8(pincushion_name_cstr);
  1379.  
  1380. sprintf(phosphor_name_cstr, "%s\\phosphor.fx", fx_dir);
  1381. TCHAR *phosphor_name = tstring_from_utf8(phosphor_name_cstr);
  1382.  
  1383. sprintf(focus_name_cstr, "%s\\focus.fx", fx_dir);
  1384. TCHAR *focus_name = tstring_from_utf8(focus_name_cstr);
  1385.  
  1386. sprintf(deconverge_name_cstr, "%s\\deconverge.fx", fx_dir);
  1387. TCHAR *deconverge_name = tstring_from_utf8(deconverge_name_cstr);
  1388.  
  1389. sprintf(color_name_cstr, "%s\\color.fx", fx_dir);
  1390. TCHAR *color_name = tstring_from_utf8(color_name_cstr);
  1391.  
  1392. sprintf(yiq_encode_name_cstr, "%s\\yiq_encode.fx", fx_dir);
  1393. TCHAR *yiq_encode_name = tstring_from_utf8(yiq_encode_name_cstr);
  1394.  
  1395. sprintf(yiq_decode_name_cstr, "%s\\yiq_decode.fx", fx_dir);
  1396. TCHAR *yiq_decode_name = tstring_from_utf8(yiq_decode_name_cstr);
  1397.  
  1398. // create the regular shader
  1399. result = (*d3dintf->device.create_effect)(d3d->device, primary_name, &d3d->effect);
  1400. if(result != D3D_OK)
  1401. {
  1402. mame_printf_verbose("Direct3D: Unable to load primary.fx\n");
  1403. return 1;
  1404. }
  1405.  
  1406. // create the post-processing shader
  1407. result = (*d3dintf->device.create_effect)(d3d->device, post_name, &d3d->post_effect);
  1408. if(result != D3D_OK)
  1409. {
  1410. mame_printf_verbose("Direct3D: Unable to load post.fx\n");
  1411. return 1;
  1412. }
  1413.  
  1414. // create the pincushion shader
  1415. result = (*d3dintf->device.create_effect)(d3d->device, pincushion_name, &d3d->pincushion_effect);
  1416. if(result != D3D_OK)
  1417. {
  1418. mame_printf_verbose("Direct3D: Unable to load pincushion.fx\n");
  1419. return 1;
  1420. }
  1421.  
  1422. // create the phosphor shader
  1423. result = (*d3dintf->device.create_effect)(d3d->device, phosphor_name, &d3d->phosphor_effect);
  1424. if(result != D3D_OK)
  1425. {
  1426. mame_printf_verbose("Direct3D: Unable to load phosphor.fx\n");
  1427. return 1;
  1428. }
  1429.  
  1430. // create the focus shader
  1431. result = (*d3dintf->device.create_effect)(d3d->device, focus_name, &d3d->focus_effect);
  1432. if(result != D3D_OK)
  1433. {
  1434. mame_printf_verbose("Direct3D: Unable to load focus.fx\n");
  1435. return 1;
  1436. }
  1437.  
  1438. // create the deconvergence shader
  1439. result = (*d3dintf->device.create_effect)(d3d->device, deconverge_name, &d3d->deconverge_effect);
  1440. if(result != D3D_OK)
  1441. {
  1442. mame_printf_verbose("Direct3D: Unable to load deconverge.fx\n");
  1443. return 1;
  1444. }
  1445.  
  1446. // create the color convolution shader
  1447. result = (*d3dintf->device.create_effect)(d3d->device, color_name, &d3d->color_effect);
  1448. if(result != D3D_OK)
  1449. {
  1450. mame_printf_verbose("Direct3D: Unable to load color.fx\n");
  1451. return 1;
  1452. }
  1453.  
  1454. // create the YIQ modulation shader
  1455. result = (*d3dintf->device.create_effect)(d3d->device, yiq_encode_name, &d3d->yiq_encode_effect);
  1456. if(result != D3D_OK)
  1457. {
  1458. mame_printf_verbose("Direct3D: Unable to load yiq_encode.fx\n");
  1459. return 1;
  1460. }
  1461.  
  1462. // create the YIQ demodulation shader
  1463. result = (*d3dintf->device.create_effect)(d3d->device, yiq_decode_name, &d3d->yiq_decode_effect);
  1464. if(result != D3D_OK)
  1465. {
  1466. mame_printf_verbose("Direct3D: Unable to load yiq_decode.fx\n");
  1467. return 1;
  1468. }
  1469.  
  1470. if (primary_name)
  1471. osd_free(primary_name);
  1472. if (post_name)
  1473. osd_free(post_name);
  1474. if (pincushion_name)
  1475. osd_free(pincushion_name);
  1476. if (phosphor_name)
  1477. osd_free(phosphor_name);
  1478. if (focus_name)
  1479. osd_free(focus_name);
  1480. if (deconverge_name)
  1481. osd_free(deconverge_name);
  1482. if (color_name)
  1483. osd_free(color_name);
  1484. if (yiq_encode_name)
  1485. osd_free(yiq_encode_name);
  1486. if (yiq_decode_name)
  1487. osd_free(yiq_decode_name);
  1488. }
  1489.  
  1490. return device_create_resources(d3d);
  1491. }
  1492.  
  1493.  
  1494.  
  1495. //============================================================
  1496. // device_create_resources
  1497. //============================================================
  1498.  
  1499. static int device_create_resources(d3d_info *d3d)
  1500. {
  1501. HRESULT result;
  1502.  
  1503. // allocate a vertex buffer to use
  1504. result = (*d3dintf->device.create_vertex_buffer)(d3d->device,
  1505. sizeof(d3d_vertex) * VERTEX_BUFFER_SIZE,
  1506. D3DUSAGE_DYNAMIC | D3DUSAGE_SOFTWAREPROCESSING | D3DUSAGE_WRITEONLY,
  1507. VERTEX_BASE_FORMAT | ((d3d->hlsl_enable && d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW), D3DPOOL_DEFAULT, &d3d->vertexbuf);
  1508. if (result != D3D_OK)
  1509. {
  1510. mame_printf_error("Error creating vertex buffer (%08X)", (UINT32)result);
  1511. return 1;
  1512. }
  1513.  
  1514. // set the vertex format
  1515. result = (*d3dintf->device.set_vertex_format)(d3d->device, (D3DFORMAT)(VERTEX_BASE_FORMAT | ((d3d->hlsl_enable && d3dintf->post_fx_available) ? D3DFVF_XYZW : D3DFVF_XYZRHW)));
  1516. if (result != D3D_OK)
  1517. {
  1518. mame_printf_error("Error setting vertex format (%08X)", (UINT32)result);
  1519. return 1;
  1520. }
  1521.  
  1522. // set the fixed render state
  1523. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_ZENABLE, D3DZB_FALSE);
  1524. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_FILLMODE, D3DFILL_SOLID);
  1525. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_SHADEMODE, D3DSHADE_FLAT);
  1526. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_ZWRITEENABLE, FALSE);
  1527. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_ALPHATESTENABLE, TRUE);
  1528. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_LASTPIXEL, TRUE);
  1529. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_CULLMODE, D3DCULL_NONE);
  1530. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_ZFUNC, D3DCMP_LESS);
  1531. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_ALPHAREF, 0);
  1532. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_ALPHAFUNC, D3DCMP_GREATER);
  1533. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_DITHERENABLE, FALSE);
  1534. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_FOGENABLE, FALSE);
  1535. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_SPECULARENABLE, FALSE);
  1536. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_STENCILENABLE, FALSE);
  1537. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_WRAP0, FALSE);
  1538. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_CLIPPING, TRUE);
  1539. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_LIGHTING, FALSE);
  1540. result = (*d3dintf->device.set_render_state)(d3d->device, D3DRS_COLORVERTEX, TRUE);
  1541.  
  1542. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 0, D3DTSS_COLOROP, D3DTOP_MODULATE);
  1543. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
  1544. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 1, D3DTSS_COLOROP, D3DTOP_MODULATE);
  1545. result = (*d3dintf->device.set_texture_stage_state)(d3d->device, 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
  1546.  
  1547. // reset the local states to force updates
  1548. reset_render_states(d3d);
  1549.  
  1550. // clear the buffer
  1551. result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
  1552. result = (*d3dintf->device.present)(d3d->device, NULL, NULL, NULL, NULL, 0);
  1553.  
  1554. // experimental: if we have a vector bitmap, create a texture for it
  1555. if (d3d->vector_bitmap != NULL)
  1556. {
  1557. render_texinfo texture;
  1558.  
  1559. // fake in the basic data so it looks like it came from render.c
  1560. texture.base = d3d->vector_bitmap->base;
  1561. texture.rowpixels = d3d->vector_bitmap->rowpixels;
  1562. texture.width = d3d->vector_bitmap->width;
  1563. texture.height = d3d->vector_bitmap->height;
  1564. texture.palette = NULL;
  1565. texture.seqid = 0;
  1566.  
  1567. // now create it
  1568. d3d->vector_texture = texture_create(d3d, &texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
  1569. }
  1570.  
  1571. // experimental: initialize some more things if we're using HLSL
  1572. if(d3d->hlsl_enable && d3dintf->post_fx_available)
  1573. {
  1574. // experimental: create a default bitmap for our shader
  1575. if (d3d->default_bitmap != NULL)
  1576. {
  1577. render_texinfo texture;
  1578.  
  1579. // fake in the basic data so it looks like it came from render.c
  1580. texture.base = d3d->default_bitmap->base;
  1581. texture.rowpixels = d3d->default_bitmap->rowpixels;
  1582. texture.width = d3d->default_bitmap->width;
  1583. texture.height = d3d->default_bitmap->height;
  1584. texture.palette = NULL;
  1585. texture.seqid = 0;
  1586.  
  1587. // now create it
  1588. d3d->default_texture = texture_create(d3d, &texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
  1589. }
  1590.  
  1591. windows_options &options = downcast<windows_options &>(d3d->window->machine().options());
  1592.  
  1593. // experimental: load a PNG to use for vector rendering; it is treated
  1594. // as a brightness map
  1595. emu_file file(d3d->window->machine().options().art_path(), OPEN_FLAG_READ);
  1596. d3d->shadow_bitmap = render_load_png(file, NULL, options.screen_shadow_mask_texture(), NULL, NULL);
  1597.  
  1598. // experimental: if we have a shadow bitmap, create a texture for it
  1599. if (d3d->shadow_bitmap != NULL)
  1600. {
  1601. render_texinfo texture;
  1602.  
  1603. // fake in the basic data so it looks like it came from render.c
  1604. texture.base = d3d->shadow_bitmap->base;
  1605. texture.rowpixels = d3d->shadow_bitmap->rowpixels;
  1606. texture.width = d3d->shadow_bitmap->width;
  1607. texture.height = d3d->shadow_bitmap->height;
  1608. texture.palette = NULL;
  1609. texture.seqid = 0;
  1610.  
  1611. // now create it
  1612. d3d->shadow_texture = texture_create(d3d, &texture, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA) | PRIMFLAG_TEXFORMAT(TEXFORMAT_ARGB32));
  1613. }
  1614.  
  1615. d3d->hlsl_options = (d3d_options*)global_alloc_clear(d3d_options);
  1616. d3d->hlsl_options->screen_shadow_mask_alpha = options.screen_shadow_mask_alpha();
  1617. d3d->hlsl_options->screen_shadow_mask_count_x = options.screen_shadow_mask_count_x();
  1618. d3d->hlsl_options->screen_shadow_mask_count_y = options.screen_shadow_mask_count_y();
  1619. d3d->hlsl_options->screen_shadow_mask_u_size = options.screen_shadow_mask_u_size();
  1620. d3d->hlsl_options->screen_shadow_mask_v_size = options.screen_shadow_mask_v_size();
  1621. d3d->hlsl_options->screen_curvature = options.screen_curvature();
  1622. d3d->hlsl_options->screen_pincushion = options.screen_pincushion();
  1623. d3d->hlsl_options->screen_scanline_alpha = options.screen_scanline_amount();
  1624. d3d->hlsl_options->screen_scanline_scale = options.screen_scanline_scale();
  1625. d3d->hlsl_options->screen_scanline_bright_scale = options.screen_scanline_bright_scale();
  1626. d3d->hlsl_options->screen_scanline_bright_offset = options.screen_scanline_bright_offset();
  1627. d3d->hlsl_options->screen_scanline_offset = options.screen_scanline_offset();
  1628. d3d->hlsl_options->screen_defocus_x = options.screen_defocus_x();
  1629. d3d->hlsl_options->screen_defocus_y = options.screen_defocus_y();
  1630. d3d->hlsl_options->screen_red_converge_x = options.screen_red_converge_x();
  1631. d3d->hlsl_options->screen_red_converge_y = options.screen_red_converge_y();
  1632. d3d->hlsl_options->screen_green_converge_x = options.screen_green_converge_x();
  1633. d3d->hlsl_options->screen_green_converge_y = options.screen_green_converge_y();
  1634. d3d->hlsl_options->screen_blue_converge_x = options.screen_blue_converge_x();
  1635. d3d->hlsl_options->screen_blue_converge_y = options.screen_blue_converge_y();
  1636. d3d->hlsl_options->screen_red_radial_converge_x = options.screen_red_radial_converge_x();
  1637. d3d->hlsl_options->screen_red_radial_converge_y = options.screen_red_radial_converge_y();
  1638. d3d->hlsl_options->screen_green_radial_converge_x = options.screen_green_radial_converge_x();
  1639. d3d->hlsl_options->screen_green_radial_converge_y = options.screen_green_radial_converge_y();
  1640. d3d->hlsl_options->screen_blue_radial_converge_x = options.screen_blue_radial_converge_x();
  1641. d3d->hlsl_options->screen_blue_radial_converge_y = options.screen_blue_radial_converge_y();
  1642. d3d->hlsl_options->screen_red_from_red = options.screen_red_from_red();
  1643. d3d->hlsl_options->screen_red_from_green = options.screen_red_from_green();
  1644. d3d->hlsl_options->screen_red_from_blue = options.screen_red_from_blue();
  1645. d3d->hlsl_options->screen_green_from_red = options.screen_green_from_red();
  1646. d3d->hlsl_options->screen_green_from_green = options.screen_green_from_green();
  1647. d3d->hlsl_options->screen_green_from_blue = options.screen_green_from_blue();
  1648. d3d->hlsl_options->screen_blue_from_red = options.screen_blue_from_red();
  1649. d3d->hlsl_options->screen_blue_from_green = options.screen_blue_from_green();
  1650. d3d->hlsl_options->screen_blue_from_blue = options.screen_blue_from_blue();
  1651. d3d->hlsl_options->screen_red_offset = options.screen_red_offset();
  1652. d3d->hlsl_options->screen_green_offset = options.screen_green_offset();
  1653. d3d->hlsl_options->screen_blue_offset = options.screen_blue_offset();
  1654. d3d->hlsl_options->screen_red_scale = options.screen_red_scale();
  1655. d3d->hlsl_options->screen_green_scale = options.screen_green_scale();
  1656. d3d->hlsl_options->screen_blue_scale = options.screen_blue_scale();
  1657. d3d->hlsl_options->screen_red_power = options.screen_red_power();
  1658. d3d->hlsl_options->screen_green_power = options.screen_green_power();
  1659. d3d->hlsl_options->screen_blue_power = options.screen_blue_power();
  1660. d3d->hlsl_options->screen_red_floor = options.screen_red_floor();
  1661. d3d->hlsl_options->screen_green_floor = options.screen_green_floor();
  1662. d3d->hlsl_options->screen_blue_floor = options.screen_blue_floor();
  1663. d3d->hlsl_options->screen_red_phosphor_life = options.screen_red_phosphor();
  1664. d3d->hlsl_options->screen_green_phosphor_life = options.screen_green_phosphor();
  1665. d3d->hlsl_options->screen_blue_phosphor_life = options.screen_blue_phosphor();
  1666. d3d->hlsl_options->screen_saturation = options.screen_saturation();
  1667.  
  1668. slider_list = init_slider_list(d3d);
  1669. }
  1670. else
  1671. {
  1672. d3d->hlsl_options = NULL;
  1673. }
  1674.  
  1675. return 0;
  1676. }
  1677.  
  1678.  
  1679.  
  1680. //============================================================
  1681. // device_delete
  1682. //============================================================
  1683.  
  1684. static void device_delete(d3d_info *d3d)
  1685. {
  1686. // free resources
  1687. device_delete_resources(d3d);
  1688.  
  1689. // free the device itself
  1690. if (d3d->device != NULL)
  1691. (*d3dintf->device.release)(d3d->device);
  1692. d3d->device = NULL;
  1693. }
  1694.  
  1695.  
  1696.  
  1697. //============================================================
  1698. // device_delete_resources
  1699. //============================================================
  1700.  
  1701. static void device_delete_resources(d3d_info *d3d)
  1702. {
  1703. // free all textures
  1704. while (d3d->texlist != NULL)
  1705. {
  1706. texture_info *tex = d3d->texlist;
  1707. d3d->texlist = tex->next;
  1708. if (tex->d3dfinaltex != NULL)
  1709. (*d3dintf->texture.release)(tex->d3dfinaltex);
  1710. if (tex->d3dtex != NULL && tex->d3dtex != tex->d3dfinaltex)
  1711. (*d3dintf->texture.release)(tex->d3dtex);
  1712. if (tex->d3dsurface != NULL)
  1713. (*d3dintf->surface.release)(tex->d3dsurface);
  1714. if (tex->d3dtexture0 != NULL)
  1715. (*d3dintf->texture.release)(tex->d3dtexture0);
  1716. if (tex->d3dtexture1 != NULL)
  1717. (*d3dintf->texture.release)(tex->d3dtexture1);
  1718. if (tex->d3dtexture2 != NULL)
  1719. (*d3dintf->texture.release)(tex->d3dtexture2);
  1720. if (tex->d3dtexture3 != NULL)
  1721. (*d3dintf->texture.release)(tex->d3dtexture3);
  1722. if (tex->d3dtexture4 != NULL)
  1723. (*d3dintf->texture.release)(tex->d3dtexture4);
  1724. if (tex->d3dsmalltexture0 != NULL)
  1725. (*d3dintf->texture.release)(tex->d3dsmalltexture0);
  1726. if (tex->d3dtarget0 != NULL)
  1727. (*d3dintf->surface.release)(tex->d3dtarget0);
  1728. if (tex->d3dtarget1 != NULL)
  1729. (*d3dintf->surface.release)(tex->d3dtarget1);
  1730. if (tex->d3dtarget2 != NULL)
  1731. (*d3dintf->surface.release)(tex->d3dtarget2);
  1732. if (tex->d3dtarget3 != NULL)
  1733. (*d3dintf->surface.release)(tex->d3dtarget3);
  1734. if (tex->d3dtarget4 != NULL)
  1735. (*d3dintf->surface.release)(tex->d3dtarget4);
  1736. if (tex->d3dsmalltarget0 != NULL)
  1737. (*d3dintf->surface.release)(tex->d3dsmalltarget0);
  1738. global_free(tex);
  1739. }
  1740.  
  1741. // free the vertex buffer
  1742. if (d3d->vertexbuf != NULL)
  1743. (*d3dintf->vertexbuf.release)(d3d->vertexbuf);
  1744. d3d->vertexbuf = NULL;
  1745.  
  1746. global_free(d3d->default_texture);
  1747.  
  1748. // free our effects
  1749. if(d3d->effect != NULL)
  1750. {
  1751. (*d3dintf->effect.release)(d3d->effect);
  1752. d3d->effect = NULL;
  1753. }
  1754. if(d3d->post_effect != NULL)
  1755. {
  1756. (*d3dintf->effect.release)(d3d->post_effect);
  1757. d3d->post_effect = NULL;
  1758. }
  1759. if(d3d->pincushion_effect != NULL)
  1760. {
  1761. (*d3dintf->effect.release)(d3d->pincushion_effect);
  1762. d3d->pincushion_effect = NULL;
  1763. }
  1764. if(d3d->phosphor_effect != NULL)
  1765. {
  1766. (*d3dintf->effect.release)(d3d->phosphor_effect);
  1767. d3d->phosphor_effect = NULL;
  1768. }
  1769. if(d3d->focus_effect != NULL)
  1770. {
  1771. (*d3dintf->effect.release)(d3d->focus_effect);
  1772. d3d->focus_effect = NULL;
  1773. }
  1774. if(d3d->deconverge_effect != NULL)
  1775. {
  1776. (*d3dintf->effect.release)(d3d->deconverge_effect);
  1777. d3d->deconverge_effect = NULL;
  1778. }
  1779. if(d3d->color_effect != NULL)
  1780. {
  1781. (*d3dintf->effect.release)(d3d->color_effect);
  1782. d3d->color_effect = NULL;
  1783. }
  1784. if(d3d->yiq_encode_effect != NULL)
  1785. {
  1786. (*d3dintf->effect.release)(d3d->yiq_encode_effect);
  1787. d3d->yiq_encode_effect = NULL;
  1788. }
  1789. if(d3d->yiq_decode_effect != NULL)
  1790. {
  1791. (*d3dintf->effect.release)(d3d->yiq_decode_effect);
  1792. d3d->yiq_decode_effect = NULL;
  1793. }
  1794.  
  1795. for(int index = 0; index < 9; index++)
  1796. {
  1797. if(d3d->last_d3dtexture[index] != NULL)
  1798. {
  1799. (*d3dintf->texture.release)(d3d->last_d3dtexture[index]);
  1800. d3d->last_d3dtexture[index] = NULL;
  1801. }
  1802. if(d3d->last_d3dtarget[index] != NULL)
  1803. {
  1804. (*d3dintf->surface.release)(d3d->last_d3dtarget[index]);
  1805. d3d->last_d3dtarget[index] = NULL;
  1806. }
  1807. }
  1808.  
  1809. if(d3d->hlsl_options != NULL)
  1810. {
  1811. global_free(d3d->hlsl_options);
  1812. }
  1813.  
  1814. d3d->registered_targets = 0;
  1815.  
  1816. if(d3d->shadow_texture != NULL)
  1817. {
  1818. global_free(d3d->shadow_texture);
  1819. d3d->shadow_texture = NULL;
  1820. }
  1821. }
  1822.  
  1823.  
  1824.  
  1825. //============================================================
  1826. // device_verify_caps
  1827. //============================================================
  1828.  
  1829. static int device_verify_caps(d3d_info *d3d, win_window_info *window)
  1830. {
  1831. int retval = 0;
  1832. HRESULT result;
  1833. DWORD tempcaps;
  1834.  
  1835. // fetch a few core caps
  1836. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_TEXTURE_CAPS, &d3d->texture_caps);
  1837. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1838. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_ASPECT, &d3d->texture_max_aspect);
  1839. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1840. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_WIDTH, &d3d->texture_max_width);
  1841. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1842. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_MAX_TEXTURE_HEIGHT, &d3d->texture_max_height);
  1843. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1844.  
  1845. d3d->hlsl_enable = downcast<windows_options &>(window->machine().options()).d3d_hlsl_enable() && d3dintf->post_fx_available;
  1846. d3d->yiq_enable = downcast<windows_options &>(window->machine().options()).screen_yiq_enable();
  1847. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_MAX_PS30_INSN_SLOTS, &tempcaps);
  1848. if (result != D3D_OK) mame_printf_verbose("Direct3D Error %08X during get_caps_dword call\n", (int)result);
  1849. if(tempcaps < 512 && d3d->hlsl_enable)
  1850. {
  1851. mame_printf_verbose("Direct3D: Warning - Device does not support Pixel Shader 3.0, falling back to non-PS rendering\n");
  1852. d3d->hlsl_enable = false;
  1853. }
  1854.  
  1855. // verify presentation capabilities
  1856. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_PRESENTATION_INTERVALS, &tempcaps);
  1857. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1858. if (!(tempcaps & D3DPRESENT_INTERVAL_IMMEDIATE))
  1859. {
  1860. mame_printf_verbose("Direct3D: Error - Device does not support immediate presentations\n");
  1861. retval = 2;
  1862. }
  1863. if (!(tempcaps & D3DPRESENT_INTERVAL_ONE))
  1864. {
  1865. mame_printf_verbose("Direct3D: Error - Device does not support per-refresh presentations\n");
  1866. retval = 2;
  1867. }
  1868.  
  1869. // verify device capabilities
  1870. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_DEV_CAPS, &tempcaps);
  1871. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1872. if (!(tempcaps & D3DDEVCAPS_CANRENDERAFTERFLIP))
  1873. {
  1874. mame_printf_verbose("Direct3D: Warning - Device does not support queued rendering after a page flip\n");
  1875. retval = 1;
  1876. }
  1877. if (!(tempcaps & D3DDEVCAPS_HWRASTERIZATION))
  1878. {
  1879. mame_printf_verbose("Direct3D: Warning - Device does not support hardware rasterization\n");
  1880. retval = 1;
  1881. }
  1882.  
  1883. // verify source blend capabilities
  1884. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_SRCBLEND_CAPS, &tempcaps);
  1885. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1886. if (!(tempcaps & D3DPBLENDCAPS_SRCALPHA))
  1887. {
  1888. mame_printf_verbose("Direct3D: Error - Device does not support source alpha blending with source alpha\n");
  1889. retval = 2;
  1890. }
  1891. if (!(tempcaps & D3DPBLENDCAPS_DESTCOLOR))
  1892. {
  1893. mame_printf_verbose("Direct3D: Error - Device does not support source alpha blending with destination color\n");
  1894. retval = 2;
  1895. }
  1896.  
  1897. // verify destination blend capabilities
  1898. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_DSTBLEND_CAPS, &tempcaps);
  1899. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1900. if (!(tempcaps & D3DPBLENDCAPS_ZERO))
  1901. {
  1902. mame_printf_verbose("Direct3D: Error - Device does not support dest alpha blending with zero\n");
  1903. retval = 2;
  1904. }
  1905. if (!(tempcaps & D3DPBLENDCAPS_ONE))
  1906. {
  1907. mame_printf_verbose("Direct3D: Error - Device does not support dest alpha blending with one\n");
  1908. retval = 2;
  1909. }
  1910. if (!(tempcaps & D3DPBLENDCAPS_INVSRCALPHA))
  1911. {
  1912. mame_printf_verbose("Direct3D: Error - Device does not support dest alpha blending with inverted source alpha\n");
  1913. retval = 2;
  1914. }
  1915.  
  1916. // verify texture capabilities
  1917. if (!(d3d->texture_caps & D3DPTEXTURECAPS_ALPHA))
  1918. {
  1919. mame_printf_verbose("Direct3D: Error - Device does not support texture alpha\n");
  1920. retval = 2;
  1921. }
  1922.  
  1923. // verify texture filter capabilities
  1924. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_TEXTURE_FILTER_CAPS, &tempcaps);
  1925. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1926. if (!(tempcaps & D3DPTFILTERCAPS_MAGFPOINT))
  1927. {
  1928. mame_printf_verbose("Direct3D: Warning - Device does not support point-sample texture filtering for magnification\n");
  1929. retval = 1;
  1930. }
  1931. if (!(tempcaps & D3DPTFILTERCAPS_MAGFLINEAR))
  1932. {
  1933. mame_printf_verbose("Direct3D: Warning - Device does not support bilinear texture filtering for magnification\n");
  1934. retval = 1;
  1935. }
  1936. if (!(tempcaps & D3DPTFILTERCAPS_MINFPOINT))
  1937. {
  1938. mame_printf_verbose("Direct3D: Warning - Device does not support point-sample texture filtering for minification\n");
  1939. retval = 1;
  1940. }
  1941. if (!(tempcaps & D3DPTFILTERCAPS_MINFLINEAR))
  1942. {
  1943. mame_printf_verbose("Direct3D: Warning - Device does not support bilinear texture filtering for minification\n");
  1944. retval = 1;
  1945. }
  1946.  
  1947. // verify texture addressing capabilities
  1948. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_TEXTURE_ADDRESS_CAPS, &tempcaps);
  1949. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1950. if (!(tempcaps & D3DPTADDRESSCAPS_CLAMP))
  1951. {
  1952. mame_printf_verbose("Direct3D: Warning - Device does not support texture clamping\n");
  1953. retval = 1;
  1954. }
  1955. if (!(tempcaps & D3DPTADDRESSCAPS_WRAP))
  1956. {
  1957. mame_printf_verbose("Direct3D: Warning - Device does not support texture wrapping\n");
  1958. retval = 1;
  1959. }
  1960.  
  1961. // verify texture operation capabilities
  1962. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_TEXTURE_OP_CAPS, &tempcaps);
  1963. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1964. if (!(tempcaps & D3DTEXOPCAPS_MODULATE))
  1965. {
  1966. mame_printf_verbose("Direct3D: Warning - Device does not support texture modulation\n");
  1967. retval = 1;
  1968. }
  1969.  
  1970. // set a simpler flag to indicate mod2x and mod4x texture modes
  1971. d3d->mod2x_supported = ((tempcaps & D3DTEXOPCAPS_MODULATE2X) != 0);
  1972. d3d->mod4x_supported = ((tempcaps & D3DTEXOPCAPS_MODULATE4X) != 0);
  1973.  
  1974. // set a simpler flag to indicate we can use a gamma ramp
  1975. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_CAPS2, &tempcaps);
  1976. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1977. d3d->dynamic_supported = ((tempcaps & D3DCAPS2_DYNAMICTEXTURES) != 0);
  1978. d3d->gamma_supported = ((tempcaps & D3DCAPS2_FULLSCREENGAMMA) != 0);
  1979. if (d3d->dynamic_supported) mame_printf_verbose("Direct3D: Using dynamic textures\n");
  1980.  
  1981. // set a simpler flag to indicate we can use StretchRect
  1982. result = (*d3dintf->d3d.get_caps_dword)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, CAPS_STRETCH_RECT_FILTER, &tempcaps);
  1983. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during get_caps_dword call\n", (int)result);
  1984. d3d->stretch_supported = ((tempcaps & D3DPTFILTERCAPS_MAGFPOINT) != 0);
  1985. if (d3d->stretch_supported && video_config.prescale > 1) mame_printf_verbose("Direct3D: Using StretchRect for prescaling\n");
  1986.  
  1987. return retval;
  1988. }
  1989.  
  1990.  
  1991.  
  1992. //============================================================
  1993. // device_test_cooperative
  1994. //============================================================
  1995.  
  1996. static int device_test_cooperative(d3d_info *d3d)
  1997. {
  1998. HRESULT result;
  1999.  
  2000. // check our current status; if we lost the device, punt to GDI
  2001. result = (*d3dintf->device.test_cooperative_level)(d3d->device);
  2002. if (result == D3DERR_DEVICELOST)
  2003. return 1;
  2004.  
  2005. // if we're able to reset ourselves, try it
  2006. if (result == D3DERR_DEVICENOTRESET)
  2007. {
  2008. mame_printf_verbose("Direct3D: resetting device\n");
  2009.  
  2010. // free all existing resources and call reset on the device
  2011. device_delete_resources(d3d);
  2012. result = (*d3dintf->device.reset)(d3d->device, &d3d->presentation);
  2013.  
  2014. // if it didn't work, punt to GDI
  2015. if (result != D3D_OK)
  2016. return 1;
  2017.  
  2018. // try to create the resources again; if that didn't work, delete the whole thing
  2019. if (device_create_resources(d3d))
  2020. {
  2021. mame_printf_verbose("Direct3D: failed to recreate resources for device; failing permanently\n");
  2022. device_delete(d3d);
  2023. return 1;
  2024. }
  2025. }
  2026. return 0;
  2027. }
  2028.  
  2029.  
  2030.  
  2031. //============================================================
  2032. // config_adapter_mode
  2033. //============================================================
  2034.  
  2035. static int config_adapter_mode(win_window_info *window)
  2036. {
  2037. d3d_adapter_identifier identifier;
  2038. d3d_info *d3d = (d3d_info *)window->drawdata;
  2039. HRESULT result;
  2040.  
  2041. // choose the monitor number
  2042. d3d->adapter = get_adapter_for_monitor(d3d, window->monitor);
  2043.  
  2044. // get the identifier
  2045. result = (*d3dintf->d3d.get_adapter_identifier)(d3dintf, d3d->adapter, 0, &identifier);
  2046. if (result != D3D_OK)
  2047. {
  2048. mame_printf_error("Error getting identifier for adapter #%d\n", d3d->adapter);
  2049. return 1;
  2050. }
  2051. mame_printf_verbose("Direct3D: Configuring adapter #%d = %s\n", d3d->adapter, identifier.Description);
  2052.  
  2053. // get the current display mode
  2054. result = (*d3dintf->d3d.get_adapter_display_mode)(d3dintf, d3d->adapter, &d3d->origmode);
  2055. if (result != D3D_OK)
  2056. {
  2057. mame_printf_error("Error getting mode for adapter #%d\n", d3d->adapter);
  2058. return 1;
  2059. }
  2060.  
  2061. // choose a resolution: window mode case
  2062. if (!window->fullscreen || !video_config.switchres || win_has_menu(window))
  2063. {
  2064. RECT client;
  2065.  
  2066. // bounds are from the window client rect
  2067. GetClientRectExceptMenu(window->hwnd, &client, window->fullscreen);
  2068. d3d->width = client.right - client.left;
  2069. d3d->height = client.bottom - client.top;
  2070.  
  2071. // pix format is from the current mode
  2072. d3d->pixformat = d3d->origmode.Format;
  2073. d3d->refresh = 0;
  2074.  
  2075. // make sure it's a pixel format we can get behind
  2076. if (d3d->pixformat != D3DFMT_X1R5G5B5 && d3d->pixformat != D3DFMT_R5G6B5 && d3d->pixformat != D3DFMT_X8R8G8B8)
  2077. {
  2078. char *utf8_device = utf8_from_tstring(window->monitor->info.szDevice);
  2079. if (utf8_device != NULL)
  2080. {
  2081. mame_printf_error("Device %s currently in an unsupported mode\n", utf8_device);
  2082. osd_free(utf8_device);
  2083. }
  2084. return 1;
  2085. }
  2086. }
  2087.  
  2088. // choose a resolution: full screen mode case
  2089. else
  2090. {
  2091. // default to the current mode exactly
  2092. d3d->width = d3d->origmode.Width;
  2093. d3d->height = d3d->origmode.Height;
  2094. d3d->pixformat = d3d->origmode.Format;
  2095. d3d->refresh = d3d->origmode.RefreshRate;
  2096.  
  2097. // if we're allowed to switch resolutions, override with something better
  2098. if (video_config.switchres)
  2099. pick_best_mode(window);
  2100. }
  2101.  
  2102. // see if we can handle the device type
  2103. result = (*d3dintf->d3d.check_device_type)(d3dintf, d3d->adapter, D3DDEVTYPE_HAL, d3d->pixformat, d3d->pixformat, !window->fullscreen);
  2104. if (result != D3D_OK)
  2105. {
  2106. char *utf8_device = utf8_from_tstring(window->monitor->info.szDevice);
  2107. if (utf8_device != NULL)
  2108. {
  2109. mame_printf_error("Proposed video mode not supported on device %s\n", utf8_device);
  2110. osd_free(utf8_device);
  2111. }
  2112. return 1;
  2113. }
  2114. return 0;
  2115. }
  2116.  
  2117.  
  2118.  
  2119. //============================================================
  2120. // get_adapter_for_monitor
  2121. //============================================================
  2122.  
  2123. static int get_adapter_for_monitor(d3d_info *d3d, win_monitor_info *monitor)
  2124. {
  2125. int maxadapter = (*d3dintf->d3d.get_adapter_count)(d3dintf);
  2126. int adapternum;
  2127.  
  2128. // iterate over adapters until we error or find a match
  2129. for (adapternum = 0; adapternum < maxadapter; adapternum++)
  2130. {
  2131. HMONITOR curmonitor;
  2132.  
  2133. // get the monitor for this adapter
  2134. curmonitor = (*d3dintf->d3d.get_adapter_monitor)(d3dintf, adapternum);
  2135.  
  2136. // if we match the proposed monitor, this is it
  2137. if (curmonitor == monitor->handle)
  2138. return adapternum;
  2139. }
  2140.  
  2141. // default to the default
  2142. return D3DADAPTER_DEFAULT;
  2143. }
  2144.  
  2145.  
  2146.  
  2147. //============================================================
  2148. // pick_best_mode
  2149. //============================================================
  2150.  
  2151. static void pick_best_mode(win_window_info *window)
  2152. {
  2153. double target_refresh = 60.0;
  2154. INT32 target_width, target_height;
  2155. d3d_info *d3d = (d3d_info *)window->drawdata;
  2156. INT32 minwidth, minheight;
  2157. float best_score = 0.0f;
  2158. int maxmodes;
  2159. int modenum;
  2160.  
  2161. // determine the refresh rate of the primary screen
  2162. const screen_device *primary_screen = window->machine().config().first_screen();
  2163. if (primary_screen != NULL)
  2164. target_refresh = ATTOSECONDS_TO_HZ(primary_screen->refresh_attoseconds());
  2165.  
  2166. // determine the minimum width/height for the selected target
  2167. // note: technically we should not be calling this from an alternate window
  2168. // thread; however, it is only done during init time, and the init code on
  2169. // the main thread is waiting for us to finish, so it is safe to do so here
  2170. window->target->compute_minimum_size(minwidth, minheight);
  2171.  
  2172. // use those as the target for now
  2173. target_width = minwidth;
  2174. target_height = minheight;
  2175.  
  2176. // determine the maximum number of modes
  2177. maxmodes = (*d3dintf->d3d.get_adapter_mode_count)(d3dintf, d3d->adapter, D3DFMT_X8R8G8B8);
  2178.  
  2179. // enumerate all the video modes and find the best match
  2180. mame_printf_verbose("Direct3D: Selecting video mode...\n");
  2181. for (modenum = 0; modenum < maxmodes; modenum++)
  2182. {
  2183. float size_score, refresh_score, final_score;
  2184. D3DDISPLAYMODE mode;
  2185. HRESULT result;
  2186.  
  2187. // check this mode
  2188. result = (*d3dintf->d3d.enum_adapter_modes)(d3dintf, d3d->adapter, D3DFMT_X8R8G8B8, modenum, &mode);
  2189. if (result != D3D_OK)
  2190. break;
  2191.  
  2192. // skip non-32 bit modes
  2193. if (mode.Format != D3DFMT_X8R8G8B8)
  2194. continue;
  2195.  
  2196. // compute initial score based on difference between target and current
  2197. size_score = 1.0f / (1.0f + fabs((float)(mode.Width - target_width)) + fabs((float)(mode.Height - target_height)));
  2198.  
  2199. // if the mode is too small, give a big penalty
  2200. if (mode.Width < minwidth || mode.Height < minheight)
  2201. size_score *= 0.01f;
  2202.  
  2203. // if mode is smaller than we'd like, it only scores up to 0.1
  2204. if (mode.Width < target_width || mode.Height < target_height)
  2205. size_score *= 0.1f;
  2206.  
  2207. // if we're looking for a particular mode, that's a winner
  2208. if (mode.Width == window->maxwidth && mode.Height == window->maxheight)
  2209. size_score = 2.0f;
  2210.  
  2211. // compute refresh score
  2212. refresh_score = 1.0f / (1.0f + fabs((double)mode.RefreshRate - target_refresh));
  2213.  
  2214. // if refresh is smaller than we'd like, it only scores up to 0.1
  2215. if ((double)mode.RefreshRate < target_refresh)
  2216. refresh_score *= 0.1f;
  2217.  
  2218. // if we're looking for a particular refresh, make sure it matches
  2219. if (mode.RefreshRate == window->refresh)
  2220. refresh_score = 2.0f;
  2221.  
  2222. // weight size and refresh equally
  2223. final_score = size_score + refresh_score;
  2224.  
  2225. // best so far?
  2226. mame_printf_verbose(" %4dx%4d@%3dHz -> %f\n", mode.Width, mode.Height, mode.RefreshRate, final_score * 1000.0f);
  2227. if (final_score > best_score)
  2228. {
  2229. best_score = final_score;
  2230. d3d->width = mode.Width;
  2231. d3d->height = mode.Height;
  2232. d3d->pixformat = mode.Format;
  2233. d3d->refresh = mode.RefreshRate;
  2234. }
  2235. }
  2236. mame_printf_verbose("Direct3D: Mode selected = %4dx%4d@%3dHz\n", d3d->width, d3d->height, d3d->refresh);
  2237. }
  2238.  
  2239.  
  2240.  
  2241. //============================================================
  2242. // update_window_size
  2243. //============================================================
  2244.  
  2245. static int update_window_size(win_window_info *window)
  2246. {
  2247. d3d_info *d3d = (d3d_info *)window->drawdata;
  2248. RECT client;
  2249.  
  2250. // get the current window bounds
  2251. GetClientRectExceptMenu(window->hwnd, &client, window->fullscreen);
  2252.  
  2253. // if we have a device and matching width/height, nothing to do
  2254. if (d3d->device != NULL && rect_width(&client) == d3d->width && rect_height(&client) == d3d->height)
  2255. {
  2256. // clear out any pending resizing if the area didn't change
  2257. if (window->resize_state == RESIZE_STATE_PENDING)
  2258. window->resize_state = RESIZE_STATE_NORMAL;
  2259. return FALSE;
  2260. }
  2261.  
  2262. // if we're in the middle of resizing, leave it alone as well
  2263. if (window->resize_state == RESIZE_STATE_RESIZING)
  2264. return FALSE;
  2265.  
  2266. // set the new bounds and create the device again
  2267. d3d->width = rect_width(&client);
  2268. d3d->height = rect_height(&client);
  2269. if (device_create(window))
  2270. return FALSE;
  2271.  
  2272. // reset the resize state to normal, and indicate we made a change
  2273. window->resize_state = RESIZE_STATE_NORMAL;
  2274. return TRUE;
  2275. }
  2276.  
  2277.  
  2278.  
  2279. //============================================================
  2280. // draw_line
  2281. //============================================================
  2282.  
  2283. static void draw_line(d3d_info *d3d, const render_primitive *prim)
  2284. {
  2285. const line_aa_step *step = line_aa_4step;
  2286. render_bounds b0, b1;
  2287. d3d_vertex *vertex;
  2288. INT32 r, g, b, a;
  2289. poly_info *poly;
  2290. float effwidth;
  2291. DWORD color;
  2292. int i;
  2293.  
  2294. // compute the effective width based on the direction of the line
  2295. effwidth = prim->width;
  2296. if (effwidth < 0.5f)
  2297. effwidth = 0.5f;
  2298.  
  2299. // determine the bounds of a quad to draw this line
  2300. render_line_to_quad(&prim->bounds, effwidth, &b0, &b1);
  2301.  
  2302. // iterate over AA steps
  2303. for (step = PRIMFLAG_GET_ANTIALIAS(prim->flags) ? line_aa_4step : line_aa_1step; step->weight != 0; step++)
  2304. {
  2305. // get a pointer to the vertex buffer
  2306. vertex = primitive_alloc(d3d, 4);
  2307. if (vertex == NULL)
  2308. return;
  2309.  
  2310. // rotate the unit vector by 135 degrees and add to point 0
  2311. vertex[0].x = b0.x0 + step->xoffs;
  2312. vertex[0].y = b0.y0 + step->yoffs;
  2313.  
  2314. // rotate the unit vector by -135 degrees and add to point 0
  2315. vertex[1].x = b0.x1 + step->xoffs;
  2316. vertex[1].y = b0.y1 + step->yoffs;
  2317.  
  2318. // rotate the unit vector by 45 degrees and add to point 1
  2319. vertex[2].x = b1.x0 + step->xoffs;
  2320. vertex[2].y = b1.y0 + step->yoffs;
  2321.  
  2322. // rotate the unit vector by -45 degrees and add to point 1
  2323. vertex[3].x = b1.x1 + step->xoffs;
  2324. vertex[3].y = b1.y1 + step->yoffs;
  2325.  
  2326. // determine the color of the line
  2327. r = (INT32)(prim->color.r * step->weight * 255.0f);
  2328. g = (INT32)(prim->color.g * step->weight * 255.0f);
  2329. b = (INT32)(prim->color.b * step->weight * 255.0f);
  2330. a = (INT32)(prim->color.a * 255.0f);
  2331. if (r > 255) r = 255;
  2332. if (g > 255) g = 255;
  2333. if (b > 255) b = 255;
  2334. if (a > 255) a = 255;
  2335. color = D3DCOLOR_ARGB(a, r, g, b);
  2336.  
  2337. // if we have a texture to use for the vectors, use it here
  2338. if (d3d->vector_texture != NULL)
  2339. {
  2340. vertex[0].u0 = d3d->vector_texture->ustart;
  2341. vertex[0].v0 = d3d->vector_texture->vstart;
  2342.  
  2343. vertex[2].u0 = d3d->vector_texture->ustop;
  2344. vertex[2].v0 = d3d->vector_texture->vstart;
  2345.  
  2346. vertex[1].u0 = d3d->vector_texture->ustart;
  2347. vertex[1].v0 = d3d->vector_texture->vstop;
  2348.  
  2349. vertex[3].u0 = d3d->vector_texture->ustop;
  2350. vertex[3].v0 = d3d->vector_texture->vstop;
  2351. }
  2352. else if(d3d->default_texture != NULL)
  2353. {
  2354. vertex[0].u0 = d3d->default_texture->ustart;
  2355. vertex[0].v0 = d3d->default_texture->vstart;
  2356.  
  2357. vertex[2].u0 = d3d->default_texture->ustart;
  2358. vertex[2].v0 = d3d->default_texture->vstart;
  2359.  
  2360. vertex[1].u0 = d3d->default_texture->ustart;
  2361. vertex[1].v0 = d3d->default_texture->vstart;
  2362.  
  2363. vertex[3].u0 = d3d->default_texture->ustart;
  2364. vertex[3].v0 = d3d->default_texture->vstart;
  2365. }
  2366.  
  2367. // set the color, Z parameters to standard values
  2368. for (i = 0; i < 4; i++)
  2369. {
  2370. vertex[i].z = 0.0f;
  2371. vertex[i].rhw = 1.0f;
  2372. vertex[i].color = color;
  2373. }
  2374.  
  2375. // now add a polygon entry
  2376. poly = &d3d->poly[d3d->numpolys++];
  2377. poly->type = D3DPT_TRIANGLESTRIP;
  2378. poly->count = 2;
  2379. poly->numverts = 4;
  2380. poly->flags = prim->flags;
  2381. poly->modmode = D3DTOP_MODULATE;
  2382. poly->texture = d3d->vector_texture;
  2383. }
  2384. }
  2385.  
  2386.  
  2387.  
  2388. //============================================================
  2389. // draw_quad
  2390. //============================================================
  2391.  
  2392. static void draw_quad(d3d_info *d3d, const render_primitive *prim)
  2393. {
  2394. texture_info *texture = texture_find(d3d, prim);
  2395. DWORD color, modmode;
  2396. d3d_vertex *vertex;
  2397. INT32 r, g, b, a;
  2398. poly_info *poly;
  2399. int i;
  2400.  
  2401. texture = texture != NULL ? texture : d3d->default_texture;
  2402.  
  2403. // get a pointer to the vertex buffer
  2404. vertex = primitive_alloc(d3d, 4);
  2405. if (vertex == NULL)
  2406. return;
  2407.  
  2408. // fill in the vertexes clockwise
  2409. vertex[0].x = prim->bounds.x0 - 0.5f;
  2410. vertex[0].y = prim->bounds.y0 - 0.5f;
  2411. vertex[1].x = prim->bounds.x1 - 0.5f;
  2412. vertex[1].y = prim->bounds.y0 - 0.5f;
  2413. vertex[2].x = prim->bounds.x0 - 0.5f;
  2414. vertex[2].y = prim->bounds.y1 - 0.5f;
  2415. vertex[3].x = prim->bounds.x1 - 0.5f;
  2416. vertex[3].y = prim->bounds.y1 - 0.5f;
  2417.  
  2418. // set the texture coordinates
  2419. if(texture != NULL)
  2420. {
  2421. float du = texture->ustop - texture->ustart;
  2422. float dv = texture->vstop - texture->vstart;
  2423. vertex[0].u0 = texture->ustart + du * prim->texcoords.tl.u;
  2424. vertex[0].v0 = texture->vstart + dv * prim->texcoords.tl.v;
  2425. vertex[1].u0 = texture->ustart + du * prim->texcoords.tr.u;
  2426. vertex[1].v0 = texture->vstart + dv * prim->texcoords.tr.v;
  2427. vertex[2].u0 = texture->ustart + du * prim->texcoords.bl.u;
  2428. vertex[2].v0 = texture->vstart + dv * prim->texcoords.bl.v;
  2429. vertex[3].u0 = texture->ustart + du * prim->texcoords.br.u;
  2430. vertex[3].v0 = texture->vstart + dv * prim->texcoords.br.v;
  2431. }
  2432.  
  2433. // determine the color, allowing for over modulation
  2434. r = (INT32)(prim->color.r * 255.0f);
  2435. g = (INT32)(prim->color.g * 255.0f);
  2436. b = (INT32)(prim->color.b * 255.0f);
  2437. a = (INT32)(prim->color.a * 255.0f);
  2438. modmode = D3DTOP_MODULATE;
  2439. if (texture != NULL)
  2440. {
  2441. if (d3d->mod2x_supported && (r > 255 || g > 255 || b > 255))
  2442. {
  2443. if (d3d->mod4x_supported && (r > 2*255 || g > 2*255 || b > 2*255))
  2444. {
  2445. r >>= 2; g >>= 2; b >>= 2;
  2446. modmode = D3DTOP_MODULATE4X;
  2447. }
  2448. else
  2449. {
  2450. r >>= 1; g >>= 1; b >>= 1;
  2451. modmode = D3DTOP_MODULATE2X;
  2452. }
  2453. }
  2454. }
  2455. if (r > 255) r = 255;
  2456. if (g > 255) g = 255;
  2457. if (b > 255) b = 255;
  2458. if (a > 255) a = 255;
  2459. color = D3DCOLOR_ARGB(a, r, g, b);
  2460.  
  2461. // set the color, Z parameters to standard values
  2462. for (i = 0; i < 4; i++)
  2463. {
  2464. vertex[i].z = 0.0f;
  2465. vertex[i].rhw = 1.0f;
  2466. vertex[i].color = color;
  2467. }
  2468.  
  2469. // now add a polygon entry
  2470. poly = &d3d->poly[d3d->numpolys++];
  2471. poly->type = D3DPT_TRIANGLESTRIP;
  2472. poly->count = 2;
  2473. poly->numverts = 4;
  2474. poly->flags = prim->flags;
  2475. poly->modmode = modmode;
  2476. poly->texture = texture;
  2477. }
  2478.  
  2479.  
  2480.  
  2481. //============================================================
  2482. // init_fsfx_quad
  2483. //============================================================
  2484.  
  2485. static void init_fsfx_quad(d3d_info *d3d)
  2486. {
  2487. // get a pointer to the vertex buffer
  2488. d3d->fsfx_vertices = primitive_alloc(d3d, 4);
  2489. if (d3d->fsfx_vertices == NULL)
  2490. return;
  2491.  
  2492. // fill in the vertexes clockwise
  2493. windows_options &options = downcast<windows_options &>(d3d->window->machine().options());
  2494. float scale_top = options.screen_scale_top();
  2495. float scale_bottom = options.screen_scale_bottom();
  2496.  
  2497. d3d->fsfx_vertices[0].x = (d3d->width * (scale_top * 0.5f - 0.5f));
  2498. d3d->fsfx_vertices[0].y = 0.0f;
  2499. d3d->fsfx_vertices[1].x = d3d->width - (d3d->width * (scale_top * 0.5f - 0.5f));
  2500. d3d->fsfx_vertices[1].y = 0.0f;
  2501. d3d->fsfx_vertices[2].x = (d3d->width * (scale_bottom * 0.5f - 0.5f));
  2502. d3d->fsfx_vertices[2].y = d3d->height;
  2503. d3d->fsfx_vertices[3].x = d3d->width - (d3d->width * (scale_bottom * 0.5f - 0.5f));
  2504. d3d->fsfx_vertices[3].y = d3d->height;
  2505.  
  2506. d3d->fsfx_vertices[0].u0 = 0.0f;
  2507. d3d->fsfx_vertices[0].v0 = 0.0f;
  2508. d3d->fsfx_vertices[1].u0 = 1.0f;
  2509. d3d->fsfx_vertices[1].v0 = 0.0f;
  2510. d3d->fsfx_vertices[2].u0 = 0.0f;
  2511. d3d->fsfx_vertices[2].v0 = 1.0f;
  2512. d3d->fsfx_vertices[3].u0 = 1.0f;
  2513. d3d->fsfx_vertices[3].v0 = 1.0f;
  2514.  
  2515. // set the color, Z parameters to standard values
  2516. for (int i = 0; i < 4; i++)
  2517. {
  2518. d3d->fsfx_vertices[i].z = 0.0f;
  2519. d3d->fsfx_vertices[i].rhw = 1.0f;
  2520. d3d->fsfx_vertices[i].color = D3DCOLOR_ARGB(255, 255, 255, 255);
  2521. }
  2522. }
  2523.  
  2524.  
  2525.  
  2526. //============================================================
  2527. // primitive_alloc
  2528. //============================================================
  2529.  
  2530. static d3d_vertex *primitive_alloc(d3d_info *d3d, int numverts)
  2531. {
  2532. HRESULT result;
  2533.  
  2534. // if we're going to overflow, flush
  2535. if (d3d->lockedbuf != NULL && d3d->numverts + numverts >= VERTEX_BUFFER_SIZE)
  2536. primitive_flush_pending(d3d);
  2537.  
  2538. // if we don't have a lock, grab it now
  2539. if (d3d->lockedbuf == NULL)
  2540. {
  2541. result = (*d3dintf->vertexbuf.lock)(d3d->vertexbuf, 0, 0, (VOID **)&d3d->lockedbuf, D3DLOCK_DISCARD);
  2542. if (result != D3D_OK)
  2543. return NULL;
  2544. }
  2545.  
  2546. // if we already have the lock and enough room, just return a pointer
  2547. if (d3d->lockedbuf != NULL && d3d->numverts + numverts < VERTEX_BUFFER_SIZE)
  2548. {
  2549. int oldverts = d3d->numverts;
  2550. d3d->numverts += numverts;
  2551. return &d3d->lockedbuf[oldverts];
  2552. }
  2553. return NULL;
  2554. }
  2555.  
  2556.  
  2557.  
  2558. //============================================================
  2559. // primitive_flush_pending
  2560. //============================================================
  2561.  
  2562. static void primitive_flush_pending(d3d_info *d3d)
  2563. {
  2564. HRESULT result;
  2565. int polynum;
  2566. int vertnum;
  2567.  
  2568. // ignore if we're not locked
  2569. if (d3d->lockedbuf == NULL)
  2570. return;
  2571.  
  2572. // unlock the buffer
  2573. result = (*d3dintf->vertexbuf.unlock)(d3d->vertexbuf);
  2574. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during vertex buffer unlock call\n", (int)result);
  2575. d3d->lockedbuf = NULL;
  2576.  
  2577. // set the stream
  2578. result = (*d3dintf->device.set_stream_source)(d3d->device, 0, d3d->vertexbuf, sizeof(d3d_vertex));
  2579. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_stream_source call\n", (int)result);
  2580.  
  2581. d3d_effect *curr_effect = d3d->effect;
  2582.  
  2583. if(d3d->hlsl_enable && d3dintf->post_fx_available)
  2584. {
  2585. (*d3dintf->effect.set_technique)(d3d->effect, "TestTechnique");
  2586. (*d3dintf->effect.set_technique)(d3d->post_effect, "ScanMaskTechnique");
  2587. (*d3dintf->effect.set_technique)(d3d->pincushion_effect, "TestTechnique");
  2588. (*d3dintf->effect.set_technique)(d3d->phosphor_effect, "TestTechnique");
  2589. (*d3dintf->effect.set_technique)(d3d->focus_effect, "TestTechnique");
  2590. (*d3dintf->effect.set_technique)(d3d->deconverge_effect, "DeconvergeTechnique");
  2591. (*d3dintf->effect.set_technique)(d3d->color_effect, "ColorTechnique");
  2592. (*d3dintf->effect.set_technique)(d3d->yiq_encode_effect, "EncodeTechnique");
  2593. (*d3dintf->effect.set_technique)(d3d->yiq_decode_effect, "DecodeTechnique");
  2594. }
  2595.  
  2596. d3d_surface *backbuffer = NULL;
  2597. windows_options &winoptions = downcast<windows_options &>(d3d->window->machine().options());
  2598.  
  2599. // first remember the original render target in case we need to set a new one
  2600. if(d3d->hlsl_enable && d3dintf->post_fx_available)
  2601. {
  2602. result = (*d3dintf->device.get_render_target)(d3d->device, 0, &backbuffer);
  2603. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
  2604. vertnum = 4;
  2605. }
  2606. else
  2607. {
  2608. vertnum = 0;
  2609. }
  2610.  
  2611. d3d_options *options = d3d->hlsl_options;
  2612.  
  2613. int cur_render_screen = 0;
  2614. // now do the polys
  2615. for (polynum = 0; polynum < d3d->numpolys; polynum++)
  2616. {
  2617. poly_info *poly = &d3d->poly[polynum];
  2618. int newfilter;
  2619.  
  2620. // set the texture if different
  2621. set_texture(d3d, poly->texture);
  2622.  
  2623. // set filtering if different
  2624. if (poly->texture != NULL)
  2625. {
  2626. newfilter = FALSE;
  2627. if (PRIMFLAG_GET_SCREENTEX(poly->flags))
  2628. newfilter = video_config.filter;
  2629. set_filter(d3d, newfilter);
  2630. set_wrap(d3d, PRIMFLAG_GET_TEXWRAP(poly->flags));
  2631. set_modmode(d3d, poly->modmode);
  2632.  
  2633. if(d3d->hlsl_enable && d3dintf->post_fx_available)
  2634. {
  2635. if(PRIMFLAG_GET_TEXSHADE(d3d->last_texture_flags))
  2636. {
  2637. curr_effect = d3d->pincushion_effect;
  2638. }
  2639. else if(PRIMFLAG_GET_SCREENTEX(d3d->last_texture_flags) && poly->texture != NULL)
  2640. {
  2641. // Plug in all of the shader settings we're going to need
  2642. // This is extremely slow, but we're not rendering models here,
  2643. // just post-processing.
  2644. curr_effect = d3d->post_effect;
  2645.  
  2646. (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth);
  2647. (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight);
  2648. (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", 1.0f / (poly->texture->ustop - poly->texture->ustart));
  2649. (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", 1.0f / (poly->texture->vstop - poly->texture->vstart));
  2650. (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
  2651. (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
  2652. (*d3dintf->effect.set_float)(curr_effect, "PincushionAmount", options->screen_pincushion);
  2653. (*d3dintf->effect.set_float)(curr_effect, "CurvatureAmount", options->screen_curvature);
  2654. (*d3dintf->effect.set_float)(curr_effect, "UseShadow", d3d->shadow_texture == NULL ? 0.0f : 1.0f);
  2655. (*d3dintf->effect.set_texture)(curr_effect, "Shadow", d3d->shadow_texture == NULL ? NULL : d3d->shadow_texture->d3dfinaltex);
  2656. (*d3dintf->effect.set_float)(curr_effect, "ShadowBrightness", options->screen_shadow_mask_alpha);
  2657. (*d3dintf->effect.set_float)(curr_effect, "ShadowMaskSizeX", (float)options->screen_shadow_mask_count_x);
  2658. (*d3dintf->effect.set_float)(curr_effect, "ShadowMaskSizeY", (float)options->screen_shadow_mask_count_y);
  2659. (*d3dintf->effect.set_float)(curr_effect, "ShadowU", options->screen_shadow_mask_u_size);
  2660. (*d3dintf->effect.set_float)(curr_effect, "ShadowV", options->screen_shadow_mask_v_size);
  2661. (*d3dintf->effect.set_float)(curr_effect, "ShadowWidth", d3d->shadow_texture == NULL ? 1.0f : (float)d3d->shadow_texture->rawwidth);
  2662. (*d3dintf->effect.set_float)(curr_effect, "ShadowHeight", d3d->shadow_texture == NULL ? 1.0f : (float)d3d->shadow_texture->rawheight);
  2663. (*d3dintf->effect.set_float)(curr_effect, "ScanlineAmount", options->screen_scanline_alpha);
  2664. (*d3dintf->effect.set_float)(curr_effect, "ScanlineScale", options->screen_scanline_scale);
  2665. (*d3dintf->effect.set_float)(curr_effect, "ScanlineBrightScale", options->screen_scanline_bright_scale);
  2666. (*d3dintf->effect.set_float)(curr_effect, "ScanlineBrightOffset", options->screen_scanline_bright_offset);
  2667. (*d3dintf->effect.set_float)(curr_effect, "ScanlineOffset", (poly->texture->cur_frame == 0) ? 0.0f : options->screen_scanline_offset);
  2668. }
  2669. else
  2670. {
  2671. curr_effect = d3d->effect;
  2672.  
  2673. (*d3dintf->effect.set_float)(curr_effect, "FixedAlpha", 1.0f);
  2674. }
  2675. }
  2676. }
  2677.  
  2678. // set the blendmode if different
  2679. set_blendmode(d3d, PRIMFLAG_GET_BLENDMODE(poly->flags));
  2680.  
  2681. if(d3d->hlsl_enable && d3dintf->post_fx_available)
  2682. {
  2683. assert(vertnum + poly->numverts <= d3d->numverts);
  2684.  
  2685. UINT num_passes = 0;
  2686.  
  2687. if(PRIMFLAG_GET_SCREENTEX(d3d->last_texture_flags) && poly->texture != NULL)
  2688. {
  2689. if(d3d->yiq_enable)
  2690. {
  2691. /* Convert our signal into YIQ */
  2692. curr_effect = d3d->yiq_encode_effect;
  2693.  
  2694. (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth);
  2695. (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight);
  2696. (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", 1.0f / (poly->texture->ustop - poly->texture->ustart));
  2697. (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", 1.0f / (poly->texture->vstop - poly->texture->vstart));
  2698. (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
  2699. (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
  2700. (*d3dintf->effect.set_float)(curr_effect, "WValue", winoptions.screen_yiq_w());
  2701. (*d3dintf->effect.set_float)(curr_effect, "AValue", winoptions.screen_yiq_a());
  2702. (*d3dintf->effect.set_float)(curr_effect, "BValue", (float)poly->texture->cur_frame * winoptions.screen_yiq_b());
  2703. (*d3dintf->effect.set_float)(curr_effect, "FscScale", winoptions.screen_yiq_fsc_scale());
  2704. (*d3dintf->effect.set_float)(curr_effect, "FscValue", winoptions.screen_yiq_fsc());
  2705.  
  2706. result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget4);
  2707.  
  2708. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
  2709. result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
  2710. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
  2711.  
  2712. (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
  2713.  
  2714. for (UINT pass = 0; pass < num_passes; pass++)
  2715. {
  2716. (*d3dintf->effect.begin_pass)(curr_effect, pass);
  2717. // add the primitives
  2718. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, 0, poly->count);
  2719. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  2720. (*d3dintf->effect.end_pass)(curr_effect);
  2721. }
  2722.  
  2723. (*d3dintf->effect.end)(curr_effect);
  2724.  
  2725. /* Convert our signal from YIQ */
  2726. curr_effect = d3d->yiq_decode_effect;
  2727.  
  2728. (*d3dintf->effect.set_texture)(curr_effect, "Composite", poly->texture->d3dtexture4);
  2729. (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dfinaltex);
  2730. (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth);
  2731. (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight);
  2732. (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", 1.0f / (poly->texture->ustop - poly->texture->ustart));
  2733. (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", 1.0f / (poly->texture->vstop - poly->texture->vstart));
  2734. (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
  2735. (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
  2736. (*d3dintf->effect.set_float)(curr_effect, "WValue", winoptions.screen_yiq_w());
  2737. (*d3dintf->effect.set_float)(curr_effect, "AValue", winoptions.screen_yiq_a());
  2738. (*d3dintf->effect.set_float)(curr_effect, "BValue", (float)poly->texture->cur_frame * winoptions.screen_yiq_b());
  2739. (*d3dintf->effect.set_float)(curr_effect, "FscValue", winoptions.screen_yiq_fsc());
  2740.  
  2741. result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget3);
  2742.  
  2743. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
  2744. result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
  2745. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
  2746.  
  2747. (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
  2748.  
  2749. for (UINT pass = 0; pass < num_passes; pass++)
  2750. {
  2751. (*d3dintf->effect.begin_pass)(curr_effect, pass);
  2752. // add the primitives
  2753. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, 0, poly->count);
  2754. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  2755. (*d3dintf->effect.end_pass)(curr_effect);
  2756. }
  2757.  
  2758. (*d3dintf->effect.end)(curr_effect);
  2759.  
  2760. curr_effect = d3d->color_effect;
  2761.  
  2762. (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture3);
  2763. }
  2764.  
  2765. curr_effect = d3d->color_effect;
  2766.  
  2767. /* Render the initial color-convolution pass */
  2768. (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth);
  2769. (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight);
  2770. (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", d3d->yiq_enable ? 1.0f : (1.0f / (poly->texture->ustop - poly->texture->ustart)));
  2771. (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", d3d->yiq_enable ? 1.0f : (1.0f / (poly->texture->vstop - poly->texture->vstart)));
  2772. (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
  2773. (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
  2774. (*d3dintf->effect.set_float)(curr_effect, "YIQEnable", d3d->yiq_enable ? 1.0f : 0.0f);
  2775. (*d3dintf->effect.set_float)(curr_effect, "RedFromRed", options->screen_red_from_red);
  2776. (*d3dintf->effect.set_float)(curr_effect, "RedFromGrn", options->screen_red_from_green);
  2777. (*d3dintf->effect.set_float)(curr_effect, "RedFromBlu", options->screen_red_from_blue);
  2778. (*d3dintf->effect.set_float)(curr_effect, "GrnFromRed", options->screen_green_from_red);
  2779. (*d3dintf->effect.set_float)(curr_effect, "GrnFromGrn", options->screen_green_from_green);
  2780. (*d3dintf->effect.set_float)(curr_effect, "GrnFromBlu", options->screen_green_from_blue);
  2781. (*d3dintf->effect.set_float)(curr_effect, "BluFromRed", options->screen_blue_from_red);
  2782. (*d3dintf->effect.set_float)(curr_effect, "BluFromGrn", options->screen_blue_from_green);
  2783. (*d3dintf->effect.set_float)(curr_effect, "BluFromBlu", options->screen_blue_from_blue);
  2784. (*d3dintf->effect.set_float)(curr_effect, "RedOffset", options->screen_red_offset);
  2785. (*d3dintf->effect.set_float)(curr_effect, "GrnOffset", options->screen_green_offset);
  2786. (*d3dintf->effect.set_float)(curr_effect, "BluOffset", options->screen_blue_offset);
  2787. (*d3dintf->effect.set_float)(curr_effect, "RedScale", options->screen_red_scale);
  2788. (*d3dintf->effect.set_float)(curr_effect, "GrnScale", options->screen_green_scale);
  2789. (*d3dintf->effect.set_float)(curr_effect, "BluScale", options->screen_blue_scale);
  2790. (*d3dintf->effect.set_float)(curr_effect, "RedPower", options->screen_red_power);
  2791. (*d3dintf->effect.set_float)(curr_effect, "GrnPower", options->screen_green_power);
  2792. (*d3dintf->effect.set_float)(curr_effect, "BluPower", options->screen_blue_power);
  2793. (*d3dintf->effect.set_float)(curr_effect, "RedFloor", options->screen_red_floor);
  2794. (*d3dintf->effect.set_float)(curr_effect, "GrnFloor", options->screen_green_floor);
  2795. (*d3dintf->effect.set_float)(curr_effect, "BluFloor", options->screen_blue_floor);
  2796. (*d3dintf->effect.set_float)(curr_effect, "Saturation", options->screen_saturation);
  2797.  
  2798. result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dsmalltarget0);
  2799.  
  2800. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call\n", (int)result);
  2801. result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
  2802. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
  2803.  
  2804. (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
  2805.  
  2806. for (UINT pass = 0; pass < num_passes; pass++)
  2807. {
  2808. (*d3dintf->effect.begin_pass)(curr_effect, pass);
  2809. // add the primitives
  2810. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, 0, poly->count);
  2811. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  2812. (*d3dintf->effect.end_pass)(curr_effect);
  2813. }
  2814.  
  2815. (*d3dintf->effect.end)(curr_effect);
  2816.  
  2817. /* Deconverge pass */
  2818. curr_effect = d3d->deconverge_effect;
  2819. (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dsmalltexture0);
  2820.  
  2821. (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
  2822. (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
  2823. (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth);
  2824. (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight);
  2825. (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", 1.0f / (poly->texture->ustop - poly->texture->ustart));
  2826. (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", 1.0f / (poly->texture->vstop - poly->texture->vstart));
  2827. (*d3dintf->effect.set_float)(curr_effect, "RedConvergeX", options->screen_red_converge_x);
  2828. (*d3dintf->effect.set_float)(curr_effect, "RedConvergeY", options->screen_red_converge_y);
  2829. (*d3dintf->effect.set_float)(curr_effect, "GrnConvergeX", options->screen_green_converge_x);
  2830. (*d3dintf->effect.set_float)(curr_effect, "GrnConvergeY", options->screen_green_converge_y);
  2831. (*d3dintf->effect.set_float)(curr_effect, "BluConvergeX", options->screen_blue_converge_x);
  2832. (*d3dintf->effect.set_float)(curr_effect, "BluConvergeY", options->screen_blue_converge_y);
  2833. (*d3dintf->effect.set_float)(curr_effect, "RedRadialConvergeX", options->screen_red_radial_converge_x);
  2834. (*d3dintf->effect.set_float)(curr_effect, "RedRadialConvergeY", options->screen_red_radial_converge_y);
  2835. (*d3dintf->effect.set_float)(curr_effect, "GrnRadialConvergeX", options->screen_green_radial_converge_x);
  2836. (*d3dintf->effect.set_float)(curr_effect, "GrnRadialConvergeY", options->screen_green_radial_converge_y);
  2837. (*d3dintf->effect.set_float)(curr_effect, "BluRadialConvergeX", options->screen_blue_radial_converge_x);
  2838. (*d3dintf->effect.set_float)(curr_effect, "BluRadialConvergeY", options->screen_blue_radial_converge_y);
  2839.  
  2840. (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
  2841.  
  2842. result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget2);
  2843. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
  2844. result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
  2845. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
  2846.  
  2847. for (UINT pass = 0; pass < num_passes; pass++)
  2848. {
  2849. (*d3dintf->effect.begin_pass)(curr_effect, pass);
  2850. // add the primitives
  2851. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, 0, poly->count);
  2852. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  2853. (*d3dintf->effect.end_pass)(curr_effect);
  2854. }
  2855.  
  2856. (*d3dintf->effect.end)(curr_effect);
  2857.  
  2858. float defocus_x = options->screen_defocus_x;
  2859. float defocus_y = options->screen_defocus_y;
  2860. bool focus_enable = defocus_x != 0.0f || defocus_y != 0.0f;
  2861. if(focus_enable)
  2862. {
  2863. /* Defocus pass 1 */
  2864. curr_effect = d3d->focus_effect;
  2865.  
  2866. (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture2);
  2867.  
  2868. (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
  2869. (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
  2870. (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth);
  2871. (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight);
  2872. (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", poly->texture != NULL ? (1.0f / (poly->texture->ustop - poly->texture->ustart)) : 0.0f);
  2873. (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", poly->texture != NULL ? (1.0f / (poly->texture->vstop - poly->texture->vstart)) : 0.0f);
  2874. (*d3dintf->effect.set_float)(curr_effect, "DefocusX", defocus_x);
  2875. (*d3dintf->effect.set_float)(curr_effect, "DefocusY", defocus_y);
  2876. (*d3dintf->effect.set_float)(curr_effect, "FocusEnable", (defocus_x == 0.0f && defocus_y == 0.0f) ? 0.0f : 1.0f);
  2877.  
  2878. (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
  2879.  
  2880. result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget0);
  2881. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 6\n", (int)result);
  2882. result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
  2883. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
  2884.  
  2885. for (UINT pass = 0; pass < num_passes; pass++)
  2886. {
  2887. (*d3dintf->effect.begin_pass)(curr_effect, pass);
  2888. // add the primitives
  2889. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, 0, poly->count);
  2890. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  2891. (*d3dintf->effect.end_pass)(curr_effect);
  2892. }
  2893.  
  2894. (*d3dintf->effect.end)(curr_effect);
  2895.  
  2896. /* Defocus pass 2 */
  2897.  
  2898. (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture0);
  2899.  
  2900. (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
  2901. (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
  2902. (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth);
  2903. (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight);
  2904. (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", 1.0f);
  2905. (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", 1.0f);
  2906. (*d3dintf->effect.set_float)(curr_effect, "DefocusX", defocus_x);
  2907. (*d3dintf->effect.set_float)(curr_effect, "DefocusY", defocus_y);
  2908. (*d3dintf->effect.set_float)(curr_effect, "FocusEnable", (defocus_x == 0.0f && defocus_y == 0.0f) ? 0.0f : 1.0f);
  2909.  
  2910. (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
  2911.  
  2912. result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget1);
  2913. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 7\n", (int)result);
  2914.  
  2915. for (UINT pass = 0; pass < num_passes; pass++)
  2916. {
  2917. (*d3dintf->effect.begin_pass)(curr_effect, pass);
  2918. // add the primitives
  2919. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, 0, poly->count);
  2920. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  2921. (*d3dintf->effect.end_pass)(curr_effect);
  2922. }
  2923.  
  2924. (*d3dintf->effect.end)(curr_effect);
  2925. }
  2926.  
  2927. // Simulate phosphorescence. This should happen after the shadow/scanline pass, but since
  2928. // the phosphors are a direct result of the incoming texture, might as well just change the
  2929. // input texture.
  2930. curr_effect = d3d->phosphor_effect;
  2931.  
  2932. (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
  2933. (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
  2934. (*d3dintf->effect.set_float)(curr_effect, "RawWidth", (float)poly->texture->rawwidth);
  2935. (*d3dintf->effect.set_float)(curr_effect, "RawHeight", (float)poly->texture->rawheight);
  2936. (*d3dintf->effect.set_float)(curr_effect, "RedPhosphor", options->screen_red_phosphor_life);
  2937. (*d3dintf->effect.set_float)(curr_effect, "GreenPhosphor", options->screen_green_phosphor_life);
  2938. (*d3dintf->effect.set_float)(curr_effect, "BluePhosphor", options->screen_blue_phosphor_life);
  2939.  
  2940. (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", focus_enable ? poly->texture->d3dtexture1 : poly->texture->d3dtexture2);
  2941. (*d3dintf->effect.set_texture)(curr_effect, "LastPass", d3d->last_d3dtexture[cur_render_screen]);
  2942.  
  2943. result = (*d3dintf->device.set_render_target)(d3d->device, 0, poly->texture->d3dtarget0);
  2944. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 4\n", (int)result);
  2945. result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
  2946. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
  2947.  
  2948. (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
  2949.  
  2950. for (UINT pass = 0; pass < num_passes; pass++)
  2951. {
  2952. (*d3dintf->effect.begin_pass)(curr_effect, pass);
  2953. // add the primitives
  2954. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, 0, poly->count);
  2955. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  2956. (*d3dintf->effect.end_pass)(curr_effect);
  2957. }
  2958.  
  2959. (*d3dintf->effect.end)(curr_effect);
  2960.  
  2961. /* Pass along our phosphor'd screen */
  2962. curr_effect = d3d->phosphor_effect;
  2963.  
  2964. (*d3dintf->effect.set_float)(curr_effect, "FixedAlpha", 1.0f);
  2965.  
  2966. (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", focus_enable ? poly->texture->d3dtexture1 : poly->texture->d3dtexture2);
  2967. (*d3dintf->effect.set_texture)(curr_effect, "LastPass", focus_enable ? poly->texture->d3dtexture1 : poly->texture->d3dtexture2);
  2968.  
  2969. result = (*d3dintf->device.set_render_target)(d3d->device, 0, d3d->last_d3dtarget[cur_render_screen++]);
  2970. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 5\n", (int)result);
  2971. result = (*d3dintf->device.clear)(d3d->device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(0,0,0,0), 0, 0);
  2972. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device clear call\n", (int)result);
  2973.  
  2974. (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
  2975.  
  2976. for (UINT pass = 0; pass < num_passes; pass++)
  2977. {
  2978. (*d3dintf->effect.begin_pass)(curr_effect, pass);
  2979. // add the primitives
  2980. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, 0, poly->count);
  2981. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  2982. (*d3dintf->effect.end_pass)(curr_effect);
  2983. }
  2984.  
  2985. (*d3dintf->effect.end)(curr_effect);
  2986.  
  2987. /* Scanlines and shadow mask */
  2988. curr_effect = d3d->post_effect;
  2989.  
  2990. (*d3dintf->effect.set_texture)(curr_effect, "Diffuse", poly->texture->d3dtexture0);
  2991.  
  2992. result = (*d3dintf->device.set_render_target)(d3d->device, 0, backbuffer);
  2993. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 5\n", (int)result);
  2994.  
  2995. (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
  2996.  
  2997. for (UINT pass = 0; pass < num_passes; pass++)
  2998. {
  2999. (*d3dintf->effect.begin_pass)(curr_effect, pass);
  3000. // add the primitives
  3001. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, vertnum, poly->count);
  3002. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  3003. (*d3dintf->effect.end_pass)(curr_effect);
  3004. }
  3005.  
  3006. (*d3dintf->effect.end)(curr_effect);
  3007.  
  3008. poly->texture->cur_frame++;
  3009. poly->texture->cur_frame %= winoptions.screen_yiq_phase_count();
  3010. }
  3011. else
  3012. {
  3013. (*d3dintf->effect.set_float)(curr_effect, "RawWidth", poly->texture != NULL ? (float)poly->texture->rawwidth : 8.0f);
  3014. (*d3dintf->effect.set_float)(curr_effect, "RawHeight", poly->texture != NULL ? (float)poly->texture->rawheight : 8.0f);
  3015. (*d3dintf->effect.set_float)(curr_effect, "WidthRatio", poly->texture != NULL ? (1.0f / (poly->texture->ustop - poly->texture->ustart)) : 0.0f);
  3016. (*d3dintf->effect.set_float)(curr_effect, "HeightRatio", poly->texture != NULL ? (1.0f / (poly->texture->vstop - poly->texture->vstart)) : 0.0f);
  3017. (*d3dintf->effect.set_float)(curr_effect, "TargetWidth", (float)d3d->width);
  3018. (*d3dintf->effect.set_float)(curr_effect, "TargetHeight", (float)d3d->height);
  3019. (*d3dintf->effect.set_float)(curr_effect, "PostPass", 0.0f);
  3020. (*d3dintf->effect.set_float)(curr_effect, "PincushionAmountX", options->screen_pincushion);
  3021. (*d3dintf->effect.set_float)(curr_effect, "PincushionAmountY", options->screen_pincushion);
  3022.  
  3023. (*d3dintf->effect.begin)(curr_effect, &num_passes, 0);
  3024.  
  3025. for (UINT pass = 0; pass < num_passes; pass++)
  3026. {
  3027. (*d3dintf->effect.begin_pass)(curr_effect, pass);
  3028. // add the primitives
  3029. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, vertnum, poly->count);
  3030. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  3031. (*d3dintf->effect.end_pass)(curr_effect);
  3032. }
  3033.  
  3034. (*d3dintf->effect.end)(curr_effect);
  3035. }
  3036. }
  3037. else
  3038. {
  3039. assert(vertnum + poly->numverts <= d3d->numverts);
  3040.  
  3041. // add the primitives
  3042. result = (*d3dintf->device.draw_primitive)(d3d->device, poly->type, vertnum, poly->count);
  3043. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  3044. }
  3045.  
  3046. vertnum += poly->numverts;
  3047. }
  3048.  
  3049. if(d3d->hlsl_enable && d3dintf->post_fx_available)
  3050. {
  3051. (*d3dintf->surface.release)(backbuffer);
  3052. }
  3053.  
  3054. // reset the vertex count
  3055. d3d->numverts = 0;
  3056. d3d->numpolys = 0;
  3057. }
  3058.  
  3059.  
  3060.  
  3061. //============================================================
  3062. // texture_create
  3063. //============================================================
  3064.  
  3065. static texture_info *texture_create(d3d_info *d3d, const render_texinfo *texsource, UINT32 flags)
  3066. {
  3067. texture_info *texture;
  3068. HRESULT result;
  3069.  
  3070. // allocate a new texture
  3071. texture = global_alloc_clear(texture_info);
  3072.  
  3073. // fill in the core data
  3074. texture->hash = texture_compute_hash(texsource, flags);
  3075. texture->flags = flags;
  3076. texture->texinfo = *texsource;
  3077. texture->xprescale = video_config.prescale;
  3078. texture->yprescale = video_config.prescale;
  3079.  
  3080. // compute the size
  3081. texture_compute_size(d3d, texsource->width, texsource->height, texture);
  3082.  
  3083. d3d->oversample_x = downcast<windows_options &>(d3d->window->machine().options()).screen_oversample_x();
  3084. d3d->oversample_y = downcast<windows_options &>(d3d->window->machine().options()).screen_oversample_y();
  3085.  
  3086. // non-screen textures are easy
  3087. if (!PRIMFLAG_GET_SCREENTEX(flags))
  3088. {
  3089. assert(PRIMFLAG_TEXFORMAT(flags) != TEXFORMAT_YUY16);
  3090. result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture->d3dtex);
  3091. if (result != D3D_OK)
  3092. goto error;
  3093. texture->d3dfinaltex = texture->d3dtex;
  3094. texture->type = TEXTURE_TYPE_PLAIN;
  3095. }
  3096.  
  3097. // screen textures are allocated differently
  3098. else
  3099. {
  3100. D3DFORMAT format;
  3101. DWORD usage = d3d->dynamic_supported ? D3DUSAGE_DYNAMIC : 0;
  3102. D3DPOOL pool = d3d->dynamic_supported ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
  3103. int maxdim = MAX(d3d->presentation.BackBufferWidth, d3d->presentation.BackBufferHeight);
  3104. int attempt;
  3105.  
  3106. // pick the format
  3107. if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_YUY16)
  3108. format = d3d->yuv_format;
  3109. else if (PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_ARGB32 || PRIMFLAG_GET_TEXFORMAT(flags) == TEXFORMAT_PALETTEA16)
  3110. format = D3DFMT_A8R8G8B8;
  3111. else
  3112. format = d3d->screen_format;
  3113.  
  3114. // don't prescale above screen size
  3115. while (texture->xprescale > 1 && texture->rawwidth * texture->xprescale >= 2 * maxdim)
  3116. texture->xprescale--;
  3117. while (texture->xprescale > 1 && texture->rawwidth * texture->xprescale > d3d->texture_max_width)
  3118. texture->xprescale--;
  3119. while (texture->yprescale > 1 && texture->rawheight * texture->yprescale >= 2 * maxdim)
  3120. texture->yprescale--;
  3121. while (texture->yprescale > 1 && texture->rawheight * texture->yprescale > d3d->texture_max_height)
  3122. texture->yprescale--;
  3123. if (texture->xprescale != video_config.prescale || texture->yprescale != video_config.prescale)
  3124. mame_printf_verbose("Direct3D: adjusting prescale from %dx%d to %dx%d\n", video_config.prescale, video_config.prescale, texture->xprescale, texture->yprescale);
  3125.  
  3126. // loop until we allocate something or error
  3127. for (attempt = 0; attempt < 2; attempt++)
  3128. {
  3129. // second attempt is always 1:1
  3130. if (attempt == 1)
  3131. texture->xprescale = texture->yprescale = 1;
  3132.  
  3133. // screen textures with no prescaling are pretty easy
  3134. if (texture->xprescale == 1 && texture->yprescale == 1)
  3135. {
  3136. result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, usage, format, pool, &texture->d3dtex);
  3137. if (result == D3D_OK)
  3138. {
  3139. texture->d3dfinaltex = texture->d3dtex;
  3140. texture->type = d3d->dynamic_supported ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
  3141.  
  3142. if(d3d->hlsl_enable && d3dintf->post_fx_available)
  3143. {
  3144. result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture0);
  3145. if (result != D3D_OK)
  3146. goto error;
  3147. (*d3dintf->texture.get_surface_level)(texture->d3dtexture0, 0, &texture->d3dtarget0);
  3148.  
  3149. result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->last_d3dtexture[d3d->registered_targets]);
  3150. if (result != D3D_OK)
  3151. goto error;
  3152. (*d3dintf->texture.get_surface_level)(d3d->last_d3dtexture[d3d->registered_targets], 0, &d3d->last_d3dtarget[d3d->registered_targets]);
  3153.  
  3154. result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture1);
  3155. if (result != D3D_OK)
  3156. goto error;
  3157. (*d3dintf->texture.get_surface_level)(texture->d3dtexture1, 0, &texture->d3dtarget1);
  3158.  
  3159. result = (*d3dintf->device.create_texture)(d3d->device, (int)(d3d->width * d3d->oversample_x), (int)(d3d->height * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture2);
  3160. if (result != D3D_OK)
  3161. goto error;
  3162. (*d3dintf->texture.get_surface_level)(texture->d3dtexture2, 0, &texture->d3dtarget2);
  3163.  
  3164. result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture3);
  3165. if (result != D3D_OK)
  3166. goto error;
  3167. (*d3dintf->texture.get_surface_level)(texture->d3dtexture3, 0, &texture->d3dtarget3);
  3168.  
  3169. result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture4);
  3170. if (result != D3D_OK)
  3171. goto error;
  3172. (*d3dintf->texture.get_surface_level)(texture->d3dtexture4, 0, &texture->d3dtarget4);
  3173.  
  3174. result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dsmalltexture0);
  3175. if (result != D3D_OK)
  3176. goto error;
  3177. (*d3dintf->texture.get_surface_level)(texture->d3dsmalltexture0, 0, &texture->d3dsmalltarget0);
  3178.  
  3179. d3d->registered_targets++;
  3180. }
  3181.  
  3182. break;
  3183. }
  3184. }
  3185.  
  3186. // screen textures with prescaling require two allocations
  3187. else
  3188. {
  3189. int scwidth, scheight;
  3190. D3DFORMAT finalfmt;
  3191.  
  3192. // use an offscreen plain surface for stretching if supported
  3193. // (won't work for YUY textures)
  3194. if (d3d->stretch_supported && PRIMFLAG_GET_TEXFORMAT(flags) != TEXFORMAT_YUY16)
  3195. {
  3196. result = (*d3dintf->device.create_offscreen_plain_surface)(d3d->device, texture->rawwidth, texture->rawheight, format, D3DPOOL_DEFAULT, &texture->d3dsurface);
  3197. if (result != D3D_OK)
  3198. continue;
  3199. texture->type = TEXTURE_TYPE_SURFACE;
  3200. }
  3201.  
  3202. // otherwise, we allocate a dynamic texture for the source
  3203. else
  3204. {
  3205. result = (*d3dintf->device.create_texture)(d3d->device, texture->rawwidth, texture->rawheight, 1, usage, format, pool, &texture->d3dtex);
  3206. if (result != D3D_OK)
  3207. continue;
  3208. texture->type = d3d->dynamic_supported ? TEXTURE_TYPE_DYNAMIC : TEXTURE_TYPE_PLAIN;
  3209. }
  3210.  
  3211. // for the target surface, we allocate a render target texture
  3212. scwidth = texture->rawwidth * texture->xprescale;
  3213. scheight = texture->rawheight * texture->yprescale;
  3214.  
  3215. // target surfaces typically cannot be YCbCr, so we always pick RGB in that case
  3216. finalfmt = (format != d3d->yuv_format) ? format : D3DFMT_A8R8G8B8;
  3217. result = (*d3dintf->device.create_texture)(d3d->device, scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, finalfmt, D3DPOOL_DEFAULT, &texture->d3dfinaltex);
  3218. if (result == D3D_OK)
  3219. {
  3220. if(d3d->hlsl_enable && d3dintf->post_fx_available)
  3221. {
  3222. result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture0);
  3223. if (result != D3D_OK)
  3224. goto error;
  3225. (*d3dintf->texture.get_surface_level)(texture->d3dtexture0, 0, &texture->d3dtarget0);
  3226.  
  3227. result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &d3d->last_d3dtexture[d3d->registered_targets]);
  3228. if (result != D3D_OK)
  3229. goto error;
  3230. (*d3dintf->texture.get_surface_level)(d3d->last_d3dtexture[d3d->registered_targets], 0, &d3d->last_d3dtarget[d3d->registered_targets]);
  3231. d3d->registered_targets++;
  3232.  
  3233. result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture1);
  3234. if (result != D3D_OK)
  3235. goto error;
  3236. (*d3dintf->texture.get_surface_level)(texture->d3dtexture1, 0, &texture->d3dtarget1);
  3237.  
  3238. result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture2);
  3239. if (result != D3D_OK)
  3240. goto error;
  3241. (*d3dintf->texture.get_surface_level)(texture->d3dtexture2, 0, &texture->d3dtarget2);
  3242.  
  3243. result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture3);
  3244. if (result != D3D_OK)
  3245. goto error;
  3246. (*d3dintf->texture.get_surface_level)(texture->d3dtexture3, 0, &texture->d3dtarget3);
  3247.  
  3248. result = (*d3dintf->device.create_texture)(d3d->device, (int)(scwidth * d3d->oversample_x), (int)(scheight * d3d->oversample_y), 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dtexture4);
  3249. if (result != D3D_OK)
  3250. goto error;
  3251. (*d3dintf->texture.get_surface_level)(texture->d3dtexture4, 0, &texture->d3dtarget4);
  3252.  
  3253. result = (*d3dintf->device.create_texture)(d3d->device, scwidth, scheight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &texture->d3dsmalltexture0);
  3254. if (result != D3D_OK)
  3255. goto error;
  3256. (*d3dintf->texture.get_surface_level)(texture->d3dsmalltexture0, 0, &texture->d3dsmalltarget0);
  3257. }
  3258. break;
  3259. }
  3260. (*d3dintf->texture.release)(texture->d3dtex);
  3261. texture->d3dtex = NULL;
  3262. }
  3263. }
  3264. }
  3265.  
  3266. // copy the data to the texture
  3267. texture_set_data(d3d, texture, texsource, flags);
  3268.  
  3269. // add us to the texture list
  3270. texture->next = d3d->texlist;
  3271. d3d->texlist = texture;
  3272. return texture;
  3273.  
  3274. error:
  3275. d3dintf->post_fx_available = false;
  3276. mame_printf_verbose("Direct3D: Critical warning: A texture failed to allocate. Expect things to get bad quickly.\n");
  3277. if (texture->d3dsurface != NULL)
  3278. (*d3dintf->surface.release)(texture->d3dsurface);
  3279. if (texture->d3dtex != NULL)
  3280. (*d3dintf->texture.release)(texture->d3dtex);
  3281. global_free(texture);
  3282. return NULL;
  3283. }
  3284.  
  3285.  
  3286.  
  3287. //============================================================
  3288. // texture_compute_size
  3289. //============================================================
  3290.  
  3291. static void texture_compute_size(d3d_info *d3d, int texwidth, int texheight, texture_info *texture)
  3292. {
  3293. int finalheight = texheight;
  3294. int finalwidth = texwidth;
  3295.  
  3296. // if we're not wrapping, add a 1-2 pixel border on all sides
  3297. texture->xborderpix = 0;
  3298. texture->yborderpix = 0;
  3299. if (ENABLE_BORDER_PIX && !(texture->flags & PRIMFLAG_TEXWRAP_MASK))
  3300. {
  3301. // note we need 2 pixels in X for YUY textures
  3302. texture->xborderpix = (PRIMFLAG_GET_TEXFORMAT(texture->flags) == TEXFORMAT_YUY16) ? 2 : 1;
  3303. texture->yborderpix = 1;
  3304. }
  3305.  
  3306. // compute final texture size
  3307. finalwidth += 2 * texture->xborderpix;
  3308. finalheight += 2 * texture->yborderpix;
  3309.  
  3310. // round width/height up to nearest power of 2 if we need to
  3311. if (!(d3d->texture_caps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL))
  3312. {
  3313. // first the width
  3314. if (finalwidth & (finalwidth - 1))
  3315. {
  3316. finalwidth |= finalwidth >> 1;
  3317. finalwidth |= finalwidth >> 2;
  3318. finalwidth |= finalwidth >> 4;
  3319. finalwidth |= finalwidth >> 8;
  3320. finalwidth++;
  3321. }
  3322.  
  3323. // then the height
  3324. if (finalheight & (finalheight - 1))
  3325. {
  3326. finalheight |= finalheight >> 1;
  3327. finalheight |= finalheight >> 2;
  3328. finalheight |= finalheight >> 4;
  3329. finalheight |= finalheight >> 8;
  3330. finalheight++;
  3331. }
  3332. }
  3333.  
  3334. // round up to square if we need to
  3335. if (d3d->texture_caps & D3DPTEXTURECAPS_SQUAREONLY)
  3336. {
  3337. if (finalwidth < finalheight)
  3338. finalwidth = finalheight;
  3339. else
  3340. finalheight = finalwidth;
  3341. }
  3342.  
  3343. // adjust the aspect ratio if we need to
  3344. while (finalwidth < finalheight && finalheight / finalwidth > d3d->texture_max_aspect)
  3345. finalwidth *= 2;
  3346. while (finalheight < finalwidth && finalwidth / finalheight > d3d->texture_max_aspect)
  3347. finalheight *= 2;
  3348.  
  3349. // if we added pixels for the border, and that just barely pushed us over, take it back
  3350. if ((finalwidth > d3d->texture_max_width && finalwidth - 2 * texture->xborderpix <= d3d->texture_max_width) ||
  3351. (finalheight > d3d->texture_max_height && finalheight - 2 * texture->yborderpix <= d3d->texture_max_height))
  3352. {
  3353. finalwidth -= 2 * texture->xborderpix;
  3354. finalheight -= 2 * texture->yborderpix;
  3355. texture->xborderpix = 0;
  3356. texture->yborderpix = 0;
  3357. }
  3358.  
  3359. // if we're above the max width/height, do what?
  3360. if (finalwidth > d3d->texture_max_width || finalheight > d3d->texture_max_height)
  3361. {
  3362. static int printed = FALSE;
  3363. if (!printed) mame_printf_warning("Texture too big! (wanted: %dx%d, max is %dx%d)\n", finalwidth, finalheight, (int)d3d->texture_max_width, (int)d3d->texture_max_height);
  3364. printed = TRUE;
  3365. }
  3366.  
  3367. // compute the U/V scale factors
  3368. texture->ustart = (float)texture->xborderpix / (float)finalwidth;
  3369. texture->ustop = (float)(texwidth + texture->xborderpix) / (float)finalwidth;
  3370. texture->vstart = (float)texture->yborderpix / (float)finalheight;
  3371. texture->vstop = (float)(texheight + texture->yborderpix) / (float)finalheight;
  3372.  
  3373. // set the final values
  3374. texture->rawwidth = finalwidth;
  3375. texture->rawheight = finalheight;
  3376. }
  3377.  
  3378.  
  3379.  
  3380. //============================================================
  3381. // copyline_palette16
  3382. //============================================================
  3383.  
  3384. INLINE void copyline_palette16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
  3385. {
  3386. int x;
  3387.  
  3388. assert(xborderpix == 0 || xborderpix == 1);
  3389. if (xborderpix)
  3390. *dst++ = 0xff000000 | palette[*src];
  3391. for (x = 0; x < width; x++)
  3392. *dst++ = 0xff000000 | palette[*src++];
  3393. if (xborderpix)
  3394. *dst++ = 0xff000000 | palette[*--src];
  3395. }
  3396.  
  3397.  
  3398.  
  3399. //============================================================
  3400. // copyline_palettea16
  3401. //============================================================
  3402.  
  3403. INLINE void copyline_palettea16(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
  3404. {
  3405. int x;
  3406.  
  3407. assert(xborderpix == 0 || xborderpix == 1);
  3408. if (xborderpix)
  3409. *dst++ = palette[*src];
  3410. for (x = 0; x < width; x++)
  3411. *dst++ = palette[*src++];
  3412. if (xborderpix)
  3413. *dst++ = palette[*--src];
  3414. }
  3415.  
  3416.  
  3417.  
  3418. //============================================================
  3419. // copyline_rgb15
  3420. //============================================================
  3421.  
  3422. INLINE void copyline_rgb15(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
  3423. {
  3424. int x;
  3425.  
  3426. assert(xborderpix == 0 || xborderpix == 1);
  3427.  
  3428. // palette (really RGB map) case
  3429. if (palette != NULL)
  3430. {
  3431. if (xborderpix)
  3432. {
  3433. UINT16 pix = *src;
  3434. *dst++ = 0xff000000 | palette[0x40 + ((pix >> 10) & 0x1f)] | palette[0x20 + ((pix >> 5) & 0x1f)] | palette[0x00 + ((pix >> 0) & 0x1f)];
  3435. }
  3436. for (x = 0; x < width; x++)
  3437. {
  3438. UINT16 pix = *src++;
  3439. *dst++ = 0xff000000 | palette[0x40 + ((pix >> 10) & 0x1f)] | palette[0x20 + ((pix >> 5) & 0x1f)] | palette[0x00 + ((pix >> 0) & 0x1f)];
  3440. }
  3441. if (xborderpix)
  3442. {
  3443. UINT16 pix = *--src;
  3444. *dst++ = 0xff000000 | palette[0x40 + ((pix >> 10) & 0x1f)] | palette[0x20 + ((pix >> 5) & 0x1f)] | palette[0x00 + ((pix >> 0) & 0x1f)];
  3445. }
  3446. }
  3447.  
  3448. // direct case
  3449. else
  3450. {
  3451. if (xborderpix)
  3452. {
  3453. UINT16 pix = *src;
  3454. UINT32 color = ((pix & 0x7c00) << 9) | ((pix & 0x03e0) << 6) | ((pix & 0x001f) << 3);
  3455. *dst++ = 0xff000000 | color | ((color >> 5) & 0x070707);
  3456. }
  3457. for (x = 0; x < width; x++)
  3458. {
  3459. UINT16 pix = *src++;
  3460. UINT32 color = ((pix & 0x7c00) << 9) | ((pix & 0x03e0) << 6) | ((pix & 0x001f) << 3);
  3461. *dst++ = 0xff000000 | color | ((color >> 5) & 0x070707);
  3462. }
  3463. if (xborderpix)
  3464. {
  3465. UINT16 pix = *--src;
  3466. UINT32 color = ((pix & 0x7c00) << 9) | ((pix & 0x03e0) << 6) | ((pix & 0x001f) << 3);
  3467. *dst++ = 0xff000000 | color | ((color >> 5) & 0x070707);
  3468. }
  3469. }
  3470. }
  3471.  
  3472.  
  3473.  
  3474. //============================================================
  3475. // copyline_rgb32
  3476. //============================================================
  3477.  
  3478. INLINE void copyline_rgb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette, int xborderpix)
  3479. {
  3480. int x;
  3481.  
  3482. assert(xborderpix == 0 || xborderpix == 1);
  3483.  
  3484. // palette (really RGB map) case
  3485. if (palette != NULL)
  3486. {
  3487. if (xborderpix)
  3488. {
  3489. UINT32 srcpix = *src;
  3490. *dst++ = 0xff000000 | palette[0x200 + RGB_RED(srcpix)] | palette[0x100 + RGB_GREEN(srcpix)] | palette[RGB_BLUE(srcpix)];
  3491. }
  3492. for (x = 0; x < width; x++)
  3493. {
  3494. UINT32 srcpix = *src++;
  3495. *dst++ = 0xff000000 | palette[0x200 + RGB_RED(srcpix)] | palette[0x100 + RGB_GREEN(srcpix)] | palette[RGB_BLUE(srcpix)];
  3496. }
  3497. if (xborderpix)
  3498. {
  3499. UINT32 srcpix = *--src;
  3500. *dst++ = 0xff000000 | palette[0x200 + RGB_RED(srcpix)] | palette[0x100 + RGB_GREEN(srcpix)] | palette[RGB_BLUE(srcpix)];
  3501. }
  3502. }
  3503.  
  3504. // direct case
  3505. else
  3506. {
  3507. if (xborderpix)
  3508. *dst++ = 0xff000000 | *src;
  3509. for (x = 0; x < width; x++)
  3510. *dst++ = 0xff000000 | *src++;
  3511. if (xborderpix)
  3512. *dst++ = 0xff000000 | *--src;
  3513. }
  3514. }
  3515.  
  3516.  
  3517.  
  3518. //============================================================
  3519. // copyline_argb32
  3520. //============================================================
  3521.  
  3522. INLINE void copyline_argb32(UINT32 *dst, const UINT32 *src, int width, const rgb_t *palette, int xborderpix)
  3523. {
  3524. int x;
  3525.  
  3526. assert(xborderpix == 0 || xborderpix == 1);
  3527.  
  3528. // palette (really RGB map) case
  3529. if (palette != NULL)
  3530. {
  3531. if (xborderpix)
  3532. {
  3533. UINT32 srcpix = *src;
  3534. *dst++ = (srcpix & 0xff000000) | palette[0x200 + RGB_RED(srcpix)] | palette[0x100 + RGB_GREEN(srcpix)] | palette[RGB_BLUE(srcpix)];
  3535. }
  3536. for (x = 0; x < width; x++)
  3537. {
  3538. UINT32 srcpix = *src++;
  3539. *dst++ = (srcpix & 0xff000000) | palette[0x200 + RGB_RED(srcpix)] | palette[0x100 + RGB_GREEN(srcpix)] | palette[RGB_BLUE(srcpix)];
  3540. }
  3541. if (xborderpix)
  3542. {
  3543. UINT32 srcpix = *--src;
  3544. *dst++ = (srcpix & 0xff000000) | palette[0x200 + RGB_RED(srcpix)] | palette[0x100 + RGB_GREEN(srcpix)] | palette[RGB_BLUE(srcpix)];
  3545. }
  3546. }
  3547.  
  3548. // direct case
  3549. else
  3550. {
  3551. if (xborderpix)
  3552. *dst++ = *src;
  3553. for (x = 0; x < width; x++)
  3554. *dst++ = *src++;
  3555. if (xborderpix)
  3556. *dst++ = *--src;
  3557. }
  3558. }
  3559.  
  3560.  
  3561.  
  3562. //============================================================
  3563. // copyline_yuy16_to_yuy2
  3564. //============================================================
  3565.  
  3566. INLINE void copyline_yuy16_to_yuy2(UINT16 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
  3567. {
  3568. int x;
  3569.  
  3570. assert(xborderpix == 0 || xborderpix == 2);
  3571. assert(width % 2 == 0);
  3572.  
  3573. // palette (really RGB map) case
  3574. if (palette != NULL)
  3575. {
  3576. if (xborderpix)
  3577. {
  3578. UINT16 srcpix0 = *src++;
  3579. UINT16 srcpix1 = *src--;
  3580. *dst++ = palette[0x000 + (srcpix0 >> 8)] | (srcpix0 << 8);
  3581. *dst++ = palette[0x000 + (srcpix0 >> 8)] | (srcpix1 << 8);
  3582. }
  3583. for (x = 0; x < width; x += 2)
  3584. {
  3585. UINT16 srcpix0 = *src++;
  3586. UINT16 srcpix1 = *src++;
  3587. *dst++ = palette[0x000 + (srcpix0 >> 8)] | (srcpix0 << 8);
  3588. *dst++ = palette[0x000 + (srcpix1 >> 8)] | (srcpix1 << 8);
  3589. }
  3590. if (xborderpix)
  3591. {
  3592. UINT16 srcpix1 = *--src;
  3593. UINT16 srcpix0 = *--src;
  3594. *dst++ = palette[0x000 + (srcpix1 >> 8)] | (srcpix0 << 8);
  3595. *dst++ = palette[0x000 + (srcpix1 >> 8)] | (srcpix1 << 8);
  3596. }
  3597. }
  3598.  
  3599. // direct case
  3600. else
  3601. {
  3602. if (xborderpix)
  3603. {
  3604. UINT16 srcpix0 = *src++;
  3605. UINT16 srcpix1 = *src--;
  3606. *dst++ = (srcpix0 >> 8) | (srcpix0 << 8);
  3607. *dst++ = (srcpix0 >> 8) | (srcpix1 << 8);
  3608. }
  3609. for (x = 0; x < width; x += 2)
  3610. {
  3611. UINT16 srcpix0 = *src++;
  3612. UINT16 srcpix1 = *src++;
  3613. *dst++ = (srcpix0 >> 8) | (srcpix0 << 8);
  3614. *dst++ = (srcpix1 >> 8) | (srcpix1 << 8);
  3615. }
  3616. if (xborderpix)
  3617. {
  3618. UINT16 srcpix1 = *--src;
  3619. UINT16 srcpix0 = *--src;
  3620. *dst++ = (srcpix1 >> 8) | (srcpix0 << 8);
  3621. *dst++ = (srcpix1 >> 8) | (srcpix1 << 8);
  3622. }
  3623. }
  3624. }
  3625.  
  3626.  
  3627.  
  3628. //============================================================
  3629. // copyline_yuy16_to_uyvy
  3630. //============================================================
  3631.  
  3632. INLINE void copyline_yuy16_to_uyvy(UINT16 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
  3633. {
  3634. int x;
  3635.  
  3636. assert(xborderpix == 0 || xborderpix == 2);
  3637. assert(width % 2 == 0);
  3638.  
  3639. // palette (really RGB map) case
  3640. if (palette != NULL)
  3641. {
  3642. if (xborderpix)
  3643. {
  3644. UINT16 srcpix0 = *src++;
  3645. UINT16 srcpix1 = *src--;
  3646. *dst++ = palette[0x100 + (srcpix0 >> 8)] | (srcpix0 & 0xff);
  3647. *dst++ = palette[0x100 + (srcpix0 >> 8)] | (srcpix1 & 0xff);
  3648. }
  3649. for (x = 0; x < width; x += 2)
  3650. {
  3651. UINT16 srcpix0 = *src++;
  3652. UINT16 srcpix1 = *src++;
  3653. *dst++ = palette[0x100 + (srcpix0 >> 8)] | (srcpix0 & 0xff);
  3654. *dst++ = palette[0x100 + (srcpix1 >> 8)] | (srcpix1 & 0xff);
  3655. }
  3656. if (xborderpix)
  3657. {
  3658. UINT16 srcpix1 = *--src;
  3659. UINT16 srcpix0 = *--src;
  3660. *dst++ = palette[0x100 + (srcpix1 >> 8)] | (srcpix0 & 0xff);
  3661. *dst++ = palette[0x100 + (srcpix1 >> 8)] | (srcpix1 & 0xff);
  3662. }
  3663. }
  3664.  
  3665. // direct case
  3666. else
  3667. {
  3668. if (xborderpix)
  3669. {
  3670. UINT16 srcpix0 = src[0];
  3671. UINT16 srcpix1 = src[1];
  3672. *dst++ = srcpix0;
  3673. *dst++ = (srcpix0 & 0xff00) | (srcpix1 & 0x00ff);
  3674. }
  3675. for (x = 0; x < width; x += 2)
  3676. {
  3677. *dst++ = *src++;
  3678. *dst++ = *src++;
  3679. }
  3680. if (xborderpix)
  3681. {
  3682. UINT16 srcpix1 = *--src;
  3683. UINT16 srcpix0 = *--src;
  3684. *dst++ = (srcpix1 & 0xff00) | (srcpix0 & 0x00ff);
  3685. *dst++ = srcpix1;
  3686. }
  3687. }
  3688. }
  3689.  
  3690.  
  3691.  
  3692. //============================================================
  3693. // copyline_yuy16_to_argb
  3694. //============================================================
  3695.  
  3696. INLINE void copyline_yuy16_to_argb(UINT32 *dst, const UINT16 *src, int width, const rgb_t *palette, int xborderpix)
  3697. {
  3698. int x;
  3699.  
  3700. assert(xborderpix == 0 || xborderpix == 2);
  3701. assert(width % 2 == 0);
  3702.  
  3703. // palette (really RGB map) case
  3704. if (palette != NULL)
  3705. {
  3706. if (xborderpix)
  3707. {
  3708. UINT16 srcpix0 = src[0];
  3709. UINT16 srcpix1 = src[1];
  3710. UINT8 cb = srcpix0 & 0xff;
  3711. UINT8 cr = srcpix1 & 0xff;
  3712. *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
  3713. *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
  3714. }
  3715. for (x = 0; x < width / 2; x++)
  3716. {
  3717. UINT16 srcpix0 = *src++;
  3718. UINT16 srcpix1 = *src++;
  3719. UINT8 cb = srcpix0 & 0xff;
  3720. UINT8 cr = srcpix1 & 0xff;
  3721. *dst++ = ycc_to_rgb(palette[0x000 + (srcpix0 >> 8)], cb, cr);
  3722. *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
  3723. }
  3724. if (xborderpix)
  3725. {
  3726. UINT16 srcpix1 = *--src;
  3727. UINT16 srcpix0 = *--src;
  3728. UINT8 cb = srcpix0 & 0xff;
  3729. UINT8 cr = srcpix1 & 0xff;
  3730. *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
  3731. *dst++ = ycc_to_rgb(palette[0x000 + (srcpix1 >> 8)], cb, cr);
  3732. }
  3733. }
  3734.  
  3735. // direct case
  3736. else
  3737. {
  3738. if (xborderpix)
  3739. {
  3740. UINT16 srcpix0 = src[0];
  3741. UINT16 srcpix1 = src[1];
  3742. UINT8 cb = srcpix0 & 0xff;
  3743. UINT8 cr = srcpix1 & 0xff;
  3744. *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
  3745. *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
  3746. }
  3747. for (x = 0; x < width; x += 2)
  3748. {
  3749. UINT16 srcpix0 = *src++;
  3750. UINT16 srcpix1 = *src++;
  3751. UINT8 cb = srcpix0 & 0xff;
  3752. UINT8 cr = srcpix1 & 0xff;
  3753. *dst++ = ycc_to_rgb(srcpix0 >> 8, cb, cr);
  3754. *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
  3755. }
  3756. if (xborderpix)
  3757. {
  3758. UINT16 srcpix1 = *--src;
  3759. UINT16 srcpix0 = *--src;
  3760. UINT8 cb = srcpix0 & 0xff;
  3761. UINT8 cr = srcpix1 & 0xff;
  3762. *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
  3763. *dst++ = ycc_to_rgb(srcpix1 >> 8, cb, cr);
  3764. }
  3765. }
  3766. }
  3767.  
  3768.  
  3769.  
  3770. //============================================================
  3771. // texture_set_data
  3772. //============================================================
  3773.  
  3774. static void texture_set_data(d3d_info *d3d, texture_info *texture, const render_texinfo *texsource, UINT32 flags)
  3775. {
  3776. D3DLOCKED_RECT rect;
  3777. HRESULT result;
  3778. int miny, maxy;
  3779. int dsty;
  3780.  
  3781. // lock the texture
  3782. switch (texture->type)
  3783. {
  3784. default:
  3785. case TEXTURE_TYPE_PLAIN: result = (*d3dintf->texture.lock_rect)(texture->d3dtex, 0, &rect, NULL, 0); break;
  3786. case TEXTURE_TYPE_DYNAMIC: result = (*d3dintf->texture.lock_rect)(texture->d3dtex, 0, &rect, NULL, D3DLOCK_DISCARD); break;
  3787. case TEXTURE_TYPE_SURFACE: result = (*d3dintf->surface.lock_rect)(texture->d3dsurface, &rect, NULL, D3DLOCK_DISCARD); break;
  3788. }
  3789. if (result != D3D_OK)
  3790. return;
  3791.  
  3792. // loop over Y
  3793. miny = 0 - texture->yborderpix;
  3794. maxy = texsource->height + texture->yborderpix;
  3795. for (dsty = miny; dsty < maxy; dsty++)
  3796. {
  3797. int srcy = (dsty < 0) ? 0 : (dsty >= texsource->height) ? texsource->height - 1 : dsty;
  3798. void *dst = (BYTE *)rect.pBits + (dsty + texture->yborderpix) * rect.Pitch;
  3799.  
  3800. // switch off of the format and
  3801. switch (PRIMFLAG_GET_TEXFORMAT(flags))
  3802. {
  3803. case TEXFORMAT_PALETTE16:
  3804. copyline_palette16((UINT32 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, texture->xborderpix);
  3805. break;
  3806.  
  3807. case TEXFORMAT_PALETTEA16:
  3808. copyline_palettea16((UINT32 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, texture->xborderpix);
  3809. break;
  3810.  
  3811. case TEXFORMAT_RGB15:
  3812. copyline_rgb15((UINT32 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, texture->xborderpix);
  3813. break;
  3814.  
  3815. case TEXFORMAT_RGB32:
  3816. copyline_rgb32((UINT32 *)dst, (UINT32 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, texture->xborderpix);
  3817. break;
  3818.  
  3819. case TEXFORMAT_ARGB32:
  3820. copyline_argb32((UINT32 *)dst, (UINT32 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, texture->xborderpix);
  3821. break;
  3822.  
  3823. case TEXFORMAT_YUY16:
  3824. if (d3d->yuv_format == D3DFMT_YUY2)
  3825. copyline_yuy16_to_yuy2((UINT16 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, texture->xborderpix);
  3826. else if (d3d->yuv_format == D3DFMT_UYVY)
  3827. copyline_yuy16_to_uyvy((UINT16 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, texture->xborderpix);
  3828. else
  3829. copyline_yuy16_to_argb((UINT32 *)dst, (UINT16 *)texsource->base + srcy * texsource->rowpixels, texsource->width, texsource->palette, texture->xborderpix);
  3830. break;
  3831.  
  3832. default:
  3833. mame_printf_error("Unknown texture blendmode=%d format=%d\n", PRIMFLAG_GET_BLENDMODE(flags), PRIMFLAG_GET_TEXFORMAT(flags));
  3834. break;
  3835. }
  3836. }
  3837.  
  3838. // unlock
  3839. switch (texture->type)
  3840. {
  3841. default:
  3842. case TEXTURE_TYPE_PLAIN: result = (*d3dintf->texture.unlock_rect)(texture->d3dtex, 0); break;
  3843. case TEXTURE_TYPE_DYNAMIC: result = (*d3dintf->texture.unlock_rect)(texture->d3dtex, 0); break;
  3844. case TEXTURE_TYPE_SURFACE: result = (*d3dintf->surface.unlock_rect)(texture->d3dsurface); break;
  3845. }
  3846. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during texture unlock_rect call\n", (int)result);
  3847.  
  3848. // prescale
  3849. texture_prescale(d3d, texture);
  3850. }
  3851.  
  3852.  
  3853.  
  3854. //============================================================
  3855. // texture_prescale
  3856. //============================================================
  3857.  
  3858. static void texture_prescale(d3d_info *d3d, texture_info *texture)
  3859. {
  3860. d3d_surface *surface;
  3861. HRESULT result;
  3862. int i;
  3863.  
  3864. // if we don't need to, just skip it
  3865. if (texture->d3dtex == texture->d3dfinaltex)
  3866. return;
  3867.  
  3868. // for all cases, we need to get the surface of the render target
  3869. result = (*d3dintf->texture.get_surface_level)(texture->d3dfinaltex, 0, &surface);
  3870. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during texture get_surface_level call\n", (int)result);
  3871.  
  3872. // if we have an offscreen plain surface, we can just StretchRect to it
  3873. if (texture->type == TEXTURE_TYPE_SURFACE)
  3874. {
  3875. RECT source, dest;
  3876.  
  3877. assert(texture->d3dsurface != NULL);
  3878.  
  3879. // set the source bounds
  3880. source.left = source.top = 0;
  3881. source.right = texture->texinfo.width + 2 * texture->xborderpix;
  3882. source.bottom = texture->texinfo.height + 2 * texture->yborderpix;
  3883.  
  3884. // set the target bounds
  3885. dest = source;
  3886. dest.right *= texture->xprescale;
  3887. dest.bottom *= texture->yprescale;
  3888.  
  3889. // do the stretchrect
  3890. result = (*d3dintf->device.stretch_rect)(d3d->device, texture->d3dsurface, &source, surface, &dest, D3DTEXF_POINT);
  3891. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device stretct_rect call\n", (int)result);
  3892. }
  3893.  
  3894. // if we are using a texture render target, we need to do more preparations
  3895. else
  3896. {
  3897. d3d_surface *backbuffer;
  3898.  
  3899. assert(texture->d3dtex != NULL);
  3900.  
  3901. // first remember the original render target and set the new one
  3902. result = (*d3dintf->device.get_render_target)(d3d->device, 0, &backbuffer);
  3903. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device get_render_target call\n", (int)result);
  3904. result = (*d3dintf->device.set_render_target)(d3d->device, 0, surface);
  3905. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 1\n", (int)result);
  3906. reset_render_states(d3d);
  3907.  
  3908. // start the scene
  3909. result = (*d3dintf->device.begin_scene)(d3d->device);
  3910. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device begin_scene call\n", (int)result);
  3911.  
  3912. // configure the rendering pipeline
  3913. set_filter(d3d, FALSE);
  3914. set_blendmode(d3d, BLENDMODE_NONE);
  3915. result = (*d3dintf->device.set_texture)(d3d->device, 0, texture->d3dtex);
  3916. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_texture call\n", (int)result);
  3917.  
  3918. // lock the vertex buffer
  3919. result = (*d3dintf->vertexbuf.lock)(d3d->vertexbuf, 0, 0, (VOID **)&d3d->lockedbuf, D3DLOCK_DISCARD);
  3920. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during vertex buffer lock call\n", (int)result);
  3921.  
  3922. // configure the X/Y coordinates on the target surface
  3923. d3d->lockedbuf[0].x = -0.5f;
  3924. d3d->lockedbuf[0].y = -0.5f;
  3925. d3d->lockedbuf[1].x = (float)((texture->texinfo.width + 2 * texture->xborderpix) * texture->xprescale) - 0.5f;
  3926. d3d->lockedbuf[1].y = -0.5f;
  3927. d3d->lockedbuf[2].x = -0.5f;
  3928. d3d->lockedbuf[2].y = (float)((texture->texinfo.height + 2 * texture->yborderpix) * texture->yprescale) - 0.5f;
  3929. d3d->lockedbuf[3].x = (float)((texture->texinfo.width + 2 * texture->xborderpix) * texture->xprescale) - 0.5f;
  3930. d3d->lockedbuf[3].y = (float)((texture->texinfo.height + 2 * texture->yborderpix) * texture->yprescale) - 0.5f;
  3931.  
  3932. // configure the U/V coordintes on the source texture
  3933. d3d->lockedbuf[0].u0 = 0.0f;
  3934. d3d->lockedbuf[0].v0 = 0.0f;
  3935. d3d->lockedbuf[1].u0 = (float)(texture->texinfo.width + 2 * texture->xborderpix) / (float)texture->rawwidth;
  3936. d3d->lockedbuf[1].v0 = 0.0f;
  3937. d3d->lockedbuf[2].u0 = 0.0f;
  3938. d3d->lockedbuf[2].v0 = (float)(texture->texinfo.height + 2 * texture->yborderpix) / (float)texture->rawheight;
  3939. d3d->lockedbuf[3].u0 = (float)(texture->texinfo.width + 2 * texture->xborderpix) / (float)texture->rawwidth;
  3940. d3d->lockedbuf[3].v0 = (float)(texture->texinfo.height + 2 * texture->yborderpix) / (float)texture->rawheight;
  3941.  
  3942. // reset the remaining vertex parameters
  3943. for (i = 0; i < 4; i++)
  3944. {
  3945. d3d->lockedbuf[i].z = 0.0f;
  3946. d3d->lockedbuf[i].rhw = 1.0f;
  3947. d3d->lockedbuf[i].color = D3DCOLOR_ARGB(0xff,0xff,0xff,0xff);
  3948. }
  3949.  
  3950. // unlock the vertex buffer
  3951. result = (*d3dintf->vertexbuf.unlock)(d3d->vertexbuf);
  3952. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during vertex buffer unlock call\n", (int)result);
  3953. d3d->lockedbuf = NULL;
  3954.  
  3955. // set the stream and draw the triangle strip
  3956. result = (*d3dintf->device.set_stream_source)(d3d->device, 0, d3d->vertexbuf, sizeof(d3d_vertex));
  3957. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_stream_source call\n", (int)result);
  3958. result = (*d3dintf->device.draw_primitive)(d3d->device, D3DPT_TRIANGLESTRIP, 0, 2);
  3959. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device draw_primitive call\n", (int)result);
  3960.  
  3961. // end the scene
  3962. result = (*d3dintf->device.end_scene)(d3d->device);
  3963. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device end_scene call\n", (int)result);
  3964.  
  3965. // reset the render target and release our reference to the backbuffer
  3966. result = (*d3dintf->device.set_render_target)(d3d->device, 0, backbuffer);
  3967. if (result != D3D_OK) mame_printf_verbose("Direct3D: Error %08X during device set_render_target call 2\n", (int)result);
  3968. (*d3dintf->surface.release)(backbuffer);
  3969. reset_render_states(d3d);
  3970. }
  3971.  
  3972. // release our reference to the target surface
  3973. (*d3dintf->surface.release)(surface);
  3974. }
  3975.  
  3976.  
  3977.  
  3978. //============================================================
  3979. // texture_find
  3980. //============================================================
  3981.  
  3982. static texture_info *texture_find(d3d_info *d3d, const render_primitive *prim)
  3983. {
  3984. UINT32 texhash = texture_compute_hash(&prim->texture, prim->flags);
  3985. texture_info *texture;
  3986.  
  3987. // find a match
  3988. for (texture = d3d->texlist; texture != NULL; texture = texture->next)
  3989. if (texture->hash == texhash &&
  3990. texture->texinfo.base == prim->texture.base &&
  3991. texture->texinfo.width == prim->texture.width &&
  3992. texture->texinfo.height == prim->texture.height &&
  3993. ((texture->flags ^ prim->flags) & (PRIMFLAG_BLENDMODE_MASK | PRIMFLAG_TEXFORMAT_MASK)) == 0)
  3994. return texture;
  3995.  
  3996. // nothing found
  3997. return NULL;
  3998. }
  3999.  
  4000.  
  4001.  
  4002. //============================================================
  4003. // texture_update
  4004. //============================================================
  4005.  
  4006. static void texture_update(d3d_info *d3d, const render_primitive *prim)
  4007. {
  4008. texture_info *texture = texture_find(d3d, prim);
  4009.  
  4010. // if we didn't find one, create a new texture
  4011. if (texture == NULL)
  4012. {
  4013. texture = texture_create(d3d, &prim->texture, prim->flags);
  4014. }
  4015.  
  4016. // if we found it, but with a different seqid, copy the data
  4017. if (texture->texinfo.seqid != prim->texture.seqid)
  4018. {
  4019. texture_set_data(d3d, texture, &prim->texture, prim->flags);
  4020. texture->texinfo.seqid = prim->texture.seqid;
  4021. }
  4022. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement