source: golgotha/src/render/software/r1_software.cc

Last change on this file was 80, checked in by Sam Hocevar, 12 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: 20.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 <windows.h>
10#include <ddraw.h>
11#include <math.h>
12#include <memory.h>
13
14#include "r1_clip.hh"
15
16#include "software/r1_software.hh"
17#include "software/r1_software_texture.hh"
18#include "software/r1_software_globals.hh"
19#include "software/mappers.hh"
20#include "software/inline_fpu.hh"
21
22#include "time/profile.hh"
23
24static i4_profile_class pf_software_render_poly("software::render_poly");
25
26#define R1_ABS(x) ((x)>0)?(x):(-(x))
27
28r1_software_class::r1_software_class()
29
30  last_node=0;
31
32  cur_s_width  = 0;
33  cur_t_height = 0;
34
35  render_device_flags = R1_SOFTWARE;
36 
37  allow_backfaces = i4_T;
38  use_spans       = i4_T;
39  do_perspective  = i4_T;
40  do_flat         = i4_F;
41  lock_cheat      = i4_F;
42 
43  cur_color_tint = -1;
44
45  holy_mode         = i4_F;
46  alphatexture_mode = i4_F;
47}
48
49r1_software_class::~r1_software_class()
50
51}
52
53void r1_software_class::uninit()
54{
55  delete tmanager;
56  tmanager = 0; 
57}
58
59void r1_software_class::set_write_mode(r1_write_mask_type mask)
60{     
61  write_mask=mask;
62  //update_tri_function(); not needed on a write mask change
63}
64
65void r1_software_class::set_alpha_mode(r1_alpha_type type)
66{
67  if (alpha_mode != type)
68  {
69    alpha_mode = type;
70    update_tri_function();
71  }
72}
73
74void r1_software_class::set_shading_mode(r1_shading_type type)
75{
76  if (shade_mode != type)
77  {
78    shade_mode = type;
79    update_tri_function();
80  }
81}
82
83static i4_profile_class pf_software_select_texture("software select texture");
84
85void r1_software_class::use_texture(r1_texture_handle material_ref, sw32 desired_width, w32 frame)
86{
87  if (!tmanager->valid_handle(material_ref))
88  {
89    disable_texture();
90    return;
91  }
92
93  sw32 w,h;
94
95  pf_software_select_texture.start();
96
97  r1_miplevel_t *mip = tmanager->get_texture(material_ref, frame, desired_width, w,h);
98  if (!mip)
99  {
100    disable_texture();
101    return ;
102  }
103
104  r1_software_texture_class::used_node *n = (r1_software_texture_class::used_node *)mip->vram_handle;
105  r1_software_texture_class::free_node *f = (r1_software_texture_class::free_node *)n->node;
106
107  r1_software_texture_ptr    = (w16 *)f->start;
108  r1_software_texture_width  = f->mip->width;
109  r1_software_texture_height = f->mip->height;
110 
111  switch (f->mip->width)
112  {
113    case    1: r1_software_twidth_log2 =  0; break;
114    case    2: r1_software_twidth_log2 =  1; break;
115    case    4: r1_software_twidth_log2 =  2; break;
116    case    8: r1_software_twidth_log2 =  3; break;
117    case   16: r1_software_twidth_log2 =  4; break;
118    case   32: r1_software_twidth_log2 =  5; break;
119    case   64: r1_software_twidth_log2 =  6; break;
120    case  128: r1_software_twidth_log2 =  7; break;
121    case  256: r1_software_twidth_log2 =  8; break;
122    case  512: r1_software_twidth_log2 =  9; break;
123    case 1024: r1_software_twidth_log2 = 10; break;
124  }
125
126  // don't select the texture again if it's the same one we used last time
127  if (mip)
128  {       
129    if (mip->entry->is_transparent())   
130    {
131      holy_mode = i4_T;
132      alphatexture_mode = i4_F;
133    }   
134    else
135    if (mip->entry->is_alphatexture())
136    {
137      alphatexture_mode = i4_T;
138      holy_mode = i4_F;
139    }
140    else
141    {
142      holy_mode = i4_F;
143      alphatexture_mode = i4_F;
144    }
145
146    if (mip != last_node)
147    {   
148      ((r1_software_texture_class *)tmanager)->select_texture(mip->vram_handle, cur_s_width, cur_t_height);
149      last_node = mip;
150    }
151  }
152
153  texture_mode=i4_T; 
154
155  update_tri_function();
156  pf_software_select_texture.stop();
157}
158
159// drawing will be done with the constant color if textures are disabled
160void r1_software_class::disable_texture()
161
162  texture_mode=i4_F;
163  last_node=0;
164  holy_mode=i4_F;
165  alphatexture_mode=i4_F;
166  update_tri_function();
167}
168
169void r1_software_class::set_z_range(i4_float near_z, i4_float far_z)
170{
171  r1_near_clip_z = near_z;
172  r1_far_clip_z  = far_z;
173}
174
175//initialized during init_ctable
176
177void r1_software_class::prepare_verts(s_vert *s_verts, r1_vert *r1_verts, sw32 num_verts)
178{
179  sw32 i;
180   
181  s_vert  *s_v  = s_verts;
182  r1_vert *r1_v = r1_verts;
183   
184  start_ceil(); //qftoi will use the ceil() function to convert floats to ints
185
186  if (r1_software_render_expand_type!=R1_COPY_1x1_SCANLINE_SKIP)
187  {
188    for (i=0;i<num_verts;i++)
189    {       
190      s_v->px = r1_v->px;
191      s_v->py = r1_v->py;
192
193      if (s_v->px < 0.0001) s_v->px = 0;
194      else
195      if (s_v->px > width_compare) s_v->px = width_compare;
196   
197      if (s_v->py < 0.0001) s_v->py = 0;
198      else
199      if (s_v->py > height_compare) s_v->py = height_compare;
200         
201      s_v->ix = qftoi(s_v->px);
202      s_v->iy = qftoi(s_v->py);
203     
204      s_v->ooz = r1_v->w;
205   
206      s_v++;
207      r1_v++;
208    }
209  }
210  else
211  {
212    for (i=0;i<num_verts;i++)
213    {       
214      s_v->px = r1_v->px;
215      s_v->py = r1_v->py*0.5;
216
217      if (s_v->px < 0.0001) s_v->px = 0;
218      else
219      if (s_v->px > width_compare) s_v->px = width_compare;
220   
221      if (s_v->py < 0.0001) s_v->py = 0;
222      else
223      if (s_v->py > (height_compare>>1)) s_v->py = (height_compare>>1);
224         
225      s_v->ix = qftoi(s_v->px);
226      s_v->iy = qftoi(s_v->py);
227     
228      s_v->ooz = r1_v->w;
229     
230      s_v++;
231      r1_v++;
232    }
233  }
234
235  stop_ceil();
236
237  w32     r,g,b;
238 
239  start_trunc(); //qftoi will now truncate floats to ints
240
241  switch (shade_mode)
242  {
243  case R1_CONSTANT_SHADING:
244    //whenever set_constant_color is called, cur_color
245    //is adjusted for the proper bit depth / display mode
246    s_verts->color = cur_color;
247    break;
248
249  case R1_COLORED_SHADING:
250    s_v  = s_verts;
251    r1_v = r1_verts;   
252    for (i=0;i<num_verts;i++)
253    {                   
254      //these muls and shifts adjust for the proper bit depth / display mode
255      r = qftoi(r1_v->r*red_clight_mul);
256      g = qftoi(r1_v->g*green_clight_mul);
257      b = qftoi(r1_v->b*blue_clight_mul);
258
259      s_v->color = (r<<fmt.red_shift) | (g<<fmt.green_shift) | (b<<fmt.blue_shift);
260      s_v->color = s_v->color | (s_v->color << 16);
261      s_v++;
262      r1_v++;
263    }
264  //even in colored shade mode, we need to calculate l
265  case R1_WHITE_SHADING:
266    s_v  = s_verts;
267    r1_v = r1_verts;
268   
269    for (i=0;i<num_verts;i++)
270    { 
271      s_v->l = qftoi(r1_v->r*(i4_float)NUM_LIGHT_SHADES);     
272
273#ifdef DEBUG
274      if (s_v->l > NUM_LIGHT_SHADES || s_v->l < 0)
275      {
276        if (s_v->l < 0)  s_v->l = 0;
277        else
278        if (s_v->l > NUM_LIGHT_SHADES) s_v->l = NUM_LIGHT_SHADES;
279        i4_warning("Bad lighting value");
280      }
281#endif       
282     
283      s_v++;
284      r1_v++;
285    }
286    break;
287  } 
288 
289  stop_trunc();
290
291  if (texture_mode)
292  {   
293    s_vert  *s_v  = s_verts;
294    r1_vert *r1_v = r1_verts;
295
296    for (i=0;i<num_verts;i++)
297    {     
298#ifdef DEBUG
299     
300      if (r1_v->s > 1.0001f || r1_v->s < -0.0001f)
301      {
302//        i4_warning("bad s texture coordinate");       
303      }
304      if (r1_v->t > 1.0001f || r1_v->t < -0.0001f)
305      {
306//        i4_warning("bad t texture coordinate");       
307      }
308     
309#endif
310      //not perspective correct just yet, the poly might be affine mapped
311      s_v->st_projected = i4_F;
312
313      //software safety: computes texture coordinates as though valid texture ranges are from 0.5 to max-0.5
314      //decreases chance of stepping off texture. *could* be replaced to go from 0 to max but its probably risky
315     
316      s_v->s = (r1_v->s * (cur_s_width  - 1.f) ) + 0.5f;
317      s_v->t = (r1_v->t * (cur_t_height - 1.f) ) + 0.5f;
318
319      //cap the values
320      //this almost certainly cannot be removed since the maxtool often produces invalid texture coordinates,
321      //although you might be able to cap it to the range [0,max] instead of [0.5, max-0.5]
322      if (s_v->s < 0.5f)
323      {
324        s_v->s = 0.5f;
325      }
326      else
327      if (s_v->s > cur_s_width - 0.5f)
328      {
329        s_v->s = cur_s_width - 0.5f;
330      }
331
332      if (s_v->t < 0.5f)
333      {
334        s_v->t = 0.5f;
335      }
336      else
337      if (s_v->t > cur_t_height - 0.5f)
338      {
339        s_v->t = cur_t_height - 0.5f;
340      }
341     
342      s_v++;
343      r1_v++;
344    }
345  } 
346}
347
348s_vert temp_s_verts[128];
349
350void r1_software_class::render_poly(int t_verts, r1_vert *verts)
351{
352  if (t_verts>128) return;
353   
354  if (!poly_setup_functions[small_poly_type]) return;
355  if (!poly_setup_functions[big_poly_type])   return;
356
357  pf_software_render_poly.start();
358 
359  prepare_verts(temp_s_verts,verts,t_verts);
360
361  s_vert *v0 = &temp_s_verts[0];
362  s_vert *v1 = &temp_s_verts[1];
363  s_vert *v2 = &temp_s_verts[2];
364   
365  sw32 i;
366 
367  //make sure polys are valid
368  //compute the area of the whole polygon
369  tri_area_struct *t = triangle_info;
370
371  total_poly_area = 0;
372
373  for (i=1; i<t_verts-1; i++,t++)
374  {
375    t->calc_area(v0->px, v1->px, v2->px, v0->py, v1->py, v2->py);
376   
377    total_poly_area += t->area;
378   
379    v1++;
380    v2++;
381  }
382
383  //if its < 500 pixels, draw a "small" polygon (affine mapped)
384 
385  start_trunc();
386  //everything inside here pretty much uses the truncation qftoi()
387
388  if (!do_perspective || ((R1_ABS(total_poly_area)) < 500) )
389  {
390    //setup as a small poly
391    (poly_setup_functions[small_poly_type])(temp_s_verts,t_verts);
392  }       
393  else
394  { 
395    //setup as a big poly
396    (poly_setup_functions[big_poly_type])(temp_s_verts,t_verts);
397  }
398 
399  stop_trunc();
400
401  pf_software_render_poly.stop();
402}
403
404void r1_software_class::render_sprite(r1_vert *verts)
405{
406  if (!poly_setup_functions[small_poly_type]) return;
407 
408  pf_software_render_poly.start();
409
410  prepare_verts(temp_s_verts,verts,4);
411
412  tri_area_struct *t = triangle_info;
413
414  total_poly_area = 0;
415
416  s_vert *v0 = &temp_s_verts[0];
417  s_vert *v1 = &temp_s_verts[1];
418  s_vert *v2 = &temp_s_verts[2];
419   
420  sw32 i;
421
422  for (i=1; i<3; i++,t++)
423  {
424    t->calc_area(v0->px, v1->px, v2->px, v0->py, v1->py, v2->py);
425   
426    total_poly_area += t->area;
427   
428    v1++;
429    v2++;
430  }
431
432  start_trunc();
433
434  //special case alpha-blended sprites
435  if (small_poly_type==SPAN_TRI_AFFINE_UNLIT_ALPHA)
436  {
437    small_poly_type=SPAN_TRI_AFFINE_UNLIT_ALPHA_SPRITE;
438
439    //sets it up as a sprite (doesnt do some of the unnecessary steps required on polygons)
440    sprite_setup_affine_unlit_alpha(temp_s_verts,4);
441  }
442  else
443  {
444    //set it up as a polygon
445    poly_setup_functions[small_poly_type](temp_s_verts,4); 
446  }
447 
448  stop_trunc();
449
450  pf_software_render_poly.stop();
451}
452
453void r1_software_class::render_lines(int t_lines, r1_vert *verts)
454{
455  if (num_buffered_lines>=max_soft_lines) return;
456
457  sw32 i;
458  w32 r,g,b;
459  i4_float fr,fg,fb;
460  w16 start_color,end_color;
461 
462  start_trunc();
463 
464  for (i=0;i<t_lines;i++)
465  {
466    if (shade_mode==R1_CONSTANT_SHADING)
467    {
468      start_color = end_color = cur_color;
469    }
470    else
471    {
472      //draw the line w/a color that is sort of a combination of the 2 endpoints
473      fr = verts[i].r;// + verts[i+1].r; if (fr > 1.f) fr = 1.f;
474      fg = verts[i].g;// + verts[i+1].g; if (fg > 1.f) fg = 1.f;
475      fb = verts[i].b;// + verts[i+1].b; if (fb > 1.f) fb = 1.f;
476   
477      r = qftoi(fr*red_clight_mul);
478      g = qftoi(fg*green_clight_mul);
479      b = qftoi(fb*blue_clight_mul);
480     
481      start_color = (r<<fmt.red_shift) | (g<<fmt.green_shift) | (b<<fmt.blue_shift);
482
483      fr = verts[i+1].r;// + verts[i+1].r; if (fr > 1.f) fr = 1.f;
484      fg = verts[i+1].g;// + verts[i+1].g; if (fg > 1.f) fg = 1.f;
485      fb = verts[i+1].b;// + verts[i+1].b; if (fb > 1.f) fb = 1.f;
486   
487      r = qftoi(fr*red_clight_mul);
488      g = qftoi(fg*green_clight_mul);
489      b = qftoi(fb*blue_clight_mul);
490   
491      end_color = (r<<fmt.red_shift) | (g<<fmt.green_shift) | (b<<fmt.blue_shift);
492    }
493   
494    software_lines[num_buffered_lines].x0 = qftoi(verts[i].px);   
495    software_lines[num_buffered_lines].x1 = qftoi(verts[i+1].px);
496   
497    if (r1_software_render_expand_type==R1_COPY_1x1_SCANLINE_SKIP)
498    {
499      software_lines[num_buffered_lines].y0 = qftoi((verts[i].py*0.5)   + 0.5);
500      software_lines[num_buffered_lines].y1 = qftoi((verts[i+1].py*0.5) + 0.5);
501    }
502    else
503    {
504      software_lines[num_buffered_lines].y0 = qftoi(verts[i].py   + 0.5);
505      software_lines[num_buffered_lines].y1 = qftoi(verts[i+1].py + 0.5);
506    }
507   
508    software_lines[num_buffered_lines].start_color = start_color;
509    software_lines[num_buffered_lines].end_color   = end_color;
510    num_buffered_lines++;
511  }
512
513  stop_trunc();
514}
515
516void r1_software_class::render_pixel(r1_vert *pixel)
517{
518  //heh
519}
520
521void r1_software_class::set_constant_color(w32 color)
522{
523  const_color = color;
524 
525  w32 r = (const_color & 0x00FF0000) >> 16;
526  w32 g = (const_color & 0x0000FF00) >> 8;
527  w32 b = (const_color & 0x000000FF);
528
529  r = r >> (8-fmt.red_bits);
530  g = g >> (8-fmt.green_bits);
531  b = b >> (8-fmt.blue_bits);
532
533  cur_color = (r<<fmt.red_shift) | (g<<fmt.green_shift) | (b<<fmt.blue_shift);
534  cur_color = cur_color | (cur_color << 16);
535}
536
537
538void tri_area_struct::calc_area(float x0, float x1, float x2,
539                                float y0, float y1, float y2)
540{
541#ifdef USE_ASM
542  _asm
543  {
544    mov esi,dword ptr [this]
545
546    fld dword ptr [x0]
547    fld dword ptr [x1]
548    fsub st(0),st(1) //st(0) = x1 - x0
549
550    fld dword ptr [y0]
551    fld dword ptr [y1]
552    fsub st(0),st(1) //st(0) = y1 - y0
553
554    //(y1-y0) y0 (x1-x0) x0
555    fld dword ptr [x2]
556   
557    //x2 (y1-y0) y0 (x1-x0) x0
558    fsub st(0),st(4)  //st(0) = x2 - x0
559
560    //(x2-x0) (y1-y0) y0 (x1-x0) x0
561    fld dword ptr [y2]
562   
563    //y2 (x2-x0) (y1-y0) y0 (x1-x0) x0
564    fsub st(0),st(3) //st(0) = y2 - y0
565
566    //(y2-y0) (x2-x0) (y1-y0) y0 (x1-x0) x0
567    fxch st(4)
568   
569    //(x1-x0) (x2-x0) (y1-y0) y0 (y2-y0) x0
570    fst dword ptr [esi]tri_area_struct.dx1x0
571    fxch st(4)
572   
573    //(y2-y0) (x2-x0) (y1-y0) y0 (x1-x0) x0
574    fst dword ptr [esi]tri_area_struct.dy2y0
575
576    fmulp st(4),st(0)
577    //(x2-x0) (y1-y0) y0 (y2-y0)*(x1-x0) x0
578
579    fst dword ptr [esi]tri_area_struct.dx2x0
580    fxch st(1)
581    fst dword ptr [esi]tri_area_struct.dy1y0
582    fmulp st(1),st(0)
583   
584    //(x2-x0)*(y1-y0) y0 (y2-y0)*(x1-x0) x0
585    fxch st(1)
586
587    //y0 (x2-x0)*(y1-y0) (y2-y0)*(x1-x0) x0
588    fstp st(0)
589   
590    //(x2-x0)*(y1-y0) (y2-y0)*(x1-x0) x0
591    fxch st(2)
592    fstp st(0)
593
594    //(y2-y0)*(x1-x0) (x2-x0)*(y1-y0)
595    fsubp st(1),st(0)
596    fstp dword ptr [esi+TRI_AREA_STRUCT_AREA]   
597  }
598#else 
599  dx1x0 = x1 - x0;
600  dx2x0 = x2 - x0;
601  dy1y0 = y1 - y0;
602  dy2y0 = y2 - y0;
603  area = (float)(dx2x0*dy1y0) - (float)(dx1x0*dy2y0);
604#endif
605}
606
607void tri_area_struct::calc_area(sw32 x0, sw32 x1, sw32 x2,
608                                sw32 y0, sw32 y1, sw32 y2)
609{
610#ifdef USE_ASM
611  _asm
612  {
613    mov esi,dword ptr [this]
614
615    fild dword ptr [x0]
616    fild dword ptr [x1]
617    fsub st(0),st(1) //st(0) = x1 - x0
618
619    fild dword ptr [y0]
620    fild dword ptr [y1]
621    fsub st(0),st(1) //st(0) = y1 - y0
622
623    //(y1-y0) y0 (x1-x0) x0
624    fild dword ptr [x2]
625   
626    //x2 (y1-y0) y0 (x1-x0) x0
627    fsub st(0),st(4)  //st(0) = x2 - x0
628
629    //(x2-x0) (y1-y0) y0 (x1-x0) x0
630    fild dword ptr [y2]
631   
632    //y2 (x2-x0) (y1-y0) y0 (x1-x0) x0
633    fsub st(0),st(3) //st(0) = y2 - y0
634
635    //(y2-y0) (x2-x0) (y1-y0) y0 (x1-x0) x0
636    fxch st(4)
637   
638    //(x1-x0) (x2-x0) (y1-y0) y0 (y2-y0) x0
639    fst dword ptr [esi]tri_area_struct.dx1x0
640    fxch st(4)
641   
642    //(y2-y0) (x2-x0) (y1-y0) y0 (x1-x0) x0
643    fst dword ptr [esi]tri_area_struct.dy2y0
644
645    fmulp st(4),st(0)
646    //(x2-x0) (y1-y0) y0 (y2-y0)*(x1-x0) x0
647
648    fst dword ptr [esi]tri_area_struct.dx2x0
649    fxch st(1)
650    fst dword ptr [esi]tri_area_struct.dy1y0
651    fmulp st(1),st(0)
652   
653    //(x2-x0)*(y1-y0) y0 (y2-y0)*(x1-x0) x0
654    fxch st(1)
655
656    //y0 (x2-x0)*(y1-y0) (y2-y0)*(x1-x0) x0
657    fstp st(0)
658   
659    //(x2-x0)*(y1-y0) (y2-y0)*(x1-x0) x0
660    fxch st(2)
661    fstp st(0)
662
663    //(y2-y0)*(x1-x0) (x2-x0)*(y1-y0)
664    fsubp st(1),st(0)
665    fstp dword ptr [esi+TRI_AREA_STRUCT_AREA]   
666  }
667#else 
668  dx1x0 = x1 - x0;
669  dx2x0 = x2 - x0;
670  dy1y0 = y1 - y0;
671  dy2y0 = y2 - y0;
672  area = (float)(dx2x0*dy1y0) - (float)(dx1x0*dy2y0);
673#endif
674}
675
676
677void r1_software_class::update_tri_function()
678{
679  //based on the current state, determines what type (SPAN_TRI_<something>) is
680  //going to be drawn. this type will then be used as an index into the arrays
681  //of function pointers (initialized in mappers.cc) to call functions that
682  //handle that type of polygon / triangle
683
684  if (texture_mode)
685  {   
686    if (alpha_mode==R1_ALPHA_DISABLED)
687    {
688      if (shade_mode==R1_SHADE_DISABLED)
689      {       
690        if (holy_mode)
691        {
692          small_poly_type = SPAN_TRI_AFFINE_UNLIT_HOLY;
693          big_poly_type   = SPAN_TRI_PERSPECTIVE_UNLIT_HOLY;
694        }
695        else
696        if (alphatexture_mode)
697        {
698          small_poly_type = SPAN_TRI_AFFINE_UNLIT_ALPHA;
699          big_poly_type   = SPAN_TRI_PERSPECTIVE_UNLIT_ALPHA;
700        }
701        else
702        {
703          small_poly_type = SPAN_TRI_AFFINE_UNLIT;
704          big_poly_type   = SPAN_TRI_PERSPECTIVE_UNLIT;       
705        }       
706      }
707      else
708      if (shade_mode==R1_CONSTANT_SHADING)
709      {       
710        small_poly_type = SPAN_TRI_SOLID_FILL;
711        big_poly_type   = SPAN_TRI_SOLID_FILL;       
712      }
713      else
714      {       
715        if (holy_mode)       
716        {
717          small_poly_type = SPAN_TRI_AFFINE_UNLIT_HOLY;
718          big_poly_type   = SPAN_TRI_PERSPECTIVE_UNLIT_HOLY;
719        }
720        else
721        if (alphatexture_mode)
722        {
723          small_poly_type = SPAN_TRI_AFFINE_UNLIT_ALPHA;
724          big_poly_type   = SPAN_TRI_PERSPECTIVE_UNLIT_ALPHA;
725        }
726        else
727        {
728          small_poly_type = SPAN_TRI_AFFINE_LIT;
729          big_poly_type   = SPAN_TRI_PERSPECTIVE_LIT;
730        }       
731      }
732    }
733    else
734    {
735      //need a tmapper that does alpha
736      if (holy_mode)
737      {
738        small_poly_type   = SPAN_TRI_AFFINE_UNLIT_HOLY_BLEND;
739        big_poly_type     = SPAN_TRI_PERSPECTIVE_UNLIT_HOLY;
740      }
741      else
742      if (alphatexture_mode)
743      {
744        small_poly_type = SPAN_TRI_AFFINE_UNLIT_ALPHA;
745        big_poly_type   = SPAN_TRI_PERSPECTIVE_UNLIT_ALPHA;
746      }
747      else
748      {
749        small_poly_type   = SPAN_TRI_AFFINE_UNLIT;
750        big_poly_type     = SPAN_TRI_PERSPECTIVE_UNLIT;       
751      }
752    }       
753  }
754  else
755  {
756    if (alpha_mode==R1_ALPHA_DISABLED)
757    {
758      small_poly_type = SPAN_TRI_SOLID_FILL;
759      big_poly_type   = SPAN_TRI_SOLID_FILL;     
760    }
761    else
762    {
763      switch(shade_mode)
764      {
765      case R1_SHADE_DISABLED:
766      case R1_WHITE_SHADING:
767        small_poly_type = SPAN_TRI_UNDEFINED;
768        big_poly_type   = SPAN_TRI_UNDEFINED;       
769        break;
770
771      case R1_CONSTANT_SHADING:
772      case R1_COLORED_SHADING:
773        small_poly_type = SPAN_TRI_SOLID_BLEND;
774        big_poly_type   = SPAN_TRI_SOLID_BLEND;       
775        break;
776      }
777    }
778  }
779}
780
781void r1_software_class::modify_features(w32 feature_bits, int on)
782{
783  if (feature_bits & R1_SPANS)
784  {
785    if (on)
786      use_spans = i4_T;
787    else
788      use_spans = i4_F;
789  }
790
791  if (feature_bits & R1_PERSPECTIVE_CORRECT)
792  {
793    if (on)
794      do_perspective = i4_T;
795    else
796      do_perspective = i4_F;
797  }
798
799  if (feature_bits & R1_LOCK_CHEAT)
800  {
801    if (on)
802      lock_cheat = i4_T;
803    else
804      lock_cheat = i4_F;
805  }
806
807  if (feature_bits & R1_Z_BIAS)
808  {
809    //maybe re-implement this?
810
811    //if (on)
812    //  z_bias = 0.f;//0.01f;
813    //else
814    //  z_bias = 0.f;
815  }
816}
817
818i4_bool r1_software_class::is_feature_on(w32 feature_bits)
819{
820  if (feature_bits & R1_SPANS) return use_spans;
821  if (feature_bits & R1_PERSPECTIVE_CORRECT) return do_perspective;
822  if (feature_bits & R1_LOCK_CHEAT) return lock_cheat;
823  if (feature_bits & R1_Z_BIAS)
824  {
825    //if (z_bias!=0.f)
826    //  return i4_T;
827    //else
828    //  return i4_F;
829  }
830  return i4_F;
831}
Note: See TracBrowser for help on using the repository browser.