gpmark

view src/render3d.cpp @ 0:5019d031b485

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 05 Jun 2013 22:33:37 +0300
parents
children
line source
1 #include <math.h>
2 #include <stdlib.h>
3 #include <string.h>
5 #include "engine3d.h"
6 #include "render3d.h"
7 #include "main.h"
9 unsigned char ball_c[256];
10 unsigned int ball_p[256];
12 extern unsigned short swp[MAXDATA];
13 int zdata[MAXDATA];
15 extern point3d fpts[MAXDATA];
16 extern point3d norms[MAXDATA];
17 extern point3d pt_norms[MAXDATA];
18 extern point2d spts[MAXDATA];
19 extern point3d spls[MAXDATA];
20 tcord point_tc[MAXDATA];
22 unsigned int RenderMode = ENVMAP;
24 unsigned int zbuffer[ScreenSize];
26 int pdiv[4096];
28 extern int prticks;
29 int zb = 1;
31 int mlk = 8;
33 void initRender3D()
34 {
35 int fp = 16;
36 int i;
37 for (i=0; i<4096; i++)
38 {
39 if ((i-2048)!=0)
40 pdiv[i] = (1<<fp)/(i-2048);
41 else
42 pdiv[i] = (1<<fp);
43 }
44 }
46 static inline void drawpoint(point2d point, unsigned short *vram)
47 {
48 if (point.x>=0 && point.x<ScreenWidth && point.y>=0 && point.y<ScreenHeight)
49 *(vram + point.x + point.y * ScreenWidth) = 0xFFFF;
50 }
53 static inline void drawline (line2d line, unsigned short *vram)
54 {
56 int x1 = spts[line.p0].x;
57 int y1 = spts[line.p0].y;
58 int x2 = spts[line.p1].x;
59 int y2 = spts[line.p1].y;
60 int c = line.c;
62 int dx, dy, n, l;
63 int x00, y00;
64 int fp = 12;
65 int vramofs;
67 int x, y;
69 dx = x2 - x1;
70 dy = y2 - y1;
72 if (abs(dy) < abs(dx))
73 {
74 if (x1>x2)
75 {
76 n = x1; x1 = x2; x2 = n;
77 n = y1; y1 = y2; y2 = n;
78 }
80 if (dx!=0) l = ((dy<<fp)*pdiv[dx+2048])>>16;
81 y00 = y1<<fp;
82 for (x=x1; x<x2; x++)
83 {
84 vramofs = ((y00 += l)>>fp)*ScreenWidth + x;
85 if (vramofs>=0 && vramofs<ScreenSize) *(vram + vramofs) = c;
86 }
87 }
88 else
89 {
90 if (y1>y2)
91 {
92 n = y1; y1 = y2; y2 = n;
93 n = x1; x1 = x2; x2 = n;
94 }
96 if (dy!=0) l = ((dx<<fp)*pdiv[dy+2048])>>16;
97 x00 = x1<<fp;
99 for (y=y1; y<y2; y++)
100 {
101 vramofs = y*ScreenWidth + ((x00 += l)>>fp);
102 if (vramofs>=0 && vramofs<ScreenSize) * (vram + vramofs) = c;
103 }
105 }
106 }
109 static inline void DrawFlatTriangle (poly2d poly, unsigned short *vram, unsigned short shade[])
110 {
111 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
112 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
113 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
114 int c = shade[poly.c];
116 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
117 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
118 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
120 //156-187
121 // ===== Sort =====
123 int temp;
124 if (y1<y0)
125 {
126 temp = x0; x0 = x1; x1 = temp;
127 temp = y0; y0 = y1; y1 = temp;
128 }
129 if (y2<y0)
130 {
131 temp = x0; x0 = x2; x2 = temp;
132 temp = y0; y0 = y2; y2 = temp;
133 }
134 if (y2<y1)
135 {
136 temp = x1; x1 = x2; x2 = temp;
137 temp = y1; y1 = y2; y2 = temp;
138 }
140 // ===== Interpolation variables =====
142 int n, fp = 8;
143 int lx01=0, lx12=0, lx02=0;
145 int dx01 = x1 - x0;
146 int dy01 = y1 - y0;
148 if (dy01!=0)
149 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
151 int dx12 = x2 - x1;
152 int dy12 = y2 - y1;
154 if (dy12!=0)
155 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
157 int dx02 = x2 - x0;
158 int dy02 = y2 - y0;
160 if (dy02!=0)
161 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
163 int vramofs;
164 int x, y;
166 int x01 = x0<<fp;
167 int x02 = x01;
169 int sx1, sx2;
171 int yp = y0 * ScreenWidth;
172 for (y = y0; y<y1; y++)
173 {
174 sx1 = x01>>fp;
175 sx2 = x02>>fp;
177 if (sx1>sx2)
178 {
179 temp = sx1; sx1 = sx2; sx2 = temp;
180 }
182 yp+=ScreenWidth;
183 vramofs = yp + sx1;
184 for (x = sx1; x<sx2; x++)
185 {
186 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
187 *(vram+vramofs)=c;
188 vramofs++;
189 }
190 x01+=lx01;
191 x02+=lx02;
192 }
194 x01 = x1<<fp;
196 yp = y1 * ScreenWidth;
197 for (y = y1; y<y2; y++)
198 {
199 sx1 = x01>>fp;
200 sx2 = x02>>fp;
202 if (sx1>sx2)
203 {
204 temp = sx1; sx1 = sx2; sx2 = temp;
205 }
207 yp+=ScreenWidth;
208 vramofs = yp + sx1;
209 for (x = sx1; x<sx2; x++)
210 {
211 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
212 *(vram+vramofs)=c;
213 vramofs++;
214 }
215 x01+=lx12;
216 x02+=lx02;
217 }
218 }
221 static inline void DrawFlatTriangleZB (poly2d poly, unsigned short *vram, unsigned short shade[])
222 {
223 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
224 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
225 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
226 int c = shade[poly.c];
228 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
229 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
230 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
232 int z0 = fpts[poly.p0].z;
233 int z1 = fpts[poly.p1].z;
234 int z2 = fpts[poly.p2].z;
236 // ===== Sort =====
238 int temp;
239 if (y1<y0)
240 {
241 temp = x0; x0 = x1; x1 = temp;
242 temp = y0; y0 = y1; y1 = temp;
243 temp = z0; z0 = z1; z1 = temp;
244 }
245 if (y2<y0)
246 {
247 temp = x0; x0 = x2; x2 = temp;
248 temp = y0; y0 = y2; y2 = temp;
249 temp = z0; z0 = z2; z2 = temp;
250 }
251 if (y2<y1)
252 {
253 temp = x1; x1 = x2; x2 = temp;
254 temp = y1; y1 = y2; y2 = temp;
255 temp = z1; z1 = z2; z2 = temp;
256 }
258 // ===== Interpolation variables =====
260 int n, fp = 8;
261 int lx01=0, lx12=0, lx02=0;
262 int lz01=0, lz12=0, lz02=0;
265 int dx01 = x1 - x0;
266 int dy01 = y1 - y0;
267 int dz01 = z1 - z0;
269 if (dy01!=0)
270 {
271 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
272 lz01 = (dz01*pdiv[dy01+2048])>>16;
273 }
275 int dx12 = x2 - x1;
276 int dy12 = y2 - y1;
277 int dz12 = z2 - z1;
279 if (dy12!=0)
280 {
281 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
282 lz12 = (dz12*pdiv[dy12+2048])>>16;
283 }
285 int dx02 = x2 - x0;
286 int dy02 = y2 - y0;
287 int dz02 = z2 - z0;
289 if (dy02!=0)
290 {
291 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
292 lz02 = (dz02*pdiv[dy02+2048])>>16;
293 }
295 int vramofs;
296 int x, y;
298 int x01 = x0<<fp;
299 int x02 = x01;
300 int z01 = z0;
301 int z02 = z01;
303 int dz;
304 int sx1, sx2;
305 int sz1, sz2;
307 int yp = y0 * ScreenWidth;
308 for (y = y0; y<y1; y++)
309 {
310 sx1 = x01>>fp;
311 sx2 = x02>>fp;
312 sz1 = z01;
313 sz2 = z02;
315 if (sx1>sx2)
316 {
317 temp = sx1; sx1 = sx2; sx2 = temp;
318 temp = sz1; sz1 = sz2; sz2 = temp;
319 }
320 if (sx2!=sx1) dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
322 yp+=ScreenWidth;
323 vramofs = yp + sx1;
324 for (x = sx1; x<sx2; x++)
325 {
326 sz1+=dz;
327 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
328 {
329 zbuffer[vramofs] = sz1;
330 *(vram+vramofs)=c;
331 }
334 vramofs++;
335 }
336 x01+=lx01;
337 x02+=lx02;
338 z01+=lz01;
339 z02+=lz02;
340 }
342 x01 = x1<<fp;
343 z01 = z1;
345 yp = y1 * ScreenWidth;
346 for (y = y1; y<y2; y++)
347 {
348 sx1 = x01>>fp;
349 sx2 = x02>>fp;
350 sz1 = z01;
351 sz2 = z02;
353 if (sx1>sx2)
354 {
355 temp = sx1; sx1 = sx2; sx2 = temp;
356 temp = sz1; sz1 = sz2; sz2 = temp;
357 }
359 if (sx2!=sx1) dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
361 yp+=ScreenWidth;
362 vramofs = yp + sx1;
363 for (x = sx1; x<sx2; x++)
364 {
365 sz1+=dz;
366 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
367 {
368 zbuffer[vramofs] = sz1;
369 *(vram+vramofs)=c;
370 }
371 vramofs++;
372 }
373 x01+=lx12;
374 x02+=lx02;
375 z01+=lz12;
376 z02+=lz02;
377 }
378 }
380 static inline void DrawGouraudTriangle (poly2d poly, unsigned short *vram, unsigned short shade[])
381 {
382 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
383 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
384 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
386 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
387 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
388 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
390 int c;
391 int c0 = spts[poly.p0].c;
392 int c1 = spts[poly.p1].c;
393 int c2 = spts[poly.p2].c;
395 // ===== Sort =====
397 int temp;
398 if (y1<y0)
399 {
400 temp = c0; c0 = c1; c1 = temp;
401 temp = x0; x0 = x1; x1 = temp;
402 temp = y0; y0 = y1; y1 = temp;
403 }
404 if (y2<y0)
405 {
406 temp = c0; c0 = c2; c2 = temp;
407 temp = x0; x0 = x2; x2 = temp;
408 temp = y0; y0 = y2; y2 = temp;
409 }
410 if (y2<y1)
411 {
412 temp = c1; c1 = c2; c2 = temp;
413 temp = x1; x1 = x2; x2 = temp;
414 temp = y1; y1 = y2; y2 = temp;
415 }
417 // ===== Interpolation variables =====
419 int n;
420 int fp = 8;
421 int lx01=0, lx12=0, lx02=0;
422 int lc01=0, lc12=0, lc02=0;
424 int dx01 = x1 - x0;
425 int dy01 = y1 - y0;
426 int dc01 = c1 - c0;
428 if (dy01!=0)
429 {
430 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
431 lc01 = ((dc01<<fp)*pdiv[dy01+2048])>>16;
432 }
434 int dx12 = x2 - x1;
435 int dy12 = y2 - y1;
436 int dc12 = c2 - c1;
438 if (dy12!=0)
439 {
440 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
441 lc12 = ((dc12<<fp)*pdiv[dy12+2048])>>16;
442 }
444 int dx02 = x2 - x0;
445 int dy02 = y2 - y0;
446 int dc02 = c2 - c0;
448 if (dy02!=0)
449 {
450 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
451 lc02 = ((dc02<<fp)*pdiv[dy02+2048])>>16;
452 }
454 int vramofs;
455 int x, y;
457 int x01 = x0<<fp;
458 int x02 = x01;
459 int c01 = c0<<fp;
460 int c02 = c01;
462 int dc;
463 int sc1, sc2;
464 int sx1, sx2;
466 int yp = y0 * ScreenWidth;
467 for (y = y0; y<y1; y++)
468 {
469 sx1 = x01>>fp;
470 sx2 = x02>>fp;
471 sc1 = c01;
472 sc2 = c02;
474 if (sx1>sx2)
475 {
476 temp = sx1; sx1 = sx2; sx2 = temp;
477 temp = sc1; sc1 = sc2; sc2 = temp;
478 }
480 if (sx2!=sx1)
481 dc = ((sc2 - sc1)*pdiv[(sx2-sx1)+2048])>>16;
483 yp+=ScreenWidth;
484 vramofs = yp + sx1;
485 for (x = sx1; x<sx2; x++)
486 {
487 sc1+=dc;
488 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
489 {
490 c = sc1>>fp;
491 if (c<0) c = 0;
492 *(vram+vramofs)=shade[c];
493 }
494 vramofs++;
495 }
496 x01+=lx01;
497 x02+=lx02;
498 c01+=lc01;
499 c02+=lc02;
500 }
502 x01 = x1<<fp;
503 c01 = c1<<fp;
505 yp = y1 * ScreenWidth;
506 for (y = y1; y<y2; y++)
507 {
508 sx1 = x01>>fp;
509 sx2 = x02>>fp;
510 sc1 = c01;
511 sc2 = c02;
513 if (sx1>sx2)
514 {
515 temp = sx1; sx1 = sx2; sx2 = temp;
516 temp = sc1; sc1 = sc2; sc2 = temp;
517 }
519 if (sx2!=sx1)
520 dc = ((sc2 - sc1)*pdiv[(sx2-sx1)+2048])>>16;
522 yp+=ScreenWidth;
523 vramofs = yp + sx1;
524 for (x = sx1; x<sx2; x++)
525 {
526 sc1+=dc;
527 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
528 {
529 c = sc1>>fp;
530 if (c<0) c = 0;
531 *(vram+vramofs)=shade[c];
532 }
533 vramofs++;
534 }
535 x01+=lx12;
536 x02+=lx02;
537 c01+=lc12;
538 c02+=lc02;
539 }
540 }
542 static inline void DrawGouraudTriangleZB (poly2d poly, unsigned short *vram, unsigned short shade[])
543 {
544 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
545 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
546 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
548 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
549 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
550 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
552 int c;
553 int c0 = spts[poly.p0].c;
554 int c1 = spts[poly.p1].c;
555 int c2 = spts[poly.p2].c;
557 int z0 = fpts[poly.p0].z;
558 int z1 = fpts[poly.p1].z;
559 int z2 = fpts[poly.p2].z;
561 // ===== Sort =====
563 int temp;
564 if (y1<y0)
565 {
566 temp = c0; c0 = c1; c1 = temp;
567 temp = z0; z0 = z1; z1 = temp;
568 temp = x0; x0 = x1; x1 = temp;
569 temp = y0; y0 = y1; y1 = temp;
570 }
571 if (y2<y0)
572 {
573 temp = c0; c0 = c2; c2 = temp;
574 temp = z0; z0 = z2; z2 = temp;
575 temp = x0; x0 = x2; x2 = temp;
576 temp = y0; y0 = y2; y2 = temp;
577 }
578 if (y2<y1)
579 {
580 temp = c1; c1 = c2; c2 = temp;
581 temp = z1; z1 = z2; z2 = temp;
582 temp = x1; x1 = x2; x2 = temp;
583 temp = y1; y1 = y2; y2 = temp;
584 }
586 // ===== Interpolation variables =====
588 int n;
589 int fp = 8;
590 int lx01=0, lx12=0, lx02=0;
591 int lc01=0, lc12=0, lc02=0;
592 int lz01=0, lz12=0, lz02=0;
594 int dx01 = x1 - x0;
595 int dy01 = y1 - y0;
596 int dc01 = c1 - c0;
597 int dz01 = z1 - z0;
599 if (dy01!=0)
600 {
601 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
602 lc01 = ((dc01<<fp)*pdiv[dy01+2048])>>16;
603 lz01 = (dz01*pdiv[dy01+2048])>>16;
604 }
606 int dx12 = x2 - x1;
607 int dy12 = y2 - y1;
608 int dc12 = c2 - c1;
609 int dz12 = z2 - z1;
611 if (dy12!=0)
612 {
613 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
614 lc12 = ((dc12<<fp)*pdiv[dy12+2048])>>16;
615 lz12 = (dz12*pdiv[dy12+2048])>>16;
616 }
618 int dx02 = x2 - x0;
619 int dy02 = y2 - y0;
620 int dc02 = c2 - c0;
621 int dz02 = z2 - z0;
623 if (dy02!=0)
624 {
625 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
626 lc02 = ((dc02<<fp)*pdiv[dy02+2048])>>16;
627 lz02 = (dz02*pdiv[dy02+2048])>>16;
628 }
630 int vramofs;
631 int x, y;
633 int x01 = x0<<fp;
634 int x02 = x01;
635 int c01 = c0<<fp;
636 int c02 = c01;
637 int z01 = z0;
638 int z02 = z01;
640 int dc, dz;
641 int sc1, sc2;
642 int sx1, sx2;
643 int sz1, sz2;
645 int yp = y0 * ScreenWidth;
646 for (y = y0; y<y1; y++)
647 {
648 sx1 = x01>>fp;
649 sx2 = x02>>fp;
650 sc1 = c01;
651 sc2 = c02;
652 sz1 = z01;
653 sz2 = z02;
655 if (sx1>sx2)
656 {
657 temp = sx1; sx1 = sx2; sx2 = temp;
658 temp = sc1; sc1 = sc2; sc2 = temp;
659 temp = sz1; sz1 = sz2; sz2 = temp;
660 }
662 if (sx2!=sx1)
663 {
664 dc = ((sc2 - sc1)*pdiv[(sx2-sx1)+2048])>>16;
665 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
666 }
668 yp+=ScreenWidth;
669 vramofs = yp + sx1;
670 for (x = sx1; x<sx2; x++)
671 {
672 sc1+=dc;
673 sz1+=dz;
674 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
675 {
676 c = sc1>>fp;
677 if (c<0) c=0;
678 zbuffer[vramofs] = sz1;
679 *(vram+vramofs)=shade[c];
680 }
681 vramofs++;
682 }
683 x01+=lx01;
684 x02+=lx02;
685 c01+=lc01;
686 c02+=lc02;
687 z01+=lz01;
688 z02+=lz02;
689 }
691 x01 = x1<<fp;
692 c01 = c1<<fp;
693 z01 = z1;
695 yp = y1 * ScreenWidth;
696 for (y = y1; y<y2; y++)
697 {
698 sx1 = x01>>fp;
699 sx2 = x02>>fp;
700 sc1 = c01;
701 sc2 = c02;
702 sz1 = z01;
703 sz2 = z02;
705 if (sx1>sx2)
706 {
707 temp = sx1; sx1 = sx2; sx2 = temp;
708 temp = sc1; sc1 = sc2; sc2 = temp;
709 temp = sz1; sz1 = sz2; sz2 = temp;
710 }
712 if (sx2!=sx1)
713 {
714 dc = ((sc2 - sc1)*pdiv[(sx2-sx1)+2048])>>16;
715 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
716 }
718 yp+=ScreenWidth;
719 vramofs = yp + sx1;
720 for (x = sx1; x<sx2; x++)
721 {
722 sc1+=dc;
723 sz1+=dz;
724 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
725 {
726 c = sc1>>fp;
727 if (c<0) c=0;
728 zbuffer[vramofs] = sz1;
729 *(vram+vramofs)=shade[c];
730 }
731 vramofs++;
732 }
733 x01+=lx12;
734 x02+=lx02;
735 c01+=lc12;
736 c02+=lc02;
737 z01+=lz12;
738 z02+=lz02;
739 }
740 }
742 static inline void DrawTextureTriangle(poly2d poly, unsigned short *vram, int tshr, unsigned short texture[])
743 {
744 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
745 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
746 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
748 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
749 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
750 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
752 int c;
754 int u0 = poly.tc0.u; int v0 = poly.tc0.v;
755 int u1 = poly.tc1.u; int v1 = poly.tc1.v;
756 int u2 = poly.tc2.u; int v2 = poly.tc2.v;
758 // ===== Sort =====
760 int temp;
761 if (y1<y0)
762 {
763 temp = u0; u0 = u1; u1 = temp;
764 temp = v0; v0 = v1; v1 = temp;
765 temp = x0; x0 = x1; x1 = temp;
766 temp = y0; y0 = y1; y1 = temp;
767 }
768 if (y2<y0)
769 {
770 temp = u0; u0 = u2; u2 = temp;
771 temp = v0; v0 = v2; v2 = temp;
772 temp = x0; x0 = x2; x2 = temp;
773 temp = y0; y0 = y2; y2 = temp;
774 }
775 if (y2<y1)
776 {
777 temp = u1; u1 = u2; u2 = temp;
778 temp = v1; v1 = v2; v2 = temp;
779 temp = x1; x1 = x2; x2 = temp;
780 temp = y1; y1 = y2; y2 = temp;
781 }
783 // ===== Interpolation variables =====
785 int n;
786 int fp = 8;
787 int lx01=0, lx12=0, lx02=0;
788 int lu01=0, lu12=0, lu02=0;
789 int lv01=0, lv12=0, lv02=0;
791 int dx01 = x1 - x0;
792 int dy01 = y1 - y0;
793 int du01 = u1 - u0;
794 int dv01 = v1 - v0;
796 if (dy01!=0)
797 {
798 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
799 lu01 = ((du01<<fp)*pdiv[dy01+2048])>>16;
800 lv01 = ((dv01<<fp)*pdiv[dy01+2048])>>16;
801 }
803 int dx12 = x2 - x1;
804 int dy12 = y2 - y1;
805 int du12 = u2 - u1;
806 int dv12 = v2 - v1;
808 if (dy12!=0)
809 {
810 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
811 lu12 = ((du12<<fp)*pdiv[dy12+2048])>>16;
812 lv12 = ((dv12<<fp)*pdiv[dy12+2048])>>16;
813 }
815 int dx02 = x2 - x0;
816 int dy02 = y2 - y0;
817 int du02 = u2 - u0;
818 int dv02 = v2 - v0;
820 if (dy02!=0)
821 {
822 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
823 lu02 = ((du02<<fp)*pdiv[dy02+2048])>>16;
824 lv02 = ((dv02<<fp)*pdiv[dy02+2048])>>16;
825 }
827 int vramofs;
828 int x, y;
830 int x01 = x0<<fp;
831 int x02 = x01;
832 int u01 = u0<<fp;
833 int u02 = u01;
834 int v01 = v0<<fp;
835 int v02 = v01;
837 int du, dv;
838 int su1, su2;
839 int sv1, sv2;
840 int sx1, sx2;
842 int px, py;
844 int yp = y0 * ScreenWidth;
845 for (y = y0; y<y1; y++)
846 {
847 sx1 = x01>>fp;
848 sx2 = x02>>fp;
849 su1 = u01;
850 su2 = u02;
851 sv1 = v01;
852 sv2 = v02;
854 if (sx1>sx2)
855 {
856 temp = sx1; sx1 = sx2; sx2 = temp;
857 temp = su1; su1 = su2; su2 = temp;
858 temp = sv1; sv1 = sv2; sv2 = temp;
859 }
861 if (sx2!=sx1)
862 {
863 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
864 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
865 }
867 yp+=ScreenWidth;
868 vramofs = yp + sx1;
869 for (x = sx1; x<sx2; x++)
870 {
871 su1+=du;
872 sv1+=dv;
873 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
874 {
875 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
876 *(vram+vramofs) = c;
877 }
878 vramofs++;
879 }
880 x01+=lx01;
881 x02+=lx02;
882 u01+=lu01;
883 u02+=lu02;
884 v01+=lv01;
885 v02+=lv02;
886 }
888 x01 = x1<<fp;
889 u01 = u1<<fp;
890 v01 = v1<<fp;
892 yp = y1 * ScreenWidth;
893 for (y = y1; y<y2; y++)
894 {
895 sx1 = x01>>fp;
896 sx2 = x02>>fp;
897 su1 = u01;
898 su2 = u02;
899 sv1 = v01;
900 sv2 = v02;
902 if (sx1>sx2)
903 {
904 temp = sx1; sx1 = sx2; sx2 = temp;
905 temp = su1; su1 = su2; su2 = temp;
906 temp = sv1; sv1 = sv2; sv2 = temp;
907 }
909 if (sx2!=sx1)
910 {
911 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
912 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
913 }
915 yp+=ScreenWidth;
916 vramofs = yp + sx1;
917 for (x = sx1; x<sx2; x++)
918 {
919 su1+=du;
920 sv1+=dv;
921 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
922 {
923 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
924 *(vram+vramofs) = c;
925 }
926 vramofs++;
927 }
928 x01+=lx12;
929 x02+=lx02;
930 u01+=lu12;
931 u02+=lu02;
932 v01+=lv12;
933 v02+=lv02;
934 }
935 }
937 static inline void DrawTextureTriangleZB(poly2d poly, unsigned short *vram, int tshr, unsigned short texture[])
938 {
939 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
940 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
941 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
943 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
944 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
945 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
947 int c;
949 int u0 = poly.tc0.u; int v0 = poly.tc0.v;
950 int u1 = poly.tc1.u; int v1 = poly.tc1.v;
951 int u2 = poly.tc2.u; int v2 = poly.tc2.v;
953 int z0 = fpts[poly.p0].z;
954 int z1 = fpts[poly.p1].z;
955 int z2 = fpts[poly.p2].z;
957 // ===== Sort =====
959 int temp;
960 if (y1<y0)
961 {
962 temp = u0; u0 = u1; u1 = temp;
963 temp = v0; v0 = v1; v1 = temp;
964 temp = z0; z0 = z1; z1 = temp;
965 temp = x0; x0 = x1; x1 = temp;
966 temp = y0; y0 = y1; y1 = temp;
967 }
968 if (y2<y0)
969 {
970 temp = u0; u0 = u2; u2 = temp;
971 temp = v0; v0 = v2; v2 = temp;
972 temp = z0; z0 = z2; z2 = temp;
973 temp = x0; x0 = x2; x2 = temp;
974 temp = y0; y0 = y2; y2 = temp;
975 }
976 if (y2<y1)
977 {
978 temp = u1; u1 = u2; u2 = temp;
979 temp = v1; v1 = v2; v2 = temp;
980 temp = z1; z1 = z2; z2 = temp;
981 temp = x1; x1 = x2; x2 = temp;
982 temp = y1; y1 = y2; y2 = temp;
983 }
985 // ===== Interpolation variables =====
987 int n;
988 int fp = 8;
989 int lx01=0, lx12=0, lx02=0;
990 int lu01=0, lu12=0, lu02=0;
991 int lv01=0, lv12=0, lv02=0;
992 int lz01=0, lz12=0, lz02=0;
994 int dx01 = x1 - x0;
995 int dy01 = y1 - y0;
996 int du01 = u1 - u0;
997 int dv01 = v1 - v0;
998 int dz01 = z1 - z0;
1000 if (dy01!=0)
1002 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
1003 lu01 = ((du01<<fp)*pdiv[dy01+2048])>>16;
1004 lv01 = ((dv01<<fp)*pdiv[dy01+2048])>>16;
1005 lz01 = (dz01*pdiv[dy01+2048])>>16;
1008 int dx12 = x2 - x1;
1009 int dy12 = y2 - y1;
1010 int du12 = u2 - u1;
1011 int dv12 = v2 - v1;
1012 int dz12 = z2 - z1;
1014 if (dy12!=0)
1016 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
1017 lu12 = ((du12<<fp)*pdiv[dy12+2048])>>16;
1018 lv12 = ((dv12<<fp)*pdiv[dy12+2048])>>16;
1019 lz12 = (dz12*pdiv[dy12+2048])>>16;
1022 int dx02 = x2 - x0;
1023 int dy02 = y2 - y0;
1024 int du02 = u2 - u0;
1025 int dv02 = v2 - v0;
1026 int dz02 = z2 - z0;
1028 if (dy02!=0)
1030 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
1031 lu02 = ((du02<<fp)*pdiv[dy02+2048])>>16;
1032 lv02 = ((dv02<<fp)*pdiv[dy02+2048])>>16;
1033 lz02 = (dz02*pdiv[dy02+2048])>>16;
1036 int vramofs;
1037 int x, y;
1039 int x01 = x0<<fp;
1040 int x02 = x01;
1041 int u01 = u0<<fp;
1042 int u02 = u01;
1043 int v01 = v0<<fp;
1044 int v02 = v01;
1045 int z01 = z0;
1046 int z02 = z01;
1048 int du, dv, dz;
1049 int su1, su2;
1050 int sv1, sv2;
1051 int sx1, sx2;
1052 int sz1, sz2;
1054 int px, py;
1056 int yp = y0 * ScreenWidth;
1057 for (y = y0; y<y1; y++)
1059 sx1 = x01>>fp;
1060 sx2 = x02>>fp;
1061 su1 = u01;
1062 su2 = u02;
1063 sv1 = v01;
1064 sv2 = v02;
1065 sz1 = z01;
1066 sz2 = z02;
1068 if (sx1>sx2)
1070 temp = sx1; sx1 = sx2; sx2 = temp;
1071 temp = su1; su1 = su2; su2 = temp;
1072 temp = sv1; sv1 = sv2; sv2 = temp;
1073 temp = sz1; sz1 = sz2; sz2 = temp;
1076 if (sx2!=sx1)
1078 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
1079 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
1080 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
1083 yp+=ScreenWidth;
1084 vramofs = yp + sx1;
1085 for (x = sx1; x<sx2; x++)
1087 su1+=du;
1088 sv1+=dv;
1089 sz1+=dz;
1090 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
1092 zbuffer[vramofs] = sz1;
1093 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
1094 *(vram+vramofs) = c;
1096 vramofs++;
1098 x01+=lx01;
1099 x02+=lx02;
1100 u01+=lu01;
1101 u02+=lu02;
1102 v01+=lv01;
1103 v02+=lv02;
1104 z01+=lz01;
1105 z02+=lz02;
1108 x01 = x1<<fp;
1109 u01 = u1<<fp;
1110 v01 = v1<<fp;
1111 z01 = z1;
1113 yp = y1 * ScreenWidth;
1114 for (y = y1; y<y2; y++)
1116 sx1 = x01>>fp;
1117 sx2 = x02>>fp;
1118 su1 = u01;
1119 su2 = u02;
1120 sv1 = v01;
1121 sv2 = v02;
1122 sz1 = z01;
1123 sz2 = z02;
1125 if (sx1>sx2)
1127 temp = sx1; sx1 = sx2; sx2 = temp;
1128 temp = su1; su1 = su2; su2 = temp;
1129 temp = sv1; sv1 = sv2; sv2 = temp;
1130 temp = sz1; sz1 = sz2; sz2 = temp;
1133 if (sx2!=sx1)
1135 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
1136 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
1137 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
1140 yp+=ScreenWidth;
1141 vramofs = yp + sx1;
1142 for (x = sx1; x<sx2; x++)
1144 su1+=du;
1145 sv1+=dv;
1146 sz1+=dz;
1147 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
1149 zbuffer[vramofs] = sz1;
1150 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
1151 *(vram+vramofs) = c;
1153 vramofs++;
1155 x01+=lx12;
1156 x02+=lx02;
1157 u01+=lu12;
1158 u02+=lu02;
1159 v01+=lv12;
1160 v02+=lv02;
1161 z01+=lz12;
1162 z02+=lz02;
1166 static inline void DrawEnvmappedTriangle(poly2d poly, unsigned short *vram, int tshr, unsigned short texture[])
1168 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
1169 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
1170 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
1172 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
1173 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
1174 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
1176 int c;
1178 int u0 = point_tc[poly.p0].u; int v0 = point_tc[poly.p0].v;
1179 int u1 = point_tc[poly.p1].u; int v1 = point_tc[poly.p1].v;
1180 int u2 = point_tc[poly.p2].u; int v2 = point_tc[poly.p2].v;
1182 // ===== Sort =====
1184 int temp;
1185 if (y1<y0)
1187 temp = u0; u0 = u1; u1 = temp;
1188 temp = v0; v0 = v1; v1 = temp;
1189 temp = x0; x0 = x1; x1 = temp;
1190 temp = y0; y0 = y1; y1 = temp;
1192 if (y2<y0)
1194 temp = u0; u0 = u2; u2 = temp;
1195 temp = v0; v0 = v2; v2 = temp;
1196 temp = x0; x0 = x2; x2 = temp;
1197 temp = y0; y0 = y2; y2 = temp;
1199 if (y2<y1)
1201 temp = u1; u1 = u2; u2 = temp;
1202 temp = v1; v1 = v2; v2 = temp;
1203 temp = x1; x1 = x2; x2 = temp;
1204 temp = y1; y1 = y2; y2 = temp;
1207 // ===== Interpolation variables =====
1209 int n;
1210 int fp = 8;
1211 int lx01=0, lx12=0, lx02=0;
1212 int lu01=0, lu12=0, lu02=0;
1213 int lv01=0, lv12=0, lv02=0;
1215 int dx01 = x1 - x0;
1216 int dy01 = y1 - y0;
1217 int du01 = u1 - u0;
1218 int dv01 = v1 - v0;
1220 if (dy01!=0)
1222 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
1223 lu01 = ((du01<<fp)*pdiv[dy01+2048])>>16;
1224 lv01 = ((dv01<<fp)*pdiv[dy01+2048])>>16;
1227 int dx12 = x2 - x1;
1228 int dy12 = y2 - y1;
1229 int du12 = u2 - u1;
1230 int dv12 = v2 - v1;
1232 if (dy12!=0)
1234 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
1235 lu12 = ((du12<<fp)*pdiv[dy12+2048])>>16;
1236 lv12 = ((dv12<<fp)*pdiv[dy12+2048])>>16;
1239 int dx02 = x2 - x0;
1240 int dy02 = y2 - y0;
1241 int du02 = u2 - u0;
1242 int dv02 = v2 - v0;
1244 if (dy02!=0)
1246 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
1247 lu02 = ((du02<<fp)*pdiv[dy02+2048])>>16;
1248 lv02 = ((dv02<<fp)*pdiv[dy02+2048])>>16;
1251 int vramofs;
1252 int x, y;
1254 int x01 = x0<<fp;
1255 int x02 = x01;
1256 int u01 = u0<<fp;
1257 int u02 = u01;
1258 int v01 = v0<<fp;
1259 int v02 = v01;
1261 int du, dv;
1262 int su1, su2;
1263 int sv1, sv2;
1264 int sx1, sx2;
1266 int px, py;
1268 int yp = y0 * ScreenWidth;
1269 for (y = y0; y<y1; y++)
1271 sx1 = x01>>fp;
1272 sx2 = x02>>fp;
1273 su1 = u01;
1274 su2 = u02;
1275 sv1 = v01;
1276 sv2 = v02;
1278 if (sx1>sx2)
1280 temp = sx1; sx1 = sx2; sx2 = temp;
1281 temp = su1; su1 = su2; su2 = temp;
1282 temp = sv1; sv1 = sv2; sv2 = temp;
1285 if (sx2!=sx1)
1287 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
1288 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
1291 yp+=ScreenWidth;
1292 vramofs = yp + sx1;
1293 for (x = sx1; x<sx2; x++)
1295 su1+=du;
1296 sv1+=dv;
1297 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
1299 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
1300 *(vram+vramofs) = c;
1302 vramofs++;
1304 x01+=lx01;
1305 x02+=lx02;
1306 u01+=lu01;
1307 u02+=lu02;
1308 v01+=lv01;
1309 v02+=lv02;
1312 x01 = x1<<fp;
1313 u01 = u1<<fp;
1314 v01 = v1<<fp;
1316 yp = y1 * ScreenWidth;
1317 for (y = y1; y<y2; y++)
1319 sx1 = x01>>fp;
1320 sx2 = x02>>fp;
1321 su1 = u01;
1322 su2 = u02;
1323 sv1 = v01;
1324 sv2 = v02;
1326 if (sx1>sx2)
1328 temp = sx1; sx1 = sx2; sx2 = temp;
1329 temp = su1; su1 = su2; su2 = temp;
1330 temp = sv1; sv1 = sv2; sv2 = temp;
1333 if (sx2!=sx1)
1335 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
1336 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
1339 yp+=ScreenWidth;
1340 vramofs = yp + sx1;
1341 for (x = sx1; x<sx2; x++)
1343 su1+=du;
1344 sv1+=dv;
1345 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
1347 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
1348 *(vram+vramofs) = c;
1350 vramofs++;
1352 x01+=lx12;
1353 x02+=lx02;
1354 u01+=lu12;
1355 u02+=lu02;
1356 v01+=lv12;
1357 v02+=lv02;
1362 static inline void DrawEnvmappedTriangleZB(poly2d poly, unsigned short *vram, int tshr, unsigned short texture[])
1364 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
1365 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
1366 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
1368 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
1369 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
1370 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
1372 int c;
1374 int u0 = point_tc[poly.p0].u; int v0 = point_tc[poly.p0].v;
1375 int u1 = point_tc[poly.p1].u; int v1 = point_tc[poly.p1].v;
1376 int u2 = point_tc[poly.p2].u; int v2 = point_tc[poly.p2].v;
1378 int z0 = fpts[poly.p0].z;
1379 int z1 = fpts[poly.p1].z;
1380 int z2 = fpts[poly.p2].z;
1382 // ===== Sort =====
1384 int temp;
1385 if (y1<y0)
1387 temp = u0; u0 = u1; u1 = temp;
1388 temp = v0; v0 = v1; v1 = temp;
1389 temp = z0; z0 = z1; z1 = temp;
1390 temp = x0; x0 = x1; x1 = temp;
1391 temp = y0; y0 = y1; y1 = temp;
1393 if (y2<y0)
1395 temp = u0; u0 = u2; u2 = temp;
1396 temp = v0; v0 = v2; v2 = temp;
1397 temp = z0; z0 = z2; z2 = temp;
1398 temp = x0; x0 = x2; x2 = temp;
1399 temp = y0; y0 = y2; y2 = temp;
1401 if (y2<y1)
1403 temp = u1; u1 = u2; u2 = temp;
1404 temp = v1; v1 = v2; v2 = temp;
1405 temp = z1; z1 = z2; z2 = temp;
1406 temp = x1; x1 = x2; x2 = temp;
1407 temp = y1; y1 = y2; y2 = temp;
1410 // ===== Interpolation variables =====
1412 int n;
1413 int fp = 8;
1414 int lx01=0, lx12=0, lx02=0;
1415 int lu01=0, lu12=0, lu02=0;
1416 int lv01=0, lv12=0, lv02=0;
1417 int lz01=0, lz12=0, lz02=0;
1419 int dx01 = x1 - x0;
1420 int dy01 = y1 - y0;
1421 int du01 = u1 - u0;
1422 int dv01 = v1 - v0;
1423 int dz01 = z1 - z0;
1425 if (dy01!=0)
1427 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
1428 lu01 = ((du01<<fp)*pdiv[dy01+2048])>>16;
1429 lv01 = ((dv01<<fp)*pdiv[dy01+2048])>>16;
1430 lz01 = (dz01*pdiv[dy01+2048])>>16;
1433 int dx12 = x2 - x1;
1434 int dy12 = y2 - y1;
1435 int du12 = u2 - u1;
1436 int dv12 = v2 - v1;
1437 int dz12 = z2 - z1;
1439 if (dy12!=0)
1441 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
1442 lu12 = ((du12<<fp)*pdiv[dy12+2048])>>16;
1443 lv12 = ((dv12<<fp)*pdiv[dy12+2048])>>16;
1444 lz12 = (dz12*pdiv[dy12+2048])>>16;
1447 int dx02 = x2 - x0;
1448 int dy02 = y2 - y0;
1449 int du02 = u2 - u0;
1450 int dv02 = v2 - v0;
1451 int dz02 = z2 - z0;
1453 if (dy02!=0)
1455 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
1456 lu02 = ((du02<<fp)*pdiv[dy02+2048])>>16;
1457 lv02 = ((dv02<<fp)*pdiv[dy02+2048])>>16;
1458 lz02 = (dz02*pdiv[dy02+2048])>>16;
1461 int vramofs;
1462 int x, y;
1464 int x01 = x0<<fp;
1465 int x02 = x01;
1466 int u01 = u0<<fp;
1467 int u02 = u01;
1468 int v01 = v0<<fp;
1469 int v02 = v01;
1470 int z01 = z0;
1471 int z02 = z01;
1473 int du, dv, dz;
1474 int su1, su2;
1475 int sv1, sv2;
1476 int sx1, sx2;
1477 int sz1, sz2;
1479 int px, py;
1481 int yp = y0 * ScreenWidth;
1482 for (y = y0; y<y1; y++)
1484 sx1 = x01>>fp;
1485 sx2 = x02>>fp;
1486 su1 = u01;
1487 su2 = u02;
1488 sv1 = v01;
1489 sv2 = v02;
1490 sz1 = z01;
1491 sz2 = z02;
1493 if (sx1>sx2)
1495 temp = sx1; sx1 = sx2; sx2 = temp;
1496 temp = su1; su1 = su2; su2 = temp;
1497 temp = sv1; sv1 = sv2; sv2 = temp;
1498 temp = sz1; sz1 = sz2; sz2 = temp;
1501 if (sx2!=sx1)
1503 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
1504 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
1505 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
1508 yp+=ScreenWidth;
1509 vramofs = yp + sx1;
1510 for (x = sx1; x<sx2; x++)
1512 su1+=du;
1513 sv1+=dv;
1514 sz1+=dz;
1515 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
1517 zbuffer[vramofs] = sz1;
1518 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
1519 *(vram+vramofs) = c;
1521 vramofs++;
1523 x01+=lx01;
1524 x02+=lx02;
1525 u01+=lu01;
1526 u02+=lu02;
1527 v01+=lv01;
1528 v02+=lv02;
1529 z01+=lz01;
1530 z02+=lz02;
1533 x01 = x1<<fp;
1534 u01 = u1<<fp;
1535 v01 = v1<<fp;
1536 z01 = z1;
1538 yp = y1 * ScreenWidth;
1539 for (y = y1; y<y2; y++)
1541 sx1 = x01>>fp;
1542 sx2 = x02>>fp;
1543 su1 = u01;
1544 su2 = u02;
1545 sv1 = v01;
1546 sv2 = v02;
1547 sz1 = z01;
1548 sz2 = z02;
1550 if (sx1>sx2)
1552 temp = sx1; sx1 = sx2; sx2 = temp;
1553 temp = su1; su1 = su2; su2 = temp;
1554 temp = sv1; sv1 = sv2; sv2 = temp;
1555 temp = sz1; sz1 = sz2; sz2 = temp;
1558 if (sx2!=sx1)
1560 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
1561 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
1562 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
1565 yp+=ScreenWidth;
1566 vramofs = yp + sx1;
1567 for (x = sx1; x<sx2; x++)
1569 su1+=du;
1570 sv1+=dv;
1571 sz1+=dz;
1572 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
1574 zbuffer[vramofs] = sz1;
1575 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
1576 *(vram+vramofs) = c;
1578 vramofs++;
1580 x01+=lx12;
1581 x02+=lx02;
1582 u01+=lu12;
1583 u02+=lu02;
1584 v01+=lv12;
1585 v02+=lv02;
1586 z01+=lz12;
1587 z02+=lz02;
1591 void zsort(int zsortdata[], object3d *obj)
1593 int i, mz;
1594 for (i=0; i<obj->npls; i++)
1596 mz = (fpts[obj->poly[i].p0].z + fpts[obj->poly[i].p1].z + fpts[obj->poly[i].p2].z)>>2;
1597 zsortdata[i] = -mz;
1598 swp[i] = i;
1603 inline void ClearZbuffer()
1605 memset(zbuffer, 0xFFFFFF, sizeof(unsigned int) * ScreenSize);
1608 void Render(object3d *obj, unsigned short shade[], unsigned short texture[], unsigned short texture_size, unsigned short *vram)
1610 int i, j;
1611 int vx0, vy0, vx1, vy1, n;
1612 int tu, tv, s;
1613 int texshr = (int)(log(256 / texture_size)/ log(2));
1615 int rmode;
1616 if (zb==1 && RenderMode>=FLAT) rmode = RenderMode | ZBUFFER;
1617 else rmode = RenderMode;
1619 switch (rmode)
1622 case POINTS:
1623 for (i=obj->npts-1; i>=0; i--)
1624 if (spts[i].x>=0 && spts[i].x<ScreenWidth && spts[i].y>=0 && spts[i].y<ScreenHeight)
1625 *(vram + spts[i].x + spts[i].y * ScreenWidth) = 0xFFFF;
1626 break;
1629 case WIRE:
1630 for (i=obj->nlns-1; i>=0; i--)
1631 drawline(obj->line[i], vram);
1632 break;
1634 case FLAT:
1635 rotate3d_normals(obj);
1636 CalcPolyColor(obj);
1638 zsort (zdata, obj);
1639 quicksort(0, obj->npls - 1, zdata);
1641 for (i=0; i<obj->npls; i++)
1643 j = swp[i];
1644 vx0 = spts[obj->poly[j].p0].x - spts[obj->poly[j].p1].x;
1645 vy0 = spts[obj->poly[j].p0].y - spts[obj->poly[j].p1].y;
1646 vx1 = spts[obj->poly[j].p2].x - spts[obj->poly[j].p1].x;
1647 vy1 = spts[obj->poly[j].p2].y - spts[obj->poly[j].p1].y;
1648 n = vx0 * vy1 - vx1 * vy0;
1649 if (n<0)
1651 obj->poly[j].c = spls[j].c;
1652 DrawFlatTriangle(obj->poly[j], vram, shade);
1655 break;
1657 case (FLAT | ZBUFFER):
1658 rotate3d_normals(obj);
1659 CalcPolyColor(obj);
1661 ClearZbuffer();
1662 for (i=obj->npls-1; i>=0; i--)
1664 obj->poly[i].c = spls[i].c;
1665 if (norms[i].z>=0)
1666 DrawFlatTriangleZB(obj->poly[i], vram, shade);
1668 break;
1670 case GOURAUD:
1671 rotate3d_pt_normals(obj);
1672 CalcPointColor(obj);
1674 zsort (zdata, obj);
1675 quicksort(0, obj->npls - 1, zdata);
1677 for (i=0; i<obj->npls; i++)
1679 j = swp[i];
1680 vx0 = spts[obj->poly[j].p0].x - spts[obj->poly[j].p1].x;
1681 vy0 = spts[obj->poly[j].p0].y - spts[obj->poly[j].p1].y;
1682 vx1 = spts[obj->poly[j].p2].x - spts[obj->poly[j].p1].x;
1683 vy1 = spts[obj->poly[j].p2].y - spts[obj->poly[j].p1].y;
1684 n = vx0 * vy1 - vx1 * vy0;
1685 if (n<0)
1686 DrawGouraudTriangle(obj->poly[j], vram, shade);
1688 break;
1690 case (GOURAUD | ZBUFFER):
1691 rotate3d_normals(obj);
1692 rotate3d_pt_normals(obj);
1694 CalcPointColor(obj);
1695 ClearZbuffer();
1696 for (i=obj->npls-1; i>=0; i--)
1698 if (norms[i].z>=0)
1699 DrawGouraudTriangleZB(obj->poly[i], vram, shade);
1701 break;
1703 case (TEXTURE):
1704 zsort (zdata, obj);
1705 quicksort(0, obj->npls - 1, zdata);
1707 for (i=0; i<obj->npls; i++)
1709 j = swp[i];
1710 vx0 = spts[obj->poly[j].p0].x - spts[obj->poly[j].p1].x;
1711 vy0 = spts[obj->poly[j].p0].y - spts[obj->poly[j].p1].y;
1712 vx1 = spts[obj->poly[j].p2].x - spts[obj->poly[j].p1].x;
1713 vy1 = spts[obj->poly[j].p2].y - spts[obj->poly[j].p1].y;
1714 n = vx0 * vy1 - vx1 * vy0;
1715 if (n<0)
1717 DrawTextureTriangle(obj->poly[j], vram, texshr, texture);
1720 break;
1722 case (TEXTURE | ZBUFFER):
1723 rotate3d_normals(obj);
1725 ClearZbuffer();
1726 for (i=obj->npls-1; i>=0; i--)
1728 if (norms[i].z>=0)
1729 DrawTextureTriangleZB(obj->poly[i], vram, 0, texture);
1731 break;
1733 case (ENVMAP):
1734 rotate3d_pt_normals(obj);
1736 zsort (zdata, obj);
1737 quicksort(0, obj->npls - 1, zdata);
1739 for (i=0; i<obj->npts; i++)
1741 tu = (pt_norms[i].x>>9) + 127;
1742 tv = (pt_norms[i].y>>9) + 127;
1743 point_tc[i].u = abs(tu) & 255;
1744 point_tc[i].v = abs(tv) & 255;
1747 for (i=0; i<obj->npls; i++)
1749 j = swp[i];
1750 vx0 = spts[obj->poly[j].p0].x - spts[obj->poly[j].p1].x;
1751 vy0 = spts[obj->poly[j].p0].y - spts[obj->poly[j].p1].y;
1752 vx1 = spts[obj->poly[j].p2].x - spts[obj->poly[j].p1].x;
1753 vy1 = spts[obj->poly[j].p2].y - spts[obj->poly[j].p1].y;
1754 n = vx0 * vy1 - vx1 * vy0;
1755 if (n<0)
1756 DrawEnvmappedTriangle(obj->poly[j], vram, texshr, texture);
1758 break;
1760 case (ENVMAP | ZBUFFER):
1761 rotate3d_normals(obj);
1762 rotate3d_pt_normals(obj);
1764 ClearZbuffer();
1765 for (i=obj->npts-1; i>=0; i--)
1767 tu = (pt_norms[i].x>>9) + 127;
1768 tv = (pt_norms[i].y>>9) + 127;
1769 point_tc[i].u = abs(tu) & 255;
1770 point_tc[i].v = abs(tv) & 255;
1774 for (i=obj->npls-1; i>=0; i--)
1776 if (norms[i].z>=0)
1777 DrawEnvmappedTriangleZB(obj->poly[i], vram, 2, texture);
1779 break;
1781 default:
1782 break;