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

Last change on this file 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: 12.9 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 "software/r1_software.hh"
10#include "software/r1_software_globals.hh"
11#include "software/span_buffer.hh"
12#include "software/inline_fpu.hh"
13#include "software/mappers.hh"
14
15//all calls to qftoi() here assume it will truncate, so be sure that start_trunc() gets
16//called before these functions execute
17
18void tri_draw_affine_lit(tri_edge &top_to_middle,tri_edge &top_to_bottom, tri_edge &mid_to_bottom, sw32 start_y, i4_bool edge_comp)
19{
20  sw32 cur_y = start_y; 
21 
22  w16 *screen_line;
23 
24  screen_line = r1_software_render_buffer_ptr + cur_y*r1_software_render_buffer_wpl;
25 
26  tri_edge *left;
27  tri_edge *right;
28  tri_edge *last_left = 0;
29 
30  affine_span cas; //cur_affine_span
31 
32  float cur_s,cur_t,cur_l;
33  float systep,tystep,lystep;
34
35  //rasterize top to middle / top to bottom
36  if (top_to_middle.dy)
37  {
38    if (edge_comp)
39    {     
40      left  = &top_to_bottom;
41      right = &top_to_middle;
42    }
43    else
44    {     
45      left  = &top_to_middle;
46      right = &top_to_bottom;
47    }
48   
49    last_left = left;
50
51    sw32 lx,rx;
52
53    lx = (left->px  + 0xFFFF) >> 16;
54    rx = (right->px + 0xFFFF) >> 16;
55   
56    cur_s = cur_grads.sat00 + ((float)cur_y*cur_grads.dsdy) + ((float)lx * cur_grads.dsdx);
57    cur_t = cur_grads.tat00 + ((float)cur_y*cur_grads.dtdy) + ((float)lx * cur_grads.dtdx);
58    cur_l = cur_grads.lat00 + ((float)cur_y*cur_grads.dldy) + ((float)lx * cur_grads.dldx);
59   
60    systep = cur_grads.dsdy + cur_grads.dsdx * left->dxdy;
61    tystep = cur_grads.dtdy + cur_grads.dtdx * left->dxdy;
62    lystep = cur_grads.dldy + cur_grads.dldx * left->dxdy;
63
64    while (top_to_middle.dy)
65    {     
66      lx = (left->px  + 0xFFFF) >> 16;
67      rx = (right->px + 0xFFFF) >> 16;
68
69      sw32 width = rx - lx;
70      if (width>0)
71      {               
72        cas.s = qftoi(cur_s);
73        cas.t = qftoi(cur_t);
74        cas.l = qftoi(cur_l);
75
76        cur_scanline_texture_func(screen_line,(lx<<1),&cas,width);       
77      }
78     
79      //advance y down
80      cur_y++;
81
82      cur_s += systep;
83      cur_t += tystep;
84      cur_l += lystep;
85
86      top_to_middle.px += top_to_middle.dxdy_fixed;
87      top_to_bottom.px += top_to_bottom.dxdy_fixed;
88     
89      top_to_middle.dy--;
90      top_to_bottom.dy--;
91     
92      screen_line += r1_software_render_buffer_wpl;
93    }   
94  }
95 
96  if (mid_to_bottom.dy)
97  {
98    if (edge_comp)
99    {
100      left  = &top_to_bottom;
101      right = &mid_to_bottom;
102    }
103    else
104    {
105      left  = &mid_to_bottom;
106      right = &top_to_bottom;
107    }
108
109    sw32 lx,rx;
110
111    lx = (left->px  + 0xFFFF) >> 16;
112    rx = (right->px + 0xFFFF) >> 16;
113
114    if (left != last_left)
115    {
116      cur_s = cur_grads.sat00 + ((float)cur_y*cur_grads.dsdy) + ((float)lx * cur_grads.dsdx);
117      cur_t = cur_grads.tat00 + ((float)cur_y*cur_grads.dtdy) + ((float)lx * cur_grads.dtdx);
118      cur_l = cur_grads.lat00 + ((float)cur_y*cur_grads.dldy) + ((float)lx * cur_grads.dldx);
119   
120      systep = cur_grads.dsdy + cur_grads.dsdx * left->dxdy;
121      tystep = cur_grads.dtdy + cur_grads.dtdx * left->dxdy;
122      lystep = cur_grads.dldy + cur_grads.dldx * left->dxdy;
123    }   
124
125    while (mid_to_bottom.dy)
126    {     
127      lx = (left->px  + 0xFFFF) >> 16;
128      rx = (right->px + 0xFFFF) >> 16;
129
130      sw32 width = rx - lx;
131      if (width>0)
132      {               
133        cas.s = qftoi(cur_s);
134        cas.t = qftoi(cur_t);
135        cas.l = qftoi(cur_l);       
136
137        cur_scanline_texture_func(screen_line,(lx<<1),&cas,width);       
138      }
139     
140      //advance y down
141      cur_y++;
142
143      cur_s += systep;
144      cur_t += tystep;
145      cur_l += lystep;
146
147      top_to_bottom.px += top_to_bottom.dxdy_fixed;
148      mid_to_bottom.px += mid_to_bottom.dxdy_fixed;
149     
150      top_to_bottom.dy--;
151      mid_to_bottom.dy--;
152           
153      screen_line += r1_software_render_buffer_wpl;
154    }
155  }
156}
157
158void tri_draw_affine_unlit(tri_edge &top_to_middle,tri_edge &top_to_bottom, tri_edge &mid_to_bottom, sw32 start_y, i4_bool edge_comp)
159{
160  sw32 cur_y = start_y;
161 
162  w16 *screen_line;
163 
164  screen_line = r1_software_render_buffer_ptr + cur_y*r1_software_render_buffer_wpl;
165
166  tri_edge *left;
167  tri_edge *right;
168  tri_edge *last_left = 0;
169 
170  affine_span cas; //cur_affine_span
171 
172  float cur_s,cur_t;
173  float systep,tystep;
174
175  //rasterize top to middle / top to bottom
176  if (top_to_middle.dy)
177  {
178    if (edge_comp)
179    {     
180      left  = &top_to_bottom;
181      right = &top_to_middle;
182    }
183    else
184    {     
185      left  = &top_to_middle;
186      right = &top_to_bottom;
187    }
188   
189    last_left = left;
190
191    sw32 lx,rx;
192
193    lx = (left->px  + 0xFFFF) >> 16;
194    rx = (right->px + 0xFFFF) >> 16;
195   
196    cur_s = cur_grads.sat00 + ((float)cur_y*cur_grads.dsdy) + ((float)lx * cur_grads.dsdx);
197    cur_t = cur_grads.tat00 + ((float)cur_y*cur_grads.dtdy) + ((float)lx * cur_grads.dtdx);   
198   
199    systep = cur_grads.dsdy + cur_grads.dsdx * left->dxdy;
200    tystep = cur_grads.dtdy + cur_grads.dtdx * left->dxdy;
201
202    while (top_to_middle.dy)
203    {     
204      lx = (left->px  + 0xFFFF) >> 16;
205      rx = (right->px + 0xFFFF) >> 16;
206
207      sw32 width = rx - lx;
208      if (width>0)
209      {               
210        cas.s = qftoi(cur_s);
211        cas.t = qftoi(cur_t);       
212
213        cur_scanline_texture_func(screen_line,(lx<<1),&cas,width);       
214      }
215     
216      //advance y down
217      cur_y++;
218
219      cur_s += systep;
220      cur_t += tystep;     
221
222      top_to_middle.px += top_to_middle.dxdy_fixed;
223      top_to_bottom.px += top_to_bottom.dxdy_fixed;
224     
225      top_to_middle.dy--;
226      top_to_bottom.dy--;
227                 
228      screen_line += r1_software_render_buffer_wpl;
229    }   
230  }
231 
232  if (mid_to_bottom.dy)
233  {
234    if (edge_comp)
235    {
236      left  = &top_to_bottom;
237      right = &mid_to_bottom;
238    }
239    else
240    {
241      left  = &mid_to_bottom;
242      right = &top_to_bottom;
243    }
244
245    sw32 lx,rx;
246
247    lx = (left->px  + 0xFFFF) >> 16;
248    rx = (right->px + 0xFFFF) >> 16;
249
250    if (left != last_left)
251    {
252      cur_s = cur_grads.sat00 + ((float)cur_y*cur_grads.dsdy) + ((float)lx * cur_grads.dsdx);
253      cur_t = cur_grads.tat00 + ((float)cur_y*cur_grads.dtdy) + ((float)lx * cur_grads.dtdx);     
254   
255      systep = cur_grads.dsdy + cur_grads.dsdx * left->dxdy;
256      tystep = cur_grads.dtdy + cur_grads.dtdx * left->dxdy;
257    }   
258
259    while (mid_to_bottom.dy)
260    {     
261      lx = (left->px  + 0xFFFF) >> 16;
262      rx = (right->px + 0xFFFF) >> 16;
263   
264      sw32 width = rx - lx;
265      if (width>0)
266      {               
267        cas.s = qftoi(cur_s);
268        cas.t = qftoi(cur_t);       
269
270        cur_scanline_texture_func(screen_line,(lx<<1),&cas,width);       
271      }
272     
273      //advance y down
274      cur_y++;
275
276      cur_s += systep;
277      cur_t += tystep;
278
279      top_to_bottom.px += top_to_bottom.dxdy_fixed;
280      mid_to_bottom.px += mid_to_bottom.dxdy_fixed;
281     
282      top_to_bottom.dy--;
283      mid_to_bottom.dy--;
284
285      screen_line += r1_software_render_buffer_wpl;
286    }
287  }
288}
289
290void span_draw_affine_unlit(span_tri_info *tri)
291
292  //setup some of the global variables
293  r1_software_texture_ptr   = tri->texture;
294  r1_software_twidth_log2   = tri->twidth_log2;
295  r1_software_texture_width = tri->texture_width;
296  cur_grads                 = tri->grads;
297
298  //about to draw, setup pertinent global vars (s_frac_add, t_frac_add, and s_t_carry)
299  temp_dsdx = qftoi(tri->grads.dsdx);
300  temp_dtdx = qftoi(tri->grads.dtdx);
301
302  s_t_carry[1] = (temp_dsdx>>16) + ((temp_dtdx>>16)<<r1_software_twidth_log2); //integral add when t doesnt carry
303  s_t_carry[0] = s_t_carry[1] + r1_software_texture_width;                     //integral add when t carrys
304
305  dsdx_frac = (temp_dsdx<<16);
306  dtdx_frac = (temp_dtdx<<16);
307
308  span_entry *s = &global_span_list[tri->span_list_head];
309
310  affine_span left; 
311  while (s!=global_span_list)
312  {   
313    float fx = s->s.x;
314    float fy = s->s.y;
315
316    left.t   = qftoi(tri->grads.tat00 + (fx * tri->grads.dtdx) + (fy * tri->grads.dtdy)) + tri->grads.t_adjust;
317    left.s   = qftoi(tri->grads.sat00 + (fx * tri->grads.dsdx) + (fy * tri->grads.dsdy)) + tri->grads.s_adjust;   
318
319    cur_scanline_texture_func(s->s.scanline_ptr,(s->s.x<<1),&left,s->s.width);   
320    s = &global_span_list[s->s.next_tri_span];
321  } 
322}
323
324void span_draw_affine_lit(span_tri_info *tri)
325
326  //setup some of the global variables
327  r1_software_class_instance.set_color_tint(tri->color_tint);
328
329  r1_software_texture_ptr   = tri->texture;
330  r1_software_twidth_log2   = tri->twidth_log2;
331  r1_software_texture_width = tri->texture_width;
332  cur_grads                 = tri->grads;
333
334  //about to draw, setup pertinent global vars (s_t_frac_add, s_t_carry, dldx_fixed)
335  temp_dsdx = qftoi(tri->grads.dsdx);
336  temp_dtdx = qftoi(tri->grads.dtdx);
337
338  dsdx_frac = (temp_dsdx<<16);
339  dtdx_frac = (temp_dtdx<<16);
340   
341  s_t_carry[1] = (temp_dsdx>>16) + ((temp_dtdx>>16)<<r1_software_twidth_log2); //integral add when t doesnt carry
342  s_t_carry[0] = s_t_carry[1] + r1_software_texture_width;           //integral add when t carrys
343
344  //dont forget the light
345  dldx_fixed = qftoi(tri->grads.dldx);
346
347  span_entry *s = &global_span_list[tri->span_list_head]; 
348
349  affine_span left; 
350  while (s!=global_span_list)
351  {
352#ifndef USE_ASM
353    float fx = s->x;
354    float fy = s->y;
355    left.t   = qftoi(tri->grads.tat00 + (fx * tri->grads.dtdx) + (fy * tri->grads.dtdy)) + tri->grads.t_adjust;
356    left.s   = qftoi(tri->grads.sat00 + (fx * tri->grads.dsdx) + (fy * tri->grads.dsdy)) + tri->grads.s_adjust;
357    left.l   = qftoi(tri->grads.lat00 + (fx * tri->grads.dldx) + (fy * tri->grads.dldy));
358#else
359
360    _asm
361    {
362      mov edi,dword ptr [s]
363     
364      fild dword ptr [edi]span_entry.s.x
365      fild dword ptr [edi]span_entry.s.y
366
367      fld dword ptr [cur_grads]tri_gradients.dtdx
368      fld dword ptr [cur_grads]tri_gradients.dtdy
369
370      //dtdy  dtdx  y   x
371      fmul st(0),st(2)
372      fxch st(1)
373
374      //dtdx  dtdy*y  y  x
375
376      fmul st(0),st(3)
377      fxch st(1)
378
379      //dtdy*y  dtdx*x  y  x
380
381      fld dword ptr [cur_grads]tri_gradients.dsdx
382      fld dword ptr [cur_grads]tri_gradients.dsdy
383
384      //dsdy  dsdx  dtdy*y  dtdx*x  y  x
385
386      fmul st(0),st(4)
387      fxch st(1)
388
389      //dsdx  dsdy*y  dtdy*y  dtdx*x  y  x
390
391      fmul st(0),st(5)
392      fxch st(1)
393
394      //dsdy*y  dsdx*x  dtdy*y  dtdx*x  y  x
395      fld dword ptr [cur_grads]tri_gradients.dldx
396      fld dword ptr [cur_grads]tri_gradients.dldy
397
398      //dldy  dldx  dsdy*y  dsdx*x  dtdy*y  dtdx*x  y  x
399
400      fmul st(0),st(6)
401      fxch st(1)
402
403      //dldx  dldy*y  dsdy*y  dsdx*x  dtdy*y  dtdx*x  y  x
404
405      fmul st(0),st(7)
406      fxch st(4)
407     
408      //dtdy*y  dldx*x  dsdy*y  dsdx*x  dldy*y  dtdx*x  y  x
409     
410      fadd dword ptr [cur_grads]tri_gradients.tat00
411      fxch st(2)
412
413      //dsdy*y  dldx*x  dtdy*y+tat00  dsdx*x  dldy*y  dtdx*x  y  x
414
415      fadd dword ptr [cur_grads]tri_gradients.sat00
416      fxch st(4)
417
418      //dldy*y  dldx*x  dtdy*y+tat00  dsdx*x  dsdy*y+sat00  dtdx*x  y  x
419
420      fadd dword ptr [cur_grads]tri_gradients.lat00
421      fxch st(2)
422
423      //dtdy*y+tat00  dldx*x  dldy*y+lat00  dsdx*x  dsdy*y+sat00  dtdx*x  y  x
424      faddp st(5),st(0)
425
426      //dldx*x  dldy*y+lat00  dsdx*x  dsdy*y+sat00  dtdx*x+dtdy*y+tat00  y  x
427      fxch st(3)
428
429      //dsdy*y+sat00  dldy*y+lat00  dsdx*x  dldx*x  dtdx*x+dtdy*y+tat00  y  x
430      faddp st(2),st(0)
431
432      //dldy*y+lat00  dsdx*x+dsdy*y+sat00  dldx*x  dtdx*x+dtdy*y+tat00  y  x
433      faddp st(2),st(0)
434
435      //dsdx*x+dsdy*y+sat00  dldx*x+dldy*y+lat00  dtdx*x+dtdy*y+tat00  y  x
436      fxch st(3)
437     
438      //y  dldx*x+dldy*y+lat00  dtdx*x+dtdy*y+tat00  dsdx*x+dsdy*y+sat00  x
439      fstp st(0)
440      fxch st(3)
441     
442      //x  dtdx*x+dtdy*y+tat00  dsdx*x+dsdy*y+sat00  dldx*x+dldy*y+lat00
443      fstp st(0)
444
445      fistp dword ptr [left]affine_span.t
446      fistp dword ptr [left]affine_span.s
447      fistp dword ptr [left]affine_span.l
448
449      mov eax,dword ptr [left]affine_span.s
450      mov ebx,dword ptr [left]affine_span.t
451
452      add eax,dword ptr [cur_grads]tri_gradients.s_adjust
453      add ebx,dword ptr [cur_grads]tri_gradients.t_adjust
454
455      mov dword ptr [left]affine_span.s,eax
456      mov dword ptr [left]affine_span.t,ebx
457    }
458#endif
459   
460    cur_scanline_texture_func(s->s.scanline_ptr,(s->s.x<<1),&left,s->s.width);   
461    s = &global_span_list[s->s.next_tri_span];
462  } 
463}
Note: See TracBrowser for help on using the repository browser.