source: golgotha/src/render/glide/gr_render.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 11 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: 26.4 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 "glide/gr_vram.hh"
10#include "image/image.hh"
11#include "r1_api.hh"
12#include "time/profile.hh"
13#include "video/glide/glide_display.hh"
14#include "r1_clip.hh"
15#include "r1_win.hh"
16#include "video/glide/glide.h"
17#include "device/processor.hh"
18
19#ifdef _WINDOWS
20#include "software/amd3d/amd3d.h"
21#define USE_AMD3D
22#endif
23
24static i4_bool gr_support_amd3d = i4_F;
25
26static float gr_const_r, gr_const_g, gr_const_b, gr_const_a, gr_x2, gr_y2;
27
28//dont reorder this
29static struct gr_static_struct
30{
31  float gr_xadd, gr_yadd;    // window offset additions
32  float gr_smul, gr_tmul;    // texture coordinate multiplers
33  float gr_r_tint_mul, gr_g_tint_mul;
34  float gr_a_mul, gr_w_mul;            // scales the w value to best fit application's range 
35  float VTX_SNAP_1, VTX_SNAP_2;
36  float gr_b_tint_mul;
37  float gr_xoff, gr_yoff;    // window offset additions
38} gr_static_info = {0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 255.f, 1.f, (float)(1L<<19), (float)(1L<<19), 1.f };
39
40static i4_profile_class pf_glide_single_poly("glide render single poly");
41static i4_profile_class pf_glide_shadows("glide shadows");
42static i4_profile_class pf_glide_sprite("glide sprite");
43static i4_profile_class pf_render_list("glide render list");
44static i4_profile_class pf_use_texture("glide use texture");
45static i4_profile_class pf_begin_render("glide begin render");
46static i4_profile_class pf_end_render("glide end render");
47static i4_profile_class pf_vram_select_texture("glide select texture");
48static i4_profile_class pf_setup_vert("glide setup vert");
49
50
51typedef i4_bool (*gr_copy_vert_function_type)(GrVertex *dst, r1_vert *src, int t_verts);
52gr_copy_vert_function_type gr_copy_vert_function=0;
53
54w32 gr_old_flags;
55
56#ifdef _WINDOWS
57inline w32 gset_and_get_flags() // returns old flags
58{
59  w32 control_word_new;
60  w32 control_word_old;
61
62  _asm {
63    finit
64    fwait
65    fnstcw    control_word_old ;
66    fwait
67    mov       eax, control_word_old ;     
68    and       eax, 0xfffffcff ;
69    mov       control_word_new, eax ;
70    fldcw     control_word_new ;
71    fwait
72  }
73  return control_word_old;
74}
75
76inline void grestore_flags(w32 old_value) // returns old flags
77{
78  _asm {
79    fldcw old_value ;
80  }
81}
82
83inline void gsnap_vert(GrVertex *dst)
84{
85  dst->x += gr_static_info.VTX_SNAP_1;
86  dst->x -= gr_static_info.VTX_SNAP_1;
87
88  dst->y += gr_static_info.VTX_SNAP_1;
89  dst->y -= gr_static_info.VTX_SNAP_1;
90}
91
92#else
93
94inline w32 gset_and_get_flags()
95{
96  return 0;
97}
98
99inline void grestore_flags(w32 old)
100{
101}
102
103
104inline void gsnap_vert(GrVertex *dst)
105{
106  dst->x = float(int(dst->x * 16.0))/16.;
107  dst->y = float(int(dst->y * 16.0))/16.;
108}
109
110#endif
111
112 
113#if 1
114
115inline i4_bool gr_check_vert(GrVertex *dst) { return i4_T; }
116
117#else
118inline i4_bool gr_check_vert(GrVertex *dst)
119{
120  if (dst->x<gr_xoff || dst->y<gr_yoff || dst->x>gr_x2 || dst->y>gr_y2)
121    return i4_F;
122  else
123    return i4_T;
124}
125#endif
126
127i4_bool gr_copy_all_amd3d(GrVertex *dst, r1_vert *src, int t_verts);
128
129i4_bool gr_copy_all(GrVertex *dst, r1_vert *src, int t_verts)
130{
131  while (t_verts--)
132  {
133    float oow = src->w * gr_static_info.gr_w_mul;
134
135    dst->x = src->px + gr_static_info.gr_xoff;
136    dst->y = src->py + gr_static_info.gr_yoff;
137    gsnap_vert(dst);
138             
139    dst->oow = oow;
140
141    dst->r = src->r * gr_static_info.gr_r_tint_mul;
142    dst->g = src->g * gr_static_info.gr_g_tint_mul;
143    dst->b = src->b * gr_static_info.gr_b_tint_mul;
144
145    dst->tmuvtx[0].sow = src->s * gr_static_info.gr_smul * oow;
146    dst->tmuvtx[0].tow = src->t * gr_static_info.gr_tmul * oow;
147    dst->tmuvtx[0].oow = oow;
148
149    dst->a = src->a*255.f;
150   
151    //if (!gr_check_vert(dst))
152    //{     
153    //  i4_warning("vert out of window");
154    //  return i4_F;
155    //}   
156
157    dst++;
158    src++;   
159  }
160
161  return i4_T;
162}
163
164
165// this is used if R1_ALPHA_DISABLED & R1_WHITE_SHADING
166i4_bool gr_copy_white_shade(GrVertex *dst, r1_vert *src, int t_verts)
167{
168  while (t_verts--)
169  {
170    float oow = src->w * gr_static_info.gr_w_mul;
171
172    dst->x=src->px + gr_static_info.gr_xoff;
173    dst->y=src->py + gr_static_info.gr_yoff;
174    gsnap_vert(dst);
175
176    dst->oow=oow;
177
178    float base_color=src->r;
179    dst->r=base_color * gr_static_info.gr_r_tint_mul;
180    dst->g=base_color * gr_static_info.gr_g_tint_mul;
181    dst->b=base_color * gr_static_info.gr_b_tint_mul;
182
183    dst->tmuvtx[0].sow=src->s * gr_static_info.gr_smul * oow;
184    dst->tmuvtx[0].tow=src->t * gr_static_info.gr_tmul * oow;
185    dst->tmuvtx[0].oow=oow;
186
187    dst->a=src->a * 255;
188
189
190    if (!gr_check_vert(dst))
191    {
192      i4_warning("vert out of window");
193      return i4_F;
194    }
195
196    dst++;
197    src++;   
198
199  }
200  return i4_T;
201}
202
203i4_bool gr_copy_fullbright_shade(GrVertex *dst, r1_vert *src, int t_verts)
204{
205  while (t_verts--)
206  {
207    float oow = src->w * gr_static_info.gr_w_mul;
208
209    dst->x=src->px + gr_static_info.gr_xoff;
210    dst->y=src->py + gr_static_info.gr_yoff;
211    gsnap_vert(dst);
212
213    dst->oow=oow;
214
215    dst->r = gr_static_info.gr_r_tint_mul;
216    dst->g = gr_static_info.gr_g_tint_mul;
217    dst->b = gr_static_info.gr_b_tint_mul;
218
219    dst->tmuvtx[0].sow=src->s * gr_static_info.gr_smul * oow;
220    dst->tmuvtx[0].tow=src->t * gr_static_info.gr_tmul * oow;
221    dst->tmuvtx[0].oow=oow;
222
223    dst->a=src->a * 255;
224
225    if (!gr_check_vert(dst))
226    {
227      i4_warning("vert out of window");
228      return i4_F;
229    }
230
231    dst++;
232    src++;   
233  }
234  return i4_T;
235}
236
237
238
239i4_bool gr_copy_no_shade(GrVertex *dst, r1_vert *src, int t_verts)
240{
241  while (t_verts--)
242  {
243    float oow = src->w * gr_static_info.gr_w_mul;
244
245    dst->x=src->px + gr_static_info.gr_xoff;
246    dst->y=src->py + gr_static_info.gr_yoff;
247    gsnap_vert(dst);
248
249    dst->oow=oow;
250
251    dst->r = gr_const_r * gr_static_info.gr_r_tint_mul;
252    dst->g = gr_const_g * gr_static_info.gr_g_tint_mul;
253    dst->b = gr_const_b * gr_static_info.gr_b_tint_mul;
254
255    dst->tmuvtx[0].sow=src->s * gr_static_info.gr_smul * oow;
256    dst->tmuvtx[0].tow=src->t * gr_static_info.gr_tmul * oow;
257    dst->tmuvtx[0].oow=oow;
258
259    dst->a=src->a * 255;
260
261    if (!gr_check_vert(dst))
262    {
263      i4_warning("vert out of window");
264      return i4_F;
265    }
266
267    dst++;
268    src++;   
269  }
270  return i4_T;
271}
272
273
274
275class r1_glide_render_window_class : public r1_render_window_class
276{
277public:
278  r1_glide_render_window_class *next_rw;
279
280  i4_bool need_flip_update;
281
282  r1_glide_render_window_class(w16 w, w16 h,
283                               r1_expand_type expand_type,
284                               r1_render_api_class *api);
285
286  ~r1_glide_render_window_class();
287
288  void draw(i4_draw_context_class &context);
289
290  void request_redraw(i4_bool for_a_child)
291  {
292    if (!for_a_child)
293    {
294      if (children.begin()!=children.end())
295        children.begin()->request_redraw(i4_F);
296    }
297
298    need_flip_update=i4_T;
299
300    r1_render_window_class::request_redraw(for_a_child);
301  }
302
303  char *name() { return  "glide render window"; }
304};
305
306
307r1_glide_render_window_class *r1_render_window_list=0;
308
309
310r1_glide_render_window_class::r1_glide_render_window_class(w16 w, w16 h,
311                                                           r1_expand_type expand_type,
312                                                           r1_render_api_class *api)
313  : r1_render_window_class(w,h, expand_type, api)
314
315  need_flip_update=i4_T;
316  next_rw=r1_render_window_list;
317  r1_render_window_list=this;
318}
319
320r1_glide_render_window_class::~r1_glide_render_window_class()
321{
322  if (this==r1_render_window_list)
323    r1_render_window_list=next_rw;
324  else
325  {
326    r1_glide_render_window_class *last=0;
327    for (r1_glide_render_window_class *p=r1_render_window_list; p && p!=this;)
328    {
329      last=p;
330      p=p->next_rw;
331    }
332    last->next_rw=next_rw;
333  }
334}
335
336
337class r1_glide_render_class : public r1_render_api_class
338{
339  static i4_display_class       *display;
340 
341  r1_write_mask_type pre_holy_write_mask;
342  r1_alpha_type      pre_holy_alpha_mode;
343
344  i4_bool texture_mode;
345  i4_bool holy_mode;
346  i4_bool holy_mode_lock;
347 
348public:
349  r1_glide_render_class *next_rw;
350
351  enum { MAX_VERTS=32 };
352  char *name() { return "glide"; }
353
354  virtual void copy_part(i4_image_class *im,                                         
355                         int x, int y,             // position on screen
356                         int x1, int y1,           // area of image to copy
357                         int x2, int y2)
358  {
359    if (i4_glide_display)
360    {
361      i4_image_class *bbuf;
362      bbuf=i4_glide_display->lock_frame_buffer(I4_BACK_FRAME_BUFFER, I4_FRAME_BUFFER_WRITE);
363      if (bbuf)
364      {
365        im->put_part(bbuf, i4_f_to_i(gr_static_info.gr_xoff) + x,
366                      i4_f_to_i(gr_static_info.gr_yoff) + y,x1,y1,x2,y2,
367                      *context);
368        i4_glide_display->unlock_frame_buffer(I4_BACK_FRAME_BUFFER);
369      }
370     
371    }
372
373
374  }
375
376
377
378
379  void enable_holy()
380  {   
381    if (!holy_mode && !holy_mode_lock)
382    {         
383      holy_mode_lock = i4_T;
384
385      pre_holy_write_mask = get_write_mask();
386      pre_holy_alpha_mode = get_alpha_mode();
387
388      set_write_mode(R1_COMPARE_W | R1_WRITE_COLOR);
389
390      holy_mode = i4_T;
391
392      set_alpha_mode(R1_ALPHA_LINEAR);
393
394      holy_mode_lock = i4_F;
395    }
396  }
397
398  void disable_holy()
399  {
400    if (holy_mode && !holy_mode_lock)
401    {     
402      holy_mode_lock = i4_T;
403
404      set_write_mode(pre_holy_write_mask);
405     
406      holy_mode=i4_F;
407     
408      set_alpha_mode(pre_holy_alpha_mode);
409     
410      holy_mode_lock = i4_F;
411    }
412  }
413
414
415  virtual void set_z_range(float _near_z, float _far_z)
416  {   
417    r1_near_clip_z = _near_z;
418    r1_far_clip_z  = _far_z;
419
420    gr_static_info.gr_w_mul = _far_z / (float)GR_WDEPTHVALUE_FARTHEST;
421  }
422
423
424  r1_color_tint_handle register_color_tint(i4_float r, i4_float g, i4_float b)
425  {
426    if (num_color_tints==MAX_COLOR_TINTS) return 0;
427
428    color_tint_list[num_color_tints].r = r * 255.f;
429    color_tint_list[num_color_tints].g = g * 255.f;
430    color_tint_list[num_color_tints].b = b * 255.f;
431
432    num_color_tints++;
433
434    return num_color_tints-1;
435  }
436
437
438  void set_color_tint(r1_color_tint_handle c)
439  {
440    if (c==0)
441    {
442      gr_static_info.gr_r_tint_mul = 255.f;
443      gr_static_info.gr_g_tint_mul = 255.f;
444      gr_static_info.gr_b_tint_mul = 255.f;
445
446      color_tint_on = i4_F;
447    }
448    else
449    {
450      color_tint_on = i4_T;
451     
452      gr_static_info.gr_r_tint_mul = color_tint_list[c].r;
453      gr_static_info.gr_g_tint_mul = color_tint_list[c].g;
454      gr_static_info.gr_b_tint_mul = color_tint_list[c].b;
455    }
456  }
457
458
459  virtual void set_shading_mode(r1_shading_type type)
460  {
461    if (type!=shade_mode)
462    {
463      if (type==R1_SHADE_DISABLED)
464        gr_copy_vert_function=gr_copy_fullbright_shade;
465      else if (type==R1_CONSTANT_SHADING)
466      {
467        gr_const_r=((const_color&0xff0000)>>16)/255.0;
468        gr_const_g=((const_color&0xff00)>>8)/255.0;
469        gr_const_b=((const_color&0xff)>>0)/255.0;
470        gr_copy_vert_function=gr_copy_no_shade;
471      }
472      else if (type==R1_WHITE_SHADING)
473        gr_copy_vert_function=gr_copy_white_shade;
474      else
475      {
476        if (!gr_support_amd3d)
477          gr_copy_vert_function = gr_copy_all;
478        else
479          gr_copy_vert_function = gr_copy_all_amd3d;
480      }
481
482      r1_render_api_class::set_shading_mode(type);
483    }
484  }
485
486  virtual void set_constant_color(w32 color)
487  {
488    if (color!=get_constant_color())
489    {
490      r1_render_api_class::set_constant_color(color);
491
492      switch (shade_mode)
493      {
494        case R1_SHADE_DISABLED :
495          gr_copy_vert_function=gr_copy_fullbright_shade;
496          break;
497
498        case R1_CONSTANT_SHADING :
499        {
500          gr_const_r=((const_color&0xff0000)>>16)/255.0;
501          gr_const_g=((const_color&0xff00)>>8)/255.0;
502          gr_const_b=((const_color&0xff)>>0)/255.0;
503          gr_copy_vert_function=gr_copy_no_shade;
504        } break;
505       
506        case R1_WHITE_SHADING :
507          gr_copy_vert_function=gr_copy_white_shade;
508          break;
509         
510        case R1_COLORED_SHADING :
511          if (!gr_support_amd3d)
512            gr_copy_vert_function = gr_copy_all;
513          else
514            gr_copy_vert_function = gr_copy_all_amd3d;
515          break;
516      }
517
518      grConstantColorValue(color);
519      //grAlphaTestReferenceValue(color>>24);
520    }
521  }
522
523  r1_glide_render_class()
524  {
525    holy_mode      = i4_F;
526    holy_mode_lock = i4_F;
527    last_node=0;
528    write_mask=R1_COMPARE_W | R1_WRITE_W | R1_WRITE_COLOR;
529    shade_mode=R1_SHADE_DISABLED;
530    alpha_mode=R1_ALPHA_DISABLED;
531    texture_mode=i4_T;
532
533    //currently, only flag is R1_SOFTWARE (and this is hardware)
534    render_device_flags=0;
535  }
536
537  r1_glide_vram_class *vram() { return (r1_glide_vram_class *)tmanager; }
538 
539
540  // returns false if display is not compatible with render_api, i.e. if you pass
541  // the directx display to the glide render api it return false
542  // init will create the texture manager, which can be used after this call
543  virtual i4_bool init(i4_display_class *_display)
544  {
545    if (_display==i4_glide_display)
546    {
547      display=_display;
548
549      tmanager=new r1_glide_vram_class(display->get_palette());
550
551#ifdef USE_AMD3D
552      i4_cpu_info_struct s;
553      i4_get_cpu_info(&s);
554
555      if (s.cpu_flags & i4_cpu_info_struct::AMD3D)
556        gr_support_amd3d = i4_T;
557     
558#endif
559      if (!gr_support_amd3d)
560        gr_copy_vert_function = gr_copy_all;
561      else
562        gr_copy_vert_function = gr_copy_all_amd3d;
563
564
565      return i4_T;
566    }
567    else return i4_F;
568  }
569
570  // texture handle is obtained from the texture manager, this is enables texture mapping
571  virtual void use_texture(r1_texture_handle material_ref, sw32 desired_width, w32 frame)
572  {
573    pf_use_texture.start();
574
575    if (!tmanager->valid_handle(material_ref))
576    {
577      disable_texture();
578      pf_use_texture.stop();
579      return;
580    }
581    else
582    if (!texture_mode)
583    {
584      guColorCombineFunction(GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB);
585      texture_mode = i4_T;
586    }   
587
588    sw32 width,height;   
589
590    r1_miplevel_t *mip = tmanager->get_texture(material_ref, frame, desired_width, width, height);
591
592    // don't select the texture again if it's the same one we used last time
593    if (mip)
594    {       
595      i4_bool is_alpha = mip->entry->is_alphatexture();
596      i4_bool is_holy  = mip->entry->is_transparent();
597
598      if (is_alpha || is_holy)     
599        enable_holy();     
600      else
601        disable_holy();
602
603      if (mip != last_node)
604      {
605        last_node = mip;
606
607        pf_vram_select_texture.start();
608        vram()->select_texture(mip->vram_handle, gr_static_info.gr_smul, gr_static_info.gr_tmul, is_holy, is_alpha);
609        pf_vram_select_texture.stop();
610      }
611    }
612   
613    pf_use_texture.stop();
614  }
615
616
617  // drawing will the constant color to render with if textures are disabled
618  virtual void disable_texture()
619  {
620    if (texture_mode)
621    {
622      guColorCombineFunction(GR_COLORCOMBINE_ITRGB);  // turn off textures
623      texture_mode = i4_F;
624      last_node    = 0;
625
626      disable_holy();
627    }       
628  }
629
630
631  virtual void set_alpha_mode(r1_alpha_type type)
632  {
633    if (holy_mode)
634      disable_holy();
635
636    if (type==get_alpha_mode()) return;
637
638    switch (type)
639    {
640      case R1_ALPHA_DISABLED :
641        grAlphaBlendFunction(GR_BLEND_ONE,GR_BLEND_ZERO,
642                             GR_BLEND_ZERO,GR_BLEND_ZERO);
643
644        grAlphaCombine(GR_COMBINE_FUNCTION_ZERO, GR_COMBINE_FACTOR_NONE,
645                       GR_COMBINE_LOCAL_NONE,GR_COMBINE_OTHER_NONE,0);
646
647        break;
648
649      case R1_ALPHA_CONSTANT :    // enable alpha
650        grAlphaBlendFunction(GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA,
651                             GR_BLEND_ZERO,GR_BLEND_ZERO);
652
653        if (!holy_mode)
654        {
655          grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_OTHER_CONSTANT,
656                         GR_COMBINE_LOCAL_NONE,GR_COMBINE_OTHER_CONSTANT,0);
657        }
658        else
659        {
660          grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
661                         GR_COMBINE_FACTOR_TEXTURE_ALPHA,
662                         GR_COMBINE_LOCAL_NONE,
663                         GR_COMBINE_OTHER_CONSTANT,0);
664        }
665        break;
666         
667      case R1_ALPHA_LINEAR :
668        grAlphaBlendFunction(GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA,
669                             GR_BLEND_ZERO,GR_BLEND_ZERO);
670
671        if (!holy_mode)
672        {
673          grAlphaCombine(GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE,
674                         GR_COMBINE_LOCAL_ITERATED, GR_COMBINE_OTHER_NONE, 0);
675        }
676        else
677        {
678          grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER,
679                         GR_COMBINE_FACTOR_TEXTURE_ALPHA,
680                         GR_COMBINE_LOCAL_NONE,
681                         GR_COMBINE_OTHER_ITERATED,0);
682        }
683        break;
684    }   
685
686    r1_render_api_class::set_alpha_mode(type);
687  }
688
689  virtual void set_filter_mode(r1_filter_type type)
690  {
691    if (type!=filter_mode)
692    {
693      //if (type==R1_NO_FILTERING)
694      //  grTexFilterMode(GR_TMU0,GR_TEXTUREFILTER_POINT_SAMPLED,GR_TEXTUREFILTER_POINT_SAMPLED);
695      //else
696      //if (type==R1_BILINEAR_FILTERING)       
697        grTexFilterMode(GR_TMU0,GR_TEXTUREFILTER_BILINEAR,GR_TEXTUREFILTER_BILINEAR);
698    }
699
700    r1_render_api_class::set_filter_mode(type);
701  }
702
703  virtual void set_write_mode(r1_write_mask_type mask)
704  {
705    if (holy_mode)
706      disable_holy();
707   
708    w32 diff=mask^get_write_mask();      // bits that differ
709
710    if (diff & R1_WRITE_COLOR)  // need to change the color write mask
711      grColorMask(mask & R1_WRITE_COLOR ? 1 : 0, 0);  // turn on color writes
712
713    if (diff & (R1_WRITE_W | R1_COMPARE_W))  // change z write or compare?
714    {
715      switch (mask & (R1_WRITE_W | R1_COMPARE_W))
716      {
717        case R1_WRITE_W :
718          grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
719          grDepthMask(1);
720          grDepthBufferFunction(GR_CMP_ALWAYS);  // write to all z always (no compare)
721          break;
722
723        case R1_WRITE_W | R1_COMPARE_W :
724          grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
725          grDepthMask(1);
726          grDepthBufferFunction(GR_CMP_LESS);
727          break;
728
729        case R1_COMPARE_W :
730          grDepthBufferMode(GR_DEPTHBUFFER_WBUFFER);
731          grDepthMask(0);
732          grDepthBufferFunction(GR_CMP_LESS);
733          break;
734
735        case 0 :
736          grDepthBufferMode(GR_DEPTHBUFFER_DISABLE);
737          grDepthMask(0);
738          break;         
739      }
740    }
741
742    r1_render_api_class::set_write_mode(mask);
743  }
744
745
746  /*
747  virtual void render_poly(int t_verts, r1_vert *verts, int *vertex_index)
748  {
749    pf_setup_vert.start();
750    GrVertex g_vert_buf[MAX_VERTS];
751   
752    for (int i=0; i<t_verts; i++)
753    {
754      if (!gr_copy_vert_function(g_vert_buf + i, verts+vertex_index[i], 1))
755      {
756        pf_setup_vert.stop();
757        return;
758      }
759    }
760    pf_setup_vert.stop();
761
762    pf_glide_single_poly.start();
763    grDrawPolygonVertexList(t_verts, g_vert_buf);
764    pf_glide_single_poly.stop();
765  }
766  */
767
768  virtual void render_poly(int t_verts, r1_vert *verts)
769  {
770    pf_setup_vert.start();
771   
772    GrVertex g_vert_buf[MAX_VERTS];
773    if (!gr_copy_vert_function(g_vert_buf, verts, t_verts))
774    {
775      pf_setup_vert.stop();
776      return;
777    }
778    pf_setup_vert.stop();
779
780    pf_glide_single_poly.start();   
781    grDrawPolygonVertexList(t_verts, g_vert_buf);
782    pf_glide_single_poly.stop();
783  }
784
785  virtual void render_pixel(r1_vert *pixel)
786  {
787    GrVertex p;
788    if (gr_copy_vert_function(&p, pixel, 1))
789      grDrawPoint(&p);
790  }
791
792  virtual void render_lines(int t_lines, r1_vert *verts)
793  {
794    GrVertex g_vert_buf[MAX_VERTS];
795    if (gr_copy_vert_function(g_vert_buf, verts, t_lines+1))
796      for (int i=0; i<t_lines; i++)
797        grDrawLine(g_vert_buf+i , g_vert_buf+i+1);
798  }
799
800
801 
802  // creates an image of the same bit depth and palette of screen (for use with put_image)
803  virtual i4_image_class *create_compatible_image(w16 w, w16 h)
804  {
805    return i4_create_image(w,h,display->get_palette());   
806  }
807
808
809
810  r1_render_window_class *create_render_window(int visable_w, int visable_h,
811                                               r1_expand_type type)
812  {
813    return new r1_glide_render_window_class(visable_w, visable_h, R1_COPY_1x1, this);
814  }
815
816  void clear_area(int x1, int y1, int x2, int y2, w32 color, float z)
817  {
818    w32 old_const_color=get_constant_color();
819    set_constant_color(color);
820
821    r1_shading_type old_shade_mode=get_shade_mode();
822    set_shading_mode(R1_CONSTANT_SHADING);
823
824    disable_texture();
825    disable_holy();
826
827    r1_vert v[4];
828
829    float w = 1.f/z;
830
831    v[0].px=x1;     v[0].py=y1;
832    v[1].px=x1;     v[1].py=y2+1;
833    v[2].px=x2+1;   v[2].py=y2+1;
834    v[3].px=x2+1;   v[3].py=y1; 
835   
836    GrVertex g_vert_buf[4];
837    if (!gr_copy_vert_function(g_vert_buf, v, 4)) return;
838   
839    if (z==r1_far_clip_z)
840    {
841      g_vert_buf[0].oow = GR_WDEPTHVALUE_NEAREST;
842      g_vert_buf[1].oow = GR_WDEPTHVALUE_NEAREST;
843      g_vert_buf[2].oow = GR_WDEPTHVALUE_NEAREST;
844      g_vert_buf[3].oow = GR_WDEPTHVALUE_NEAREST;
845    }
846    else
847    if (z==r1_near_clip_z)
848    {
849      g_vert_buf[0].oow = GR_WDEPTHVALUE_FARTHEST;
850      g_vert_buf[1].oow = GR_WDEPTHVALUE_FARTHEST;
851      g_vert_buf[2].oow = GR_WDEPTHVALUE_FARTHEST;
852      g_vert_buf[3].oow = GR_WDEPTHVALUE_FARTHEST;
853    }
854    else
855    {
856      float oow = (1.f/(float)z) * gr_static_info.gr_w_mul;
857      g_vert_buf[0].oow = oow;
858      g_vert_buf[1].oow = oow;
859      g_vert_buf[2].oow = oow;
860      g_vert_buf[3].oow = oow;
861    }
862
863    grDrawPolygonVertexList(4, g_vert_buf);
864   
865    set_shading_mode(old_shade_mode);
866    set_constant_color(old_const_color);
867  }
868};
869
870r1_glide_render_class r1_glide_render;
871
872i4_display_class *r1_glide_render_class::display=0;
873
874
875
876void r1_glide_render_window_class::draw(i4_draw_context_class &_context)
877{
878  r1_render_api_class::context = &_context;
879
880  gr_static_info.gr_xoff = _context.xoff;
881  gr_static_info.gr_yoff = _context.yoff;
882
883  gr_static_info.gr_xadd = _context.xoff + gr_static_info.VTX_SNAP_1;
884  gr_static_info.gr_yadd = _context.yoff + gr_static_info.VTX_SNAP_1;
885
886  gr_x2 = gr_static_info.gr_xoff + width();
887  gr_y2 = gr_static_info.gr_yoff + height();
888
889  pf_begin_render.start();
890  clip_with_z(_context);
891  pf_begin_render.stop();
892
893  gr_old_flags=gset_and_get_flags();
894  r1_render_window_class::draw(_context);     
895  grestore_flags(gr_old_flags);
896   
897  if (need_flip_update)
898  {     
899    request_redraw(i4_T);
900     
901    for (win_iter i=children.begin(); i!=children.end(); ++i)
902      i->request_redraw(i4_F);
903
904    need_flip_update=i4_F;
905  }
906
907  // if there was a texture miss
908  if (r1_glide_render.get_tmanager()->texture_resolution_change())
909    for (r1_glide_render_window_class *w=r1_render_window_list; w; w=w->next_rw)
910      w->request_redraw(i4_F);
911
912}
913
914#ifdef USE_AMD3D
915 
916w32 r1vtxsize = sizeof(r1_vert);
917w32 grvtxsize = sizeof(GrVertex);
918
919i4_bool gr_copy_all_amd3d(GrVertex *dst, r1_vert *src, int t_verts)
920{
921  _asm
922  {
923    mov esi,dword ptr [t_verts]
924    mov edi,dword ptr [src]
925
926    and esi,esi
927    jz  done
928
929    lea ecx, dword ptr [gr_static_info]   
930    mov edx,dword ptr [dst]
931
932    movq mm7, qword ptr [ecx]gr_static_struct.gr_xadd        //gr_y_add  | gr_x_add
933    mov eax,edi
934
935    movq mm6, qword ptr [ecx]gr_static_struct.gr_smul        //gr_tmul   | gr_smul
936    mov ebx,edx
937
938    movq mm5, qword ptr [ecx]gr_static_struct.gr_r_tint_mul  //gr_g_tint | gr_r_tint
939    add eax,dword ptr [r1vtxsize]
940
941    movq mm4, qword ptr [ecx]gr_static_struct.gr_a_mul       //gr_w_mul  | gr_a_mul
942    add ebx,dword ptr [grvtxsize]
943 
944  //while (t_verts--)
945  //{
946  looper:
947    cmp esi,1
948    je  dont_prefetch
949 
950    prefetch (_eax)
951    prefetch (_ebx)
952 
953  dont_prefetch:
954   
955    movq mm3, qword ptr [edi]r1_vert.a  //src->w  | src->a
956    movq mm2, qword ptr [edi]r1_vert.r  //src->g  | src->r
957     
958    movq mm1, qword ptr [edi]r1_vert.s  //src->t  | src->s
959    movq mm0, qword ptr [edi]r1_vert.px //src->py | src->px
960   
961    pfmul (m3, m4) //mm3 - src->w * gr_w_mul | src->a * gr_a_mul
962    pfmul (m2, m5) //mm2 - src->g * gr_g_mul | src->r * gr_r_mul
963   
964    pfmul (m1, m6) //mm1 - src->t * gr_tmul  | src->s * gr_smul
965    pfadd (m0, m7) //mm0 - src->py + gr_yoff + VTX_SNAP | src->px + gr_xoff + VTX_SNAP
966   
967    movq qword ptr [edx]GrVertex.a, mm3 //dst->oow = src->w*gr_w_mul | dst->a = src->a * 255.f
968    punpckhdq mm3,mm3 //mm3 - oow | oow
969   
970    movq qword ptr [edx]GrVertex.r, mm2 //dst->r = src->r*gr_r_mul | dst->g = src->g * gr_g_mul
971    add eax,dword ptr [r1vtxsize]
972   
973    movd dword ptr [edx]GrVertex.tmuvtx[0].oow,mm3           
974    pfmul (m1, m3) //mm1 - tow | sow
975   
976    movq mm3,qword ptr [ecx]gr_static_struct.VTX_SNAP_1
977    add ebx,dword ptr [grvtxsize]
978   
979    movd mm2, dword ptr [edi]r1_vert.b  //mm2 - src->b
980    movq qword ptr [edx]GrVertex.tmuvtx[0].sow,mm1 //dst->tmuvtx[0].sow = src->s*src->oow;
981                                                     //dst->tmuvtx[0].tow = src->t*src->tow
982   
983    pfsub (m0,m3) //mm0 - src->py + gr_yoff | src->px + gr_xoff
984    movd mm3, dword ptr [ecx]gr_static_struct.gr_b_tint_mul //mm3 - gr_b_mul     
985   
986    movq qword ptr [edx]GrVertex.x,mm0 //dst->x = src->px+VTX_SNAP-VTX_SNAP+gr_x_off
987                                       //dst->y = src->py+VTX_SNAP-VTX_SNAP+gr_y_off
988   
989    pfmul (m2,m3) //mm2 - src->b * gr_b_mul
990    add edi,dword ptr [r1vtxsize]
991   
992    movd dword ptr [edx]GrVertex.b, mm2 //dst->b = src->b * gr_b_mul
993    add edx,dword ptr [grvtxsize]
994   
995    dec esi
996    jnz looper
997   
998    femms
999  done:
1000  }
1001
1002  return i4_T;
1003}
1004
1005#else
1006
1007i4_bool gr_copy_all_amd3d(GrVertex *dst, r1_vert *src, int t_verts)
1008{
1009}
1010#endif
Note: See TracBrowser for help on using the repository browser.