00001
00002 #include "revolt.h"
00003 #include "main.h"
00004 #include "dx.h"
00005 #include "geom.h"
00006 #include "model.h"
00007 #include "text.h"
00008 #include "light.h"
00009 #include "draw.h"
00010 #include "play.h"
00011 #include "particle.h"
00012 #include "aerial.h"
00013 #include "NewColl.h"
00014 #include "Body.h"
00015 #include "car.h"
00016 #include "camera.h"
00017 #include "level.h"
00018 #include "registry.h"
00019 #include "mirror.h"
00020 #include "ctrlread.h"
00021 #include "object.h"
00022 #include "control.h"
00023 #include "player.h"
00024 #include "timing.h"
00025
00026
00027
00028 float ModelVertFog;
00029 short ModelPolyCount, ModelDrawnCount, EnvTpage;
00030 MAT EnvMatrix;
00031 MODEL_RGB EnvRgb;
00032 long ModelAddLit;
00033 REAL ModelScale;
00034 float EnvXoffset, EnvYoffset, EnvScale;
00035 float GhostSineCount, GhostSinePos, GhostSineOffset;
00036 LEVEL_MODEL LevelModel[MAX_LEVEL_MODELS];
00037 MODEL *ModelMeshModel;
00038 MAT *ModelMeshMat;
00039 VEC *ModelMeshPos;
00040 short *ModelMeshFlag;
00041
00042 static char AerialSectionName[] = "CARS\\misc\\Aerial.m";
00043 static char AerialTopName[] = "CARS\\misc\\Aerialt.m";
00044
00045 static short ModelFog;
00046 static BUCKET_TEX0 *ModelBucketHeadRGB, *ModelBucketHeadClipRGB;
00047 static BUCKET_TEX1 *ModelBucketHead, *ModelBucketHeadClip;
00048 static BUCKET_ENV *ModelBucketHeadEnv, *ModelBucketHeadEnvClip;
00049
00050
00051
00052 static char *LevelModelList[] = {
00053 "models\\barrel",
00054 "models\\beachball",
00055 "models\\mercury",
00056 "models\\venus",
00057 "models\\earth",
00058 "models\\mars",
00059 "models\\jupiter",
00060 "models\\saturn",
00061 "models\\uranus",
00062 "models\\neptune",
00063 "models\\pluto",
00064 "models\\moon",
00065 "models\\rings",
00066 "models\\plane",
00067 "models\\plane2",
00068 "models\\copter",
00069 "models\\copter2",
00070 "models\\copter3",
00071 "models\\dragon1",
00072 "models\\dragon2",
00073 "models\\water",
00074 "models\\boat1",
00075 "models\\boat2",
00076 "models\\speedup",
00077 "models\\radar",
00078 "models\\balloon",
00079 "models\\horse",
00080 "models\\train",
00081 "models\\train2",
00082 "models\\train3",
00083 "models\\light1",
00084 "models\\light2",
00085 "models\\football",
00086 "models\\spaceman",
00087 "models\\pickup",
00088 "models\\flap",
00089
00090 "edit\\spot",
00091 "models\\firework",
00092 "models\\ball",
00093 "models\\wbomb",
00094 "models\\ball",
00095 };
00096
00098
00100
00101 long LoadModel(char *file, MODEL *m, char tpage, char prmlevel, char loadflag, long RgbPer)
00102 {
00103 FILE *fp;
00104 MODEL_HEADER mh;
00105 MODEL_POLY_LOAD mpl;
00106 MODEL_VERTEX_LOAD mvl;
00107 POLY_RGB *mrgb, rgb;
00108 MODEL_POLY *mp, poly;
00109 float rad;
00110 long size, i, j, k, a, b, count;
00111 char buf[128];
00112 char prm;
00113
00114
00115
00116 if (file == NULL || file[0] == '\0')
00117 return FALSE;
00118
00119 fp = fopen(file, "rb");
00120 if (fp == NULL)
00121 {
00122 wsprintf(buf, "Can't load model %s", file);
00123 Box(NULL, buf, MB_OK);
00124 return FALSE;
00125 }
00126
00127
00128
00129 count = 0;
00130
00131 for (prm = 0 ; prm < prmlevel ; prm++, m++, count++)
00132 {
00133
00134
00135
00136 fread(&mh, sizeof(mh), 1, fp);
00137
00138
00139
00140 if (feof(fp))
00141 {
00142 for ( ; prm < prmlevel ; prm++, m++)
00143 {
00144 m->PolyNum = 0;
00145 m->VertNum = 0;
00146 m->AllocPtr = NULL;
00147 m->VertPtrMorph = NULL;
00148 }
00149 break;
00150 }
00151
00152
00153
00154 m->PolyNum = mh.PolyNum;
00155 m->VertNum = mh.VertNum;
00156
00157 size = sizeof(POLY_RGB) * m->PolyNum;
00158 size += sizeof(MODEL_POLY) * m->PolyNum;
00159 size += sizeof(MODEL_VERTEX) * m->VertNum;
00160
00161 m->AllocPtr = malloc(size);
00162 if (m->AllocPtr == NULL)
00163 {
00164 wsprintf(buf, "Can't alloc memory for %s (%d)", file, prm);
00165 Box("ERROR", buf, MB_OK);
00166 return FALSE;
00167 }
00168
00169 m->PolyRGB = (POLY_RGB*)(m->AllocPtr);
00170 m->PolyPtr = (MODEL_POLY*)(m->PolyRGB + m->PolyNum);
00171 m->VertPtr = (MODEL_VERTEX*)(m->PolyPtr + m->PolyNum);
00172 m->VertPtrMorph = NULL;
00173
00174
00175
00176 mrgb = m->PolyRGB;
00177 mp = m->PolyPtr;
00178
00179 m->QuadNumTex = 0;
00180 m->TriNumTex = 0;
00181 m->QuadNumRGB = 0;
00182 m->TriNumRGB = 0;
00183
00184 for (i = 0 ; i < m->PolyNum ; i++, mrgb++, mp++)
00185 {
00186 fread(&mpl, sizeof(mpl), 1, fp);
00187
00188 mp->Type = mpl.Type;
00189
00190 if ((mp->Tpage = mpl.Tpage) != -1)
00191 {
00192 if (loadflag & LOADMODEL_FORCE_TPAGE) mp->Tpage = tpage;
00193 if (loadflag & LOADMODEL_OFFSET_TPAGE) mp->Tpage += tpage;
00194 }
00195
00196 if (mp->Tpage < -1 || mp->Tpage > MAX_POLY_BUCKETS - 1)
00197 {
00198 wsprintf(buf, "Dodgy poly texture num %d in %s", mp->Tpage, file);
00199 Box(NULL, buf, MB_OK);
00200 mp->Tpage = -1;
00201 }
00202
00203 if (GameSettings.Mirrored)
00204 {
00205 if (mp->Type & POLY_QUAD)
00206 {
00207 *(long*)&mrgb->rgb[0] = mpl.c3;
00208 *(long*)&mrgb->rgb[1] = mpl.c2;
00209 *(long*)&mrgb->rgb[2] = mpl.c1;
00210 *(long*)&mrgb->rgb[3] = mpl.c0;
00211
00212 mp->tu0 = mpl.u3;
00213 mp->tv0 = mpl.v3;
00214 mp->tu1 = mpl.u2;
00215 mp->tv1 = mpl.v2;
00216 mp->tu2 = mpl.u1;
00217 mp->tv2 = mpl.v1;
00218 mp->tu3 = mpl.u0;
00219 mp->tv3 = mpl.v0;
00220
00221 mp->v0 = m->VertPtr + mpl.vi3;
00222 mp->v1 = m->VertPtr + mpl.vi2;
00223 mp->v2 = m->VertPtr + mpl.vi1;
00224 mp->v3 = m->VertPtr + mpl.vi0;
00225 }
00226 else
00227 {
00228 *(long*)&mrgb->rgb[0] = mpl.c2;
00229 *(long*)&mrgb->rgb[1] = mpl.c1;
00230 *(long*)&mrgb->rgb[2] = mpl.c0;
00231
00232 mp->tu0 = mpl.u2;
00233 mp->tv0 = mpl.v2;
00234 mp->tu1 = mpl.u1;
00235 mp->tv1 = mpl.v1;
00236 mp->tu2 = mpl.u0;
00237 mp->tv2 = mpl.v0;
00238
00239 mp->v0 = m->VertPtr + mpl.vi2;
00240 mp->v1 = m->VertPtr + mpl.vi1;
00241 mp->v2 = m->VertPtr + mpl.vi0;
00242 }
00243 }
00244 else
00245 {
00246 *(long*)&mrgb->rgb[0] = mpl.c0;
00247 *(long*)&mrgb->rgb[1] = mpl.c1;
00248 *(long*)&mrgb->rgb[2] = mpl.c2;
00249 *(long*)&mrgb->rgb[3] = mpl.c3;
00250
00251 mp->tu0 = mpl.u0;
00252 mp->tv0 = mpl.v0;
00253 mp->tu1 = mpl.u1;
00254 mp->tv1 = mpl.v1;
00255 mp->tu2 = mpl.u2;
00256 mp->tv2 = mpl.v2;
00257 mp->tu3 = mpl.u3;
00258 mp->tv3 = mpl.v3;
00259
00260 mp->v0 = m->VertPtr + mpl.vi0;
00261 mp->v1 = m->VertPtr + mpl.vi1;
00262 mp->v2 = m->VertPtr + mpl.vi2;
00263 mp->v3 = m->VertPtr + mpl.vi3;
00264 }
00265
00266 ModelChangeGouraud(&mrgb->rgb[0], RgbPer);
00267 ModelChangeGouraud(&mrgb->rgb[1], RgbPer);
00268 ModelChangeGouraud(&mrgb->rgb[2], RgbPer);
00269 ModelChangeGouraud(&mrgb->rgb[3], RgbPer);
00270
00271 if (mp->Tpage != -1)
00272 {
00273 if (mp->Type & POLY_QUAD) m->QuadNumTex++;
00274 else m->TriNumTex++;
00275 }
00276 else
00277 {
00278 if (mp->Type & POLY_QUAD) m->QuadNumRGB++;
00279 else m->TriNumRGB++;
00280 }
00281 }
00282
00283
00284
00285 mp = m->PolyPtr;
00286
00287 for (j = m->PolyNum - 1; j ; j--) for (k = 0 ; k < j ; k++)
00288 {
00289 a = mp[k].Type & POLY_QUAD;
00290 if (mp[k].Tpage != -1) a += 256;
00291
00292 b = mp[k + 1].Type & POLY_QUAD;
00293 if (mp[k + 1].Tpage != -1) b += 256;
00294
00295 if (b > a)
00296 {
00297 poly = mp[k];
00298 mp[k] = mp[k + 1];
00299 mp[k + 1] = poly;
00300
00301 rgb = m->PolyRGB[k];
00302 m->PolyRGB[k] = m->PolyRGB[k + 1];
00303 m->PolyRGB[k + 1] = rgb;
00304 }
00305 }
00306
00307
00308
00309 m->Radius = 0;
00310 m->Xmin = m->Ymin = m->Zmin = 999999;
00311 m->Xmax = m->Ymax = m->Zmax = -999999;
00312
00313 for (i = 0 ; i < m->VertNum ; i++)
00314 {
00315 fread(&mvl, sizeof(mvl), 1, fp);
00316
00317 m->VertPtr[i].x = mvl.x;
00318 m->VertPtr[i].y = mvl.y;
00319 m->VertPtr[i].z = mvl.z;
00320
00321 m->VertPtr[i].nx = mvl.nx;
00322 m->VertPtr[i].ny = mvl.ny;
00323 m->VertPtr[i].nz = mvl.nz;
00324
00325 rad = Length((VEC*)&m->VertPtr[i].x);
00326 if (rad > m->Radius) m->Radius = rad;
00327
00328 if (m->VertPtr[i].x < m->Xmin) m->Xmin = m->VertPtr[i].x;
00329 if (m->VertPtr[i].x > m->Xmax) m->Xmax = m->VertPtr[i].x;
00330 if (m->VertPtr[i].y < m->Ymin) m->Ymin = m->VertPtr[i].y;
00331 if (m->VertPtr[i].y > m->Ymax) m->Ymax = m->VertPtr[i].y;
00332 if (m->VertPtr[i].z < m->Zmin) m->Zmin = m->VertPtr[i].z;
00333 if (m->VertPtr[i].z > m->Zmax) m->Zmax = m->VertPtr[i].z;
00334 }
00335 }
00336
00337
00338
00339 fclose(fp);
00340 return count;
00341 }
00342
00344
00346
00347 void FreeModel(MODEL *m, long prmlevel)
00348 {
00349 long i;
00350
00351 for (i = 0 ; i < prmlevel ; i++, m++)
00352 {
00353 if (m->VertPtrMorph)
00354 free(m->VertPtrMorph);
00355
00356 if (m->AllocPtr)
00357 free(m->AllocPtr);
00358 }
00359 }
00360
00362
00364
00365 void DrawModel(MODEL *m, MAT *worldmat, VEC *worldpos, short flag)
00366 {
00367 long i;
00368 MAT eyematrix;
00369 VEC mirrorpos, eyetrans;
00370 float mirroradd;
00371 MODEL_VERTEX *mv;
00372
00373
00374
00375 if (!RenderSettings.Env)
00376 flag &= ~MODEL_ENV;
00377
00378
00379
00380 ModelFog = flag & MODEL_FOG;
00381
00382
00383
00384 if (ModelFog)
00385 {
00386 FOG_ON();
00387
00388 ModelBucketHead = BucketFog;
00389 ModelBucketHeadRGB = &BucketFogRGB;
00390 ModelBucketHeadClip = BucketClipFog;
00391 ModelBucketHeadClipRGB = &BucketClipFogRGB;
00392 }
00393 else
00394 {
00395 ModelBucketHead = Bucket;
00396 ModelBucketHeadRGB = &BucketRGB;
00397 ModelBucketHeadClip = BucketClip;
00398 ModelBucketHeadClipRGB = &BucketClipRGB;
00399 }
00400
00401
00402
00403 MulMatrix(&ViewMatrixScaled, worldmat, &eyematrix);
00404 RotTransVector(&ViewMatrixScaled, &ViewTransScaled, worldpos, &eyetrans);
00405
00406
00407
00408 if (flag & MODEL_GHOST)
00409 {
00410 SetModelVertsGhost(m);
00411 }
00412
00413
00414
00415 if (flag & MODEL_ENV)
00416 {
00417 if (ModelFog)
00418 {
00419 if (EnvTpage == TPAGE_ENVSTILL)
00420 {
00421 ModelBucketHeadEnv = &BucketEnvStillFog;
00422 ModelBucketHeadEnvClip = &BucketEnvStillClipFog;
00423 }
00424 else
00425 {
00426 ModelBucketHeadEnv = &BucketEnvRollFog;
00427 ModelBucketHeadEnvClip = &BucketEnvRollClipFog;
00428 }
00429 }
00430 else
00431 {
00432 if (EnvTpage == TPAGE_ENVSTILL)
00433 {
00434 ModelBucketHeadEnv = &BucketEnvStill;
00435 ModelBucketHeadEnvClip = &BucketEnvStillClip;
00436 }
00437 else
00438 {
00439 ModelBucketHeadEnv = &BucketEnvRoll;
00440 ModelBucketHeadEnvClip = &BucketEnvRollClip;
00441 }
00442 }
00443
00444 if (flag & MODEL_LIT) SetModelVertsEnvLit(m);
00445 else SetModelVertsEnvPlain(m);
00446 }
00447
00448
00449
00450 if (flag & MODEL_ADDLIT)
00451 {
00452 mv = m->VertPtr;
00453
00454 if (flag & MODEL_LIT)
00455 {
00456 for (i = m->VertNum ; i ; i--, mv++)
00457 {
00458 mv->r += ModelAddLit;
00459 mv->g += ModelAddLit;
00460 mv->b += ModelAddLit;
00461 }
00462 }
00463 else
00464 {
00465 for (i = m->VertNum ; i ; i--, mv++)
00466 {
00467 mv->r = ModelAddLit;
00468 mv->g = ModelAddLit;
00469 mv->b = ModelAddLit;
00470 }
00471
00472 flag |= MODEL_LIT;
00473 }
00474 }
00475
00476
00477
00478 if (flag & MODEL_SCALE)
00479 {
00480 VecMulScalar(&eyematrix.mv[R], ModelScale);
00481 VecMulScalar(&eyematrix.mv[U], ModelScale);
00482 VecMulScalar(&eyematrix.mv[L], ModelScale);
00483 }
00484
00485
00486
00487 if (flag & MODEL_USENEWVERTS)
00488 {
00489 if (flag & MODEL_DONOTCLIP)
00490 {
00491 if (ModelFog) TransModelVertsFogNewVerts(m, &eyematrix, &eyetrans);
00492 else TransModelVertsPlainNewVerts(m, &eyematrix, &eyetrans);
00493 DrawModelPolys(m, flag & MODEL_LIT, flag & MODEL_ENV);
00494 }
00495 else
00496 {
00497 if (ModelFog) TransModelVertsFogClipNewVerts(m, &eyematrix, &eyetrans);
00498 else TransModelVertsPlainClipNewVerts(m, &eyematrix, &eyetrans);
00499 DrawModelPolysClip(m, flag & MODEL_LIT, flag & MODEL_ENV);
00500 }
00501 }
00502 else
00503 {
00504 if (flag & MODEL_DONOTCLIP)
00505 {
00506 if (ModelFog) TransModelVertsFog(m, &eyematrix, &eyetrans);
00507 else TransModelVertsPlain(m, &eyematrix, &eyetrans);
00508 DrawModelPolys(m, flag & MODEL_LIT, flag & MODEL_ENV);
00509 }
00510 else
00511 {
00512 if (ModelFog) TransModelVertsFogClip(m, &eyematrix, &eyetrans);
00513 else TransModelVertsPlainClip(m, &eyematrix, &eyetrans);
00514 DrawModelPolysClip(m, flag & MODEL_LIT, flag & MODEL_ENV);
00515 }
00516 }
00517
00518
00519
00520 if (flag & MODEL_MIRROR)
00521 {
00522 mirroradd = MirrorHeight - worldpos->v[Y];
00523 if (mirroradd > -MIRROR_OVERLAP_TOL)
00524 {
00525 if (!ModelFog)
00526 {
00527 FOG_ON();
00528
00529 ModelBucketHead = BucketFog;
00530 ModelBucketHeadRGB = &BucketFogRGB;
00531 ModelBucketHeadClip = BucketClipFog;
00532 ModelBucketHeadClipRGB = &BucketClipFogRGB;
00533 }
00534
00535 mirrorpos.v[X] = worldpos->v[X];
00536 mirrorpos.v[Y] = MirrorHeight + mirroradd;
00537 mirrorpos.v[Z] = worldpos->v[Z];
00538
00539 MulMatrix(&ViewMatrixScaledMirrorY, worldmat, &eyematrix);
00540 RotTransVector(&ViewMatrixScaled, &ViewTransScaled, &mirrorpos, &eyetrans);
00541
00542 if (flag & MODEL_USENEWVERTS)
00543 {
00544 TransModelVertsMirrorNewVerts(m, &eyematrix, &eyetrans, worldmat, worldpos);
00545 DrawModelPolysMirror(m, flag & MODEL_LIT);
00546 }
00547 else
00548 {
00549 TransModelVertsMirror(m, &eyematrix, &eyetrans, worldmat, worldpos);
00550 DrawModelPolysMirror(m, flag & MODEL_LIT);
00551 }
00552 }
00553 }
00554
00555
00556
00557 if (flag & MODEL_GLARE)
00558 {
00559 SetModelVertsGlare(m, worldpos, worldmat, flag);
00560 }
00561
00562
00563
00564 FOG_OFF();
00565 }
00566
00568
00570
00571 void TransModelVertsPlainClip(MODEL *m, MAT *mat, VEC *trans)
00572 {
00573 short i;
00574 float z;
00575 MODEL_VERTEX *mv;
00576
00577 mv = m->VertPtr;
00578
00579 for (i = 0 ; i < m->VertNum ; i++, mv++)
00580 {
00581 z = mv->x * mat->m[RZ] + mv->y * mat->m[UZ] + mv->z * mat->m[LZ] + trans->v[Z];
00582 if (z < 1) z = 1;
00583
00584 mv->sx = (mv->x * mat->m[RX] + mv->y * mat->m[UX] + mv->z * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00585 mv->sy = (mv->x * mat->m[RY] + mv->y * mat->m[UY] + mv->z * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00586
00587 mv->rhw = 1 / z;
00588 mv->sz = GET_ZBUFFER(z);
00589
00590 mv->Clip = 0;
00591 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
00592 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
00593 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
00594 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
00595 if (mv->sz < 0) mv->Clip |= 16;
00596 else if (mv->sz >= 1) mv->Clip |= 32;
00597 }
00598 }
00599
00601
00603
00604 void TransModelVertsFogClip(MODEL *m, MAT *mat, VEC *trans)
00605 {
00606 short i;
00607 float z;
00608 float fog;
00609 MODEL_VERTEX *mv;
00610
00611 mv = m->VertPtr;
00612
00613 for (i = 0 ; i < m->VertNum ; i++, mv++)
00614 {
00615 z = mv->x * mat->m[RZ] + mv->y * mat->m[UZ] + mv->z * mat->m[LZ] + trans->v[Z];
00616 if (z < 1) z = 1;
00617
00618 mv->sx = (mv->x * mat->m[RX] + mv->y * mat->m[UX] + mv->z * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00619 mv->sy = (mv->x * mat->m[RY] + mv->y * mat->m[UY] + mv->z * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00620
00621 mv->rhw = 1 / z;
00622 mv->sz = GET_ZBUFFER(z);
00623
00624 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
00625 if (fog > 255) fog = 255;
00626 fog -= ModelVertFog;
00627 if (fog < 0) fog = 0;
00628 mv->specular = FTOL3(fog) << 24;
00629
00630 mv->Clip = 0;
00631 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
00632 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
00633 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
00634 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
00635 if (mv->sz < 0) mv->Clip |= 16;
00636 else if (mv->sz >= 1) mv->Clip |= 32;
00637 }
00638 }
00639
00641
00643
00644 void TransModelVertsPlain(MODEL *m, MAT *mat, VEC *trans)
00645 {
00646 short i;
00647 float z;
00648 MODEL_VERTEX *mv;
00649
00650 mv = m->VertPtr;
00651
00652 for (i = 0 ; i < m->VertNum ; i++, mv++)
00653 {
00654 z = mv->x * mat->m[RZ] + mv->y * mat->m[UZ] + mv->z * mat->m[LZ] + trans->v[Z];
00655 mv->rhw = 1 / z;
00656
00657 mv->sx = (mv->x * mat->m[RX] + mv->y * mat->m[UX] + mv->z * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00658 mv->sy = (mv->x * mat->m[RY] + mv->y * mat->m[UY] + mv->z * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00659
00660 mv->sz = GET_ZBUFFER(z);
00661 }
00662 }
00663
00665
00667
00668 void TransModelVertsFog(MODEL *m, MAT *mat, VEC *trans)
00669 {
00670 short i;
00671 float z;
00672 float fog;
00673 MODEL_VERTEX *mv;
00674
00675 mv = m->VertPtr;
00676
00677 for (i = 0 ; i < m->VertNum ; i++, mv++)
00678 {
00679 z = mv->x * mat->m[RZ] + mv->y * mat->m[UZ] + mv->z * mat->m[LZ] + trans->v[Z];
00680 mv->rhw = 1 / z;
00681
00682 mv->sx = (mv->x * mat->m[RX] + mv->y * mat->m[UX] + mv->z * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00683 mv->sy = (mv->x * mat->m[RY] + mv->y * mat->m[UY] + mv->z * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00684
00685 mv->sz = GET_ZBUFFER(z);
00686
00687 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
00688 if (fog > 255) fog = 255;
00689 fog -= ModelVertFog;
00690 if (fog < 0) fog = 0;
00691 mv->specular = FTOL3(fog) << 24;
00692 }
00693 }
00694
00696
00698
00699 void TransModelVertsPlainClipNewVerts(MODEL *m, MAT *mat, VEC *trans)
00700 {
00701 short i;
00702 float z;
00703 MODEL_VERTEX *mv;
00704
00705 mv = m->VertPtr;
00706
00707 for (i = 0 ; i < m->VertNum ; i++, mv++)
00708 {
00709 z = mv->x2 * mat->m[RZ] + mv->y2 * mat->m[UZ] + mv->z2 * mat->m[LZ] + trans->v[Z];
00710 if (z < 1) z = 1;
00711
00712 mv->sx = (mv->x2 * mat->m[RX] + mv->y2 * mat->m[UX] + mv->z2 * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00713 mv->sy = (mv->x2 * mat->m[RY] + mv->y2 * mat->m[UY] + mv->z2 * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00714
00715 mv->rhw = 1 / z;
00716 mv->sz = GET_ZBUFFER(z);
00717
00718 mv->Clip = 0;
00719 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
00720 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
00721 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
00722 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
00723 if (mv->sz < 0) mv->Clip |= 16;
00724 else if (mv->sz >= 1) mv->Clip |= 32;
00725 }
00726 }
00727
00729
00731
00732 void TransModelVertsFogClipNewVerts(MODEL *m, MAT *mat, VEC *trans)
00733 {
00734 short i;
00735 float z;
00736 float fog;
00737 MODEL_VERTEX *mv;
00738
00739 mv = m->VertPtr;
00740
00741 for (i = 0 ; i < m->VertNum ; i++, mv++)
00742 {
00743 z = mv->x2 * mat->m[RZ] + mv->y2 * mat->m[UZ] + mv->z2 * mat->m[LZ] + trans->v[Z];
00744 if (z < 1) z = 1;
00745
00746 mv->sx = (mv->x2 * mat->m[RX] + mv->y2 * mat->m[UX] + mv->z2 * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00747 mv->sy = (mv->x2 * mat->m[RY] + mv->y2 * mat->m[UY] + mv->z2 * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00748
00749 mv->rhw = 1 / z;
00750 mv->sz = GET_ZBUFFER(z);
00751
00752 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
00753 if (fog > 255) fog = 255;
00754 fog -= ModelVertFog;
00755 if (fog < 0) fog = 0;
00756 mv->specular = FTOL3(fog) << 24;
00757
00758 mv->Clip = 0;
00759 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
00760 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
00761 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
00762 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
00763 if (mv->sz < 0) mv->Clip |= 16;
00764 else if (mv->sz >= 1) mv->Clip |= 32;
00765 }
00766 }
00767
00769
00771
00772 void TransModelVertsPlainNewVerts(MODEL *m, MAT *mat, VEC *trans)
00773 {
00774 short i;
00775 float z;
00776 MODEL_VERTEX *mv;
00777
00778 mv = m->VertPtr;
00779
00780 for (i = 0 ; i < m->VertNum ; i++, mv++)
00781 {
00782 z = mv->x2 * mat->m[RZ] + mv->y2 * mat->m[UZ] + mv->z2 * mat->m[LZ] + trans->v[Z];
00783 mv->rhw = 1 / z;
00784
00785 mv->sx = (mv->x2 * mat->m[RX] + mv->y2 * mat->m[UX] + mv->z2 * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00786 mv->sy = (mv->x2 * mat->m[RY] + mv->y2 * mat->m[UY] + mv->z2 * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00787
00788 mv->sz = GET_ZBUFFER(z);
00789 }
00790 }
00791
00793
00795
00796 void TransModelVertsFogNewVerts(MODEL *m, MAT *mat, VEC *trans)
00797 {
00798 short i;
00799 float z;
00800 float fog;
00801 MODEL_VERTEX *mv;
00802
00803 mv = m->VertPtr;
00804
00805 for (i = 0 ; i < m->VertNum ; i++, mv++)
00806 {
00807 z = mv->x2 * mat->m[RZ] + mv->y2 * mat->m[UZ] + mv->z2 * mat->m[LZ] + trans->v[Z];
00808 mv->rhw = 1 / z;
00809
00810 mv->sx = (mv->x2 * mat->m[RX] + mv->y2 * mat->m[UX] + mv->z2 * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00811 mv->sy = (mv->x2 * mat->m[RY] + mv->y2 * mat->m[UY] + mv->z2 * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00812
00813 mv->sz = GET_ZBUFFER(z);
00814
00815 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
00816 if (fog > 255) fog = 255;
00817 fog -= ModelVertFog;
00818 if (fog < 0) fog = 0;
00819 mv->specular = FTOL3(fog) << 24;
00820 }
00821 }
00822
00824
00826
00827 void TransModelVertsMirror(MODEL *m, MAT *mat, VEC *trans, MAT *worldmat, VEC *worldpos)
00828 {
00829 short i;
00830 float z;
00831 float fog, mirrorfog;
00832 MODEL_VERTEX *mv;
00833
00834 mv = m->VertPtr;
00835
00836 for (i = 0 ; i < m->VertNum ; i++, mv++)
00837 {
00838 z = mv->x * mat->m[RZ] + mv->y * mat->m[UZ] + mv->z * mat->m[LZ] + trans->v[Z];
00839 if (z < 1) z = 1;
00840
00841 mv->sx = (mv->x * mat->m[RX] + mv->y * mat->m[UX] + mv->z * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00842 mv->sy = (mv->x * mat->m[RY] + mv->y * mat->m[UY] + mv->z * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00843
00844 mv->rhw = 1 / z;
00845 mv->sz = GET_ZBUFFER(z);
00846
00847 mv->Clip = 0;
00848 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
00849 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
00850 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
00851 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
00852 if (mv->sz < 0) mv->Clip |= 16;
00853 else if (mv->sz >= 1) mv->Clip |= 32;
00854
00855 mirrorfog = mv->x * worldmat->m[RY] + mv->y * worldmat->m[UY] + mv->z * worldmat->m[LY] + worldpos->v[Y];
00856 mirrorfog = GET_MIRROR_FOG(MirrorHeight - mirrorfog);
00857 if (mirrorfog < 0) mirrorfog = 0;
00858
00859 if (mirrorfog >= 255)
00860 {
00861 mv->Clip |= 64;
00862 mv->specular = 0;
00863 }
00864 else
00865 {
00866 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
00867 if (fog > 255) fog = 255;
00868 fog -= mirrorfog;
00869 if (fog < 0) fog = 0;
00870 mv->specular = FTOL3(fog) << 24;
00871 }
00872 }
00873 }
00874
00876
00878
00879 void TransModelVertsMirrorNewVerts(MODEL *m, MAT *mat, VEC *trans, MAT *worldmat, VEC *worldpos)
00880 {
00881 short i;
00882 float z;
00883 float fog, mirrorfog;
00884 MODEL_VERTEX *mv;
00885
00886 mv = m->VertPtr;
00887
00888 for (i = 0 ; i < m->VertNum ; i++, mv++)
00889 {
00890 z = mv->x2 * mat->m[RZ] + mv->y2 * mat->m[UZ] + mv->z2 * mat->m[LZ] + trans->v[Z];
00891 if (z < 1) z = 1;
00892
00893 mv->sx = (mv->x2 * mat->m[RX] + mv->y2 * mat->m[UX] + mv->z2 * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00894 mv->sy = (mv->x2 * mat->m[RY] + mv->y2 * mat->m[UY] + mv->z2 * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00895
00896 mv->rhw = 1 / z;
00897 mv->sz = GET_ZBUFFER(z);
00898
00899 mv->Clip = 0;
00900 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
00901 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
00902 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
00903 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
00904 if (mv->sz < 0) mv->Clip |= 16;
00905 else if (mv->sz >= 1) mv->Clip |= 32;
00906
00907 mirrorfog = mv->x * worldmat->m[RY] + mv->y * worldmat->m[UY] + mv->z * worldmat->m[LY] + worldpos->v[Y];
00908 mirrorfog = GET_MIRROR_FOG(MirrorHeight - mirrorfog);
00909 if (mirrorfog < 0) mirrorfog = 0;
00910
00911 if (mirrorfog >= 255)
00912 {
00913 mv->Clip |= 64;
00914 mv->specular = 0;
00915 }
00916 else
00917 {
00918 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
00919 if (fog > 255) fog = 255;
00920 fog -= mirrorfog;
00921 if (fog < 0) fog = 0;
00922 mv->specular = FTOL3(fog) << 24;
00923 }
00924 }
00925 }
00926
00928
00930
00931 void SetModelVertsEnvPlain(MODEL *m)
00932 {
00933 short i;
00934 MODEL_VERTEX *mv;
00935
00936 mv = m->VertPtr;
00937
00938 for (i = 0 ; i < m->VertNum ; i++, mv++)
00939 {
00940 mv->tu = (mv->nx * EnvMatrix.m[RX] + mv->ny * EnvMatrix.m[UX] + mv->nz * EnvMatrix.m[LX]) + EnvXoffset;
00941 mv->tv = (mv->nx * EnvMatrix.m[RY] + mv->ny * EnvMatrix.m[UY] + mv->nz * EnvMatrix.m[LY]) + EnvYoffset;
00942 mv->color = *(long*)&EnvRgb;
00943 }
00944 }
00945
00947
00949
00950 void SetModelVertsEnvLit(MODEL *m)
00951 {
00952 short i;
00953 MODEL_VERTEX *mv;
00954
00955 mv = m->VertPtr;
00956
00957 for (i = 0 ; i < m->VertNum ; i++, mv++)
00958 {
00959 mv->tu = (mv->nx * EnvMatrix.m[RX] + mv->ny * EnvMatrix.m[UX] + mv->nz * EnvMatrix.m[LX]) + EnvXoffset;
00960 mv->tv = (mv->nx * EnvMatrix.m[RY] + mv->ny * EnvMatrix.m[UY] + mv->nz * EnvMatrix.m[LY]) + EnvYoffset;
00961 ModelAddGouraud(&EnvRgb, &mv->r, (MODEL_RGB*)&mv->color);
00962 }
00963 }
00964
00966
00968
00969 void SetModelVertsGhost(MODEL *m)
00970 {
00971 short i;
00972 MODEL_VERTEX *mv;
00973 MODEL_POLY *mp;
00974 POLY_RGB *mrgb;
00975 float fz, pos;
00976
00977
00978
00979 pos = GhostSineOffset - GhostSinePos;
00980 mv = m->VertPtr;
00981
00982 for (i = 0 ; i < m->VertNum ; i++, mv++)
00983 {
00984 fz = abs((mv->z + pos) * 2);
00985 mv->a = -FTOL2(fz) + 255;
00986 if (mv->a < 0) mv->a = 0;
00987 }
00988
00989
00990
00991 mp = m->PolyPtr;
00992 mrgb = m->PolyRGB;
00993
00994 for (i = 0 ; i < m->PolyNum ; i++, mp++, mrgb++)
00995 {
00996 mrgb->rgb[0].a = (unsigned char)mp->v0->a;
00997 mrgb->rgb[1].a = (unsigned char)mp->v1->a;
00998 mrgb->rgb[2].a = (unsigned char)mp->v2->a;
00999 if(mp->Type & POLY_QUAD)
01000 {
01001 mrgb->rgb[3].a = (unsigned char)mp->v3->a;
01002 }
01003 }
01004 }
01005
01007
01009
01010 void SetModelVertsGlare(MODEL *m, VEC *pos, MAT *mat, short flag)
01011 {
01012 FACING_POLY poly;
01013 MAT spinmat1, spinmat2;
01014 REAL dot;
01015 VEC look, vec, vec2;
01016 long i, col;
01017
01018
01019
01020 RotMatrixZ(&spinmat1, TIME2MS(CurrentTimer()) / 5000.0f);
01021 RotMatrixZ(&spinmat2, TIME2MS(CurrentTimer()) / 2500.0f);
01022
01023
01024
01025 TransposeRotVector(mat, &ViewCameraMatrix.mv[L], &look);
01026 NormalizeVector(&look);
01027
01028
01029
01030 poly.U = 192.0f / 256.0f;
01031 poly.V = 64.0f / 256.0f;
01032 poly.Usize = 64.0f / 256.0f;
01033 poly.Vsize = 64.0f / 256.0f;
01034 poly.Tpage = TPAGE_FX1;
01035
01036
01037
01038 MODEL_POLY *mp;
01039 MODEL_VERTEX **mvp, *v0, *v1;
01040 long j, vnum;
01041 REAL time;
01042
01043 mp = m->PolyPtr;
01044 for (i = 0 ; i < m->PolyNum ; i++, mp++) if (mp->Type & POLY_ENV)
01045 {
01046 mvp = &mp->v0;
01047 vnum = 3 + (mp->Type & 1);
01048
01049 for (j = 0 ; j < vnum ; j++)
01050 {
01051 v0 = mvp[j];
01052 v1 = mvp[(j + 1) % vnum];
01053
01054 SubVector((VEC*)&v1->x, (VEC*)&v0->x, &vec2);
01055 NormalizeVector(&vec2);
01056 dot = DotProduct(&look, &vec2);
01057 time = dot * 0.75f + 0.5f;
01058 if (time < 0.0f) continue;
01059 if (time > 1.0f) continue;
01060
01061 vec2.v[X] = v0->nx + (v1->nx - v0->nx) * time;
01062 vec2.v[Y] = v0->ny + (v1->ny - v0->ny) * time;
01063 vec2.v[Z] = v0->nz + (v1->nz - v0->nz) * time;
01064 NormalizeVector(&vec2);
01065
01066 dot = DotProduct(&look, (VEC*)&vec2);
01067 if (dot < -0.8f)
01068 {
01069 poly.Xsize = poly.Ysize = (-0.8f - dot) * 48.0f;
01070
01071 FTOL((-0.8f - dot) * 5.0f * 255, col);
01072 poly.RGB = (col * EnvRgb.b / 255) | (col * EnvRgb.g / 255) << 8 | (col * EnvRgb.r / 255) << 16;
01073
01074 if (flag & MODEL_USENEWVERTS)
01075 {
01076 vec2.v[X] = v0->x2 + (v1->x2 - v0->x2) * time;
01077 vec2.v[Y] = v0->y2 + (v1->y2 - v0->y2) * time;
01078 vec2.v[Z] = v0->z2 + (v1->z2 - v0->z2) * time;
01079 }
01080 else
01081 {
01082 vec2.v[X] = v0->x + (v1->x - v0->x) * time;
01083 vec2.v[Y] = v0->y + (v1->y - v0->y) * time;
01084 vec2.v[Z] = v0->z + (v1->z - v0->z) * time;
01085 }
01086 RotTransVector(mat, pos, &vec2, &vec);
01087
01088 DrawFacingPolyRot(&vec, &spinmat1, &poly, 1, -24.0f);
01089 DrawFacingPolyRot(&vec, &spinmat2, &poly, 1, -24.0f);
01090 }
01091 }
01092 }
01093 }
01094
01096
01098
01099 void DrawModelPolysClip(MODEL *m, long lit, long env)
01100 {
01101 long i, clip;
01102 POLY_RGB *mrgb;
01103 MODEL_POLY *mp;
01104 VERTEX_TEX1 *vert;
01105 BUCKET_TEX1 *bucket;
01106 VERTEX_TEX0 *vertrgb;
01107 BUCKET_TEX0 *bucketrgb;
01108 BUCKET_ENV *envbucket;
01109 short count;
01110
01111
01112
01113 #if SCREEN_DEBUG
01114 ModelPolyCount += (m->QuadNumTex + m->QuadNumRGB) * 2;
01115 ModelPolyCount += (m->TriNumTex + m->TriNumRGB);
01116 if (env)
01117 {
01118 ModelPolyCount += (m->QuadNumTex + m->QuadNumRGB) * 2;
01119 ModelPolyCount += (m->TriNumTex + m->TriNumRGB);
01120 }
01121 #endif
01122
01123
01124
01125 mrgb = m->PolyRGB;
01126 mp = m->PolyPtr;
01127
01128 for (i = m->QuadNumTex ; i ; i--, mrgb++, mp++)
01129 {
01130
01131
01132
01133 REJECT_MODEL_POLY();
01134 CLIP_QUAD();
01135 INC_POLY_COUNT(ModelDrawnCount, 2);
01136
01137
01138
01139 if (mp->Type & POLY_SEMITRANS)
01140 {
01141 if (!SEMI_POLY_FREE()) continue;
01142 SEMI_POLY_SETUP(vert, ModelFog, 4, mp->Tpage, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01143 }
01144 else
01145 {
01146 if (clip) bucket = &ModelBucketHeadClip[mp->Tpage];
01147 else bucket = &ModelBucketHead[mp->Tpage];
01148 count = (short)(bucket->CurrentVerts - bucket->Verts);
01149
01150 if (count > BUCKET_VERT_END)
01151 {
01152 SET_TPAGE(mp->Tpage);
01153 FlushOneBucketTEX1(bucket, clip);
01154 count = 0;
01155 }
01156
01157 bucket->CurrentIndex[0] = count;
01158 bucket->CurrentIndex[1] = count + 1;
01159 bucket->CurrentIndex[2] = count + 2;
01160 bucket->CurrentIndex[3] = count;
01161 bucket->CurrentIndex[4] = count + 2;
01162 bucket->CurrentIndex[5] = count + 3;
01163 bucket->CurrentIndex += 6;
01164
01165 vert = bucket->CurrentVerts;
01166 bucket->CurrentVerts += 4;
01167 }
01168
01169
01170
01171 COPY_QUAD_XYZRHW(vert);
01172 COPY_QUAD_UV(vert);
01173
01174 if (ModelFog)
01175 COPY_QUAD_SPECULAR(vert);
01176
01177 if (lit)
01178 {
01179 COPY_MODEL_QUAD_COLOR_LIT(vert);
01180 }
01181 else
01182 {
01183 COPY_MODEL_QUAD_COLOR(vert);
01184 }
01185
01186
01187
01188 if (env)
01189 {
01190 REJECT_MODEL_ENV_POLY();
01191 INC_POLY_COUNT(ModelDrawnCount, 2);
01192
01193
01194
01195 if (clip) envbucket = ModelBucketHeadEnvClip;
01196 else envbucket = ModelBucketHeadEnv;
01197 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01198
01199 if (count > ENV_VERT_END)
01200 continue;
01201
01202 envbucket->CurrentIndex[0] = count;
01203 envbucket->CurrentIndex[1] = count + 1;
01204 envbucket->CurrentIndex[2] = count + 2;
01205 envbucket->CurrentIndex[3] = count;
01206 envbucket->CurrentIndex[4] = count + 2;
01207 envbucket->CurrentIndex[5] = count + 3;
01208 envbucket->CurrentIndex += 6;
01209
01210 vert = envbucket->CurrentVerts;
01211 envbucket->CurrentVerts += 4;
01212
01213
01214
01215 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01216 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01217 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01218 *(MEM32*)&vert[3] = *(MEM32*)&mp->v3->sx;
01219 }
01220 }
01221
01222
01223
01224 for (i = m->TriNumTex ; i ; i--, mrgb++, mp++)
01225 {
01226
01227
01228
01229 REJECT_MODEL_POLY();
01230 CLIP_TRI();
01231 INC_POLY_COUNT(ModelDrawnCount, 1);
01232
01233
01234
01235 if (mp->Type & POLY_SEMITRANS)
01236 {
01237 if (!SEMI_POLY_FREE()) continue;
01238 SEMI_POLY_SETUP(vert, ModelFog, 3, mp->Tpage, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01239 }
01240 else
01241 {
01242 if (clip) bucket = &ModelBucketHeadClip[mp->Tpage];
01243 else bucket = &ModelBucketHead[mp->Tpage];
01244 count = (short)(bucket->CurrentVerts - bucket->Verts);
01245
01246 if (count > BUCKET_VERT_END)
01247 {
01248 SET_TPAGE(mp->Tpage);
01249 FlushOneBucketTEX1(bucket, clip);
01250 count = 0;
01251 }
01252
01253 bucket->CurrentIndex[0] = count;
01254 bucket->CurrentIndex[1] = count + 1;
01255 bucket->CurrentIndex[2] = count + 2;
01256 bucket->CurrentIndex += 3;
01257
01258 vert = bucket->CurrentVerts;
01259 bucket->CurrentVerts += 3;
01260 }
01261
01262
01263
01264 COPY_TRI_XYZRHW(vert);
01265 COPY_TRI_UV(vert);
01266
01267 if (ModelFog)
01268 COPY_TRI_SPECULAR(vert);
01269
01270 if (lit)
01271 {
01272 COPY_MODEL_TRI_COLOR_LIT(vert);
01273 }
01274 else
01275 {
01276 COPY_MODEL_TRI_COLOR(vert);
01277 }
01278
01279
01280
01281 if (env)
01282 {
01283 REJECT_MODEL_ENV_POLY();
01284 INC_POLY_COUNT(ModelDrawnCount, 1);
01285
01286
01287
01288 if (clip) envbucket = ModelBucketHeadEnvClip;
01289 else envbucket = ModelBucketHeadEnv;
01290 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01291
01292 if (count > ENV_VERT_END)
01293 continue;
01294
01295 envbucket->CurrentIndex[0] = count;
01296 envbucket->CurrentIndex[1] = count + 1;
01297 envbucket->CurrentIndex[2] = count + 2;
01298 envbucket->CurrentIndex += 3;
01299
01300 vert = envbucket->CurrentVerts;
01301 envbucket->CurrentVerts += 3;
01302
01303
01304
01305 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01306 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01307 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01308 }
01309 }
01310
01311
01312
01313 for (i = m->QuadNumRGB ; i ; i--, mrgb++, mp++)
01314 {
01315
01316
01317
01318 REJECT_MODEL_POLY();
01319 CLIP_QUAD();
01320 INC_POLY_COUNT(ModelDrawnCount, 2);
01321
01322
01323
01324 if (mp->Type & POLY_SEMITRANS)
01325 {
01326 if (!SEMI_POLY_FREE()) continue;
01327 SEMI_POLY_SETUP_RGB(vertrgb, ModelFog, 4, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01328 }
01329 else
01330 {
01331 if (clip) bucketrgb = ModelBucketHeadClipRGB;
01332 else bucketrgb = ModelBucketHeadRGB;
01333 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
01334
01335 if (count > BUCKET_VERT_END)
01336 {
01337 SET_TPAGE(-1);
01338 FlushOneBucketTEX0(bucketrgb, clip);
01339 count = 0;
01340 }
01341
01342 bucketrgb->CurrentIndex[0] = count;
01343 bucketrgb->CurrentIndex[1] = count + 1;
01344 bucketrgb->CurrentIndex[2] = count + 2;
01345 bucketrgb->CurrentIndex[3] = count;
01346 bucketrgb->CurrentIndex[4] = count + 2;
01347 bucketrgb->CurrentIndex[5] = count + 3;
01348 bucketrgb->CurrentIndex += 6;
01349
01350 vertrgb = bucketrgb->CurrentVerts;
01351 bucketrgb->CurrentVerts += 4;
01352 }
01353
01354
01355
01356 COPY_QUAD_XYZRHW(vertrgb);
01357
01358 if (ModelFog)
01359 COPY_QUAD_SPECULAR(vertrgb);
01360
01361 if (lit)
01362 {
01363 COPY_MODEL_QUAD_COLOR_LIT(vertrgb);
01364 }
01365 else
01366 {
01367 COPY_MODEL_QUAD_COLOR(vertrgb);
01368 }
01369
01370
01371
01372 if (env)
01373 {
01374 REJECT_MODEL_ENV_POLY();
01375 INC_POLY_COUNT(ModelDrawnCount, 2);
01376
01377
01378
01379 if (clip) envbucket = ModelBucketHeadEnvClip;
01380 else envbucket = ModelBucketHeadEnv;
01381 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01382
01383 if (count > ENV_VERT_END)
01384 continue;
01385
01386 envbucket->CurrentIndex[0] = count;
01387 envbucket->CurrentIndex[1] = count + 1;
01388 envbucket->CurrentIndex[2] = count + 2;
01389 envbucket->CurrentIndex[3] = count;
01390 envbucket->CurrentIndex[4] = count + 2;
01391 envbucket->CurrentIndex[5] = count + 3;
01392 envbucket->CurrentIndex += 6;
01393
01394 vert = envbucket->CurrentVerts;
01395 envbucket->CurrentVerts += 4;
01396
01397
01398
01399 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01400 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01401 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01402 *(MEM32*)&vert[3] = *(MEM32*)&mp->v3->sx;
01403 }
01404 }
01405
01406
01407
01408 for (i = m->TriNumRGB ; i ; i--, mrgb++, mp++)
01409 {
01410
01411
01412
01413 REJECT_MODEL_POLY();
01414 CLIP_TRI();
01415 INC_POLY_COUNT(ModelDrawnCount, 1);
01416
01417
01418
01419 if (mp->Type & POLY_SEMITRANS)
01420 {
01421 if (!SEMI_POLY_FREE()) continue;
01422 SEMI_POLY_SETUP_RGB(vertrgb, ModelFog, 3, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01423 }
01424 else
01425 {
01426 if (clip) bucketrgb = ModelBucketHeadClipRGB;
01427 else bucketrgb = ModelBucketHeadRGB;
01428 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
01429
01430 if (count > BUCKET_VERT_END)
01431 {
01432 SET_TPAGE(-1);
01433 FlushOneBucketTEX0(bucketrgb, clip);
01434 count = 0;
01435 }
01436
01437 bucketrgb->CurrentIndex[0] = count;
01438 bucketrgb->CurrentIndex[1] = count + 1;
01439 bucketrgb->CurrentIndex[2] = count + 2;
01440 bucketrgb->CurrentIndex += 3;
01441
01442 vertrgb = bucketrgb->CurrentVerts;
01443 bucketrgb->CurrentVerts += 3;
01444 }
01445
01446
01447
01448 COPY_TRI_XYZRHW(vertrgb);
01449
01450 if (ModelFog)
01451 COPY_TRI_SPECULAR(vertrgb);
01452
01453 if (lit)
01454 {
01455 COPY_MODEL_TRI_COLOR_LIT(vertrgb);
01456 }
01457 else
01458 {
01459 COPY_MODEL_TRI_COLOR(vertrgb);
01460 }
01461
01462
01463
01464 if (env)
01465 {
01466 REJECT_MODEL_ENV_POLY();
01467 INC_POLY_COUNT(ModelDrawnCount, 1);
01468
01469
01470
01471 if (clip) envbucket = ModelBucketHeadEnvClip;
01472 else envbucket = ModelBucketHeadEnv;
01473 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01474
01475 if (count > ENV_VERT_END)
01476 continue;
01477
01478 envbucket->CurrentIndex[0] = count;
01479 envbucket->CurrentIndex[1] = count + 1;
01480 envbucket->CurrentIndex[2] = count + 2;
01481 envbucket->CurrentIndex += 3;
01482
01483 vert = envbucket->CurrentVerts;
01484 envbucket->CurrentVerts += 3;
01485
01486
01487
01488 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01489 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01490 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01491 }
01492 }
01493 }
01494
01496
01498
01499 void DrawModelPolys(MODEL *m, long lit, long env)
01500 {
01501 long i;
01502 POLY_RGB *mrgb;
01503 MODEL_POLY *mp;
01504 VERTEX_TEX1 *vert;
01505 BUCKET_TEX1 *bucket;
01506 VERTEX_TEX0 *vertrgb;
01507 BUCKET_TEX0 *bucketrgb;
01508 BUCKET_ENV *envbucket = ModelBucketHeadEnv;
01509 short count;
01510
01511
01512
01513 #if SCREEN_DEBUG
01514 ModelPolyCount += (m->QuadNumTex + m->QuadNumRGB) * 2;
01515 ModelPolyCount += (m->TriNumTex + m->TriNumRGB);
01516 if (env)
01517 {
01518 ModelPolyCount += (m->QuadNumTex + m->QuadNumRGB) * 2;
01519 ModelPolyCount += (m->TriNumTex + m->TriNumRGB);
01520 }
01521 #endif
01522
01523
01524
01525 mrgb = m->PolyRGB;
01526 mp = m->PolyPtr;
01527
01528 for (i = m->QuadNumTex ; i ; i--, mrgb++, mp++)
01529 {
01530
01531
01532
01533 REJECT_MODEL_POLY();
01534 INC_POLY_COUNT(ModelDrawnCount, 2);
01535
01536
01537
01538 if (mp->Type & POLY_SEMITRANS)
01539 {
01540 if (!SEMI_POLY_FREE()) continue;
01541 SEMI_POLY_SETUP(vert, ModelFog, 4, mp->Tpage, FALSE, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01542 }
01543 else
01544 {
01545 bucket = &ModelBucketHead[mp->Tpage];
01546 count = (short)(bucket->CurrentVerts - bucket->Verts);
01547
01548 if (count > BUCKET_VERT_END)
01549 {
01550 SET_TPAGE(mp->Tpage);
01551 FlushOneBucketTEX1(bucket, FALSE);
01552 count = 0;
01553 }
01554
01555 bucket->CurrentIndex[0] = count;
01556 bucket->CurrentIndex[1] = count + 1;
01557 bucket->CurrentIndex[2] = count + 2;
01558 bucket->CurrentIndex[3] = count;
01559 bucket->CurrentIndex[4] = count + 2;
01560 bucket->CurrentIndex[5] = count + 3;
01561 bucket->CurrentIndex += 6;
01562
01563 vert = bucket->CurrentVerts;
01564 bucket->CurrentVerts += 4;
01565 }
01566
01567
01568
01569 COPY_QUAD_XYZRHW(vert);
01570 COPY_QUAD_UV(vert);
01571
01572 if (ModelFog)
01573 COPY_QUAD_SPECULAR(vert);
01574
01575 if (lit)
01576 {
01577 COPY_MODEL_QUAD_COLOR_LIT(vert);
01578 }
01579 else
01580 {
01581 COPY_MODEL_QUAD_COLOR(vert);
01582 }
01583
01584
01585
01586 if (env)
01587 {
01588 REJECT_MODEL_ENV_POLY();
01589 INC_POLY_COUNT(ModelDrawnCount, 2);
01590
01591
01592
01593 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01594
01595 if (count > ENV_VERT_END)
01596 continue;
01597
01598 envbucket->CurrentIndex[0] = count;
01599 envbucket->CurrentIndex[1] = count + 1;
01600 envbucket->CurrentIndex[2] = count + 2;
01601 envbucket->CurrentIndex[3] = count;
01602 envbucket->CurrentIndex[4] = count + 2;
01603 envbucket->CurrentIndex[5] = count + 3;
01604 envbucket->CurrentIndex += 6;
01605
01606 vert = envbucket->CurrentVerts;
01607 envbucket->CurrentVerts += 4;
01608
01609
01610
01611 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01612 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01613 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01614 *(MEM32*)&vert[3] = *(MEM32*)&mp->v3->sx;
01615 }
01616 }
01617
01618
01619
01620 for (i = m->TriNumTex ; i ; i--, mrgb++, mp++)
01621 {
01622
01623
01624
01625 REJECT_MODEL_POLY();
01626 INC_POLY_COUNT(ModelDrawnCount, 1);
01627
01628
01629
01630 if (mp->Type & POLY_SEMITRANS)
01631 {
01632 if (!SEMI_POLY_FREE()) continue;
01633 SEMI_POLY_SETUP(vert, ModelFog, 3, mp->Tpage, FALSE, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01634 }
01635 else
01636 {
01637 bucket = &ModelBucketHead[mp->Tpage];
01638 count = (short)(bucket->CurrentVerts - bucket->Verts);
01639
01640 if (count > BUCKET_VERT_END)
01641 {
01642 SET_TPAGE(mp->Tpage);
01643 FlushOneBucketTEX1(bucket, FALSE);
01644 count = 0;
01645 }
01646
01647 bucket->CurrentIndex[0] = count;
01648 bucket->CurrentIndex[1] = count + 1;
01649 bucket->CurrentIndex[2] = count + 2;
01650 bucket->CurrentIndex += 3;
01651
01652 vert = bucket->CurrentVerts;
01653 bucket->CurrentVerts += 3;
01654 }
01655
01656
01657
01658 COPY_TRI_XYZRHW(vert);
01659 COPY_TRI_UV(vert);
01660
01661 if (ModelFog)
01662 COPY_TRI_SPECULAR(vert);
01663
01664 if (lit)
01665 {
01666 COPY_MODEL_TRI_COLOR_LIT(vert);
01667 }
01668 else
01669 {
01670 COPY_MODEL_TRI_COLOR(vert);
01671 }
01672
01673
01674
01675 if (env)
01676 {
01677 REJECT_MODEL_ENV_POLY();
01678 INC_POLY_COUNT(ModelDrawnCount, 1);
01679
01680
01681
01682 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01683
01684 if (count > ENV_VERT_END)
01685 continue;
01686
01687 envbucket->CurrentIndex[0] = count;
01688 envbucket->CurrentIndex[1] = count + 1;
01689 envbucket->CurrentIndex[2] = count + 2;
01690 envbucket->CurrentIndex += 3;
01691
01692 vert = envbucket->CurrentVerts;
01693 envbucket->CurrentVerts += 3;
01694
01695
01696
01697 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01698 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01699 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01700 }
01701 }
01702
01703
01704
01705 for (i = m->QuadNumRGB ; i ; i--, mrgb++, mp++)
01706 {
01707
01708
01709
01710 REJECT_MODEL_POLY();
01711 INC_POLY_COUNT(ModelDrawnCount, 2);
01712
01713
01714
01715 if (mp->Type & POLY_SEMITRANS)
01716 {
01717 if (!SEMI_POLY_FREE()) continue;
01718 SEMI_POLY_SETUP_RGB(vertrgb, ModelFog, 4, FALSE, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01719 }
01720 else
01721 {
01722 bucketrgb = ModelBucketHeadRGB;
01723 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
01724
01725 if (count > BUCKET_VERT_END)
01726 {
01727 SET_TPAGE(-1);
01728 FlushOneBucketTEX0(bucketrgb, FALSE);
01729 count = 0;
01730 }
01731
01732 bucketrgb->CurrentIndex[0] = count;
01733 bucketrgb->CurrentIndex[1] = count + 1;
01734 bucketrgb->CurrentIndex[2] = count + 2;
01735 bucketrgb->CurrentIndex[3] = count;
01736 bucketrgb->CurrentIndex[4] = count + 2;
01737 bucketrgb->CurrentIndex[5] = count + 3;
01738 bucketrgb->CurrentIndex += 6;
01739
01740 vertrgb = bucketrgb->CurrentVerts;
01741 bucketrgb->CurrentVerts += 4;
01742 }
01743
01744
01745
01746 COPY_QUAD_XYZRHW(vertrgb);
01747
01748 if (ModelFog)
01749 COPY_QUAD_SPECULAR(vertrgb);
01750
01751 if (lit)
01752 {
01753 COPY_MODEL_QUAD_COLOR_LIT(vertrgb);
01754 }
01755 else
01756 {
01757 COPY_MODEL_QUAD_COLOR(vertrgb);
01758 }
01759
01760
01761
01762 if (env)
01763 {
01764 REJECT_MODEL_ENV_POLY();
01765 INC_POLY_COUNT(ModelDrawnCount, 2);
01766
01767
01768
01769 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01770
01771 if (count > ENV_VERT_END)
01772 continue;
01773
01774 envbucket->CurrentIndex[0] = count;
01775 envbucket->CurrentIndex[1] = count + 1;
01776 envbucket->CurrentIndex[2] = count + 2;
01777 envbucket->CurrentIndex[3] = count;
01778 envbucket->CurrentIndex[4] = count + 2;
01779 envbucket->CurrentIndex[5] = count + 3;
01780 envbucket->CurrentIndex += 6;
01781
01782 vert = envbucket->CurrentVerts;
01783 envbucket->CurrentVerts += 4;
01784
01785
01786
01787 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01788 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01789 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01790 *(MEM32*)&vert[3] = *(MEM32*)&mp->v3->sx;
01791 }
01792 }
01793
01794
01795
01796 for (i = m->TriNumRGB ; i ; i--, mrgb++, mp++)
01797 {
01798
01799
01800
01801 REJECT_MODEL_POLY();
01802 INC_POLY_COUNT(ModelDrawnCount, 1);
01803
01804
01805
01806 if (mp->Type & POLY_SEMITRANS)
01807 {
01808 if (!SEMI_POLY_FREE()) continue;
01809 SEMI_POLY_SETUP_RGB(vertrgb, ModelFog, 3, FALSE, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01810 }
01811 else
01812 {
01813 bucketrgb = ModelBucketHeadRGB;
01814 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
01815
01816 if (count > BUCKET_VERT_END)
01817 {
01818 SET_TPAGE(-1);
01819 FlushOneBucketTEX0(bucketrgb, FALSE);
01820 count = 0;
01821 }
01822
01823 bucketrgb->CurrentIndex[0] = count;
01824 bucketrgb->CurrentIndex[1] = count + 1;
01825 bucketrgb->CurrentIndex[2] = count + 2;
01826 bucketrgb->CurrentIndex += 3;
01827
01828 vertrgb = bucketrgb->CurrentVerts;
01829 bucketrgb->CurrentVerts += 3;
01830 }
01831
01832
01833
01834 COPY_TRI_XYZRHW(vertrgb);
01835
01836 if (ModelFog)
01837 COPY_TRI_SPECULAR(vertrgb);
01838
01839 if (lit)
01840 {
01841 COPY_MODEL_TRI_COLOR_LIT(vertrgb);
01842 }
01843 else
01844 {
01845 COPY_MODEL_TRI_COLOR(vertrgb);
01846 }
01847
01848
01849
01850 if (env)
01851 {
01852 REJECT_MODEL_ENV_POLY();
01853 INC_POLY_COUNT(ModelDrawnCount, 1);
01854
01855
01856
01857 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01858
01859 if (count > ENV_VERT_END)
01860 continue;
01861
01862 envbucket->CurrentIndex[0] = count;
01863 envbucket->CurrentIndex[1] = count + 1;
01864 envbucket->CurrentIndex[2] = count + 2;
01865 envbucket->CurrentIndex += 3;
01866
01867 vert = envbucket->CurrentVerts;
01868 envbucket->CurrentVerts += 3;
01869
01870
01871
01872 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01873 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01874 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01875 }
01876 }
01877 }
01878
01880
01882
01883 void DrawModelPolysMirror(MODEL *m, long lit)
01884 {
01885 long i, clip;
01886 POLY_RGB *mrgb;
01887 MODEL_POLY *mp;
01888 VERTEX_TEX1 *vert;
01889 BUCKET_TEX1 *bucket;
01890 VERTEX_TEX0 *vertrgb;
01891 BUCKET_TEX0 *bucketrgb;
01892 short count;
01893
01894
01895
01896 #if SCREEN_DEBUG
01897 ModelPolyCount += (m->QuadNumTex + m->QuadNumRGB) * 2;
01898 ModelPolyCount += (m->TriNumTex + m->TriNumRGB);
01899 #endif
01900
01901
01902
01903 mrgb = m->PolyRGB;
01904 mp = m->PolyPtr;
01905
01906 for (i = m->QuadNumTex ; i ; i--, mrgb++, mp++)
01907 {
01908
01909
01910
01911 REJECT_MODEL_POLY_MIRROR();
01912 CLIP_QUAD_MIRROR();
01913 INC_POLY_COUNT(ModelDrawnCount, 2);
01914
01915
01916
01917 if (mp->Type & POLY_SEMITRANS)
01918 {
01919 if (!SEMI_POLY_FREE()) continue;
01920 SEMI_POLY_SETUP(vert, ModelFog, 4, mp->Tpage, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01921 }
01922 else
01923 {
01924 if (clip) bucket = &ModelBucketHeadClip[mp->Tpage];
01925 else bucket = &ModelBucketHead[mp->Tpage];
01926 count = (short)(bucket->CurrentVerts - bucket->Verts);
01927
01928 if (count > BUCKET_VERT_END)
01929 {
01930 SET_TPAGE(mp->Tpage);
01931 FlushOneBucketTEX1(bucket, clip);
01932 count = 0;
01933 }
01934
01935 bucket->CurrentIndex[0] = count;
01936 bucket->CurrentIndex[1] = count + 1;
01937 bucket->CurrentIndex[2] = count + 2;
01938 bucket->CurrentIndex[3] = count;
01939 bucket->CurrentIndex[4] = count + 2;
01940 bucket->CurrentIndex[5] = count + 3;
01941 bucket->CurrentIndex += 6;
01942
01943 vert = bucket->CurrentVerts;
01944 bucket->CurrentVerts += 4;
01945 }
01946
01947
01948
01949 COPY_QUAD_XYZRHW(vert);
01950 COPY_QUAD_UV(vert);
01951 COPY_QUAD_SPECULAR(vert);
01952
01953 if (lit)
01954 {
01955 COPY_MODEL_QUAD_COLOR_LIT(vert);
01956 }
01957 else
01958 {
01959 COPY_MODEL_QUAD_COLOR(vert);
01960 }
01961 }
01962
01963
01964
01965 for (i = m->TriNumTex ; i ; i--, mrgb++, mp++)
01966 {
01967
01968
01969
01970 REJECT_MODEL_POLY_MIRROR();
01971 CLIP_TRI_MIRROR();
01972 INC_POLY_COUNT(ModelDrawnCount, 1);
01973
01974
01975
01976 if (mp->Type & POLY_SEMITRANS)
01977 {
01978 if (!SEMI_POLY_FREE()) continue;
01979 SEMI_POLY_SETUP(vert, ModelFog, 3, mp->Tpage, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01980 }
01981 else
01982 {
01983 if (clip) bucket = &ModelBucketHeadClip[mp->Tpage];
01984 else bucket = &ModelBucketHead[mp->Tpage];
01985 count = (short)(bucket->CurrentVerts - bucket->Verts);
01986
01987 if (count > BUCKET_VERT_END)
01988 {
01989 SET_TPAGE(mp->Tpage);
01990 FlushOneBucketTEX1(bucket, clip);
01991 count = 0;
01992 }
01993
01994 bucket->CurrentIndex[0] = count;
01995 bucket->CurrentIndex[1] = count + 1;
01996 bucket->CurrentIndex[2] = count + 2;
01997 bucket->CurrentIndex += 3;
01998
01999 vert = bucket->CurrentVerts;
02000 bucket->CurrentVerts += 3;
02001 }
02002
02003
02004
02005 COPY_TRI_XYZRHW(vert);
02006 COPY_TRI_UV(vert);
02007 COPY_TRI_SPECULAR(vert);
02008
02009 if (lit)
02010 {
02011 COPY_MODEL_TRI_COLOR_LIT(vert);
02012 }
02013 else
02014 {
02015 COPY_MODEL_TRI_COLOR(vert);
02016 }
02017 }
02018
02019
02020
02021 for (i = m->QuadNumRGB ; i ; i--, mrgb++, mp++)
02022 {
02023
02024
02025
02026 REJECT_MODEL_POLY_MIRROR();
02027 CLIP_QUAD_MIRROR();
02028 INC_POLY_COUNT(ModelDrawnCount, 2);
02029
02030
02031
02032 if (mp->Type & POLY_SEMITRANS)
02033 {
02034 if (!SEMI_POLY_FREE()) continue;
02035 SEMI_POLY_SETUP_RGB(vertrgb, ModelFog, 4, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
02036 }
02037 else
02038 {
02039 if (clip) bucketrgb = ModelBucketHeadClipRGB;
02040 else bucketrgb = ModelBucketHeadRGB;
02041 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
02042
02043 if (count > BUCKET_VERT_END)
02044 {
02045 SET_TPAGE(-1);
02046 FlushOneBucketTEX0(bucketrgb, clip);
02047 count = 0;
02048 }
02049
02050 bucketrgb->CurrentIndex[0] = count;
02051 bucketrgb->CurrentIndex[1] = count + 1;
02052 bucketrgb->CurrentIndex[2] = count + 2;
02053 bucketrgb->CurrentIndex[3] = count;
02054 bucketrgb->CurrentIndex[4] = count + 2;
02055 bucketrgb->CurrentIndex[5] = count + 3;
02056 bucketrgb->CurrentIndex += 6;
02057
02058 vertrgb = bucketrgb->CurrentVerts;
02059 bucketrgb->CurrentVerts += 4;
02060 }
02061
02062
02063
02064 COPY_QUAD_XYZRHW(vertrgb);
02065 COPY_QUAD_SPECULAR(vertrgb);
02066
02067 if (lit)
02068 {
02069 COPY_MODEL_QUAD_COLOR_LIT(vertrgb);
02070 }
02071 else
02072 {
02073 COPY_MODEL_QUAD_COLOR(vertrgb);
02074 }
02075 }
02076
02077
02078
02079 for (i = m->TriNumRGB ; i ; i--, mrgb++, mp++)
02080 {
02081
02082
02083
02084 REJECT_MODEL_POLY_MIRROR();
02085 CLIP_TRI_MIRROR();
02086 INC_POLY_COUNT(ModelDrawnCount, 1);
02087
02088
02089
02090 if (mp->Type & POLY_SEMITRANS)
02091 {
02092 if (!SEMI_POLY_FREE()) continue;
02093 SEMI_POLY_SETUP_RGB(vertrgb, ModelFog, 3, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
02094 }
02095 else
02096 {
02097 if (clip) bucketrgb = ModelBucketHeadClipRGB;
02098 else bucketrgb = ModelBucketHeadRGB;
02099 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
02100
02101 if (count > BUCKET_VERT_END)
02102 {
02103 SET_TPAGE(-1);
02104 FlushOneBucketTEX0(bucketrgb, clip);
02105 count = 0;
02106 }
02107
02108 bucketrgb->CurrentIndex[0] = count;
02109 bucketrgb->CurrentIndex[1] = count + 1;
02110 bucketrgb->CurrentIndex[2] = count + 2;
02111 bucketrgb->CurrentIndex += 3;
02112
02113 vertrgb = bucketrgb->CurrentVerts;
02114 bucketrgb->CurrentVerts += 3;
02115 }
02116
02117
02118
02119 COPY_TRI_XYZRHW(vertrgb);
02120 COPY_TRI_SPECULAR(vertrgb);
02121
02122 if (lit)
02123 {
02124 COPY_MODEL_TRI_COLOR_LIT(vertrgb);
02125 }
02126 else
02127 {
02128 COPY_MODEL_TRI_COLOR(vertrgb);
02129 }
02130 }
02131 }
02132
02134
02136
02137 void SetEnvStatic(VEC *pos, MAT *mat, long rgb, float xoff, float yoff, float scale)
02138 {
02139 MAT m, m2;
02140 float mul;
02141
02142
02143
02144 *(long*)&EnvRgb = rgb;
02145
02146
02147
02148 if (!RenderSettings.Env)
02149 return;
02150
02151
02152
02153 SubVector(pos, &ViewCameraPos, &m.mv[L]);
02154 NormalizeVector(&m.mv[L]);
02155 CrossProduct(&m.mv[L], &ViewCameraMatrix.mv[R], &m.mv[U]);
02156 CrossProduct(&m.mv[U], &m.mv[L], &m.mv[R]);
02157
02158
02159
02160 TransposeMatrix(&m, &m2);
02161
02162
02163
02164 MulMatrix(&m2, mat, &EnvMatrix);
02165
02166
02167
02168 mul = 0.5f * scale;
02169 EnvMatrix.m[RX] *= mul;
02170 EnvMatrix.m[UX] *= mul;
02171 EnvMatrix.m[LX] *= mul;
02172 EnvMatrix.m[RY] *= mul;
02173 EnvMatrix.m[UY] *= mul;
02174 EnvMatrix.m[LY] *= mul;
02175
02176
02177
02178 EnvTpage = TPAGE_ENVSTILL;
02179
02180
02181
02182 EnvXoffset = xoff + 0.5f;
02183 EnvYoffset = yoff + 0.5f;
02184 }
02185
02187
02189
02190 void SetEnvActive(VEC *pos, MAT *mat, MAT *envmat, long rgb, float xoff, float yoff, float scale)
02191 {
02192 float mul;
02193 MAT m1, m2;
02194
02195
02196
02197 *(long*)&EnvRgb = rgb;
02198
02199
02200
02201 if (!RenderSettings.Env)
02202 return;
02203
02204
02205
02206 RotMatrixY(&m1, 0.25f);
02207 MulMatrix(envmat, &m1, &m2);
02208
02209
02210
02211 MulMatrix(&m2, mat, &EnvMatrix);
02212
02213
02214
02215 mul = 0.5f * scale;
02216 EnvMatrix.m[RX] *= mul;
02217 EnvMatrix.m[UX] *= mul;
02218 EnvMatrix.m[LX] *= mul;
02219 EnvMatrix.m[RY] *= mul;
02220 EnvMatrix.m[UY] *= mul;
02221 EnvMatrix.m[LY] *= mul;
02222
02223
02224
02225 EnvTpage = TPAGE_ENVROLL;
02226
02227
02228
02229 EnvXoffset = xoff + 0.5f;
02230 EnvYoffset = yoff + 0.5f;
02231 }
02232
02234
02236
02237 void InitLevelModels(void)
02238 {
02239 long i;
02240
02241 for (i = 0 ; i < MAX_LEVEL_MODELS ; i++)
02242 {
02243 LevelModel[i].ID = -1;
02244 }
02245 }
02246
02248
02250
02251 void FreeLevelModels(void)
02252 {
02253 long i;
02254
02255 for (i = 0 ; i < MAX_LEVEL_MODELS ; i++)
02256 {
02257 if (LevelModel[i].ID != -1)
02258 {
02259 LevelModel[i].RefCount = 1;
02260 FreeOneLevelModel(i);
02261 }
02262 }
02263 }
02264
02266
02268
02269 long LoadOneLevelModel(long id, long flag, struct renderflags renderflag, long tpage)
02270 {
02271 long i, rgbper;
02272 char buf[128];
02273 FILE *fp;
02274
02275
02276
02277 for (i = 0 ; i < MAX_LEVEL_MODELS ; i++)
02278 {
02279 if (LevelModel[i].ID == id)
02280 {
02281 LevelModel[i].RefCount++;
02282 return i;
02283 }
02284 }
02285
02286
02287 for (i = 0 ; i < MAX_LEVEL_MODELS ; i++)
02288 {
02289 if (LevelModel[i].ID == -1)
02290 {
02291
02292
02293
02294 wsprintf(buf, "%s.m", LevelModelList[id]);
02295
02296 if (flag)
02297 rgbper = LevelInf[GameSettings.Level].ModelRGBper;
02298 else
02299 rgbper = 100;
02300
02301 if (!LoadModel(buf, &LevelModel[i].Model, (char)tpage, 1, LOADMODEL_OFFSET_TPAGE, rgbper))
02302 return -1;
02303
02304
02305
02306 wsprintf(buf, "%s.hul", LevelModelList[id]);
02307 if ((fp = fopen(buf, "rb")) != NULL)
02308 {
02309 if ((LevelModel[i].CollSkin.Convex = LoadConvex(fp, &LevelModel[i].CollSkin.NConvex, 0)) != NULL)
02310 {
02311 if ((LevelModel[i].CollSkin.Sphere = LoadSpheres(fp, &LevelModel[i].CollSkin.NSpheres)) != NULL)
02312 {
02313 LevelModel[i].CollSkin.CollType = BODY_COLL_CONVEX;
02314 MakeTightLocalBBox(&LevelModel[i].CollSkin);
02315 }
02316 }
02317 fclose(fp);
02318 }
02319 else
02320 {
02321 wsprintf(buf, "%s.ncp", LevelModelList[id]);
02322 if ((fp = fopen(buf, "rb")) != NULL)
02323 {
02324 LevelModel[i].CollSkin.CollPoly = LoadNewCollPolys(fp, &LevelModel[i].CollSkin.NCollPolys);
02325 fclose(fp);
02326 }
02327 }
02328
02329
02330
02331
02332
02333 LevelModel[i].ID = id;
02334 LevelModel[i].RefCount = 1;
02335 return i;
02336 }
02337 }
02338
02339
02340
02341 return -1;
02342 }
02343
02345
02347
02348 void FreeOneLevelModel(long slot)
02349 {
02350
02351
02352
02353 if (LevelModel[slot].ID == -1)
02354 return;
02355
02356
02357
02358 LevelModel[slot].RefCount--;
02359
02360
02361
02362 if (LevelModel[slot].RefCount < 1)
02363 {
02364 FreeModel(&LevelModel[slot].Model, 1);
02365 DestroyConvex(LevelModel[slot].CollSkin.Convex, LevelModel[slot].CollSkin.NConvex);
02366 LevelModel[slot].CollSkin.Convex = NULL;
02367 LevelModel[slot].CollSkin.NConvex = 0;
02368 DestroySpheres(LevelModel[slot].CollSkin.Sphere);
02369 LevelModel[slot].CollSkin.NSpheres = 0;
02370 LevelModel[slot].ID = -1;
02371 }
02372 }
02373
02375
02377
02378 void SetModelFrames(MODEL *model, char **files, long count)
02379 {
02380 long i, j;
02381 FILE *fp;
02382 MODEL_HEADER mh;
02383 MODEL_POLY_LOAD mpl;
02384 MODEL_VERTEX_LOAD mvl;
02385 MODEL_VERTEX_MORPH *mvm;
02386 char buf[128];
02387
02388
02389
02390 model->VertPtrMorph = (MODEL_VERTEX_MORPH*)malloc(sizeof(MODEL_VERTEX_MORPH) * model->VertNum * count);
02391 if (!model->VertPtrMorph)
02392 return;
02393
02394
02395
02396 for (i = 0 ; i < count ; i++)
02397 {
02398 fp = fopen(files[i], "rb");
02399 if (fp == NULL)
02400 {
02401 wsprintf(buf, "Can't load morph frame %s", files[i]);
02402 Box("ERROR", buf, MB_OK);
02403 continue;
02404 }
02405
02406
02407
02408 fread(&mh, sizeof(mh), 1, fp);
02409
02410
02411
02412 for (j = 0 ; j < mh.PolyNum ; j++)
02413 fread(&mpl, sizeof(mpl), 1, fp);
02414
02415
02416
02417 mvm = &model->VertPtrMorph[model->VertNum * i];
02418
02419 for (j = 0 ; j < model->VertNum ; j++)
02420 {
02421 fread(&mvl, sizeof(mvl), 1, fp);
02422
02423 mvm[j].x = mvl.x;
02424 mvm[j].y = mvl.y;
02425 mvm[j].z = mvl.z;
02426
02427 mvm[j].nx = mvl.nx;
02428 mvm[j].ny = mvl.ny;
02429 mvm[j].nz = mvl.nz;
02430 }
02431
02432
02433
02434 fclose(fp);
02435 }
02436 }
02437
02439
02441
02442 void SetModelMorph(MODEL *m, long frame1, long frame2, float time)
02443 {
02444 long i;
02445 MODEL_VERTEX *mv;
02446 MODEL_VERTEX_MORPH *v1, *v2;
02447
02448
02449
02450 if (!m->VertPtrMorph)
02451 return;
02452
02453
02454
02455 v1 = &m->VertPtrMorph[m->VertNum * frame1];
02456 v2 = &m->VertPtrMorph[m->VertNum * frame2];
02457 mv= m->VertPtr;
02458
02459 if (time == 0.0f)
02460 {
02461 for (i = m->VertNum ; i ; i--, v1++, v2++, mv++)
02462 {
02463 mv->x = v1->x;
02464 mv->y = v1->y;
02465 mv->z = v1->z;
02466
02467 mv->nx = v1->nx;
02468 mv->ny = v1->ny;
02469 mv->nz = v1->nz;
02470 }
02471 }
02472
02473 else
02474 {
02475 for (i = m->VertNum ; i ; i--, v1++, v2++, mv++)
02476 {
02477 mv->x = v1->x + (v2->x - v1->x) * time;
02478 mv->y = v1->y + (v2->y - v1->y) * time;
02479 mv->z = v1->z + (v2->z - v1->z) * time;
02480
02481 mv->nx = v1->nx + (v2->nx - v1->nx) * time;
02482 mv->ny = v1->ny + (v2->ny - v1->ny) * time;
02483 mv->nz = v1->nz + (v2->nz - v1->nz) * time;
02484
02485 NormalizeVector((VEC*)&mv->nx);
02486 }
02487 }
02488 }
02489
02491
02493
02494 void CheckModelMeshFx(MODEL *model, MAT *mat, VEC *pos, short *flag)
02495 {
02496 long i;
02497
02498
02499
02500 ModelMeshModel = model;
02501 ModelMeshMat = mat;
02502 ModelMeshPos = pos;
02503 ModelMeshFlag = flag;
02504
02505
02506
02507 for (i = 0 ; i < ModelMeshFxCount ; i++)
02508 ModelMeshFx[i].Checker(ModelMeshFx[i].Data);
02509 }