gpmark

annotate 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
rev   line source
nuclear@0 1 #include <math.h>
nuclear@0 2 #include <stdlib.h>
nuclear@0 3 #include <string.h>
nuclear@0 4
nuclear@0 5 #include "engine3d.h"
nuclear@0 6 #include "render3d.h"
nuclear@0 7 #include "main.h"
nuclear@0 8
nuclear@0 9 unsigned char ball_c[256];
nuclear@0 10 unsigned int ball_p[256];
nuclear@0 11
nuclear@0 12 extern unsigned short swp[MAXDATA];
nuclear@0 13 int zdata[MAXDATA];
nuclear@0 14
nuclear@0 15 extern point3d fpts[MAXDATA];
nuclear@0 16 extern point3d norms[MAXDATA];
nuclear@0 17 extern point3d pt_norms[MAXDATA];
nuclear@0 18 extern point2d spts[MAXDATA];
nuclear@0 19 extern point3d spls[MAXDATA];
nuclear@0 20 tcord point_tc[MAXDATA];
nuclear@0 21
nuclear@0 22 unsigned int RenderMode = ENVMAP;
nuclear@0 23
nuclear@0 24 unsigned int zbuffer[ScreenSize];
nuclear@0 25
nuclear@0 26 int pdiv[4096];
nuclear@0 27
nuclear@0 28 extern int prticks;
nuclear@0 29 int zb = 1;
nuclear@0 30
nuclear@0 31 int mlk = 8;
nuclear@0 32
nuclear@0 33 void initRender3D()
nuclear@0 34 {
nuclear@0 35 int fp = 16;
nuclear@0 36 int i;
nuclear@0 37 for (i=0; i<4096; i++)
nuclear@0 38 {
nuclear@0 39 if ((i-2048)!=0)
nuclear@0 40 pdiv[i] = (1<<fp)/(i-2048);
nuclear@0 41 else
nuclear@0 42 pdiv[i] = (1<<fp);
nuclear@0 43 }
nuclear@0 44 }
nuclear@0 45
nuclear@0 46 static inline void drawpoint(point2d point, unsigned short *vram)
nuclear@0 47 {
nuclear@0 48 if (point.x>=0 && point.x<ScreenWidth && point.y>=0 && point.y<ScreenHeight)
nuclear@0 49 *(vram + point.x + point.y * ScreenWidth) = 0xFFFF;
nuclear@0 50 }
nuclear@0 51
nuclear@0 52
nuclear@0 53 static inline void drawline (line2d line, unsigned short *vram)
nuclear@0 54 {
nuclear@0 55
nuclear@0 56 int x1 = spts[line.p0].x;
nuclear@0 57 int y1 = spts[line.p0].y;
nuclear@0 58 int x2 = spts[line.p1].x;
nuclear@0 59 int y2 = spts[line.p1].y;
nuclear@0 60 int c = line.c;
nuclear@0 61
nuclear@0 62 int dx, dy, n, l;
nuclear@0 63 int x00, y00;
nuclear@0 64 int fp = 12;
nuclear@0 65 int vramofs;
nuclear@0 66
nuclear@0 67 int x, y;
nuclear@0 68
nuclear@0 69 dx = x2 - x1;
nuclear@0 70 dy = y2 - y1;
nuclear@0 71
nuclear@0 72 if (abs(dy) < abs(dx))
nuclear@0 73 {
nuclear@0 74 if (x1>x2)
nuclear@0 75 {
nuclear@0 76 n = x1; x1 = x2; x2 = n;
nuclear@0 77 n = y1; y1 = y2; y2 = n;
nuclear@0 78 }
nuclear@0 79
nuclear@0 80 if (dx!=0) l = ((dy<<fp)*pdiv[dx+2048])>>16;
nuclear@0 81 y00 = y1<<fp;
nuclear@0 82 for (x=x1; x<x2; x++)
nuclear@0 83 {
nuclear@0 84 vramofs = ((y00 += l)>>fp)*ScreenWidth + x;
nuclear@0 85 if (vramofs>=0 && vramofs<ScreenSize) *(vram + vramofs) = c;
nuclear@0 86 }
nuclear@0 87 }
nuclear@0 88 else
nuclear@0 89 {
nuclear@0 90 if (y1>y2)
nuclear@0 91 {
nuclear@0 92 n = y1; y1 = y2; y2 = n;
nuclear@0 93 n = x1; x1 = x2; x2 = n;
nuclear@0 94 }
nuclear@0 95
nuclear@0 96 if (dy!=0) l = ((dx<<fp)*pdiv[dy+2048])>>16;
nuclear@0 97 x00 = x1<<fp;
nuclear@0 98
nuclear@0 99 for (y=y1; y<y2; y++)
nuclear@0 100 {
nuclear@0 101 vramofs = y*ScreenWidth + ((x00 += l)>>fp);
nuclear@0 102 if (vramofs>=0 && vramofs<ScreenSize) * (vram + vramofs) = c;
nuclear@0 103 }
nuclear@0 104
nuclear@0 105 }
nuclear@0 106 }
nuclear@0 107
nuclear@0 108
nuclear@0 109 static inline void DrawFlatTriangle (poly2d poly, unsigned short *vram, unsigned short shade[])
nuclear@0 110 {
nuclear@0 111 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
nuclear@0 112 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
nuclear@0 113 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
nuclear@0 114 int c = shade[poly.c];
nuclear@0 115
nuclear@0 116 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
nuclear@0 117 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
nuclear@0 118 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
nuclear@0 119
nuclear@0 120 //156-187
nuclear@0 121 // ===== Sort =====
nuclear@0 122
nuclear@0 123 int temp;
nuclear@0 124 if (y1<y0)
nuclear@0 125 {
nuclear@0 126 temp = x0; x0 = x1; x1 = temp;
nuclear@0 127 temp = y0; y0 = y1; y1 = temp;
nuclear@0 128 }
nuclear@0 129 if (y2<y0)
nuclear@0 130 {
nuclear@0 131 temp = x0; x0 = x2; x2 = temp;
nuclear@0 132 temp = y0; y0 = y2; y2 = temp;
nuclear@0 133 }
nuclear@0 134 if (y2<y1)
nuclear@0 135 {
nuclear@0 136 temp = x1; x1 = x2; x2 = temp;
nuclear@0 137 temp = y1; y1 = y2; y2 = temp;
nuclear@0 138 }
nuclear@0 139
nuclear@0 140 // ===== Interpolation variables =====
nuclear@0 141
nuclear@0 142 int n, fp = 8;
nuclear@0 143 int lx01=0, lx12=0, lx02=0;
nuclear@0 144
nuclear@0 145 int dx01 = x1 - x0;
nuclear@0 146 int dy01 = y1 - y0;
nuclear@0 147
nuclear@0 148 if (dy01!=0)
nuclear@0 149 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 150
nuclear@0 151 int dx12 = x2 - x1;
nuclear@0 152 int dy12 = y2 - y1;
nuclear@0 153
nuclear@0 154 if (dy12!=0)
nuclear@0 155 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 156
nuclear@0 157 int dx02 = x2 - x0;
nuclear@0 158 int dy02 = y2 - y0;
nuclear@0 159
nuclear@0 160 if (dy02!=0)
nuclear@0 161 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 162
nuclear@0 163 int vramofs;
nuclear@0 164 int x, y;
nuclear@0 165
nuclear@0 166 int x01 = x0<<fp;
nuclear@0 167 int x02 = x01;
nuclear@0 168
nuclear@0 169 int sx1, sx2;
nuclear@0 170
nuclear@0 171 int yp = y0 * ScreenWidth;
nuclear@0 172 for (y = y0; y<y1; y++)
nuclear@0 173 {
nuclear@0 174 sx1 = x01>>fp;
nuclear@0 175 sx2 = x02>>fp;
nuclear@0 176
nuclear@0 177 if (sx1>sx2)
nuclear@0 178 {
nuclear@0 179 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 180 }
nuclear@0 181
nuclear@0 182 yp+=ScreenWidth;
nuclear@0 183 vramofs = yp + sx1;
nuclear@0 184 for (x = sx1; x<sx2; x++)
nuclear@0 185 {
nuclear@0 186 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
nuclear@0 187 *(vram+vramofs)=c;
nuclear@0 188 vramofs++;
nuclear@0 189 }
nuclear@0 190 x01+=lx01;
nuclear@0 191 x02+=lx02;
nuclear@0 192 }
nuclear@0 193
nuclear@0 194 x01 = x1<<fp;
nuclear@0 195
nuclear@0 196 yp = y1 * ScreenWidth;
nuclear@0 197 for (y = y1; y<y2; y++)
nuclear@0 198 {
nuclear@0 199 sx1 = x01>>fp;
nuclear@0 200 sx2 = x02>>fp;
nuclear@0 201
nuclear@0 202 if (sx1>sx2)
nuclear@0 203 {
nuclear@0 204 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 205 }
nuclear@0 206
nuclear@0 207 yp+=ScreenWidth;
nuclear@0 208 vramofs = yp + sx1;
nuclear@0 209 for (x = sx1; x<sx2; x++)
nuclear@0 210 {
nuclear@0 211 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
nuclear@0 212 *(vram+vramofs)=c;
nuclear@0 213 vramofs++;
nuclear@0 214 }
nuclear@0 215 x01+=lx12;
nuclear@0 216 x02+=lx02;
nuclear@0 217 }
nuclear@0 218 }
nuclear@0 219
nuclear@0 220
nuclear@0 221 static inline void DrawFlatTriangleZB (poly2d poly, unsigned short *vram, unsigned short shade[])
nuclear@0 222 {
nuclear@0 223 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
nuclear@0 224 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
nuclear@0 225 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
nuclear@0 226 int c = shade[poly.c];
nuclear@0 227
nuclear@0 228 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
nuclear@0 229 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
nuclear@0 230 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
nuclear@0 231
nuclear@0 232 int z0 = fpts[poly.p0].z;
nuclear@0 233 int z1 = fpts[poly.p1].z;
nuclear@0 234 int z2 = fpts[poly.p2].z;
nuclear@0 235
nuclear@0 236 // ===== Sort =====
nuclear@0 237
nuclear@0 238 int temp;
nuclear@0 239 if (y1<y0)
nuclear@0 240 {
nuclear@0 241 temp = x0; x0 = x1; x1 = temp;
nuclear@0 242 temp = y0; y0 = y1; y1 = temp;
nuclear@0 243 temp = z0; z0 = z1; z1 = temp;
nuclear@0 244 }
nuclear@0 245 if (y2<y0)
nuclear@0 246 {
nuclear@0 247 temp = x0; x0 = x2; x2 = temp;
nuclear@0 248 temp = y0; y0 = y2; y2 = temp;
nuclear@0 249 temp = z0; z0 = z2; z2 = temp;
nuclear@0 250 }
nuclear@0 251 if (y2<y1)
nuclear@0 252 {
nuclear@0 253 temp = x1; x1 = x2; x2 = temp;
nuclear@0 254 temp = y1; y1 = y2; y2 = temp;
nuclear@0 255 temp = z1; z1 = z2; z2 = temp;
nuclear@0 256 }
nuclear@0 257
nuclear@0 258 // ===== Interpolation variables =====
nuclear@0 259
nuclear@0 260 int n, fp = 8;
nuclear@0 261 int lx01=0, lx12=0, lx02=0;
nuclear@0 262 int lz01=0, lz12=0, lz02=0;
nuclear@0 263
nuclear@0 264
nuclear@0 265 int dx01 = x1 - x0;
nuclear@0 266 int dy01 = y1 - y0;
nuclear@0 267 int dz01 = z1 - z0;
nuclear@0 268
nuclear@0 269 if (dy01!=0)
nuclear@0 270 {
nuclear@0 271 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 272 lz01 = (dz01*pdiv[dy01+2048])>>16;
nuclear@0 273 }
nuclear@0 274
nuclear@0 275 int dx12 = x2 - x1;
nuclear@0 276 int dy12 = y2 - y1;
nuclear@0 277 int dz12 = z2 - z1;
nuclear@0 278
nuclear@0 279 if (dy12!=0)
nuclear@0 280 {
nuclear@0 281 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 282 lz12 = (dz12*pdiv[dy12+2048])>>16;
nuclear@0 283 }
nuclear@0 284
nuclear@0 285 int dx02 = x2 - x0;
nuclear@0 286 int dy02 = y2 - y0;
nuclear@0 287 int dz02 = z2 - z0;
nuclear@0 288
nuclear@0 289 if (dy02!=0)
nuclear@0 290 {
nuclear@0 291 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 292 lz02 = (dz02*pdiv[dy02+2048])>>16;
nuclear@0 293 }
nuclear@0 294
nuclear@0 295 int vramofs;
nuclear@0 296 int x, y;
nuclear@0 297
nuclear@0 298 int x01 = x0<<fp;
nuclear@0 299 int x02 = x01;
nuclear@0 300 int z01 = z0;
nuclear@0 301 int z02 = z01;
nuclear@0 302
nuclear@0 303 int dz;
nuclear@0 304 int sx1, sx2;
nuclear@0 305 int sz1, sz2;
nuclear@0 306
nuclear@0 307 int yp = y0 * ScreenWidth;
nuclear@0 308 for (y = y0; y<y1; y++)
nuclear@0 309 {
nuclear@0 310 sx1 = x01>>fp;
nuclear@0 311 sx2 = x02>>fp;
nuclear@0 312 sz1 = z01;
nuclear@0 313 sz2 = z02;
nuclear@0 314
nuclear@0 315 if (sx1>sx2)
nuclear@0 316 {
nuclear@0 317 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 318 temp = sz1; sz1 = sz2; sz2 = temp;
nuclear@0 319 }
nuclear@0 320 if (sx2!=sx1) dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 321
nuclear@0 322 yp+=ScreenWidth;
nuclear@0 323 vramofs = yp + sx1;
nuclear@0 324 for (x = sx1; x<sx2; x++)
nuclear@0 325 {
nuclear@0 326 sz1+=dz;
nuclear@0 327 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
nuclear@0 328 {
nuclear@0 329 zbuffer[vramofs] = sz1;
nuclear@0 330 *(vram+vramofs)=c;
nuclear@0 331 }
nuclear@0 332
nuclear@0 333
nuclear@0 334 vramofs++;
nuclear@0 335 }
nuclear@0 336 x01+=lx01;
nuclear@0 337 x02+=lx02;
nuclear@0 338 z01+=lz01;
nuclear@0 339 z02+=lz02;
nuclear@0 340 }
nuclear@0 341
nuclear@0 342 x01 = x1<<fp;
nuclear@0 343 z01 = z1;
nuclear@0 344
nuclear@0 345 yp = y1 * ScreenWidth;
nuclear@0 346 for (y = y1; y<y2; y++)
nuclear@0 347 {
nuclear@0 348 sx1 = x01>>fp;
nuclear@0 349 sx2 = x02>>fp;
nuclear@0 350 sz1 = z01;
nuclear@0 351 sz2 = z02;
nuclear@0 352
nuclear@0 353 if (sx1>sx2)
nuclear@0 354 {
nuclear@0 355 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 356 temp = sz1; sz1 = sz2; sz2 = temp;
nuclear@0 357 }
nuclear@0 358
nuclear@0 359 if (sx2!=sx1) dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 360
nuclear@0 361 yp+=ScreenWidth;
nuclear@0 362 vramofs = yp + sx1;
nuclear@0 363 for (x = sx1; x<sx2; x++)
nuclear@0 364 {
nuclear@0 365 sz1+=dz;
nuclear@0 366 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
nuclear@0 367 {
nuclear@0 368 zbuffer[vramofs] = sz1;
nuclear@0 369 *(vram+vramofs)=c;
nuclear@0 370 }
nuclear@0 371 vramofs++;
nuclear@0 372 }
nuclear@0 373 x01+=lx12;
nuclear@0 374 x02+=lx02;
nuclear@0 375 z01+=lz12;
nuclear@0 376 z02+=lz02;
nuclear@0 377 }
nuclear@0 378 }
nuclear@0 379
nuclear@0 380 static inline void DrawGouraudTriangle (poly2d poly, unsigned short *vram, unsigned short shade[])
nuclear@0 381 {
nuclear@0 382 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
nuclear@0 383 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
nuclear@0 384 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
nuclear@0 385
nuclear@0 386 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
nuclear@0 387 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
nuclear@0 388 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
nuclear@0 389
nuclear@0 390 int c;
nuclear@0 391 int c0 = spts[poly.p0].c;
nuclear@0 392 int c1 = spts[poly.p1].c;
nuclear@0 393 int c2 = spts[poly.p2].c;
nuclear@0 394
nuclear@0 395 // ===== Sort =====
nuclear@0 396
nuclear@0 397 int temp;
nuclear@0 398 if (y1<y0)
nuclear@0 399 {
nuclear@0 400 temp = c0; c0 = c1; c1 = temp;
nuclear@0 401 temp = x0; x0 = x1; x1 = temp;
nuclear@0 402 temp = y0; y0 = y1; y1 = temp;
nuclear@0 403 }
nuclear@0 404 if (y2<y0)
nuclear@0 405 {
nuclear@0 406 temp = c0; c0 = c2; c2 = temp;
nuclear@0 407 temp = x0; x0 = x2; x2 = temp;
nuclear@0 408 temp = y0; y0 = y2; y2 = temp;
nuclear@0 409 }
nuclear@0 410 if (y2<y1)
nuclear@0 411 {
nuclear@0 412 temp = c1; c1 = c2; c2 = temp;
nuclear@0 413 temp = x1; x1 = x2; x2 = temp;
nuclear@0 414 temp = y1; y1 = y2; y2 = temp;
nuclear@0 415 }
nuclear@0 416
nuclear@0 417 // ===== Interpolation variables =====
nuclear@0 418
nuclear@0 419 int n;
nuclear@0 420 int fp = 8;
nuclear@0 421 int lx01=0, lx12=0, lx02=0;
nuclear@0 422 int lc01=0, lc12=0, lc02=0;
nuclear@0 423
nuclear@0 424 int dx01 = x1 - x0;
nuclear@0 425 int dy01 = y1 - y0;
nuclear@0 426 int dc01 = c1 - c0;
nuclear@0 427
nuclear@0 428 if (dy01!=0)
nuclear@0 429 {
nuclear@0 430 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 431 lc01 = ((dc01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 432 }
nuclear@0 433
nuclear@0 434 int dx12 = x2 - x1;
nuclear@0 435 int dy12 = y2 - y1;
nuclear@0 436 int dc12 = c2 - c1;
nuclear@0 437
nuclear@0 438 if (dy12!=0)
nuclear@0 439 {
nuclear@0 440 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 441 lc12 = ((dc12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 442 }
nuclear@0 443
nuclear@0 444 int dx02 = x2 - x0;
nuclear@0 445 int dy02 = y2 - y0;
nuclear@0 446 int dc02 = c2 - c0;
nuclear@0 447
nuclear@0 448 if (dy02!=0)
nuclear@0 449 {
nuclear@0 450 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 451 lc02 = ((dc02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 452 }
nuclear@0 453
nuclear@0 454 int vramofs;
nuclear@0 455 int x, y;
nuclear@0 456
nuclear@0 457 int x01 = x0<<fp;
nuclear@0 458 int x02 = x01;
nuclear@0 459 int c01 = c0<<fp;
nuclear@0 460 int c02 = c01;
nuclear@0 461
nuclear@0 462 int dc;
nuclear@0 463 int sc1, sc2;
nuclear@0 464 int sx1, sx2;
nuclear@0 465
nuclear@0 466 int yp = y0 * ScreenWidth;
nuclear@0 467 for (y = y0; y<y1; y++)
nuclear@0 468 {
nuclear@0 469 sx1 = x01>>fp;
nuclear@0 470 sx2 = x02>>fp;
nuclear@0 471 sc1 = c01;
nuclear@0 472 sc2 = c02;
nuclear@0 473
nuclear@0 474 if (sx1>sx2)
nuclear@0 475 {
nuclear@0 476 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 477 temp = sc1; sc1 = sc2; sc2 = temp;
nuclear@0 478 }
nuclear@0 479
nuclear@0 480 if (sx2!=sx1)
nuclear@0 481 dc = ((sc2 - sc1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 482
nuclear@0 483 yp+=ScreenWidth;
nuclear@0 484 vramofs = yp + sx1;
nuclear@0 485 for (x = sx1; x<sx2; x++)
nuclear@0 486 {
nuclear@0 487 sc1+=dc;
nuclear@0 488 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
nuclear@0 489 {
nuclear@0 490 c = sc1>>fp;
nuclear@0 491 if (c<0) c = 0;
nuclear@0 492 *(vram+vramofs)=shade[c];
nuclear@0 493 }
nuclear@0 494 vramofs++;
nuclear@0 495 }
nuclear@0 496 x01+=lx01;
nuclear@0 497 x02+=lx02;
nuclear@0 498 c01+=lc01;
nuclear@0 499 c02+=lc02;
nuclear@0 500 }
nuclear@0 501
nuclear@0 502 x01 = x1<<fp;
nuclear@0 503 c01 = c1<<fp;
nuclear@0 504
nuclear@0 505 yp = y1 * ScreenWidth;
nuclear@0 506 for (y = y1; y<y2; y++)
nuclear@0 507 {
nuclear@0 508 sx1 = x01>>fp;
nuclear@0 509 sx2 = x02>>fp;
nuclear@0 510 sc1 = c01;
nuclear@0 511 sc2 = c02;
nuclear@0 512
nuclear@0 513 if (sx1>sx2)
nuclear@0 514 {
nuclear@0 515 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 516 temp = sc1; sc1 = sc2; sc2 = temp;
nuclear@0 517 }
nuclear@0 518
nuclear@0 519 if (sx2!=sx1)
nuclear@0 520 dc = ((sc2 - sc1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 521
nuclear@0 522 yp+=ScreenWidth;
nuclear@0 523 vramofs = yp + sx1;
nuclear@0 524 for (x = sx1; x<sx2; x++)
nuclear@0 525 {
nuclear@0 526 sc1+=dc;
nuclear@0 527 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
nuclear@0 528 {
nuclear@0 529 c = sc1>>fp;
nuclear@0 530 if (c<0) c = 0;
nuclear@0 531 *(vram+vramofs)=shade[c];
nuclear@0 532 }
nuclear@0 533 vramofs++;
nuclear@0 534 }
nuclear@0 535 x01+=lx12;
nuclear@0 536 x02+=lx02;
nuclear@0 537 c01+=lc12;
nuclear@0 538 c02+=lc02;
nuclear@0 539 }
nuclear@0 540 }
nuclear@0 541
nuclear@0 542 static inline void DrawGouraudTriangleZB (poly2d poly, unsigned short *vram, unsigned short shade[])
nuclear@0 543 {
nuclear@0 544 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
nuclear@0 545 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
nuclear@0 546 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
nuclear@0 547
nuclear@0 548 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
nuclear@0 549 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
nuclear@0 550 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
nuclear@0 551
nuclear@0 552 int c;
nuclear@0 553 int c0 = spts[poly.p0].c;
nuclear@0 554 int c1 = spts[poly.p1].c;
nuclear@0 555 int c2 = spts[poly.p2].c;
nuclear@0 556
nuclear@0 557 int z0 = fpts[poly.p0].z;
nuclear@0 558 int z1 = fpts[poly.p1].z;
nuclear@0 559 int z2 = fpts[poly.p2].z;
nuclear@0 560
nuclear@0 561 // ===== Sort =====
nuclear@0 562
nuclear@0 563 int temp;
nuclear@0 564 if (y1<y0)
nuclear@0 565 {
nuclear@0 566 temp = c0; c0 = c1; c1 = temp;
nuclear@0 567 temp = z0; z0 = z1; z1 = temp;
nuclear@0 568 temp = x0; x0 = x1; x1 = temp;
nuclear@0 569 temp = y0; y0 = y1; y1 = temp;
nuclear@0 570 }
nuclear@0 571 if (y2<y0)
nuclear@0 572 {
nuclear@0 573 temp = c0; c0 = c2; c2 = temp;
nuclear@0 574 temp = z0; z0 = z2; z2 = temp;
nuclear@0 575 temp = x0; x0 = x2; x2 = temp;
nuclear@0 576 temp = y0; y0 = y2; y2 = temp;
nuclear@0 577 }
nuclear@0 578 if (y2<y1)
nuclear@0 579 {
nuclear@0 580 temp = c1; c1 = c2; c2 = temp;
nuclear@0 581 temp = z1; z1 = z2; z2 = temp;
nuclear@0 582 temp = x1; x1 = x2; x2 = temp;
nuclear@0 583 temp = y1; y1 = y2; y2 = temp;
nuclear@0 584 }
nuclear@0 585
nuclear@0 586 // ===== Interpolation variables =====
nuclear@0 587
nuclear@0 588 int n;
nuclear@0 589 int fp = 8;
nuclear@0 590 int lx01=0, lx12=0, lx02=0;
nuclear@0 591 int lc01=0, lc12=0, lc02=0;
nuclear@0 592 int lz01=0, lz12=0, lz02=0;
nuclear@0 593
nuclear@0 594 int dx01 = x1 - x0;
nuclear@0 595 int dy01 = y1 - y0;
nuclear@0 596 int dc01 = c1 - c0;
nuclear@0 597 int dz01 = z1 - z0;
nuclear@0 598
nuclear@0 599 if (dy01!=0)
nuclear@0 600 {
nuclear@0 601 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 602 lc01 = ((dc01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 603 lz01 = (dz01*pdiv[dy01+2048])>>16;
nuclear@0 604 }
nuclear@0 605
nuclear@0 606 int dx12 = x2 - x1;
nuclear@0 607 int dy12 = y2 - y1;
nuclear@0 608 int dc12 = c2 - c1;
nuclear@0 609 int dz12 = z2 - z1;
nuclear@0 610
nuclear@0 611 if (dy12!=0)
nuclear@0 612 {
nuclear@0 613 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 614 lc12 = ((dc12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 615 lz12 = (dz12*pdiv[dy12+2048])>>16;
nuclear@0 616 }
nuclear@0 617
nuclear@0 618 int dx02 = x2 - x0;
nuclear@0 619 int dy02 = y2 - y0;
nuclear@0 620 int dc02 = c2 - c0;
nuclear@0 621 int dz02 = z2 - z0;
nuclear@0 622
nuclear@0 623 if (dy02!=0)
nuclear@0 624 {
nuclear@0 625 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 626 lc02 = ((dc02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 627 lz02 = (dz02*pdiv[dy02+2048])>>16;
nuclear@0 628 }
nuclear@0 629
nuclear@0 630 int vramofs;
nuclear@0 631 int x, y;
nuclear@0 632
nuclear@0 633 int x01 = x0<<fp;
nuclear@0 634 int x02 = x01;
nuclear@0 635 int c01 = c0<<fp;
nuclear@0 636 int c02 = c01;
nuclear@0 637 int z01 = z0;
nuclear@0 638 int z02 = z01;
nuclear@0 639
nuclear@0 640 int dc, dz;
nuclear@0 641 int sc1, sc2;
nuclear@0 642 int sx1, sx2;
nuclear@0 643 int sz1, sz2;
nuclear@0 644
nuclear@0 645 int yp = y0 * ScreenWidth;
nuclear@0 646 for (y = y0; y<y1; y++)
nuclear@0 647 {
nuclear@0 648 sx1 = x01>>fp;
nuclear@0 649 sx2 = x02>>fp;
nuclear@0 650 sc1 = c01;
nuclear@0 651 sc2 = c02;
nuclear@0 652 sz1 = z01;
nuclear@0 653 sz2 = z02;
nuclear@0 654
nuclear@0 655 if (sx1>sx2)
nuclear@0 656 {
nuclear@0 657 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 658 temp = sc1; sc1 = sc2; sc2 = temp;
nuclear@0 659 temp = sz1; sz1 = sz2; sz2 = temp;
nuclear@0 660 }
nuclear@0 661
nuclear@0 662 if (sx2!=sx1)
nuclear@0 663 {
nuclear@0 664 dc = ((sc2 - sc1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 665 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 666 }
nuclear@0 667
nuclear@0 668 yp+=ScreenWidth;
nuclear@0 669 vramofs = yp + sx1;
nuclear@0 670 for (x = sx1; x<sx2; x++)
nuclear@0 671 {
nuclear@0 672 sc1+=dc;
nuclear@0 673 sz1+=dz;
nuclear@0 674 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
nuclear@0 675 {
nuclear@0 676 c = sc1>>fp;
nuclear@0 677 if (c<0) c=0;
nuclear@0 678 zbuffer[vramofs] = sz1;
nuclear@0 679 *(vram+vramofs)=shade[c];
nuclear@0 680 }
nuclear@0 681 vramofs++;
nuclear@0 682 }
nuclear@0 683 x01+=lx01;
nuclear@0 684 x02+=lx02;
nuclear@0 685 c01+=lc01;
nuclear@0 686 c02+=lc02;
nuclear@0 687 z01+=lz01;
nuclear@0 688 z02+=lz02;
nuclear@0 689 }
nuclear@0 690
nuclear@0 691 x01 = x1<<fp;
nuclear@0 692 c01 = c1<<fp;
nuclear@0 693 z01 = z1;
nuclear@0 694
nuclear@0 695 yp = y1 * ScreenWidth;
nuclear@0 696 for (y = y1; y<y2; y++)
nuclear@0 697 {
nuclear@0 698 sx1 = x01>>fp;
nuclear@0 699 sx2 = x02>>fp;
nuclear@0 700 sc1 = c01;
nuclear@0 701 sc2 = c02;
nuclear@0 702 sz1 = z01;
nuclear@0 703 sz2 = z02;
nuclear@0 704
nuclear@0 705 if (sx1>sx2)
nuclear@0 706 {
nuclear@0 707 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 708 temp = sc1; sc1 = sc2; sc2 = temp;
nuclear@0 709 temp = sz1; sz1 = sz2; sz2 = temp;
nuclear@0 710 }
nuclear@0 711
nuclear@0 712 if (sx2!=sx1)
nuclear@0 713 {
nuclear@0 714 dc = ((sc2 - sc1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 715 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 716 }
nuclear@0 717
nuclear@0 718 yp+=ScreenWidth;
nuclear@0 719 vramofs = yp + sx1;
nuclear@0 720 for (x = sx1; x<sx2; x++)
nuclear@0 721 {
nuclear@0 722 sc1+=dc;
nuclear@0 723 sz1+=dz;
nuclear@0 724 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
nuclear@0 725 {
nuclear@0 726 c = sc1>>fp;
nuclear@0 727 if (c<0) c=0;
nuclear@0 728 zbuffer[vramofs] = sz1;
nuclear@0 729 *(vram+vramofs)=shade[c];
nuclear@0 730 }
nuclear@0 731 vramofs++;
nuclear@0 732 }
nuclear@0 733 x01+=lx12;
nuclear@0 734 x02+=lx02;
nuclear@0 735 c01+=lc12;
nuclear@0 736 c02+=lc02;
nuclear@0 737 z01+=lz12;
nuclear@0 738 z02+=lz02;
nuclear@0 739 }
nuclear@0 740 }
nuclear@0 741
nuclear@0 742 static inline void DrawTextureTriangle(poly2d poly, unsigned short *vram, int tshr, unsigned short texture[])
nuclear@0 743 {
nuclear@0 744 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
nuclear@0 745 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
nuclear@0 746 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
nuclear@0 747
nuclear@0 748 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
nuclear@0 749 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
nuclear@0 750 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
nuclear@0 751
nuclear@0 752 int c;
nuclear@0 753
nuclear@0 754 int u0 = poly.tc0.u; int v0 = poly.tc0.v;
nuclear@0 755 int u1 = poly.tc1.u; int v1 = poly.tc1.v;
nuclear@0 756 int u2 = poly.tc2.u; int v2 = poly.tc2.v;
nuclear@0 757
nuclear@0 758 // ===== Sort =====
nuclear@0 759
nuclear@0 760 int temp;
nuclear@0 761 if (y1<y0)
nuclear@0 762 {
nuclear@0 763 temp = u0; u0 = u1; u1 = temp;
nuclear@0 764 temp = v0; v0 = v1; v1 = temp;
nuclear@0 765 temp = x0; x0 = x1; x1 = temp;
nuclear@0 766 temp = y0; y0 = y1; y1 = temp;
nuclear@0 767 }
nuclear@0 768 if (y2<y0)
nuclear@0 769 {
nuclear@0 770 temp = u0; u0 = u2; u2 = temp;
nuclear@0 771 temp = v0; v0 = v2; v2 = temp;
nuclear@0 772 temp = x0; x0 = x2; x2 = temp;
nuclear@0 773 temp = y0; y0 = y2; y2 = temp;
nuclear@0 774 }
nuclear@0 775 if (y2<y1)
nuclear@0 776 {
nuclear@0 777 temp = u1; u1 = u2; u2 = temp;
nuclear@0 778 temp = v1; v1 = v2; v2 = temp;
nuclear@0 779 temp = x1; x1 = x2; x2 = temp;
nuclear@0 780 temp = y1; y1 = y2; y2 = temp;
nuclear@0 781 }
nuclear@0 782
nuclear@0 783 // ===== Interpolation variables =====
nuclear@0 784
nuclear@0 785 int n;
nuclear@0 786 int fp = 8;
nuclear@0 787 int lx01=0, lx12=0, lx02=0;
nuclear@0 788 int lu01=0, lu12=0, lu02=0;
nuclear@0 789 int lv01=0, lv12=0, lv02=0;
nuclear@0 790
nuclear@0 791 int dx01 = x1 - x0;
nuclear@0 792 int dy01 = y1 - y0;
nuclear@0 793 int du01 = u1 - u0;
nuclear@0 794 int dv01 = v1 - v0;
nuclear@0 795
nuclear@0 796 if (dy01!=0)
nuclear@0 797 {
nuclear@0 798 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 799 lu01 = ((du01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 800 lv01 = ((dv01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 801 }
nuclear@0 802
nuclear@0 803 int dx12 = x2 - x1;
nuclear@0 804 int dy12 = y2 - y1;
nuclear@0 805 int du12 = u2 - u1;
nuclear@0 806 int dv12 = v2 - v1;
nuclear@0 807
nuclear@0 808 if (dy12!=0)
nuclear@0 809 {
nuclear@0 810 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 811 lu12 = ((du12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 812 lv12 = ((dv12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 813 }
nuclear@0 814
nuclear@0 815 int dx02 = x2 - x0;
nuclear@0 816 int dy02 = y2 - y0;
nuclear@0 817 int du02 = u2 - u0;
nuclear@0 818 int dv02 = v2 - v0;
nuclear@0 819
nuclear@0 820 if (dy02!=0)
nuclear@0 821 {
nuclear@0 822 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 823 lu02 = ((du02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 824 lv02 = ((dv02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 825 }
nuclear@0 826
nuclear@0 827 int vramofs;
nuclear@0 828 int x, y;
nuclear@0 829
nuclear@0 830 int x01 = x0<<fp;
nuclear@0 831 int x02 = x01;
nuclear@0 832 int u01 = u0<<fp;
nuclear@0 833 int u02 = u01;
nuclear@0 834 int v01 = v0<<fp;
nuclear@0 835 int v02 = v01;
nuclear@0 836
nuclear@0 837 int du, dv;
nuclear@0 838 int su1, su2;
nuclear@0 839 int sv1, sv2;
nuclear@0 840 int sx1, sx2;
nuclear@0 841
nuclear@0 842 int px, py;
nuclear@0 843
nuclear@0 844 int yp = y0 * ScreenWidth;
nuclear@0 845 for (y = y0; y<y1; y++)
nuclear@0 846 {
nuclear@0 847 sx1 = x01>>fp;
nuclear@0 848 sx2 = x02>>fp;
nuclear@0 849 su1 = u01;
nuclear@0 850 su2 = u02;
nuclear@0 851 sv1 = v01;
nuclear@0 852 sv2 = v02;
nuclear@0 853
nuclear@0 854 if (sx1>sx2)
nuclear@0 855 {
nuclear@0 856 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 857 temp = su1; su1 = su2; su2 = temp;
nuclear@0 858 temp = sv1; sv1 = sv2; sv2 = temp;
nuclear@0 859 }
nuclear@0 860
nuclear@0 861 if (sx2!=sx1)
nuclear@0 862 {
nuclear@0 863 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 864 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 865 }
nuclear@0 866
nuclear@0 867 yp+=ScreenWidth;
nuclear@0 868 vramofs = yp + sx1;
nuclear@0 869 for (x = sx1; x<sx2; x++)
nuclear@0 870 {
nuclear@0 871 su1+=du;
nuclear@0 872 sv1+=dv;
nuclear@0 873 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
nuclear@0 874 {
nuclear@0 875 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
nuclear@0 876 *(vram+vramofs) = c;
nuclear@0 877 }
nuclear@0 878 vramofs++;
nuclear@0 879 }
nuclear@0 880 x01+=lx01;
nuclear@0 881 x02+=lx02;
nuclear@0 882 u01+=lu01;
nuclear@0 883 u02+=lu02;
nuclear@0 884 v01+=lv01;
nuclear@0 885 v02+=lv02;
nuclear@0 886 }
nuclear@0 887
nuclear@0 888 x01 = x1<<fp;
nuclear@0 889 u01 = u1<<fp;
nuclear@0 890 v01 = v1<<fp;
nuclear@0 891
nuclear@0 892 yp = y1 * ScreenWidth;
nuclear@0 893 for (y = y1; y<y2; y++)
nuclear@0 894 {
nuclear@0 895 sx1 = x01>>fp;
nuclear@0 896 sx2 = x02>>fp;
nuclear@0 897 su1 = u01;
nuclear@0 898 su2 = u02;
nuclear@0 899 sv1 = v01;
nuclear@0 900 sv2 = v02;
nuclear@0 901
nuclear@0 902 if (sx1>sx2)
nuclear@0 903 {
nuclear@0 904 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 905 temp = su1; su1 = su2; su2 = temp;
nuclear@0 906 temp = sv1; sv1 = sv2; sv2 = temp;
nuclear@0 907 }
nuclear@0 908
nuclear@0 909 if (sx2!=sx1)
nuclear@0 910 {
nuclear@0 911 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 912 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 913 }
nuclear@0 914
nuclear@0 915 yp+=ScreenWidth;
nuclear@0 916 vramofs = yp + sx1;
nuclear@0 917 for (x = sx1; x<sx2; x++)
nuclear@0 918 {
nuclear@0 919 su1+=du;
nuclear@0 920 sv1+=dv;
nuclear@0 921 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
nuclear@0 922 {
nuclear@0 923 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
nuclear@0 924 *(vram+vramofs) = c;
nuclear@0 925 }
nuclear@0 926 vramofs++;
nuclear@0 927 }
nuclear@0 928 x01+=lx12;
nuclear@0 929 x02+=lx02;
nuclear@0 930 u01+=lu12;
nuclear@0 931 u02+=lu02;
nuclear@0 932 v01+=lv12;
nuclear@0 933 v02+=lv02;
nuclear@0 934 }
nuclear@0 935 }
nuclear@0 936
nuclear@0 937 static inline void DrawTextureTriangleZB(poly2d poly, unsigned short *vram, int tshr, unsigned short texture[])
nuclear@0 938 {
nuclear@0 939 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
nuclear@0 940 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
nuclear@0 941 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
nuclear@0 942
nuclear@0 943 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
nuclear@0 944 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
nuclear@0 945 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
nuclear@0 946
nuclear@0 947 int c;
nuclear@0 948
nuclear@0 949 int u0 = poly.tc0.u; int v0 = poly.tc0.v;
nuclear@0 950 int u1 = poly.tc1.u; int v1 = poly.tc1.v;
nuclear@0 951 int u2 = poly.tc2.u; int v2 = poly.tc2.v;
nuclear@0 952
nuclear@0 953 int z0 = fpts[poly.p0].z;
nuclear@0 954 int z1 = fpts[poly.p1].z;
nuclear@0 955 int z2 = fpts[poly.p2].z;
nuclear@0 956
nuclear@0 957 // ===== Sort =====
nuclear@0 958
nuclear@0 959 int temp;
nuclear@0 960 if (y1<y0)
nuclear@0 961 {
nuclear@0 962 temp = u0; u0 = u1; u1 = temp;
nuclear@0 963 temp = v0; v0 = v1; v1 = temp;
nuclear@0 964 temp = z0; z0 = z1; z1 = temp;
nuclear@0 965 temp = x0; x0 = x1; x1 = temp;
nuclear@0 966 temp = y0; y0 = y1; y1 = temp;
nuclear@0 967 }
nuclear@0 968 if (y2<y0)
nuclear@0 969 {
nuclear@0 970 temp = u0; u0 = u2; u2 = temp;
nuclear@0 971 temp = v0; v0 = v2; v2 = temp;
nuclear@0 972 temp = z0; z0 = z2; z2 = temp;
nuclear@0 973 temp = x0; x0 = x2; x2 = temp;
nuclear@0 974 temp = y0; y0 = y2; y2 = temp;
nuclear@0 975 }
nuclear@0 976 if (y2<y1)
nuclear@0 977 {
nuclear@0 978 temp = u1; u1 = u2; u2 = temp;
nuclear@0 979 temp = v1; v1 = v2; v2 = temp;
nuclear@0 980 temp = z1; z1 = z2; z2 = temp;
nuclear@0 981 temp = x1; x1 = x2; x2 = temp;
nuclear@0 982 temp = y1; y1 = y2; y2 = temp;
nuclear@0 983 }
nuclear@0 984
nuclear@0 985 // ===== Interpolation variables =====
nuclear@0 986
nuclear@0 987 int n;
nuclear@0 988 int fp = 8;
nuclear@0 989 int lx01=0, lx12=0, lx02=0;
nuclear@0 990 int lu01=0, lu12=0, lu02=0;
nuclear@0 991 int lv01=0, lv12=0, lv02=0;
nuclear@0 992 int lz01=0, lz12=0, lz02=0;
nuclear@0 993
nuclear@0 994 int dx01 = x1 - x0;
nuclear@0 995 int dy01 = y1 - y0;
nuclear@0 996 int du01 = u1 - u0;
nuclear@0 997 int dv01 = v1 - v0;
nuclear@0 998 int dz01 = z1 - z0;
nuclear@0 999
nuclear@0 1000 if (dy01!=0)
nuclear@0 1001 {
nuclear@0 1002 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 1003 lu01 = ((du01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 1004 lv01 = ((dv01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 1005 lz01 = (dz01*pdiv[dy01+2048])>>16;
nuclear@0 1006 }
nuclear@0 1007
nuclear@0 1008 int dx12 = x2 - x1;
nuclear@0 1009 int dy12 = y2 - y1;
nuclear@0 1010 int du12 = u2 - u1;
nuclear@0 1011 int dv12 = v2 - v1;
nuclear@0 1012 int dz12 = z2 - z1;
nuclear@0 1013
nuclear@0 1014 if (dy12!=0)
nuclear@0 1015 {
nuclear@0 1016 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 1017 lu12 = ((du12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 1018 lv12 = ((dv12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 1019 lz12 = (dz12*pdiv[dy12+2048])>>16;
nuclear@0 1020 }
nuclear@0 1021
nuclear@0 1022 int dx02 = x2 - x0;
nuclear@0 1023 int dy02 = y2 - y0;
nuclear@0 1024 int du02 = u2 - u0;
nuclear@0 1025 int dv02 = v2 - v0;
nuclear@0 1026 int dz02 = z2 - z0;
nuclear@0 1027
nuclear@0 1028 if (dy02!=0)
nuclear@0 1029 {
nuclear@0 1030 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 1031 lu02 = ((du02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 1032 lv02 = ((dv02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 1033 lz02 = (dz02*pdiv[dy02+2048])>>16;
nuclear@0 1034 }
nuclear@0 1035
nuclear@0 1036 int vramofs;
nuclear@0 1037 int x, y;
nuclear@0 1038
nuclear@0 1039 int x01 = x0<<fp;
nuclear@0 1040 int x02 = x01;
nuclear@0 1041 int u01 = u0<<fp;
nuclear@0 1042 int u02 = u01;
nuclear@0 1043 int v01 = v0<<fp;
nuclear@0 1044 int v02 = v01;
nuclear@0 1045 int z01 = z0;
nuclear@0 1046 int z02 = z01;
nuclear@0 1047
nuclear@0 1048 int du, dv, dz;
nuclear@0 1049 int su1, su2;
nuclear@0 1050 int sv1, sv2;
nuclear@0 1051 int sx1, sx2;
nuclear@0 1052 int sz1, sz2;
nuclear@0 1053
nuclear@0 1054 int px, py;
nuclear@0 1055
nuclear@0 1056 int yp = y0 * ScreenWidth;
nuclear@0 1057 for (y = y0; y<y1; y++)
nuclear@0 1058 {
nuclear@0 1059 sx1 = x01>>fp;
nuclear@0 1060 sx2 = x02>>fp;
nuclear@0 1061 su1 = u01;
nuclear@0 1062 su2 = u02;
nuclear@0 1063 sv1 = v01;
nuclear@0 1064 sv2 = v02;
nuclear@0 1065 sz1 = z01;
nuclear@0 1066 sz2 = z02;
nuclear@0 1067
nuclear@0 1068 if (sx1>sx2)
nuclear@0 1069 {
nuclear@0 1070 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 1071 temp = su1; su1 = su2; su2 = temp;
nuclear@0 1072 temp = sv1; sv1 = sv2; sv2 = temp;
nuclear@0 1073 temp = sz1; sz1 = sz2; sz2 = temp;
nuclear@0 1074 }
nuclear@0 1075
nuclear@0 1076 if (sx2!=sx1)
nuclear@0 1077 {
nuclear@0 1078 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1079 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1080 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1081 }
nuclear@0 1082
nuclear@0 1083 yp+=ScreenWidth;
nuclear@0 1084 vramofs = yp + sx1;
nuclear@0 1085 for (x = sx1; x<sx2; x++)
nuclear@0 1086 {
nuclear@0 1087 su1+=du;
nuclear@0 1088 sv1+=dv;
nuclear@0 1089 sz1+=dz;
nuclear@0 1090 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
nuclear@0 1091 {
nuclear@0 1092 zbuffer[vramofs] = sz1;
nuclear@0 1093 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
nuclear@0 1094 *(vram+vramofs) = c;
nuclear@0 1095 }
nuclear@0 1096 vramofs++;
nuclear@0 1097 }
nuclear@0 1098 x01+=lx01;
nuclear@0 1099 x02+=lx02;
nuclear@0 1100 u01+=lu01;
nuclear@0 1101 u02+=lu02;
nuclear@0 1102 v01+=lv01;
nuclear@0 1103 v02+=lv02;
nuclear@0 1104 z01+=lz01;
nuclear@0 1105 z02+=lz02;
nuclear@0 1106 }
nuclear@0 1107
nuclear@0 1108 x01 = x1<<fp;
nuclear@0 1109 u01 = u1<<fp;
nuclear@0 1110 v01 = v1<<fp;
nuclear@0 1111 z01 = z1;
nuclear@0 1112
nuclear@0 1113 yp = y1 * ScreenWidth;
nuclear@0 1114 for (y = y1; y<y2; y++)
nuclear@0 1115 {
nuclear@0 1116 sx1 = x01>>fp;
nuclear@0 1117 sx2 = x02>>fp;
nuclear@0 1118 su1 = u01;
nuclear@0 1119 su2 = u02;
nuclear@0 1120 sv1 = v01;
nuclear@0 1121 sv2 = v02;
nuclear@0 1122 sz1 = z01;
nuclear@0 1123 sz2 = z02;
nuclear@0 1124
nuclear@0 1125 if (sx1>sx2)
nuclear@0 1126 {
nuclear@0 1127 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 1128 temp = su1; su1 = su2; su2 = temp;
nuclear@0 1129 temp = sv1; sv1 = sv2; sv2 = temp;
nuclear@0 1130 temp = sz1; sz1 = sz2; sz2 = temp;
nuclear@0 1131 }
nuclear@0 1132
nuclear@0 1133 if (sx2!=sx1)
nuclear@0 1134 {
nuclear@0 1135 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1136 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1137 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1138 }
nuclear@0 1139
nuclear@0 1140 yp+=ScreenWidth;
nuclear@0 1141 vramofs = yp + sx1;
nuclear@0 1142 for (x = sx1; x<sx2; x++)
nuclear@0 1143 {
nuclear@0 1144 su1+=du;
nuclear@0 1145 sv1+=dv;
nuclear@0 1146 sz1+=dz;
nuclear@0 1147 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
nuclear@0 1148 {
nuclear@0 1149 zbuffer[vramofs] = sz1;
nuclear@0 1150 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
nuclear@0 1151 *(vram+vramofs) = c;
nuclear@0 1152 }
nuclear@0 1153 vramofs++;
nuclear@0 1154 }
nuclear@0 1155 x01+=lx12;
nuclear@0 1156 x02+=lx02;
nuclear@0 1157 u01+=lu12;
nuclear@0 1158 u02+=lu02;
nuclear@0 1159 v01+=lv12;
nuclear@0 1160 v02+=lv02;
nuclear@0 1161 z01+=lz12;
nuclear@0 1162 z02+=lz02;
nuclear@0 1163 }
nuclear@0 1164 }
nuclear@0 1165
nuclear@0 1166 static inline void DrawEnvmappedTriangle(poly2d poly, unsigned short *vram, int tshr, unsigned short texture[])
nuclear@0 1167 {
nuclear@0 1168 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
nuclear@0 1169 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
nuclear@0 1170 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
nuclear@0 1171
nuclear@0 1172 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
nuclear@0 1173 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
nuclear@0 1174 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
nuclear@0 1175
nuclear@0 1176 int c;
nuclear@0 1177
nuclear@0 1178 int u0 = point_tc[poly.p0].u; int v0 = point_tc[poly.p0].v;
nuclear@0 1179 int u1 = point_tc[poly.p1].u; int v1 = point_tc[poly.p1].v;
nuclear@0 1180 int u2 = point_tc[poly.p2].u; int v2 = point_tc[poly.p2].v;
nuclear@0 1181
nuclear@0 1182 // ===== Sort =====
nuclear@0 1183
nuclear@0 1184 int temp;
nuclear@0 1185 if (y1<y0)
nuclear@0 1186 {
nuclear@0 1187 temp = u0; u0 = u1; u1 = temp;
nuclear@0 1188 temp = v0; v0 = v1; v1 = temp;
nuclear@0 1189 temp = x0; x0 = x1; x1 = temp;
nuclear@0 1190 temp = y0; y0 = y1; y1 = temp;
nuclear@0 1191 }
nuclear@0 1192 if (y2<y0)
nuclear@0 1193 {
nuclear@0 1194 temp = u0; u0 = u2; u2 = temp;
nuclear@0 1195 temp = v0; v0 = v2; v2 = temp;
nuclear@0 1196 temp = x0; x0 = x2; x2 = temp;
nuclear@0 1197 temp = y0; y0 = y2; y2 = temp;
nuclear@0 1198 }
nuclear@0 1199 if (y2<y1)
nuclear@0 1200 {
nuclear@0 1201 temp = u1; u1 = u2; u2 = temp;
nuclear@0 1202 temp = v1; v1 = v2; v2 = temp;
nuclear@0 1203 temp = x1; x1 = x2; x2 = temp;
nuclear@0 1204 temp = y1; y1 = y2; y2 = temp;
nuclear@0 1205 }
nuclear@0 1206
nuclear@0 1207 // ===== Interpolation variables =====
nuclear@0 1208
nuclear@0 1209 int n;
nuclear@0 1210 int fp = 8;
nuclear@0 1211 int lx01=0, lx12=0, lx02=0;
nuclear@0 1212 int lu01=0, lu12=0, lu02=0;
nuclear@0 1213 int lv01=0, lv12=0, lv02=0;
nuclear@0 1214
nuclear@0 1215 int dx01 = x1 - x0;
nuclear@0 1216 int dy01 = y1 - y0;
nuclear@0 1217 int du01 = u1 - u0;
nuclear@0 1218 int dv01 = v1 - v0;
nuclear@0 1219
nuclear@0 1220 if (dy01!=0)
nuclear@0 1221 {
nuclear@0 1222 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 1223 lu01 = ((du01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 1224 lv01 = ((dv01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 1225 }
nuclear@0 1226
nuclear@0 1227 int dx12 = x2 - x1;
nuclear@0 1228 int dy12 = y2 - y1;
nuclear@0 1229 int du12 = u2 - u1;
nuclear@0 1230 int dv12 = v2 - v1;
nuclear@0 1231
nuclear@0 1232 if (dy12!=0)
nuclear@0 1233 {
nuclear@0 1234 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 1235 lu12 = ((du12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 1236 lv12 = ((dv12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 1237 }
nuclear@0 1238
nuclear@0 1239 int dx02 = x2 - x0;
nuclear@0 1240 int dy02 = y2 - y0;
nuclear@0 1241 int du02 = u2 - u0;
nuclear@0 1242 int dv02 = v2 - v0;
nuclear@0 1243
nuclear@0 1244 if (dy02!=0)
nuclear@0 1245 {
nuclear@0 1246 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 1247 lu02 = ((du02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 1248 lv02 = ((dv02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 1249 }
nuclear@0 1250
nuclear@0 1251 int vramofs;
nuclear@0 1252 int x, y;
nuclear@0 1253
nuclear@0 1254 int x01 = x0<<fp;
nuclear@0 1255 int x02 = x01;
nuclear@0 1256 int u01 = u0<<fp;
nuclear@0 1257 int u02 = u01;
nuclear@0 1258 int v01 = v0<<fp;
nuclear@0 1259 int v02 = v01;
nuclear@0 1260
nuclear@0 1261 int du, dv;
nuclear@0 1262 int su1, su2;
nuclear@0 1263 int sv1, sv2;
nuclear@0 1264 int sx1, sx2;
nuclear@0 1265
nuclear@0 1266 int px, py;
nuclear@0 1267
nuclear@0 1268 int yp = y0 * ScreenWidth;
nuclear@0 1269 for (y = y0; y<y1; y++)
nuclear@0 1270 {
nuclear@0 1271 sx1 = x01>>fp;
nuclear@0 1272 sx2 = x02>>fp;
nuclear@0 1273 su1 = u01;
nuclear@0 1274 su2 = u02;
nuclear@0 1275 sv1 = v01;
nuclear@0 1276 sv2 = v02;
nuclear@0 1277
nuclear@0 1278 if (sx1>sx2)
nuclear@0 1279 {
nuclear@0 1280 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 1281 temp = su1; su1 = su2; su2 = temp;
nuclear@0 1282 temp = sv1; sv1 = sv2; sv2 = temp;
nuclear@0 1283 }
nuclear@0 1284
nuclear@0 1285 if (sx2!=sx1)
nuclear@0 1286 {
nuclear@0 1287 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1288 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1289 }
nuclear@0 1290
nuclear@0 1291 yp+=ScreenWidth;
nuclear@0 1292 vramofs = yp + sx1;
nuclear@0 1293 for (x = sx1; x<sx2; x++)
nuclear@0 1294 {
nuclear@0 1295 su1+=du;
nuclear@0 1296 sv1+=dv;
nuclear@0 1297 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
nuclear@0 1298 {
nuclear@0 1299 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
nuclear@0 1300 *(vram+vramofs) = c;
nuclear@0 1301 }
nuclear@0 1302 vramofs++;
nuclear@0 1303 }
nuclear@0 1304 x01+=lx01;
nuclear@0 1305 x02+=lx02;
nuclear@0 1306 u01+=lu01;
nuclear@0 1307 u02+=lu02;
nuclear@0 1308 v01+=lv01;
nuclear@0 1309 v02+=lv02;
nuclear@0 1310 }
nuclear@0 1311
nuclear@0 1312 x01 = x1<<fp;
nuclear@0 1313 u01 = u1<<fp;
nuclear@0 1314 v01 = v1<<fp;
nuclear@0 1315
nuclear@0 1316 yp = y1 * ScreenWidth;
nuclear@0 1317 for (y = y1; y<y2; y++)
nuclear@0 1318 {
nuclear@0 1319 sx1 = x01>>fp;
nuclear@0 1320 sx2 = x02>>fp;
nuclear@0 1321 su1 = u01;
nuclear@0 1322 su2 = u02;
nuclear@0 1323 sv1 = v01;
nuclear@0 1324 sv2 = v02;
nuclear@0 1325
nuclear@0 1326 if (sx1>sx2)
nuclear@0 1327 {
nuclear@0 1328 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 1329 temp = su1; su1 = su2; su2 = temp;
nuclear@0 1330 temp = sv1; sv1 = sv2; sv2 = temp;
nuclear@0 1331 }
nuclear@0 1332
nuclear@0 1333 if (sx2!=sx1)
nuclear@0 1334 {
nuclear@0 1335 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1336 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1337 }
nuclear@0 1338
nuclear@0 1339 yp+=ScreenWidth;
nuclear@0 1340 vramofs = yp + sx1;
nuclear@0 1341 for (x = sx1; x<sx2; x++)
nuclear@0 1342 {
nuclear@0 1343 su1+=du;
nuclear@0 1344 sv1+=dv;
nuclear@0 1345 if (vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth)
nuclear@0 1346 {
nuclear@0 1347 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
nuclear@0 1348 *(vram+vramofs) = c;
nuclear@0 1349 }
nuclear@0 1350 vramofs++;
nuclear@0 1351 }
nuclear@0 1352 x01+=lx12;
nuclear@0 1353 x02+=lx02;
nuclear@0 1354 u01+=lu12;
nuclear@0 1355 u02+=lu02;
nuclear@0 1356 v01+=lv12;
nuclear@0 1357 v02+=lv02;
nuclear@0 1358 }
nuclear@0 1359 }
nuclear@0 1360
nuclear@0 1361
nuclear@0 1362 static inline void DrawEnvmappedTriangleZB(poly2d poly, unsigned short *vram, int tshr, unsigned short texture[])
nuclear@0 1363 {
nuclear@0 1364 int x0 =spts[poly.p0].x; int y0 =spts[poly.p0].y;
nuclear@0 1365 int x1 =spts[poly.p1].x; int y1 =spts[poly.p1].y;
nuclear@0 1366 int x2 =spts[poly.p2].x; int y2 =spts[poly.p2].y;
nuclear@0 1367
nuclear@0 1368 if ((x0<-mlk || x0>ScreenWidth+mlk || y0<-mlk || y0>ScreenHeight+mlk) &&
nuclear@0 1369 (x1<-mlk || x1>ScreenWidth+mlk || y1<-mlk || y1>ScreenHeight+mlk) &&
nuclear@0 1370 (x2<-mlk || x2>ScreenWidth+mlk || y2<-mlk || y2>ScreenHeight+mlk)) return;
nuclear@0 1371
nuclear@0 1372 int c;
nuclear@0 1373
nuclear@0 1374 int u0 = point_tc[poly.p0].u; int v0 = point_tc[poly.p0].v;
nuclear@0 1375 int u1 = point_tc[poly.p1].u; int v1 = point_tc[poly.p1].v;
nuclear@0 1376 int u2 = point_tc[poly.p2].u; int v2 = point_tc[poly.p2].v;
nuclear@0 1377
nuclear@0 1378 int z0 = fpts[poly.p0].z;
nuclear@0 1379 int z1 = fpts[poly.p1].z;
nuclear@0 1380 int z2 = fpts[poly.p2].z;
nuclear@0 1381
nuclear@0 1382 // ===== Sort =====
nuclear@0 1383
nuclear@0 1384 int temp;
nuclear@0 1385 if (y1<y0)
nuclear@0 1386 {
nuclear@0 1387 temp = u0; u0 = u1; u1 = temp;
nuclear@0 1388 temp = v0; v0 = v1; v1 = temp;
nuclear@0 1389 temp = z0; z0 = z1; z1 = temp;
nuclear@0 1390 temp = x0; x0 = x1; x1 = temp;
nuclear@0 1391 temp = y0; y0 = y1; y1 = temp;
nuclear@0 1392 }
nuclear@0 1393 if (y2<y0)
nuclear@0 1394 {
nuclear@0 1395 temp = u0; u0 = u2; u2 = temp;
nuclear@0 1396 temp = v0; v0 = v2; v2 = temp;
nuclear@0 1397 temp = z0; z0 = z2; z2 = temp;
nuclear@0 1398 temp = x0; x0 = x2; x2 = temp;
nuclear@0 1399 temp = y0; y0 = y2; y2 = temp;
nuclear@0 1400 }
nuclear@0 1401 if (y2<y1)
nuclear@0 1402 {
nuclear@0 1403 temp = u1; u1 = u2; u2 = temp;
nuclear@0 1404 temp = v1; v1 = v2; v2 = temp;
nuclear@0 1405 temp = z1; z1 = z2; z2 = temp;
nuclear@0 1406 temp = x1; x1 = x2; x2 = temp;
nuclear@0 1407 temp = y1; y1 = y2; y2 = temp;
nuclear@0 1408 }
nuclear@0 1409
nuclear@0 1410 // ===== Interpolation variables =====
nuclear@0 1411
nuclear@0 1412 int n;
nuclear@0 1413 int fp = 8;
nuclear@0 1414 int lx01=0, lx12=0, lx02=0;
nuclear@0 1415 int lu01=0, lu12=0, lu02=0;
nuclear@0 1416 int lv01=0, lv12=0, lv02=0;
nuclear@0 1417 int lz01=0, lz12=0, lz02=0;
nuclear@0 1418
nuclear@0 1419 int dx01 = x1 - x0;
nuclear@0 1420 int dy01 = y1 - y0;
nuclear@0 1421 int du01 = u1 - u0;
nuclear@0 1422 int dv01 = v1 - v0;
nuclear@0 1423 int dz01 = z1 - z0;
nuclear@0 1424
nuclear@0 1425 if (dy01!=0)
nuclear@0 1426 {
nuclear@0 1427 lx01 = ((dx01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 1428 lu01 = ((du01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 1429 lv01 = ((dv01<<fp)*pdiv[dy01+2048])>>16;
nuclear@0 1430 lz01 = (dz01*pdiv[dy01+2048])>>16;
nuclear@0 1431 }
nuclear@0 1432
nuclear@0 1433 int dx12 = x2 - x1;
nuclear@0 1434 int dy12 = y2 - y1;
nuclear@0 1435 int du12 = u2 - u1;
nuclear@0 1436 int dv12 = v2 - v1;
nuclear@0 1437 int dz12 = z2 - z1;
nuclear@0 1438
nuclear@0 1439 if (dy12!=0)
nuclear@0 1440 {
nuclear@0 1441 lx12 = ((dx12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 1442 lu12 = ((du12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 1443 lv12 = ((dv12<<fp)*pdiv[dy12+2048])>>16;
nuclear@0 1444 lz12 = (dz12*pdiv[dy12+2048])>>16;
nuclear@0 1445 }
nuclear@0 1446
nuclear@0 1447 int dx02 = x2 - x0;
nuclear@0 1448 int dy02 = y2 - y0;
nuclear@0 1449 int du02 = u2 - u0;
nuclear@0 1450 int dv02 = v2 - v0;
nuclear@0 1451 int dz02 = z2 - z0;
nuclear@0 1452
nuclear@0 1453 if (dy02!=0)
nuclear@0 1454 {
nuclear@0 1455 lx02 = ((dx02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 1456 lu02 = ((du02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 1457 lv02 = ((dv02<<fp)*pdiv[dy02+2048])>>16;
nuclear@0 1458 lz02 = (dz02*pdiv[dy02+2048])>>16;
nuclear@0 1459 }
nuclear@0 1460
nuclear@0 1461 int vramofs;
nuclear@0 1462 int x, y;
nuclear@0 1463
nuclear@0 1464 int x01 = x0<<fp;
nuclear@0 1465 int x02 = x01;
nuclear@0 1466 int u01 = u0<<fp;
nuclear@0 1467 int u02 = u01;
nuclear@0 1468 int v01 = v0<<fp;
nuclear@0 1469 int v02 = v01;
nuclear@0 1470 int z01 = z0;
nuclear@0 1471 int z02 = z01;
nuclear@0 1472
nuclear@0 1473 int du, dv, dz;
nuclear@0 1474 int su1, su2;
nuclear@0 1475 int sv1, sv2;
nuclear@0 1476 int sx1, sx2;
nuclear@0 1477 int sz1, sz2;
nuclear@0 1478
nuclear@0 1479 int px, py;
nuclear@0 1480
nuclear@0 1481 int yp = y0 * ScreenWidth;
nuclear@0 1482 for (y = y0; y<y1; y++)
nuclear@0 1483 {
nuclear@0 1484 sx1 = x01>>fp;
nuclear@0 1485 sx2 = x02>>fp;
nuclear@0 1486 su1 = u01;
nuclear@0 1487 su2 = u02;
nuclear@0 1488 sv1 = v01;
nuclear@0 1489 sv2 = v02;
nuclear@0 1490 sz1 = z01;
nuclear@0 1491 sz2 = z02;
nuclear@0 1492
nuclear@0 1493 if (sx1>sx2)
nuclear@0 1494 {
nuclear@0 1495 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 1496 temp = su1; su1 = su2; su2 = temp;
nuclear@0 1497 temp = sv1; sv1 = sv2; sv2 = temp;
nuclear@0 1498 temp = sz1; sz1 = sz2; sz2 = temp;
nuclear@0 1499 }
nuclear@0 1500
nuclear@0 1501 if (sx2!=sx1)
nuclear@0 1502 {
nuclear@0 1503 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1504 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1505 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1506 }
nuclear@0 1507
nuclear@0 1508 yp+=ScreenWidth;
nuclear@0 1509 vramofs = yp + sx1;
nuclear@0 1510 for (x = sx1; x<sx2; x++)
nuclear@0 1511 {
nuclear@0 1512 su1+=du;
nuclear@0 1513 sv1+=dv;
nuclear@0 1514 sz1+=dz;
nuclear@0 1515 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
nuclear@0 1516 {
nuclear@0 1517 zbuffer[vramofs] = sz1;
nuclear@0 1518 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
nuclear@0 1519 *(vram+vramofs) = c;
nuclear@0 1520 }
nuclear@0 1521 vramofs++;
nuclear@0 1522 }
nuclear@0 1523 x01+=lx01;
nuclear@0 1524 x02+=lx02;
nuclear@0 1525 u01+=lu01;
nuclear@0 1526 u02+=lu02;
nuclear@0 1527 v01+=lv01;
nuclear@0 1528 v02+=lv02;
nuclear@0 1529 z01+=lz01;
nuclear@0 1530 z02+=lz02;
nuclear@0 1531 }
nuclear@0 1532
nuclear@0 1533 x01 = x1<<fp;
nuclear@0 1534 u01 = u1<<fp;
nuclear@0 1535 v01 = v1<<fp;
nuclear@0 1536 z01 = z1;
nuclear@0 1537
nuclear@0 1538 yp = y1 * ScreenWidth;
nuclear@0 1539 for (y = y1; y<y2; y++)
nuclear@0 1540 {
nuclear@0 1541 sx1 = x01>>fp;
nuclear@0 1542 sx2 = x02>>fp;
nuclear@0 1543 su1 = u01;
nuclear@0 1544 su2 = u02;
nuclear@0 1545 sv1 = v01;
nuclear@0 1546 sv2 = v02;
nuclear@0 1547 sz1 = z01;
nuclear@0 1548 sz2 = z02;
nuclear@0 1549
nuclear@0 1550 if (sx1>sx2)
nuclear@0 1551 {
nuclear@0 1552 temp = sx1; sx1 = sx2; sx2 = temp;
nuclear@0 1553 temp = su1; su1 = su2; su2 = temp;
nuclear@0 1554 temp = sv1; sv1 = sv2; sv2 = temp;
nuclear@0 1555 temp = sz1; sz1 = sz2; sz2 = temp;
nuclear@0 1556 }
nuclear@0 1557
nuclear@0 1558 if (sx2!=sx1)
nuclear@0 1559 {
nuclear@0 1560 du = ((su2 - su1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1561 dv = ((sv2 - sv1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1562 dz = ((sz2 - sz1)*pdiv[(sx2-sx1)+2048])>>16;
nuclear@0 1563 }
nuclear@0 1564
nuclear@0 1565 yp+=ScreenWidth;
nuclear@0 1566 vramofs = yp + sx1;
nuclear@0 1567 for (x = sx1; x<sx2; x++)
nuclear@0 1568 {
nuclear@0 1569 su1+=du;
nuclear@0 1570 sv1+=dv;
nuclear@0 1571 sz1+=dz;
nuclear@0 1572 if ((vramofs>=0 && vramofs<ScreenSize && x>=0 && x<ScreenWidth) && sz1<zbuffer[vramofs])
nuclear@0 1573 {
nuclear@0 1574 zbuffer[vramofs] = sz1;
nuclear@0 1575 c = texture[((su1>>fp)>>tshr) + (((sv1>>fp)>>tshr)<<(8-tshr))];
nuclear@0 1576 *(vram+vramofs) = c;
nuclear@0 1577 }
nuclear@0 1578 vramofs++;
nuclear@0 1579 }
nuclear@0 1580 x01+=lx12;
nuclear@0 1581 x02+=lx02;
nuclear@0 1582 u01+=lu12;
nuclear@0 1583 u02+=lu02;
nuclear@0 1584 v01+=lv12;
nuclear@0 1585 v02+=lv02;
nuclear@0 1586 z01+=lz12;
nuclear@0 1587 z02+=lz02;
nuclear@0 1588 }
nuclear@0 1589 }
nuclear@0 1590
nuclear@0 1591 void zsort(int zsortdata[], object3d *obj)
nuclear@0 1592 {
nuclear@0 1593 int i, mz;
nuclear@0 1594 for (i=0; i<obj->npls; i++)
nuclear@0 1595 {
nuclear@0 1596 mz = (fpts[obj->poly[i].p0].z + fpts[obj->poly[i].p1].z + fpts[obj->poly[i].p2].z)>>2;
nuclear@0 1597 zsortdata[i] = -mz;
nuclear@0 1598 swp[i] = i;
nuclear@0 1599 }
nuclear@0 1600 }
nuclear@0 1601
nuclear@0 1602
nuclear@0 1603 inline void ClearZbuffer()
nuclear@0 1604 {
nuclear@0 1605 memset(zbuffer, 0xFFFFFF, sizeof(unsigned int) * ScreenSize);
nuclear@0 1606 }
nuclear@0 1607
nuclear@0 1608 void Render(object3d *obj, unsigned short shade[], unsigned short texture[], unsigned short texture_size, unsigned short *vram)
nuclear@0 1609 {
nuclear@0 1610 int i, j;
nuclear@0 1611 int vx0, vy0, vx1, vy1, n;
nuclear@0 1612 int tu, tv, s;
nuclear@0 1613 int texshr = (int)(log(256 / texture_size)/ log(2));
nuclear@0 1614
nuclear@0 1615 int rmode;
nuclear@0 1616 if (zb==1 && RenderMode>=FLAT) rmode = RenderMode | ZBUFFER;
nuclear@0 1617 else rmode = RenderMode;
nuclear@0 1618
nuclear@0 1619 switch (rmode)
nuclear@0 1620 {
nuclear@0 1621
nuclear@0 1622 case POINTS:
nuclear@0 1623 for (i=obj->npts-1; i>=0; i--)
nuclear@0 1624 if (spts[i].x>=0 && spts[i].x<ScreenWidth && spts[i].y>=0 && spts[i].y<ScreenHeight)
nuclear@0 1625 *(vram + spts[i].x + spts[i].y * ScreenWidth) = 0xFFFF;
nuclear@0 1626 break;
nuclear@0 1627
nuclear@0 1628
nuclear@0 1629 case WIRE:
nuclear@0 1630 for (i=obj->nlns-1; i>=0; i--)
nuclear@0 1631 drawline(obj->line[i], vram);
nuclear@0 1632 break;
nuclear@0 1633
nuclear@0 1634 case FLAT:
nuclear@0 1635 rotate3d_normals(obj);
nuclear@0 1636 CalcPolyColor(obj);
nuclear@0 1637
nuclear@0 1638 zsort (zdata, obj);
nuclear@0 1639 quicksort(0, obj->npls - 1, zdata);
nuclear@0 1640
nuclear@0 1641 for (i=0; i<obj->npls; i++)
nuclear@0 1642 {
nuclear@0 1643 j = swp[i];
nuclear@0 1644 vx0 = spts[obj->poly[j].p0].x - spts[obj->poly[j].p1].x;
nuclear@0 1645 vy0 = spts[obj->poly[j].p0].y - spts[obj->poly[j].p1].y;
nuclear@0 1646 vx1 = spts[obj->poly[j].p2].x - spts[obj->poly[j].p1].x;
nuclear@0 1647 vy1 = spts[obj->poly[j].p2].y - spts[obj->poly[j].p1].y;
nuclear@0 1648 n = vx0 * vy1 - vx1 * vy0;
nuclear@0 1649 if (n<0)
nuclear@0 1650 {
nuclear@0 1651 obj->poly[j].c = spls[j].c;
nuclear@0 1652 DrawFlatTriangle(obj->poly[j], vram, shade);
nuclear@0 1653 }
nuclear@0 1654 }
nuclear@0 1655 break;
nuclear@0 1656
nuclear@0 1657 case (FLAT | ZBUFFER):
nuclear@0 1658 rotate3d_normals(obj);
nuclear@0 1659 CalcPolyColor(obj);
nuclear@0 1660
nuclear@0 1661 ClearZbuffer();
nuclear@0 1662 for (i=obj->npls-1; i>=0; i--)
nuclear@0 1663 {
nuclear@0 1664 obj->poly[i].c = spls[i].c;
nuclear@0 1665 if (norms[i].z>=0)
nuclear@0 1666 DrawFlatTriangleZB(obj->poly[i], vram, shade);
nuclear@0 1667 }
nuclear@0 1668 break;
nuclear@0 1669
nuclear@0 1670 case GOURAUD:
nuclear@0 1671 rotate3d_pt_normals(obj);
nuclear@0 1672 CalcPointColor(obj);
nuclear@0 1673
nuclear@0 1674 zsort (zdata, obj);
nuclear@0 1675 quicksort(0, obj->npls - 1, zdata);
nuclear@0 1676
nuclear@0 1677 for (i=0; i<obj->npls; i++)
nuclear@0 1678 {
nuclear@0 1679 j = swp[i];
nuclear@0 1680 vx0 = spts[obj->poly[j].p0].x - spts[obj->poly[j].p1].x;
nuclear@0 1681 vy0 = spts[obj->poly[j].p0].y - spts[obj->poly[j].p1].y;
nuclear@0 1682 vx1 = spts[obj->poly[j].p2].x - spts[obj->poly[j].p1].x;
nuclear@0 1683 vy1 = spts[obj->poly[j].p2].y - spts[obj->poly[j].p1].y;
nuclear@0 1684 n = vx0 * vy1 - vx1 * vy0;
nuclear@0 1685 if (n<0)
nuclear@0 1686 DrawGouraudTriangle(obj->poly[j], vram, shade);
nuclear@0 1687 }
nuclear@0 1688 break;
nuclear@0 1689
nuclear@0 1690 case (GOURAUD | ZBUFFER):
nuclear@0 1691 rotate3d_normals(obj);
nuclear@0 1692 rotate3d_pt_normals(obj);
nuclear@0 1693
nuclear@0 1694 CalcPointColor(obj);
nuclear@0 1695 ClearZbuffer();
nuclear@0 1696 for (i=obj->npls-1; i>=0; i--)
nuclear@0 1697 {
nuclear@0 1698 if (norms[i].z>=0)
nuclear@0 1699 DrawGouraudTriangleZB(obj->poly[i], vram, shade);
nuclear@0 1700 }
nuclear@0 1701 break;
nuclear@0 1702
nuclear@0 1703 case (TEXTURE):
nuclear@0 1704 zsort (zdata, obj);
nuclear@0 1705 quicksort(0, obj->npls - 1, zdata);
nuclear@0 1706
nuclear@0 1707 for (i=0; i<obj->npls; i++)
nuclear@0 1708 {
nuclear@0 1709 j = swp[i];
nuclear@0 1710 vx0 = spts[obj->poly[j].p0].x - spts[obj->poly[j].p1].x;
nuclear@0 1711 vy0 = spts[obj->poly[j].p0].y - spts[obj->poly[j].p1].y;
nuclear@0 1712 vx1 = spts[obj->poly[j].p2].x - spts[obj->poly[j].p1].x;
nuclear@0 1713 vy1 = spts[obj->poly[j].p2].y - spts[obj->poly[j].p1].y;
nuclear@0 1714 n = vx0 * vy1 - vx1 * vy0;
nuclear@0 1715 if (n<0)
nuclear@0 1716 {
nuclear@0 1717 DrawTextureTriangle(obj->poly[j], vram, texshr, texture);
nuclear@0 1718 }
nuclear@0 1719 }
nuclear@0 1720 break;
nuclear@0 1721
nuclear@0 1722 case (TEXTURE | ZBUFFER):
nuclear@0 1723 rotate3d_normals(obj);
nuclear@0 1724
nuclear@0 1725 ClearZbuffer();
nuclear@0 1726 for (i=obj->npls-1; i>=0; i--)
nuclear@0 1727 {
nuclear@0 1728 if (norms[i].z>=0)
nuclear@0 1729 DrawTextureTriangleZB(obj->poly[i], vram, 0, texture);
nuclear@0 1730 }
nuclear@0 1731 break;
nuclear@0 1732
nuclear@0 1733 case (ENVMAP):
nuclear@0 1734 rotate3d_pt_normals(obj);
nuclear@0 1735
nuclear@0 1736 zsort (zdata, obj);
nuclear@0 1737 quicksort(0, obj->npls - 1, zdata);
nuclear@0 1738
nuclear@0 1739 for (i=0; i<obj->npts; i++)
nuclear@0 1740 {
nuclear@0 1741 tu = (pt_norms[i].x>>9) + 127;
nuclear@0 1742 tv = (pt_norms[i].y>>9) + 127;
nuclear@0 1743 point_tc[i].u = abs(tu) & 255;
nuclear@0 1744 point_tc[i].v = abs(tv) & 255;
nuclear@0 1745 }
nuclear@0 1746
nuclear@0 1747 for (i=0; i<obj->npls; i++)
nuclear@0 1748 {
nuclear@0 1749 j = swp[i];
nuclear@0 1750 vx0 = spts[obj->poly[j].p0].x - spts[obj->poly[j].p1].x;
nuclear@0 1751 vy0 = spts[obj->poly[j].p0].y - spts[obj->poly[j].p1].y;
nuclear@0 1752 vx1 = spts[obj->poly[j].p2].x - spts[obj->poly[j].p1].x;
nuclear@0 1753 vy1 = spts[obj->poly[j].p2].y - spts[obj->poly[j].p1].y;
nuclear@0 1754 n = vx0 * vy1 - vx1 * vy0;
nuclear@0 1755 if (n<0)
nuclear@0 1756 DrawEnvmappedTriangle(obj->poly[j], vram, texshr, texture);
nuclear@0 1757 }
nuclear@0 1758 break;
nuclear@0 1759
nuclear@0 1760 case (ENVMAP | ZBUFFER):
nuclear@0 1761 rotate3d_normals(obj);
nuclear@0 1762 rotate3d_pt_normals(obj);
nuclear@0 1763
nuclear@0 1764 ClearZbuffer();
nuclear@0 1765 for (i=obj->npts-1; i>=0; i--)
nuclear@0 1766 {
nuclear@0 1767 tu = (pt_norms[i].x>>9) + 127;
nuclear@0 1768 tv = (pt_norms[i].y>>9) + 127;
nuclear@0 1769 point_tc[i].u = abs(tu) & 255;
nuclear@0 1770 point_tc[i].v = abs(tv) & 255;
nuclear@0 1771 }
nuclear@0 1772
nuclear@0 1773
nuclear@0 1774 for (i=obj->npls-1; i>=0; i--)
nuclear@0 1775 {
nuclear@0 1776 if (norms[i].z>=0)
nuclear@0 1777 DrawEnvmappedTriangleZB(obj->poly[i], vram, 2, texture);
nuclear@0 1778 }
nuclear@0 1779 break;
nuclear@0 1780
nuclear@0 1781 default:
nuclear@0 1782 break;
nuclear@0 1783 }
nuclear@0 1784
nuclear@0 1785 }