source: golgotha/src/render/dx5/r1_dx5.cc

Last change on this file was 80, checked in by Sam Hocevar, 13 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 22.3 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include "dx5/r1_dx5_texture.hh"
10#include "video/win32/dx5_error.hh"
11#include "video/win32/dx5.hh"
12#include "time/profile.hh"
13#include "image/image.hh"
14#include "r1_clip.hh"
15#include "r1_win.hh"
16
17#define USE_BUFFER
18void init_d3d_vert_buffer();
19
20r1_dx5_class r1_dx5_class_instance;
21   
22i4_profile_class pf_dx5_use_texture("dx5::use_texture");
23i4_profile_class pf_dx5_vertex_setup("dx5::vertex_setup");
24i4_profile_class pf_dx5_drawprimitive("dx5::drawprimitive");
25
26r1_dx5_render_window_class::~r1_dx5_render_window_class()
27{
28}
29
30r1_dx5_render_window_class::r1_dx5_render_window_class(w16 w, w16 h,
31                               r1_expand_type expand_type,
32                               r1_render_api_class *api)
33    : r1_render_window_class(w,h, expand_type, api) {}
34
35
36
37void r1_dx5_class::copy_part(i4_image_class *im,                                         
38                            int x, int y,             // position on screen
39                            int x1, int y1,           // area of image to copy
40                            int x2, int y2)
41{
42 
43  DDSURFACEDESC ddsd;
44  memset(&ddsd,0,sizeof(DDSURFACEDESC));
45  ddsd.dwSize = sizeof(DDSURFACEDESC);
46  dx5_common.back_surface->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_WRITEONLY,0); 
47 
48  //get frame buffer pointer
49  w8 *fb = (w8 *)ddsd.lpSurface;
50  w8 *im_src = (w8 *)im->data + x + y*im->bpl;
51 
52  sw32 w_pitch = ddsd.lPitch;
53  sw32 im_width  = x2-x1+1;
54  sw32 im_height = y2-y1+1;
55  sw32 i,j;
56 
57  sw32 ix_off = i4_f_to_i(x_off);
58  sw32 iy_off = i4_f_to_i(y_off);
59  if (fb)
60  {
61    fb += ((x+ix_off)*2 + (y+iy_off)*w_pitch);
62    for (i=0;i<im_height;i++)
63    {
64      memcpy(fb,im_src,im_width*2);
65      im_src += im->width()*2;
66      fb += w_pitch;
67    }
68  }
69  dx5_common.back_surface->Unlock(NULL);
70}
71
72
73void r1_dx5_render_window_class::draw(i4_draw_context_class &context)
74{
75  r1_dx5_class_instance.x_off = context.xoff;
76  r1_dx5_class_instance.y_off = context.yoff;
77   
78  clip_with_z(context);
79 
80  r1_dx5_class_instance.d3d_device->BeginScene();
81
82  r1_render_window_class::draw(context); 
83
84  r1_dx5_class_instance.flush_vert_buffer();
85
86  r1_dx5_class_instance.d3d_device->EndScene(); 
87};
88
89r1_render_window_class *r1_dx5_class::create_render_window(int visable_w, int visable_h,
90                                                           r1_expand_type type)
91{
92  return new r1_dx5_render_window_class(visable_w, visable_h, type, this);
93}
94
95void r1_dx5_class::set_write_mode(r1_write_mask_type mask)
96{
97  if (mask==get_write_mask()) return;
98
99  states_have_changed = i4_T;
100  flush_vert_buffer(); 
101 
102
103  if (mask & R1_WRITE_W)
104    d3d_device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,1);
105  else
106    d3d_device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE,0);
107
108  if (mask & R1_COMPARE_W)
109    d3d_device->SetRenderState(D3DRENDERSTATE_ZFUNC,D3DCMP_GREATER);
110  else
111    d3d_device->SetRenderState(D3DRENDERSTATE_ZFUNC,D3DCMP_ALWAYS);
112
113  r1_render_api_class::set_write_mode(mask);
114}
115
116void r1_dx5_class::set_alpha_mode(r1_alpha_type type)
117{
118  if (type==get_alpha_mode()) return;
119
120  states_have_changed = i4_T;
121  flush_vert_buffer(); 
122
123  switch (type)
124  {
125    case R1_ALPHA_DISABLED :
126      d3d_device->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,FALSE);
127      break;
128
129    case R1_ALPHA_CONSTANT :    // enable alpha
130    case R1_ALPHA_LINEAR   :    // w/constant alpha, the constant alpha value is copied into the vertices
131      d3d_device->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,TRUE);
132      d3d_device->SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_SRCALPHA);
133      d3d_device->SetRenderState(D3DRENDERSTATE_DESTBLEND,D3DBLEND_INVSRCALPHA);
134      break;   
135  }
136
137  r1_render_api_class::set_alpha_mode(type);
138}
139
140r1_dx5_class::r1_dx5_class()
141{   
142  zbuffer_surface     = 0;
143  d3d                 = 0;
144  d3d_device          = 0;
145  d3d_viewport        = 0;
146
147  render_device_flags = 0;
148
149  strcpy(dd_driver_name,"display");
150  strcpy(d3d_driver_name,"Direct3D HAL"); 
151 
152  last_node = 0;
153 
154  texture_mode = i4_F;
155  holy_mode    = i4_F;
156 
157  states_have_changed = i4_F;
158}
159
160r1_dx5_class::~r1_dx5_class()
161{
162}
163
164i4_bool r1_dx5_class::init(i4_display_class *display)
165{   
166  if (display!=i4_dx5_display || !i4_dx5_display->using_accelerated_driver())
167    return i4_F;     
168 
169  set_color_tint(0);
170  init_d3d_vert_buffer();
171
172  dx5_d3d_info *info=dx5_common.get_driver_hardware_info(dx5_common.ddraw);
173  if (!info) return i4_F;
174
175  if (!i4_dx5_check(dx5_common.ddraw->QueryInterface(IID_IDirect3D2,(void **)&d3d)))
176    return i4_F;
177
178  D3DDEVICEDESC hw_desc = info->hw_desc;
179  D3DDEVICEDESC sw_desc = info->sw_desc;
180 
181  if (hw_desc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
182    needs_square_textures = i4_T;
183  else
184    needs_square_textures = i4_F;
185
186  DDSURFACEDESC ddsd;
187  memset(&ddsd,0,sizeof(DDSURFACEDESC));
188  ddsd.dwSize  = sizeof(DDSURFACEDESC); 
189  ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_ZBUFFERBITDEPTH;
190
191  ddsd.dwWidth  = i4_dx5_display->current_mode()->xres;
192  ddsd.dwHeight = i4_dx5_display->current_mode()->yres;
193  ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
194 
195  w32 bd = hw_desc.dwDeviceZBufferBitDepth;
196  if (bd==0)
197  {
198    //zbuffer must be in system memory
199    bd = sw_desc.dwDeviceZBufferBitDepth;
200    ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
201    OutputDebugString("putting zbuffer in system memory\n");
202  }
203  else
204  {
205    //zbuffer must be in video memory
206    ddsd.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
207    OutputDebugString("putting zbuffer in video memory\n");
208  }
209 
210  switch (bd)
211  {
212   case DDBD_8:  ddsd.dwZBufferBitDepth = 8; break;
213   case DDBD_16: ddsd.dwZBufferBitDepth = 16; break;
214   case DDBD_24: ddsd.dwZBufferBitDepth = 24; break;
215   case DDBD_32: ddsd.dwZBufferBitDepth = 32; break;
216  }
217
218  IDirectDrawSurface *z_surf; 
219  if (dx5_common.ddraw->CreateSurface(&ddsd, &z_surf,0) != DD_OK) 
220    return i4_F;     
221 
222  if (!i4_dx5_check(z_surf->QueryInterface(IID_IDirectDrawSurface3,(void **)&zbuffer_surface)))
223  {
224    z_surf->Release();
225    return i4_F;
226  }
227
228  z_surf->Release();
229
230  if (dx5_common.back_surface->AddAttachedSurface(zbuffer_surface) != DD_OK)
231    return i4_F;
232
233  IDirectDrawSurface *back_surf;
234  dx5_common.back_surface->QueryInterface(IID_IDirectDrawSurface,(void **)&back_surf); 
235
236  if (d3d->CreateDevice(*info->lpGuid, back_surf, &d3d_device) !=D3D_OK)
237    return i4_F;
238 
239  back_surf->Release();
240     
241  if (d3d->CreateViewport(&d3d_viewport,0) != D3D_OK)
242    return i4_F;
243
244  if (d3d_device->AddViewport(d3d_viewport) != D3D_OK)
245    return i4_F;
246
247  hardware_tmapping = i4_T;
248 
249  /*
250  use_stipled_alpha = i4_F;
251  if (hw_desc.dwShadeCaps & D3DSHADECAPS_ALPHAFLATSTIPPLED)
252  {
253    if (!(hw_desc.dwShadeCaps & D3DPSHADECAPS_ALPHAGOURAUDBLEND))
254    {
255      //this device doesnt support gouraud alpha blending, but it does
256      //support flat stipled alpha, so lets at least use the flat
257      //stipled alpha where possible
258      use_stipled_alpha = i4_T;
259    }
260  }
261  */
262
263  D3DVIEWPORT2 viewport_desc;
264 
265  float  aspect = (float)640/(float)480;
266
267  memset(&viewport_desc, 0, sizeof(D3DVIEWPORT2)); 
268  viewport_desc.dwSize       = sizeof(D3DVIEWPORT2);
269  viewport_desc.dwX          = 0;
270  viewport_desc.dwY          = 0;
271  viewport_desc.dwWidth      = 640;
272  viewport_desc.dwHeight     = 480;
273  viewport_desc.dvClipX      = -1.0f;
274  viewport_desc.dvClipY      = aspect;
275  viewport_desc.dvClipWidth  = 2.0f;
276  viewport_desc.dvClipHeight = 2.0f * aspect;
277  viewport_desc.dvMinZ       = 0.f;
278  viewport_desc.dvMaxZ       = 1.f;
279 
280  if (d3d_viewport->SetViewport2(&viewport_desc) != D3D_OK)
281    return i4_F;
282
283  if (d3d_device->SetCurrentViewport(d3d_viewport) != D3D_OK)
284    return i4_F;
285
286  //turn zbuffering on
287  d3d_device->SetRenderState(D3DRENDERSTATE_ZENABLE,TRUE);   
288
289  //turn gouraud shading on the entire time
290  d3d_device->SetRenderState(D3DRENDERSTATE_SHADEMODE,D3DSHADE_GOURAUD);
291
292  //dithering.. eh..
293  d3d_device->SetRenderState(D3DRENDERSTATE_DITHERENABLE,1);
294 
295  //no monochomatic shading?
296  d3d_device->SetRenderState(D3DRENDERSTATE_MONOENABLE,FALSE);
297 
298  //texturemapping mode setup
299  d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREMAPBLEND,D3DTBLEND_MODULATE);
300  d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREHANDLE,0); 
301 
302  d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREADDRESS,D3DTADDRESS_CLAMP);
303  d3d_device->SetRenderState(D3DRENDERSTATE_WRAPU,0);
304  d3d_device->SetRenderState(D3DRENDERSTATE_WRAPV,0);
305
306  d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREPERSPECTIVE,1);
307   
308  //no automatic face culling
309  d3d_device->SetRenderState(D3DRENDERSTATE_CULLMODE,D3DCULL_NONE);
310
311  //setup other basic modes
312  set_write_mode(R1_WRITE_W | R1_COMPARE_W | R1_WRITE_COLOR);
313 
314  set_shading_mode(R1_COLORED_SHADING);
315
316  set_alpha_mode(R1_ALPHA_DISABLED); 
317     
318  set_filter_mode(R1_NO_FILTERING);
319
320  set_z_range(0.01,1.0);
321
322  //clear the viewport, initialize type thing
323  clear_area(0,0,639,479,0x00000000,1.0);
324
325  //if we're page flipping, flip so we can clear the other page initially as well
326  i4_dx5_display->flush();
327
328  clear_area(0,0,639,479,0x00000000,1.0); 
329
330  tmanager = new r1_dx5_texture_class(display->get_palette());
331
332  return i4_T;
333}
334
335void r1_dx5_class::set_filter_mode(r1_filter_type type)
336{
337  if (type==R1_NO_FILTERING)
338  {
339    d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREMAG,D3DFILTER_LINEAR);//NEAREST);//D3DFILTER_LINEAR);   
340    d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREMIN,D3DFILTER_LINEAR);//NEAREST);//D3DFILTER_LINEAR);
341  }
342  else
343  if (type==R1_BILINEAR_FILTERING)
344  {
345    d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREMAG,D3DFILTER_LINEAR);   
346    d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREMIN,D3DFILTER_LINEAR);
347  }
348
349  r1_render_api_class::set_filter_mode(type);
350}
351
352void r1_dx5_class::uninit()
353{
354  if (tmanager)
355  {
356    delete tmanager;
357    tmanager = 0; 
358  }
359
360  if (d3d_viewport)
361  {
362    d3d_viewport->Release();
363    d3d_viewport = 0;
364  }
365
366  if (d3d_device)
367  {
368    d3d_device->Release();
369    d3d_device = 0;
370  }
371
372  if (d3d)
373  {
374    d3d->Release(); 
375    d3d = 0;
376  }
377}
378
379void r1_dx5_class::enable_holy()
380{
381  if (!holy_mode)
382  {
383    states_have_changed = i4_T;
384    flush_vert_buffer();   
385
386    pre_holy_alpha_mode = get_alpha_mode();
387    pre_holy_write_mask = get_write_mask();
388
389    d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREMAPBLEND,D3DTBLEND_MODULATEALPHA);
390
391    set_alpha_mode(R1_ALPHA_LINEAR);
392    set_write_mode(R1_COMPARE_W);
393   
394    holy_mode = i4_T;   
395  }
396}
397
398void r1_dx5_class::disable_holy()
399{
400  if (holy_mode)
401  {   
402    states_have_changed = i4_T;
403    flush_vert_buffer();   
404   
405    d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREMAPBLEND,D3DTBLEND_MODULATE);
406   
407    set_alpha_mode(pre_holy_alpha_mode);
408    set_write_mode(pre_holy_write_mask);   
409   
410    holy_mode = i4_F;   
411  }
412}
413
414void r1_dx5_class::use_texture(r1_texture_handle material_ref, sw32 desired_width, w32 frame)
415
416  pf_dx5_use_texture.start();
417
418  if (!tmanager->valid_handle(material_ref))
419  {
420    pf_dx5_use_texture.stop();
421    disable_texture();
422    return;
423  }
424
425  texture_mode = i4_T;
426
427  sw32 width,height;   
428
429  r1_miplevel_t *mip = tmanager->get_texture(material_ref, frame, desired_width, width, height);
430
431  // don't select the texture again if it's the same one we used last time
432  if (mip)
433  {       
434    i4_bool is_alpha = mip->entry->is_alphatexture();
435    i4_bool is_holy  = mip->entry->is_transparent();
436
437    if (is_alpha || is_holy)     
438      enable_holy();     
439    else
440      disable_holy();
441
442    if (mip != last_node)
443    {
444      states_have_changed = i4_T;
445      flush_vert_buffer();
446
447      last_node = mip;
448
449      i4_float blahfloat_a, blahfloat_b;
450      ((r1_dx5_texture_class *)tmanager)->select_texture(mip->vram_handle, blahfloat_a, blahfloat_b);           
451    }
452  }
453 
454  pf_dx5_use_texture.stop();
455}
456
457// drawing will the constant color to render with if textures are disabled
458void r1_dx5_class::disable_texture()
459{
460  if (texture_mode)
461  {
462    states_have_changed = i4_T;
463    flush_vert_buffer();
464
465    d3d_device->SetRenderState(D3DRENDERSTATE_TEXTUREHANDLE,0);
466    texture_mode = i4_F;
467    last_node    = 0;
468   
469    disable_holy();
470  } 
471}
472
473static i4_float f_0_1_to_i_0_255_255 = 255.f;
474
475sw32 inline f_0_1_to_i_0_255(float f)
476{
477  sw32 res;
478  __asm
479  {
480    fld f
481    fld f_0_1_to_i_0_255_255
482    fmul
483    fistp res
484  }
485  return res;
486}
487
488i4_float inline i_to_f(sw32 i)
489{
490  i4_float res;
491  __asm
492  {
493    fild i
494    fstp res
495  }
496  return res;
497}
498
499w32 inline make_d3d_color(i4_float r, i4_float g, i4_float b)
500{
501  return (f_0_1_to_i_0_255(r) << 16) |
502         (f_0_1_to_i_0_255(g) <<  8) |
503         (f_0_1_to_i_0_255(b) <<  0);
504}
505 
506static float dx5_z_scale, dx5_z_add, dx5_w_scale, dx5_w_add, dx5_near_z, dx5_far_z;
507
508
509void r1_dx5_class::set_z_range(i4_float near_z, i4_float far_z)
510{
511  dx5_near_z = near_z;
512  dx5_far_z  = far_z;
513
514  dx5_z_scale = 0.999f / far_z;
515  dx5_w_scale = near_z * 0.999f;
516  dx5_z_add   = 0;//.01;
517  dx5_w_add   = 0;//.01;
518
519  r1_near_clip_z = near_z;
520  r1_far_clip_z  = far_z;
521}
522
523inline void make_d3d_verts(D3DTLVERTEX *dxverts,r1_vert *r1verts,r1_dx5_class *c,int total)
524{                                                                       
525  int i; 
526   
527  D3DTLVERTEX *dx_v = dxverts;
528  r1_vert     *r1_v = r1verts;
529
530  //add vertex information
531  for (i=0;i<total;i++)
532  {
533    dx_v->sx       = r1_v->px + c->x_off;
534    dx_v->sy       = r1_v->py + c->y_off;
535                                   
536    dx_v->sz       = r1_v->w * dx5_w_scale;
537
538    if (dx_v->sz<0)
539    {
540      i4_warning("dx vert z too small");
541      dx_v->sz=0;
542    }
543    else
544    if (dx_v->sz>1)
545    {
546      i4_warning("dx vert z too large");
547      dx_v->sz=1;
548    }
549
550    dx_v->rhw = r1_v->w;
551   
552    dx_v++;
553    r1_v++;
554  }
555
556  //add texture information
557  if (c->texture_mode)
558  {
559    dx_v = dxverts;
560    r1_v = r1verts;
561   
562    for (i=0;i<total;i++)
563    {
564      dx_v->tu = r1_v->s;
565      dx_v->tv = r1_v->t;
566
567      if (dx_v->tu > 1) dx_v->tu = 1;
568      else
569      if (dx_v->tu < 0) dx_v->tu = 0;
570
571      if (dx_v->tv > 1) dx_v->tv = 1;
572      else
573      if (dx_v->tv < 0) dx_v->tv = 0;
574
575      dx_v++;
576      r1_v++;
577    }
578  }
579   
580  w32 ccolor;
581  w32 red;
582  w32 alpha;
583
584  //add color information
585  switch (c->shade_mode)                                                   
586  {                                                                     
587    /* routines will draw fullbright */
588    case R1_SHADE_DISABLED:
589      dx_v = dxverts;
590      r1_v = r1verts;
591      ccolor = 0x00FFFFFF;           
592      for (i=0;i<total;i++)
593      {
594        dx_v->color    = ccolor;
595        dx_v++;
596        r1_v++;
597      }
598      break;
599    /* routines will use the constant color*/
600    case R1_CONSTANT_SHADING:
601      dx_v = dxverts;
602      r1_v = r1verts;
603      ccolor = c->const_color;
604           
605      for (i=0;i<total;i++)
606      {
607        dx_v->color = ccolor;
608        dx_v++;
609        r1_v++;
610      }
611      break;
612                                                                         
613    /* routines will use only the red component (as white) */           
614    case R1_WHITE_SHADING:                                               
615      dx_v = dxverts;
616      r1_v = r1verts;     
617     
618      for (i=0;i<total;i++)
619      {       
620        red = f_0_1_to_i_0_255(r1_v->r);
621       
622        dx_v->color = (red<<16) | (red<<8) | (red);
623        dx_v++;
624        r1_v++;
625      }     
626      break;                                                             
627                                                                         
628    /* routines will use r,g, and b*/
629    case R1_COLORED_SHADING:
630      dx_v = dxverts;
631      r1_v = r1verts;     
632     
633      for (i=0;i<total;i++)
634      {       
635        dx_v->color = make_d3d_color(r1_v->r,r1_v->g,r1_v->b);
636       
637        dx_v++;
638        r1_v++;
639      }     
640      break;
641  }   
642                                                                         
643  //add alpha - check constant alpha 1st
644  if ((c->alpha_mode & R1_ALPHA_CONSTANT) && !(c->shade_mode==R1_SHADE_DISABLED))
645  {
646    dx_v = dxverts;
647    r1_v = r1verts;         
648
649    alpha = c->const_color & 0xFF000000;
650
651    for (i=0;i<total;i++)
652    {       
653      dx_v->color |= alpha;
654       
655      dx_v++;
656      r1_v++;
657    }   
658  }
659  else
660  if (c->alpha_mode & R1_ALPHA_LINEAR)
661  {
662    dx_v = dxverts;
663    r1_v = r1verts;   
664
665    for (i=0;i<total;i++)
666    {       
667      dx_v->color |= (f_0_1_to_i_0_255(r1_v->a) << 24);
668       
669      dx_v++;
670      r1_v++;
671    }
672  } 
673}                                                                       
674
675sw32 used_verts   = 0;
676sw32 used_indices = 0;
677
678#define DX5_VERT_BUF_SIZE  128
679#define DX5_INDEX_BUF_SIZE 128
680
681D3DTLVERTEX r1_dx5_tmp_verts[DX5_VERT_BUF_SIZE];
682WORD        r1_dx5_tmp_indices[DX5_INDEX_BUF_SIZE];
683
684void init_d3d_vert_buffer()
685{
686  sw32 i;
687  for (i=0; i<128; i++)
688  {
689    r1_dx5_tmp_verts[i].specular = 0;
690  }
691 
692  used_verts   = 0;
693  used_indices = 0;
694}
695
696void r1_dx5_class::flush_vert_buffer()
697{
698#ifdef USE_BUFFER
699  if (states_have_changed && (used_verts!=0))
700  {
701    pf_dx5_drawprimitive.start();
702    d3d_device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
703                                     D3DVT_TLVERTEX,
704                                     (void *)r1_dx5_tmp_verts,
705                                     used_verts,
706                                     r1_dx5_tmp_indices,
707                                     used_indices,
708                                     D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS); 
709    pf_dx5_drawprimitive.stop();
710   
711    used_verts   = 0;
712    used_indices = 0;
713
714    states_have_changed = i4_F;
715  }
716#endif
717}
718
719void r1_dx5_class::render_poly(int t_verts, r1_vert *verts)
720{   
721  if (t_verts > DX5_VERT_BUF_SIZE)  return;
722
723#ifdef USE_BUFFER
724  sw32 t_index = (t_verts-2)*3;
725   
726  if (t_index > DX5_INDEX_BUF_SIZE) return;
727 
728  if (t_verts + used_verts   > DX5_VERT_BUF_SIZE ||
729      t_index + used_indices > DX5_INDEX_BUF_SIZE)
730  {
731    states_have_changed = i4_T;
732    flush_vert_buffer();
733  }
734 
735#endif
736
737  sw32 i;
738
739  pf_dx5_vertex_setup.start();
740  if (color_tint_on)
741  {
742    for (i=0; i<t_verts; i++)
743    {
744      verts[i].r *= r_tint_mul;
745      verts[i].g *= g_tint_mul;
746      verts[i].b *= b_tint_mul;
747    }
748  }
749 
750  make_d3d_verts(r1_dx5_tmp_verts+used_verts,verts,this,t_verts);
751  pf_dx5_vertex_setup.stop();
752
753#ifdef USE_BUFFER 
754 
755  //setup indices
756  for (i=1; i<t_verts-1; i++)
757  {
758    r1_dx5_tmp_indices[used_indices]   = used_verts;
759
760    r1_dx5_tmp_indices[used_indices+1] = used_verts+i;
761
762    r1_dx5_tmp_indices[used_indices+2] = used_verts+i+1;
763    used_indices += 3;
764  }
765
766  used_verts += t_verts;
767
768#else
769 
770  pf_dx5_drawprimitive.start();
771
772  d3d_device->DrawPrimitive(D3DPT_TRIANGLEFAN,
773                            D3DVT_TLVERTEX,
774                            (void *)r1_dx5_tmp_verts,
775                            t_verts,
776                            D3DDP_DONOTCLIP | D3DDP_DONOTUPDATEEXTENTS);
777
778  pf_dx5_drawprimitive.stop();
779
780#endif
781}
782
783void r1_dx5_class::render_pixel(r1_vert *pixel)
784{
785}
786
787void r1_dx5_class::render_lines(int t_lines, r1_vert *verts)
788{
789  if (t_lines+1>256) return;
790  D3DTLVERTEX dx_verts[256];
791
792  sw32 i;
793
794  for (i=0;i<t_lines+1;i++)
795  {
796    make_d3d_verts(&dx_verts[i],&verts[i],this,t_lines);
797  }
798
799  for (i=0;i<t_lines;i++)
800  {
801    d3d_device->DrawPrimitive(D3DPT_LINELIST,
802                              D3DVT_TLVERTEX,
803                              (void *)&dx_verts[i],
804                              2,
805                              D3DDP_DONOTCLIP); 
806  }
807}
808
809void r1_dx5_class::clear_area(int x1, int y1, int x2, int y2, w32 color, float z)
810
811  RECT    rect;
812  HRESULT res;
813 
814  rect.left   = x_off + x1;
815  rect.top    = y_off + y1; 
816  rect.right  = x_off + x2+1;
817  rect.bottom = y_off + y2+1;
818
819  DDBLTFX fx;
820  memset(&fx,0,sizeof(DDBLTFX));
821  fx.dwSize = sizeof(DDBLTFX);
822   
823  if (write_mask & R1_WRITE_COLOR)
824  {
825    fx.dwFillColor = color;
826
827    dx5_common.back_surface->Blt(&rect,NULL,NULL,DDBLT_COLORFILL,&fx);
828  }
829
830  if (write_mask & R1_WRITE_W)
831  {
832    if (z == dx5_near_z)
833    { 
834      fx.dwFillDepth = 0xFFFF;
835    }
836    else
837    if (z == dx5_far_z)
838    {
839      fx.dwFillDepth = 0;
840    }
841    else
842      fx.dwFillDepth = i4_f_to_i((1.f/(float)z) * dx5_w_scale * (float)0xFFFF);
843
844    res = zbuffer_surface->Blt(&rect,NULL,NULL,DDBLT_DEPTHFILL,&fx);
845  }
846}
847
848i4_image_class *r1_dx5_class::create_compatible_image(w16 w, w16 h)
849
850  return i4_create_image(w,h,i4_dx5_display->get_palette());
851}
852
853
854// void r1_dx5_class::copy_part(i4_image_class *im,                                         
855//                             int x, int y,             // position on screen
856//                             int x1, int y1,           // area of image to copy
857//                             int x2, int y2)
858// {
859 
860//   DDSURFACEDESC ddsd;
861//   memset(&ddsd,0,sizeof(DDSURFACEDESC));
862//   ddsd.dwSize = sizeof(DDSURFACEDESC);
863//   dx5_common.back_surface->Lock(NULL,&ddsd,DDLOCK_WAIT | DDLOCK_WRITEONLY,0); 
864 
865//   //get frame buffer pointer
866//   w8 *fb = (w8 *)ddsd.lpSurface;
867//   w8 *im_src = (w8 *)im->data + x + y*im->bpl;
868 
869//   sw32 w_pitch = ddsd.lPitch;
870//   sw32 im_width  = x2-x1+1;
871//   sw32 im_height = y2-y1+1;
872//   sw32 i,j;
873 
874//   sw32 ix_off = i4_f_to_i(x_off);
875//   sw32 iy_off = i4_f_to_i(y_off);
876//   if (fb)
877//   {
878//     fb += ((x+ix_off)*2 + (y+iy_off)*w_pitch);
879//     for (i=0;i<im_height;i++)
880//     {
881//       memcpy(fb,im_src,im_width*2);
882//       im_src += im->width()*2;
883//       fb += w_pitch;
884//     }
885//   }
886//   dx5_common.back_surface->Unlock(NULL);
887// }
Note: See TracBrowser for help on using the repository browser.