00001
00002 #include "revolt.h"
00003 #include "NewColl.h"
00004 #include "world.h"
00005 #include "geom.h"
00006 #include "dx.h"
00007 #include "light.h"
00008 #include "main.h"
00009 #include "draw.h"
00010 #include "camera.h"
00011 #include "input.h"
00012 #include "visibox.h"
00013 #include "level.h"
00014 #include "mirror.h"
00015 #include "registry.h"
00016
00017
00018
00019 WORLD World;
00020 short WorldBigCubeCount, WorldCubeCount, WorldPolyCount, WorldDrawnCount;
00021 long TexAnimNum;
00022 TEXANIM_HEADER TexAnim[MAX_TEXANIMS];
00023
00024 static short WorldFog;
00025 static BUCKET_TEX0 *WorldBucketHeadRGB, *WorldBucketHeadClipRGB;
00026 static BUCKET_TEX1 *WorldBucketHead, *WorldBucketHeadClip;
00027 static BUCKET_ENV *WorldBucketHeadEnv, *WorldBucketHeadEnvClip;
00028 static short WorldEnvMask;
00029
00030
00031
00032 static long ShellGap[] = {13, 4, 1};
00033
00035
00037
00038 bool LoadWorld(char *file)
00039 {
00040 FILE *fp;
00041 WORLD_HEADER wh;
00042 CUBE_HEADER_LOAD chl;
00043 BIG_CUBE_HEADER_LOAD bchl;
00044 WORLD_POLY *mp;
00045 WORLD_POLY_LOAD mpl;
00046 WORLD_VERTEX_LOAD mvl;
00047 WORLD_POLY wp;
00048 WORLD_VERTEX **vert, **vert2;
00049 long size, i, j, k, l, idx, a, b, rgb;
00050 char buff[128];
00051 float vf, rad, maxrad;
00052
00053
00054
00055 fp = fopen(file, "rb");
00056 if (!fp)
00057 {
00058 wsprintf(buff, "Can't load world file: '%s'", file);
00059 Box("ERROR", buff, MB_OK);
00060 return FALSE;
00061 }
00062
00063
00064
00065 fread(&wh, sizeof(wh), 1, fp);
00066 World.CubeNum = wh.CubeNum;
00067 World.Cube = (CUBE_HEADER*)malloc(World.CubeNum * sizeof(CUBE_HEADER));
00068 if (!World.Cube)
00069 {
00070 Box("ERROR", "Can't alloc memory for world cubes!", MB_OK);
00071 QuitGame = TRUE;
00072 return FALSE;
00073 }
00074
00075
00076
00077 maxrad = 0;
00078
00079 for (i = 0 ; i < World.CubeNum ; i++)
00080 {
00081
00082
00083
00084 fread(&chl, sizeof(chl), 1, fp);
00085
00086 World.Cube[i].CentreY = chl.CentreY;
00087 World.Cube[i].CentreX = chl.CentreX;
00088 World.Cube[i].CentreZ = chl.CentreZ;
00089 World.Cube[i].Radius = chl.Radius;
00090 World.Cube[i].Xmin = chl.Xmin;
00091 World.Cube[i].Xmax = chl.Xmax;
00092 World.Cube[i].Ymin = chl.Ymin;
00093 World.Cube[i].Ymax = chl.Ymax;
00094 World.Cube[i].Zmin = chl.Zmin;
00095 World.Cube[i].Zmax = chl.Zmax;
00096
00097 World.Cube[i].Model.PolyNum = chl.PolyNum;
00098 World.Cube[i].Model.VertNum = chl.VertNum;
00099
00100
00101
00102 size = sizeof(WORLD_POLY) * World.Cube[i].Model.PolyNum;
00103 size += sizeof(WORLD_VERTEX) * World.Cube[i].Model.VertNum;
00104
00105 World.Cube[i].Model.AllocPtr = malloc(size);
00106 if (World.Cube[i].Model.AllocPtr == NULL)
00107 {
00108 Box("ERROR", "Can't alloc memory for world mesh!", MB_OK);
00109 QuitGame = TRUE;
00110 return FALSE;
00111 }
00112 World.Cube[i].Model.PolyPtr = (WORLD_POLY*)World.Cube[i].Model.AllocPtr;
00113 World.Cube[i].Model.VertPtr = (WORLD_VERTEX*)(World.Cube[i].Model.PolyPtr + World.Cube[i].Model.PolyNum);
00114
00115
00116
00117 mp = World.Cube[i].Model.PolyPtr;
00118
00119 World.Cube[i].Model.QuadNumTex = 0;
00120 World.Cube[i].Model.TriNumTex = 0;
00121 World.Cube[i].Model.QuadNumRGB = 0;
00122 World.Cube[i].Model.TriNumRGB = 0;
00123
00124 for (j = 0 ; j < World.Cube[i].Model.PolyNum ; j++, mp++)
00125 {
00126 fread(&mpl, sizeof(mpl), 1, fp);
00127
00128 mp->Type = mpl.Type;
00129 mp->Tpage = mpl.Tpage;
00130
00131 if (GameSettings.Mirrored)
00132 {
00133 if (mp->Type & POLY_QUAD)
00134 {
00135 mp->rgb0 = mpl.c3;
00136 mp->rgb1 = mpl.c2;
00137 mp->rgb2 = mpl.c1;
00138 mp->rgb3 = mpl.c0;
00139
00140 mp->tu0 = mpl.u3;
00141 mp->tv0 = mpl.v3;
00142 mp->tu1 = mpl.u2;
00143 mp->tv1 = mpl.v2;
00144 mp->tu2 = mpl.u1;
00145 mp->tv2 = mpl.v1;
00146 mp->tu3 = mpl.u0;
00147 mp->tv3 = mpl.v0;
00148
00149 mp->v0 = World.Cube[i].Model.VertPtr + mpl.vi3;
00150 mp->v1 = World.Cube[i].Model.VertPtr + mpl.vi2;
00151 mp->v2 = World.Cube[i].Model.VertPtr + mpl.vi1;
00152 mp->v3 = World.Cube[i].Model.VertPtr + mpl.vi0;
00153 }
00154 else
00155 {
00156 mp->rgb0 = mpl.c2;
00157 mp->rgb1 = mpl.c1;
00158 mp->rgb2 = mpl.c0;
00159
00160 mp->tu0 = mpl.u2;
00161 mp->tv0 = mpl.v2;
00162 mp->tu1 = mpl.u1;
00163 mp->tv1 = mpl.v1;
00164 mp->tu2 = mpl.u0;
00165 mp->tv2 = mpl.v0;
00166
00167 mp->v0 = World.Cube[i].Model.VertPtr + mpl.vi2;
00168 mp->v1 = World.Cube[i].Model.VertPtr + mpl.vi1;
00169 mp->v2 = World.Cube[i].Model.VertPtr + mpl.vi0;
00170 }
00171 }
00172 else
00173 {
00174 mp->rgb0 = mpl.c0;
00175 mp->rgb1 = mpl.c1;
00176 mp->rgb2 = mpl.c2;
00177 mp->rgb3 = mpl.c3;
00178
00179 mp->tu0 = mpl.u0;
00180 mp->tv0 = mpl.v0;
00181 mp->tu1 = mpl.u1;
00182 mp->tv1 = mpl.v1;
00183 mp->tu2 = mpl.u2;
00184 mp->tv2 = mpl.v2;
00185 mp->tu3 = mpl.u3;
00186 mp->tv3 = mpl.v3;
00187
00188 mp->v0 = World.Cube[i].Model.VertPtr + mpl.vi0;
00189 mp->v1 = World.Cube[i].Model.VertPtr + mpl.vi1;
00190 mp->v2 = World.Cube[i].Model.VertPtr + mpl.vi2;
00191 mp->v3 = World.Cube[i].Model.VertPtr + mpl.vi3;
00192 }
00193
00194 ModelChangeGouraud((MODEL_RGB*)&mp->rgb0, LevelInf[GameSettings.Level].WorldRGBper);
00195 ModelChangeGouraud((MODEL_RGB*)&mp->rgb1, LevelInf[GameSettings.Level].WorldRGBper);
00196 ModelChangeGouraud((MODEL_RGB*)&mp->rgb2, LevelInf[GameSettings.Level].WorldRGBper);
00197 ModelChangeGouraud((MODEL_RGB*)&mp->rgb3, LevelInf[GameSettings.Level].WorldRGBper);
00198
00199 if (mp->Type & POLY_MIRROR)
00200 {
00201 mp->rgb0 |= MirrorAlpha;
00202 mp->rgb1 |= MirrorAlpha;
00203 mp->rgb2 |= MirrorAlpha;
00204 mp->rgb3 |= MirrorAlpha;
00205 }
00206
00207 if (mp->Tpage != -1)
00208 {
00209 if (mp->Type & POLY_QUAD) World.Cube[i].Model.QuadNumTex++;
00210 else World.Cube[i].Model.TriNumTex++;
00211 }
00212 else
00213 {
00214 if (mp->Type & POLY_QUAD) World.Cube[i].Model.QuadNumRGB++;
00215 else World.Cube[i].Model.TriNumRGB++;
00216 }
00217 }
00218
00219
00220
00221 mp = World.Cube[i].Model.PolyPtr;
00222
00223 j = World.Cube[i].Model.PolyNum;
00224 if(j > 1)
00225 {
00226 while(--j)
00227 {
00228 for (k = 0 ; k < j ; k++)
00229 {
00230 a = mp[k].Type & POLY_QUAD;
00231 if (mp[k].Tpage != -1) a += 256;
00232
00233 b = mp[k + 1].Type & POLY_QUAD;
00234 if (mp[k + 1].Tpage != -1) b += 256;
00235
00236 if (b > a)
00237 {
00238 wp = mp[k];
00239 mp[k] = mp[k + 1];
00240 mp[k + 1] = wp;
00241 }
00242 }
00243 }
00244 }
00245
00246
00247
00248 for (j = 0 ; j < World.Cube[i].Model.VertNum ; j++)
00249 {
00250 fread(&mvl, sizeof(mvl), 1, fp);
00251
00252 World.Cube[i].Model.VertPtr[j].x = mvl.x;
00253 World.Cube[i].Model.VertPtr[j].y = mvl.y;
00254 World.Cube[i].Model.VertPtr[j].z = mvl.z;
00255
00256 World.Cube[i].Model.VertPtr[j].nx = mvl.nx;
00257 World.Cube[i].Model.VertPtr[j].ny = mvl.ny;
00258 World.Cube[i].Model.VertPtr[j].nz = mvl.nz;
00259
00260 vf = (mvl.y - RenderSettings.VertFogStart) * RenderSettings.VertFogMul;
00261 vf -= (float)(rand() & 31);
00262 if (vf < 0) vf = 0;
00263 if (vf > 255) vf = 255;
00264 (World.Cube[i].Model.VertPtr + j)->VertFog = vf;
00265
00266 rad = (float)sqrt(mvl.x * mvl.x + mvl.y * mvl.y + mvl.z * mvl.z);
00267 if (rad > maxrad) maxrad = rad;
00268 }
00269
00270
00271
00272 World.Cube[i].Model.AnimPolyNum = 0;
00273 mp = World.Cube[i].Model.PolyPtr;
00274
00275 for (j = World.Cube[i].Model.PolyNum ; j ; j--, mp++) if (mp->Type & POLY_TEXANIM)
00276 {
00277 World.Cube[i].Model.AnimPolyNum++;
00278 }
00279
00280 if (!World.Cube[i].Model.AnimPolyNum)
00281 {
00282 World.Cube[i].Model.AnimPolyPtr = NULL;
00283 }
00284 else
00285 {
00286 World.Cube[i].Model.AnimPolyPtr = (WORLD_ANIM_POLY*)malloc(sizeof(WORLD_ANIM_POLY) * World.Cube[i].Model.AnimPolyNum);
00287 if (!World.Cube[i].Model.AnimPolyPtr) World.Cube[i].Model.AnimPolyNum = 0;
00288 }
00289
00290 if (World.Cube[i].Model.AnimPolyNum)
00291 {
00292 mp = World.Cube[i].Model.PolyPtr;
00293 for (j = 0 ; j < World.Cube[i].Model.AnimPolyNum ; j++)
00294 {
00295 while (!(mp->Type & POLY_TEXANIM)) mp++;
00296 World.Cube[i].Model.AnimPolyPtr[j].Poly = mp;
00297 World.Cube[i].Model.AnimPolyPtr[j].Anim = &TexAnim[mp->Tpage];
00298 mp++;
00299 }
00300 }
00301
00302
00303
00304 World.Cube[i].Model.EnvVertNum = 0;
00305 World.Cube[i].Model.EnvVertPtr = NULL;
00306
00307 vert = (WORLD_VERTEX**)malloc(sizeof(WORLD_VERTEX*) * World.Cube[i].Model.VertNum);
00308 if (vert)
00309 {
00310 mp = World.Cube[i].Model.PolyPtr;
00311
00312 for (j = 0 ; j < World.Cube[i].Model.PolyNum ; j++) if (mp[j].Type & POLY_ENV)
00313 {
00314 vert2 = &mp[j].v0;
00315 for (k = 0 ; k < 3 + (mp[j].Type & 1) ; k++)
00316 {
00317 for (l = 0 ; l < World.Cube[i].Model.EnvVertNum ; l++)
00318 {
00319 if (vert[l] == vert2[k])
00320 break;
00321 }
00322 if (l == World.Cube[i].Model.EnvVertNum)
00323 {
00324 vert[l] = vert2[k];
00325 World.Cube[i].Model.EnvVertNum++;
00326 }
00327 }
00328 }
00329
00330 if (World.Cube[i].Model.EnvVertNum)
00331 {
00332 World.Cube[i].Model.EnvVertPtr = (WORLD_VERTEX**)malloc(sizeof(WORLD_VERTEX*) * World.Cube[i].Model.EnvVertNum);
00333 if (!World.Cube[i].Model.EnvVertPtr) World.Cube[i].Model.EnvVertNum = 0;
00334 else memcpy(World.Cube[i].Model.EnvVertPtr, vert, sizeof(WORLD_VERTEX*) * World.Cube[i].Model.EnvVertNum);
00335 }
00336
00337 free(vert);
00338 }
00339 }
00340
00341
00342
00343 if (maxrad > 32767)
00344 {
00345 wsprintf(buff, "'%s' is not PSX friendly by %ld pixels!", file, (long)maxrad - 32767);
00346 Box("Warning!", buff, MB_OK);
00347 }
00348
00349
00350
00351 if (!fread(&wh, sizeof(wh), 1, fp))
00352 {
00353 Box("ERROR", "World file has no big cube info!", MB_OK);
00354 QuitGame = TRUE;
00355 return FALSE;
00356 }
00357
00358 World.BigCubeNum = wh.CubeNum;
00359 World.BigCube = (BIG_CUBE_HEADER*)malloc(World.BigCubeNum * sizeof(BIG_CUBE_HEADER));
00360 if (!World.BigCube)
00361 {
00362 Box("ERROR", "Can't alloc memory for world big cubes!", MB_OK);
00363 QuitGame = TRUE;
00364 return FALSE;
00365 }
00366
00367
00368
00369 for (i = 0 ; i < World.BigCubeNum ; i++)
00370 {
00371
00372
00373
00374 fread(&bchl, sizeof(bchl), 1, fp);
00375
00376 World.BigCube[i].x = bchl.x;
00377 World.BigCube[i].y = bchl.y;
00378 World.BigCube[i].z = bchl.z;
00379 World.BigCube[i].Radius = bchl.Radius;
00380 World.BigCube[i].CubeNum = bchl.CubeNum;
00381
00382
00383
00384 World.BigCube[i].Cubes = (CUBE_HEADER**)malloc(sizeof(CUBE_HEADER*) * World.BigCube[i].CubeNum);
00385 if (!World.BigCube[i].Cubes)
00386 {
00387 Box("ERROR", "Can't alloc memory for a cube list!", MB_OK);
00388 return FALSE;
00389 }
00390
00391
00392
00393 for (j = 0 ; j < World.BigCube[i].CubeNum ; j++)
00394 {
00395 fread(&idx, sizeof(idx), 1, fp);
00396 World.BigCube[i].Cubes[j] = &World.Cube[idx];
00397 }
00398 }
00399
00400
00401
00402 World.CubeList = (CUBE_HEADER**)malloc(sizeof(CUBE_HEADER*) * World.CubeNum);
00403 if (!World.CubeList)
00404 {
00405 Box(NULL, "Can't alloc memory for world cube list!", MB_OK);
00406 QuitGame = TRUE;
00407 return FALSE;
00408 }
00409
00410
00411
00412 if (!fread(&TexAnimNum, sizeof(TexAnimNum), 1, fp))
00413 {
00414 TexAnimNum = 0;
00415 }
00416
00417
00418
00419 for (i = 0 ; i < TexAnimNum ; i++)
00420 {
00421 fread(&TexAnim[i].FrameNum, sizeof(TexAnim[i].FrameNum), 1, fp);
00422 TexAnim[i].Frame = (TEXANIM_FRAME*)malloc(sizeof(TEXANIM_FRAME) * TexAnim[i].FrameNum);
00423 if (!TexAnim[i].Frame)
00424 {
00425 Box(NULL, "Can't alloc memory for texture animation", MB_OK);
00426 TexAnimNum = 0;
00427 break;
00428 }
00429
00430 fread(TexAnim[i].Frame, sizeof(TEXANIM_FRAME), TexAnim[i].FrameNum, fp);
00431
00432 TexAnim[i].FrameTime = 0;
00433 TexAnim[i].CurrentFrameNum = 0;
00434 TexAnim[i].CurrentFrame = TexAnim[i].Frame;
00435 }
00436
00437
00438
00439 for (i = 0 ; i < World.CubeNum ; i++)
00440 {
00441 mp = World.Cube[i].Model.PolyPtr;
00442 for (j = 0 ; j < World.Cube[i].Model.PolyNum ; j++, mp++) if (mp->Type & POLY_ENV)
00443 {
00444 fread(&rgb, sizeof(long), 1, fp);
00445
00446 mp->v0->EnvRGB = rgb;
00447 mp->v1->EnvRGB = rgb;
00448 mp->v2->EnvRGB = rgb;
00449
00450 if (mp->Type & POLY_QUAD)
00451 mp->v3->EnvRGB = rgb;
00452 }
00453 }
00454
00455
00456
00457 fclose(fp);
00458
00459
00460
00461 return TRUE;
00462 }
00463
00465
00467
00468 void FreeWorld(void)
00469 {
00470 long i;
00471
00472 for (i = 0 ; i < World.CubeNum ; i++)
00473 {
00474 free(World.Cube[i].Model.AllocPtr);
00475 free(World.Cube[i].Model.MirrorPolyPtr);
00476 free(World.Cube[i].Model.AnimPolyPtr);
00477 free(World.Cube[i].Model.EnvVertPtr);
00478 }
00479
00480 for (i = 0 ; i < World.BigCubeNum ; i++)
00481 free(World.BigCube[i].Cubes);
00482
00483 free(World.Cube);
00484 free(World.BigCube);
00485 free(World.CubeList);
00486
00487 for (i = 0 ; i < TexAnimNum ; i++)
00488 free(TexAnim[i].Frame);
00489 }
00490
00492
00494
00495 void MirrorWorldPolys(void)
00496 {
00497 short mpolynum, mvertnum;
00498 long i, j, k, l, vnum, flag, size, offset;
00499 CUBE_HEADER *cube;
00500 WORLD_POLY *p;
00501 WORLD_VERTEX **v;
00502 WORLD_MIRROR_POLY *mpolys;
00503 WORLD_MIRROR_VERTEX *mverts, **mv;
00504 MIRROR_PLANE *mplane, *plane;
00505
00506
00507
00508 cube = World.Cube;
00509 for (i = 0 ; i < World.CubeNum ; i++, cube++)
00510 {
00511
00512
00513
00514 cube->Model.MirrorPolyNum = 0;
00515 cube->Model.MirrorVertNum = 0;
00516
00517 cube->Model.MirrorQuadNumTex = 0;
00518 cube->Model.MirrorTriNumTex = 0;
00519 cube->Model.MirrorQuadNumRGB = 0;
00520 cube->Model.MirrorTriNumRGB = 0;
00521
00522 cube->Model.MirrorPolyPtr = NULL;
00523
00524 cube->MirrorHeight = -99999;
00525
00526
00527
00528 if (!MirrorPlaneNum)
00529 continue;
00530
00531
00532
00533 mpolys = (WORLD_MIRROR_POLY*)malloc(sizeof(WORLD_MIRROR_POLY) * cube->Model.PolyNum);
00534 if (!mpolys)
00535 {
00536 continue;
00537 }
00538 mverts = (WORLD_MIRROR_VERTEX*)malloc(sizeof(WORLD_MIRROR_VERTEX) * cube->Model.VertNum);
00539 if (!mverts)
00540 {
00541 free(mpolys);
00542 continue;
00543 }
00544
00545 mpolynum = 0;
00546 mvertnum = 0;
00547
00548
00549
00550 p = cube->Model.PolyPtr;
00551 for (j = 0 ; j < cube->Model.PolyNum ; j++, p++)
00552 {
00553
00554
00555
00556 if (p->Type & POLY_MIRROR) continue;
00557
00558
00559
00560 v = &p->v0;
00561 vnum = p->Type & POLY_QUAD ? 4 : 3;
00562 plane = NULL;
00563 mplane = MirrorPlanes;
00564
00565 for (l = 0 ; l < MirrorPlaneNum ; l++, mplane++)
00566 {
00567 for (k = 0 ; k < vnum ; k++)
00568 {
00569 if (v[k]->y < mplane->Height + MIRROR_OVERLAP_TOL && v[k]->y > mplane->Height - MirrorDist &&
00570 v[k]->x >= mplane->Xmin && v[k]->x <= mplane->Xmax &&
00571 v[k]->z >= mplane->Zmin && v[k]->z <= mplane->Zmax)
00572 {
00573 plane = mplane;
00574 break;
00575 }
00576 }
00577 if (plane) break;
00578 }
00579
00580
00581
00582 if (plane)
00583 {
00584 for (k = 0 ; k < vnum ; k++)
00585 {
00586 if (v[k]->y >= plane->Height + MIRROR_OVERLAP_TOL)
00587 {
00588 plane = NULL;
00589 break;
00590 }
00591 }
00592 }
00593
00594
00595
00596 if (plane)
00597 {
00598
00599
00600
00601 if (plane->Height > cube->MirrorHeight)
00602 cube->MirrorHeight = plane->Height;
00603
00604
00605
00606 mv = &mpolys[mpolynum].v0;
00607 for (k = 0 ; k < vnum ; k++)
00608 {
00609
00610
00611
00612 flag = FALSE;
00613 for (l = 0 ; l < mvertnum ; l++)
00614 {
00615 if (v[k] == mverts[l].RealVertex)
00616 {
00617 mv[k] = &mverts[l];
00618 flag = TRUE;
00619 break;
00620 }
00621 }
00622
00623
00624
00625 if (!flag)
00626 {
00627 mverts[mvertnum].x = v[k]->x;
00628 mverts[mvertnum].y = plane->Height + (plane->Height - v[k]->y);
00629 mverts[mvertnum].z = v[k]->z;
00630 mverts[mvertnum].VertFog = GET_MIRROR_FOG(mverts[mvertnum].y - plane->Height);
00631 mverts[mvertnum].RealVertex = v[k];
00632 mv[k] = &mverts[mvertnum];
00633 mvertnum++;
00634 }
00635 }
00636
00637
00638
00639 mpolys[mpolynum].Type = p->Type;
00640 mpolys[mpolynum].Tpage = p->Tpage;
00641 mpolys[mpolynum].VisiMask = p->VisiMask;
00642 mpolys[mpolynum].rgb0 = p->rgb0;
00643 mpolys[mpolynum].rgb1 = p->rgb1;
00644 mpolys[mpolynum].rgb2 = p->rgb2;
00645 mpolys[mpolynum].rgb3 = p->rgb3;
00646 mpolys[mpolynum].tu0 = p->tu0;
00647 mpolys[mpolynum].tv0 = p->tv0;
00648 mpolys[mpolynum].tu1 = p->tu1;
00649 mpolys[mpolynum].tv1 = p->tv1;
00650 mpolys[mpolynum].tu2 = p->tu2;
00651 mpolys[mpolynum].tv2 = p->tv2;
00652 mpolys[mpolynum].tu3 = p->tu3;
00653 mpolys[mpolynum].tv3 = p->tv3;
00654 mpolynum++;
00655 }
00656 }
00657
00658
00659
00660 if (mpolynum)
00661 {
00662 size = sizeof(WORLD_MIRROR_POLY) * mpolynum;
00663 size += sizeof(WORLD_MIRROR_VERTEX) * mvertnum;
00664 cube->Model.MirrorPolyPtr = (WORLD_MIRROR_POLY*)malloc(size);
00665
00666 if (cube->Model.MirrorPolyPtr)
00667 {
00668 cube->Model.MirrorVertPtr = (WORLD_MIRROR_VERTEX*)(cube->Model.MirrorPolyPtr + mpolynum);
00669 cube->Model.MirrorPolyNum = mpolynum;
00670 cube->Model.MirrorVertNum = mvertnum;
00671
00672 offset = ((long)cube->Model.MirrorVertPtr) - ((long)mverts);
00673 for (j = 0 ; j < mpolynum ; j++)
00674 {
00675 cube->Model.MirrorPolyPtr[j] = mpolys[j];
00676 cube->Model.MirrorPolyPtr[j].v0 = (WORLD_MIRROR_VERTEX*)(((long)cube->Model.MirrorPolyPtr[j].v0) + offset);
00677 cube->Model.MirrorPolyPtr[j].v1 = (WORLD_MIRROR_VERTEX*)(((long)cube->Model.MirrorPolyPtr[j].v1) + offset);
00678 cube->Model.MirrorPolyPtr[j].v2 = (WORLD_MIRROR_VERTEX*)(((long)cube->Model.MirrorPolyPtr[j].v2) + offset);
00679 cube->Model.MirrorPolyPtr[j].v3 = (WORLD_MIRROR_VERTEX*)(((long)cube->Model.MirrorPolyPtr[j].v3) + offset);
00680
00681 if (mpolys[j].Tpage != -1)
00682 {
00683 if (mpolys[j].Type & POLY_QUAD) cube->Model.MirrorQuadNumTex++;
00684 else cube->Model.MirrorTriNumTex++;
00685 }
00686 else
00687 {
00688 if (mpolys[j].Type & POLY_QUAD) cube->Model.MirrorQuadNumRGB++;
00689 else cube->Model.MirrorTriNumRGB++;
00690 }
00691 }
00692
00693 for (j = 0 ; j < mvertnum ; j++)
00694 {
00695 cube->Model.MirrorVertPtr[j] = mverts[j];
00696 }
00697 }
00698 }
00699
00700
00701
00702 free(mpolys);
00703 free(mverts);
00704 }
00705 }
00706
00708
00710
00711 void SetWorldMirror(void)
00712 {
00713 long i, j;
00714 CUBE_HEADER *cube;
00715 WORLD_POLY *p;
00716
00717
00718
00719 cube = World.Cube;
00720 for (i = 0 ; i < World.CubeNum ; i++, cube++)
00721 {
00722 p = cube->Model.PolyPtr;
00723 for (j = 0 ; j < cube->Model.PolyNum ; j++, p++)
00724 {
00725 if (p->Type & POLY_MIRROR)
00726 {
00727 if (RenderSettings.Mirror)
00728 {
00729 if (MirrorType)
00730 {
00731 p->Type |= (POLY_SEMITRANS | POLY_SEMITRANS_ONE);
00732 }
00733 else
00734 {
00735 p->Type |= POLY_SEMITRANS;
00736 }
00737 }
00738 else
00739 {
00740 p->Type &= ~(POLY_SEMITRANS | POLY_SEMITRANS_ONE);
00741 }
00742 }
00743 }
00744 }
00745 }
00746
00748
00750
00751 void DrawWorld(void)
00752 {
00753 long i, j, k, gap;
00754 float z, cuberad;
00755 float l, r, t, b, camy;
00756 VEC *cubepos;
00757 BIG_CUBE_HEADER *bch;
00758 CUBE_HEADER *ch, **chp;
00759
00760
00761
00762 #if SCREEN_DEBUG
00763 WorldBigCubeCount = 0;
00764 #endif
00765
00766 WorldCubeCount = 0;
00767 bch = World.BigCube;
00768
00769 for (i = 0 ; i < World.BigCubeNum ; i++, bch++)
00770 {
00771
00772
00773
00774 cubepos = (VEC*)&bch->x;
00775 cuberad = bch->Radius;
00776
00777 z = cubepos->v[X] * ViewMatrix.m[RZ] + cubepos->v[Y] * ViewMatrix.m[UZ] + cubepos->v[Z] * ViewMatrix.m[LZ] + ViewTrans.v[Z];
00778 if (z + cuberad < RenderSettings.NearClip) continue;
00779 if (z - cuberad >= RenderSettings.FarClip) continue;
00780
00781 if (PlaneDist(&CameraPlaneLeft, cubepos) >= cuberad) continue;
00782 if (PlaneDist(&CameraPlaneRight, cubepos) >= cuberad) continue;
00783 if (PlaneDist(&CameraPlaneBottom, cubepos) >= cuberad) continue;
00784 if (PlaneDist(&CameraPlaneTop, cubepos) >= cuberad) continue;
00785
00786
00787
00788 #if SCREEN_DEBUG
00789 WorldBigCubeCount++;
00790 #endif
00791
00792 chp = bch->Cubes;
00793
00794 for (j = 0 ; j < bch->CubeNum ; j++)
00795 {
00796
00797
00798
00799 if (chp[j]->VisiMask & CamVisiMask)
00800 {
00801 continue;
00802 }
00803
00804
00805
00806 cubepos = (VEC*)&chp[j]->CentreX;
00807 cuberad = chp[j]->Radius;
00808
00809 z = cubepos->v[X] * ViewMatrix.m[RZ] + cubepos->v[Y] * ViewMatrix.m[UZ] + cubepos->v[Z] * ViewMatrix.m[LZ] + ViewTrans.v[Z];
00810 if (z + cuberad < RenderSettings.NearClip) continue;
00811 if (z - cuberad >= RenderSettings.FarClip) continue;
00812
00813 if ((l = PlaneDist(&CameraPlaneLeft, cubepos)) >= cuberad) continue;
00814 if ((r = PlaneDist(&CameraPlaneRight, cubepos)) >= cuberad) continue;
00815 if ((b = PlaneDist(&CameraPlaneBottom, cubepos)) >= cuberad) continue;
00816 if ((t = PlaneDist(&CameraPlaneTop, cubepos)) >= cuberad) continue;
00817
00818
00819
00820 World.CubeList[WorldCubeCount] = chp[j];
00821 chp[j]->Clip = (l > -cuberad || r > -cuberad || b > -cuberad || t > -cuberad || z - cuberad < RenderSettings.NearClip || z + cuberad >= RenderSettings.FarClip);
00822 FTOL(z + cuberad, chp[j]->z);
00823 chp[j]->MeshFxFlag = 0;
00824 WorldCubeCount++;
00825 }
00826 }
00827
00828
00829
00830 if (!WorldCubeCount) return;
00831
00832
00833
00834 chp = World.CubeList;
00835
00836 for (k = 0 ; k < 3 ; k++)
00837 {
00838 gap = ShellGap[k];
00839 for (i = gap ; i < WorldCubeCount ; i++)
00840 {
00841 ch = chp[i];
00842 for (j = i - gap ; j >= 0 && ch->z < chp[j]->z ; j -= gap)
00843 {
00844 chp[j + gap] = chp[j];
00845 }
00846 chp[j + gap] = ch;
00847 }
00848 }
00849
00850
00851
00852 for (i = 0 ; i < WorldMeshFxCount ; i++)
00853 WorldMeshFx[i].Checker(WorldMeshFx[i].Data);
00854
00855
00856
00857 if (RenderSettings.Env)
00858 WorldEnvMask = POLY_ENV;
00859 else
00860 WorldEnvMask = 0;
00861
00862
00863
00864 WorldFog = FALSE;
00865 WorldBucketHead = Bucket;
00866 WorldBucketHeadRGB = &BucketRGB;
00867 WorldBucketHeadClip = BucketClip;
00868 WorldBucketHeadClipRGB = &BucketClipRGB;
00869 WorldBucketHeadEnv = &BucketEnvStill;
00870 WorldBucketHeadEnvClip = &BucketEnvStillClip;
00871
00872 for (i = 0 ; i < WorldCubeCount ; i++)
00873 {
00874 if (DxState.Fog && chp[i]->z >= RenderSettings.FogStart) break;
00875 DrawWorldCube(chp[i]);
00876 }
00877
00878
00879
00880 if (i < WorldCubeCount)
00881 {
00882 WorldFog = TRUE;
00883 WorldBucketHead = BucketFog;
00884 WorldBucketHeadRGB = &BucketFogRGB;
00885 WorldBucketHeadClip = BucketClipFog;
00886 WorldBucketHeadClipRGB = &BucketClipFogRGB;
00887 WorldBucketHeadEnv = &BucketEnvStillFog;
00888 WorldBucketHeadEnvClip = &BucketEnvStillClipFog;
00889
00890 FOG_ON();
00891 for ( ; i < WorldCubeCount ; i++)
00892 {
00893 DrawWorldCube(chp[i]);
00894 }
00895 }
00896
00897
00898
00899 if (RenderSettings.Mirror && MirrorPlaneNum)
00900 {
00901 FOG_ON();
00902 camy = ViewCameraPos.v[Y];
00903 for (i = 0 ; i < WorldCubeCount ; i++)
00904 {
00905 if (camy < chp[i]->MirrorHeight)
00906 DrawWorldCubeMirror(chp[i]);
00907 }
00908 }
00909
00910
00911
00912 FOG_OFF();
00913 }
00914
00916
00918
00919 void DrawWorldCube(CUBE_HEADER *cube)
00920 {
00921 long i;
00922 WORLD_ANIM_POLY *wap;
00923 WORLD_VERTEX *v;
00924 VEC vecx, vecy, vecz;
00925
00926
00927
00928 cube->Lit = CheckCubeLight(cube);
00929
00930
00931
00932 if (RenderSettings.Env)
00933 {
00934 for (i = 0 ; i < cube->Model.EnvVertNum ; i++)
00935 {
00936 v = cube->Model.EnvVertPtr[i];
00937
00938 SubVector((VEC*)&v->x, &ViewCameraPos, &vecz);
00939 NormalizeVector(&vecz);
00940 CrossProduct(&ViewCameraMatrix.mv[U], &vecz, &vecx)
00941 CrossProduct(&vecz, &vecx, &vecy);
00942
00943 v->tu = DotProduct((VEC*)&v->nx, &vecx) * 0.5f + 0.5f;
00944 v->tv = DotProduct((VEC*)&v->nx, &vecy) * 0.5f + 0.5f;
00945
00946 if (cube->Lit)
00947 {
00948 ModelAddGouraud((MODEL_RGB*)&v->EnvRGB, &v->r, (MODEL_RGB*)&v->color);
00949 }
00950 else
00951 {
00952 v->color = v->EnvRGB;
00953 }
00954 }
00955 }
00956
00957
00958
00959 if (cube->Model.AnimPolyNum)
00960 {
00961 wap = cube->Model.AnimPolyPtr;
00962
00963 for (i = cube->Model.AnimPolyNum ; i ; i--, wap++)
00964 {
00965 if ((wap->Anim - TexAnim) < TexAnimNum)
00966 {
00967 wap->Poly->Tpage = (short)wap->Anim->CurrentFrame->Tpage;
00968 *(MEM32*)&wap->Poly->tu0 = *(MEM32*)&wap->Anim->CurrentFrame->u0;
00969 }
00970 }
00971 }
00972
00973
00974
00975 if (cube->MeshFxFlag & MESHFX_USENEWVERTS)
00976 {
00977
00978
00979
00980 if (cube->Clip)
00981 {
00982 if (WorldFog) TransCubeVertsFogClipNewVerts(&cube->Model);
00983 else TransCubeVertsClipNewVerts(&cube->Model);
00984 DrawCubePolysClip(&cube->Model, cube->Lit);
00985 }
00986
00987
00988
00989 else
00990 {
00991 if (WorldFog) TransCubeVertsFogNewVerts(&cube->Model);
00992 else TransCubeVertsNewVerts(&cube->Model);
00993 DrawCubePolys(&cube->Model, cube->Lit);
00994 }
00995 }
00996
00997
00998
00999 else
01000 {
01001
01002
01003
01004 if (cube->Clip)
01005 {
01006 if (WorldFog) TransCubeVertsFogClip(&cube->Model);
01007 else TransCubeVertsClip(&cube->Model);
01008 DrawCubePolysClip(&cube->Model, cube->Lit);
01009 }
01010
01011
01012
01013 else
01014 {
01015 if (WorldFog) TransCubeVertsFog(&cube->Model);
01016 else TransCubeVerts(&cube->Model);
01017 DrawCubePolys(&cube->Model, cube->Lit);
01018 }
01019 }
01020
01021
01022
01023 #if SCREEN_DEBUG
01024 WorldPolyCount += cube->Model.QuadNumTex * 2;
01025 WorldPolyCount += cube->Model.TriNumTex;
01026 WorldPolyCount += cube->Model.QuadNumRGB * 2;
01027 WorldPolyCount += cube->Model.TriNumRGB;
01028 #endif
01029 }
01030
01032
01034
01035 void DrawWorldCubeMirror(CUBE_HEADER *cube)
01036 {
01037 if (cube->MeshFxFlag & MESHFX_USENEWVERTS)
01038 {
01039 TransCubeVertsMirrorNewVerts(&cube->Model);
01040 DrawCubePolysMirror(&cube->Model, cube->Lit);
01041 }
01042 else
01043 {
01044 TransCubeVertsMirror(&cube->Model);
01045 DrawCubePolysMirror(&cube->Model, cube->Lit);
01046 }
01047
01048 #if SCREEN_DEBUG
01049 WorldPolyCount += cube->Model.MirrorQuadNumTex * 2;
01050 WorldPolyCount += cube->Model.MirrorTriNumTex;
01051 WorldPolyCount += cube->Model.MirrorQuadNumRGB * 2;
01052 WorldPolyCount += cube->Model.MirrorTriNumRGB;
01053 #endif
01054 }
01055
01057
01059
01060 void TransCubeVertsClip(WORLD_MODEL *m)
01061 {
01062 short i;
01063 float z;
01064 WORLD_VERTEX *mv;
01065
01066 mv = m->VertPtr;
01067
01068 for (i = 0 ; i < m->VertNum ; i++, mv++)
01069 {
01070 z = mv->x * ViewMatrixScaled.m[RZ] + mv->y * ViewMatrixScaled.m[UZ] + mv->z * ViewMatrixScaled.m[LZ] + ViewTransScaled.v[Z];
01071 if (z < 1) z = 1;
01072
01073 mv->sx = (mv->x * ViewMatrixScaled.m[RX] + mv->y * ViewMatrixScaled.m[UX] + mv->z * ViewMatrixScaled.m[LX] + ViewTransScaled.v[X]) / z + RenderSettings.GeomCentreX;
01074 mv->sy = (mv->x * ViewMatrixScaled.m[RY] + mv->y * ViewMatrixScaled.m[UY] + mv->z * ViewMatrixScaled.m[LY] + ViewTransScaled.v[Y]) / z + RenderSettings.GeomCentreY;
01075
01076 mv->rhw = 1 / z;
01077 mv->sz = GET_ZBUFFER(z);
01078
01079 mv->Clip = 0;
01080 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
01081 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
01082 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
01083 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
01084 if (mv->sz < 0) mv->Clip |= 16;
01085 else if (mv->sz >= 1) mv->Clip |= 32;
01086 }
01087 }
01088
01090
01092
01093 void TransCubeVertsFogClip(WORLD_MODEL *m)
01094 {
01095 short i;
01096 float z;
01097 float fog;
01098 WORLD_VERTEX *mv;
01099
01100 mv = m->VertPtr;
01101
01102 for (i = 0 ; i < m->VertNum ; i++, mv++)
01103 {
01104 z = mv->x * ViewMatrixScaled.m[RZ] + mv->y * ViewMatrixScaled.m[UZ] + mv->z * ViewMatrixScaled.m[LZ] + ViewTransScaled.v[Z];
01105 if (z < 1) z = 1;
01106
01107 mv->sx = (mv->x * ViewMatrixScaled.m[RX] + mv->y * ViewMatrixScaled.m[UX] + mv->z * ViewMatrixScaled.m[LX] + ViewTransScaled.v[X]) / z + RenderSettings.GeomCentreX;
01108 mv->sy = (mv->x * ViewMatrixScaled.m[RY] + mv->y * ViewMatrixScaled.m[UY] + mv->z * ViewMatrixScaled.m[LY] + ViewTransScaled.v[Y]) / z + RenderSettings.GeomCentreY;
01109
01110 mv->rhw = 1 / z;
01111 mv->sz = GET_ZBUFFER(z);
01112
01113 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
01114 if (fog > 255) fog = 255;
01115 fog -= mv->VertFog;
01116 if (fog < 0) fog = 0;
01117 mv->specular = FTOL3(fog) << 24;
01118
01119 mv->Clip = 0;
01120 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
01121 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
01122 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
01123 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
01124 if (mv->sz < 0) mv->Clip |= 16;
01125 else if (mv->sz >= 1) mv->Clip |= 32;
01126 }
01127 }
01128
01130
01132
01133 void TransCubeVerts(WORLD_MODEL *m)
01134 {
01135 short i;
01136 float z;
01137 WORLD_VERTEX *mv;
01138
01139 mv = m->VertPtr;
01140
01141 for (i = 0 ; i < m->VertNum ; i++, mv++)
01142 {
01143 z = mv->x * ViewMatrixScaled.m[RZ] + mv->y * ViewMatrixScaled.m[UZ] + mv->z * ViewMatrixScaled.m[LZ] + ViewTransScaled.v[Z];
01144 mv->rhw = 1 / z;
01145
01146 mv->sx = (mv->x * ViewMatrixScaled.m[RX] + mv->y * ViewMatrixScaled.m[UX] + mv->z * ViewMatrixScaled.m[LX] + ViewTransScaled.v[X]) / z + RenderSettings.GeomCentreX;
01147 mv->sy = (mv->x * ViewMatrixScaled.m[RY] + mv->y * ViewMatrixScaled.m[UY] + mv->z * ViewMatrixScaled.m[LY] + ViewTransScaled.v[Y]) / z + RenderSettings.GeomCentreY;
01148
01149 mv->sz = GET_ZBUFFER(z);
01150 }
01151 }
01152
01154
01156
01157 void TransCubeVertsFog(WORLD_MODEL *m)
01158 {
01159 short i;
01160 float z;
01161 float fog;
01162 WORLD_VERTEX *mv;
01163
01164 mv = m->VertPtr;
01165
01166 for (i = 0 ; i < m->VertNum ; i++, mv++)
01167 {
01168 z = mv->x * ViewMatrixScaled.m[RZ] + mv->y * ViewMatrixScaled.m[UZ] + mv->z * ViewMatrixScaled.m[LZ] + ViewTransScaled.v[Z];
01169 mv->rhw = 1 / z;
01170
01171 mv->sx = (mv->x * ViewMatrixScaled.m[RX] + mv->y * ViewMatrixScaled.m[UX] + mv->z * ViewMatrixScaled.m[LX] + ViewTransScaled.v[X]) / z + RenderSettings.GeomCentreX;
01172 mv->sy = (mv->x * ViewMatrixScaled.m[RY] + mv->y * ViewMatrixScaled.m[UY] + mv->z * ViewMatrixScaled.m[LY] + ViewTransScaled.v[Y]) / z + RenderSettings.GeomCentreY;
01173
01174 mv->sz = GET_ZBUFFER(z);
01175
01176 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
01177 if (fog > 255) fog = 255;
01178 fog -= mv->VertFog;
01179 if (fog < 0) fog = 0;
01180 mv->specular = FTOL3(fog) << 24;
01181 }
01182 }
01183
01185
01187
01188 void TransCubeVertsClipNewVerts(WORLD_MODEL *m)
01189 {
01190 short i;
01191 float z;
01192 WORLD_VERTEX *mv;
01193
01194 mv = m->VertPtr;
01195
01196 for (i = 0 ; i < m->VertNum ; i++, mv++)
01197 {
01198 z = mv->x2 * ViewMatrixScaled.m[RZ] + mv->y2 * ViewMatrixScaled.m[UZ] + mv->z2 * ViewMatrixScaled.m[LZ] + ViewTransScaled.v[Z];
01199 if (z < 1) z = 1;
01200
01201 mv->sx = (mv->x2 * ViewMatrixScaled.m[RX] + mv->y2 * ViewMatrixScaled.m[UX] + mv->z2 * ViewMatrixScaled.m[LX] + ViewTransScaled.v[X]) / z + RenderSettings.GeomCentreX;
01202 mv->sy = (mv->x2 * ViewMatrixScaled.m[RY] + mv->y2 * ViewMatrixScaled.m[UY] + mv->z2 * ViewMatrixScaled.m[LY] + ViewTransScaled.v[Y]) / z + RenderSettings.GeomCentreY;
01203
01204 mv->rhw = 1 / z;
01205 mv->sz = GET_ZBUFFER(z);
01206
01207 mv->Clip = 0;
01208 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
01209 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
01210 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
01211 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
01212 if (mv->sz < 0) mv->Clip |= 16;
01213 else if (mv->sz >= 1) mv->Clip |= 32;
01214 }
01215 }
01216
01218
01220
01221 void TransCubeVertsFogClipNewVerts(WORLD_MODEL *m)
01222 {
01223 short i;
01224 float z;
01225 float fog;
01226 WORLD_VERTEX *mv;
01227
01228 mv = m->VertPtr;
01229
01230 for (i = 0 ; i < m->VertNum ; i++, mv++)
01231 {
01232 z = mv->x2 * ViewMatrixScaled.m[RZ] + mv->y2 * ViewMatrixScaled.m[UZ] + mv->z2 * ViewMatrixScaled.m[LZ] + ViewTransScaled.v[Z];
01233 if (z < 1) z = 1;
01234
01235 mv->sx = (mv->x2 * ViewMatrixScaled.m[RX] + mv->y2 * ViewMatrixScaled.m[UX] + mv->z2 * ViewMatrixScaled.m[LX] + ViewTransScaled.v[X]) / z + RenderSettings.GeomCentreX;
01236 mv->sy = (mv->x2 * ViewMatrixScaled.m[RY] + mv->y2 * ViewMatrixScaled.m[UY] + mv->z2 * ViewMatrixScaled.m[LY] + ViewTransScaled.v[Y]) / z + RenderSettings.GeomCentreY;
01237
01238 mv->rhw = 1 / z;
01239 mv->sz = GET_ZBUFFER(z);
01240
01241 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
01242 if (fog > 255) fog = 255;
01243 fog -= mv->VertFog;
01244 if (fog < 0) fog = 0;
01245 mv->specular = FTOL3(fog) << 24;
01246
01247 mv->Clip = 0;
01248 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
01249 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
01250 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
01251 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
01252 if (mv->sz < 0) mv->Clip |= 16;
01253 else if (mv->sz >= 1) mv->Clip |= 32;
01254 }
01255 }
01256
01258
01260
01261 void TransCubeVertsNewVerts(WORLD_MODEL *m)
01262 {
01263 short i;
01264 float z;
01265 WORLD_VERTEX *mv;
01266
01267 mv = m->VertPtr;
01268
01269 for (i = 0 ; i < m->VertNum ; i++, mv++)
01270 {
01271 z = mv->x2 * ViewMatrixScaled.m[RZ] + mv->y2 * ViewMatrixScaled.m[UZ] + mv->z2 * ViewMatrixScaled.m[LZ] + ViewTransScaled.v[Z];
01272 mv->rhw = 1 / z;
01273
01274 mv->sx = (mv->x2 * ViewMatrixScaled.m[RX] + mv->y2 * ViewMatrixScaled.m[UX] + mv->z2 * ViewMatrixScaled.m[LX] + ViewTransScaled.v[X]) / z + RenderSettings.GeomCentreX;
01275 mv->sy = (mv->x2 * ViewMatrixScaled.m[RY] + mv->y2 * ViewMatrixScaled.m[UY] + mv->z2 * ViewMatrixScaled.m[LY] + ViewTransScaled.v[Y]) / z + RenderSettings.GeomCentreY;
01276
01277 mv->sz = GET_ZBUFFER(z);
01278 }
01279 }
01280
01282
01284
01285 void TransCubeVertsFogNewVerts(WORLD_MODEL *m)
01286 {
01287 short i;
01288 float z;
01289 float fog;
01290 WORLD_VERTEX *mv;
01291
01292 mv = m->VertPtr;
01293
01294 for (i = 0 ; i < m->VertNum ; i++, mv++)
01295 {
01296 z = mv->x2 * ViewMatrixScaled.m[RZ] + mv->y2 * ViewMatrixScaled.m[UZ] + mv->z2 * ViewMatrixScaled.m[LZ] + ViewTransScaled.v[Z];
01297 mv->rhw = 1 / z;
01298
01299 mv->sx = (mv->x2 * ViewMatrixScaled.m[RX] + mv->y2 * ViewMatrixScaled.m[UX] + mv->z2 * ViewMatrixScaled.m[LX] + ViewTransScaled.v[X]) / z + RenderSettings.GeomCentreX;
01300 mv->sy = (mv->x2 * ViewMatrixScaled.m[RY] + mv->y2 * ViewMatrixScaled.m[UY] + mv->z2 * ViewMatrixScaled.m[LY] + ViewTransScaled.v[Y]) / z + RenderSettings.GeomCentreY;
01301
01302 mv->sz = GET_ZBUFFER(z);
01303
01304 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
01305 if (fog > 255) fog = 255;
01306 fog -= mv->VertFog;
01307 if (fog < 0) fog = 0;
01308 mv->specular = FTOL3(fog) << 24;
01309 }
01310 }
01311
01313
01315
01316 void TransCubeVertsMirror(WORLD_MODEL *m)
01317 {
01318 short i;
01319 float z;
01320 float fog;
01321 WORLD_MIRROR_VERTEX *mv;
01322
01323 mv = m->MirrorVertPtr;
01324
01325 for (i = 0 ; i < m->MirrorVertNum ; i++, mv++)
01326 {
01327 z = mv->x * ViewMatrixScaled.m[RZ] + mv->y * ViewMatrixScaled.m[UZ] + mv->z * ViewMatrixScaled.m[LZ] + ViewTransScaled.v[Z];
01328 if (z < 1) z = 1;
01329
01330 mv->sx = (mv->x * ViewMatrixScaled.m[RX] + mv->y * ViewMatrixScaled.m[UX] + mv->z * ViewMatrixScaled.m[LX] + ViewTransScaled.v[X]) / z + RenderSettings.GeomCentreX;
01331 mv->sy = (mv->x * ViewMatrixScaled.m[RY] + mv->y * ViewMatrixScaled.m[UY] + mv->z * ViewMatrixScaled.m[LY] + ViewTransScaled.v[Y]) / z + RenderSettings.GeomCentreY;
01332
01333 mv->rhw = 1 / z;
01334 mv->sz = GET_ZBUFFER(z);
01335
01336 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
01337 if (fog > 255) fog = 255;
01338 fog -= mv->VertFog;
01339 if (fog < 0) fog = 0;
01340 mv->specular = FTOL3(fog) << 24;
01341
01342 mv->Clip = 0;
01343 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
01344 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
01345 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
01346 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
01347 if (mv->sz < 0) mv->Clip |= 16;
01348 else if (mv->sz >= 1) mv->Clip |= 32;
01349 }
01350 }
01351
01353
01355
01356 void TransCubeVertsMirrorNewVerts(WORLD_MODEL *m)
01357 {
01358 short i;
01359 float z;
01360 float fog;
01361 WORLD_MIRROR_VERTEX *mv;
01362
01363 mv = m->MirrorVertPtr;
01364
01365 for (i = 0 ; i < m->MirrorVertNum ; i++, mv++)
01366 {
01367 z = mv->x2 * ViewMatrixScaled.m[RZ] + mv->y2 * ViewMatrixScaled.m[UZ] + mv->z2 * ViewMatrixScaled.m[LZ] + ViewTransScaled.v[Z];
01368 if (z < 1) z = 1;
01369
01370 mv->sx = (mv->x2 * ViewMatrixScaled.m[RX] + mv->y2 * ViewMatrixScaled.m[UX] + mv->z2 * ViewMatrixScaled.m[LX] + ViewTransScaled.v[X]) / z + RenderSettings.GeomCentreX;
01371 mv->sy = (mv->x2 * ViewMatrixScaled.m[RY] + mv->y2 * ViewMatrixScaled.m[UY] + mv->z2 * ViewMatrixScaled.m[LY] + ViewTransScaled.v[Y]) / z + RenderSettings.GeomCentreY;
01372
01373 mv->rhw = 1 / z;
01374 mv->sz = GET_ZBUFFER(z);
01375
01376 fog = (RenderSettings.FarClip - z) * RenderSettings.FogMul;
01377 if (fog > 255) fog = 255;
01378 fog -= mv->VertFog;
01379 if (fog < 0) fog = 0;
01380 mv->specular = FTOL3(fog) << 24;
01381
01382 mv->Clip = 0;
01383 if (mv->sx < ScreenLeftClipGuard) mv->Clip |= 1;
01384 else if (mv->sx > ScreenRightClipGuard) mv->Clip |= 2;
01385 if (mv->sy < ScreenTopClipGuard) mv->Clip |= 4;
01386 else if (mv->sy > ScreenBottomClipGuard) mv->Clip |= 8;
01387 if (mv->sz < 0) mv->Clip |= 16;
01388 else if (mv->sz >= 1) mv->Clip |= 32;
01389 }
01390 }
01391
01393
01395
01396 void DrawCubePolysClip(WORLD_MODEL *m, long lit)
01397 {
01398 long i, clip;
01399 WORLD_POLY *mp;
01400 VERTEX_TEX1 *vert;
01401 BUCKET_TEX1 *bucket;
01402 VERTEX_TEX0 *vertrgb;
01403 BUCKET_TEX0 *bucketrgb;
01404 BUCKET_ENV *envbucket;
01405 short count;
01406
01407
01408
01409 mp = m->PolyPtr;
01410
01411 for (i = m->QuadNumTex ; i ; i--, mp++)
01412 {
01413
01414
01415
01416 REJECT_WORLD_POLY();
01417 CLIP_QUAD();
01418 INC_POLY_COUNT(WorldDrawnCount, 2);
01419
01420
01421
01422 if (mp->Type & POLY_SEMITRANS)
01423 {
01424 if (!SEMI_POLY_FREE()) continue;
01425 SEMI_POLY_SETUP(vert, WorldFog, 4, mp->Tpage, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01426 }
01427 else
01428 {
01429 if (clip) bucket = &WorldBucketHeadClip[mp->Tpage];
01430 else bucket = &WorldBucketHead[mp->Tpage];
01431 count = (short)(bucket->CurrentVerts - bucket->Verts);
01432
01433 if (count > BUCKET_VERT_END)
01434 {
01435 SET_TPAGE(mp->Tpage);
01436 FlushOneBucketTEX1(bucket, clip);
01437 count = 0;
01438 }
01439
01440 bucket->CurrentIndex[0] = count;
01441 bucket->CurrentIndex[1] = count + 1;
01442 bucket->CurrentIndex[2] = count + 2;
01443 bucket->CurrentIndex[3] = count;
01444 bucket->CurrentIndex[4] = count + 2;
01445 bucket->CurrentIndex[5] = count + 3;
01446 bucket->CurrentIndex += 6;
01447
01448 vert = bucket->CurrentVerts;
01449 bucket->CurrentVerts += 4;
01450 }
01451
01452
01453
01454 COPY_QUAD_XYZRHW(vert);
01455 COPY_QUAD_UV(vert);
01456
01457 if (lit)
01458 {
01459 COPY_WORLD_QUAD_COLOR_LIT(vert);
01460 }
01461 else
01462 {
01463 COPY_WORLD_QUAD_COLOR(vert);
01464 }
01465
01466 if (WorldFog)
01467 COPY_QUAD_SPECULAR(vert);
01468
01469
01470
01471 if (mp->Type & WorldEnvMask)
01472 {
01473 INC_POLY_COUNT(WorldDrawnCount, 2);
01474
01475
01476
01477 if (clip) envbucket = WorldBucketHeadEnvClip;
01478 else envbucket = WorldBucketHeadEnv;
01479 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01480
01481 if (count > ENV_VERT_END)
01482 continue;
01483
01484 envbucket->CurrentIndex[0] = count;
01485 envbucket->CurrentIndex[1] = count + 1;
01486 envbucket->CurrentIndex[2] = count + 2;
01487 envbucket->CurrentIndex[3] = count;
01488 envbucket->CurrentIndex[4] = count + 2;
01489 envbucket->CurrentIndex[5] = count + 3;
01490 envbucket->CurrentIndex += 6;
01491
01492 vert = envbucket->CurrentVerts;
01493 envbucket->CurrentVerts += 4;
01494
01495
01496
01497 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01498 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01499 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01500 *(MEM32*)&vert[3] = *(MEM32*)&mp->v3->sx;
01501 }
01502 }
01503
01504
01505
01506 for (i = m->TriNumTex ; i ; i--, mp++)
01507 {
01508
01509
01510
01511 REJECT_WORLD_POLY();
01512 CLIP_TRI();
01513 INC_POLY_COUNT(WorldDrawnCount, 1);
01514
01515
01516
01517 if (mp->Type & POLY_SEMITRANS)
01518 {
01519 if (!SEMI_POLY_FREE()) continue;
01520 SEMI_POLY_SETUP(vert, WorldFog, 3, mp->Tpage, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01521 }
01522 else
01523 {
01524 if (clip) bucket = &WorldBucketHeadClip[mp->Tpage];
01525 else bucket = &WorldBucketHead[mp->Tpage];
01526 count = (short)(bucket->CurrentVerts - bucket->Verts);
01527
01528 if (count > BUCKET_VERT_END)
01529 {
01530 SET_TPAGE(mp->Tpage);
01531 FlushOneBucketTEX1(bucket, clip);
01532 count = 0;
01533 }
01534
01535 bucket->CurrentIndex[0] = count;
01536 bucket->CurrentIndex[1] = count + 1;
01537 bucket->CurrentIndex[2] = count + 2;
01538 bucket->CurrentIndex += 3;
01539
01540 vert = bucket->CurrentVerts;
01541 bucket->CurrentVerts += 3;
01542 }
01543
01544
01545
01546 COPY_TRI_XYZRHW(vert);
01547 COPY_TRI_UV(vert);
01548
01549 if (lit)
01550 {
01551 COPY_WORLD_TRI_COLOR_LIT(vert);
01552 }
01553 else
01554 {
01555 COPY_WORLD_TRI_COLOR(vert);
01556 }
01557
01558 if (WorldFog)
01559 COPY_TRI_SPECULAR(vert);
01560
01561
01562
01563 if (mp->Type & WorldEnvMask)
01564 {
01565 INC_POLY_COUNT(WorldDrawnCount, 1);
01566
01567
01568
01569 if (clip) envbucket = WorldBucketHeadEnvClip;
01570 else envbucket = WorldBucketHeadEnv;
01571 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01572
01573 if (count > ENV_VERT_END)
01574 continue;
01575
01576 envbucket->CurrentIndex[0] = count;
01577 envbucket->CurrentIndex[1] = count + 1;
01578 envbucket->CurrentIndex[2] = count + 2;
01579 envbucket->CurrentIndex += 3;
01580
01581 vert = envbucket->CurrentVerts;
01582 envbucket->CurrentVerts += 3;
01583
01584
01585
01586 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01587 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01588 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01589 }
01590 }
01591
01592
01593
01594 for (i = m->QuadNumRGB ; i ; i--, mp++)
01595 {
01596
01597
01598
01599 REJECT_WORLD_POLY();
01600 CLIP_QUAD();
01601 INC_POLY_COUNT(WorldDrawnCount, 2);
01602
01603
01604
01605 if (mp->Type & POLY_SEMITRANS)
01606 {
01607 if (!SEMI_POLY_FREE()) continue;
01608 SEMI_POLY_SETUP_RGB(vertrgb, WorldFog, 4, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01609 }
01610 else
01611 {
01612 if (clip) bucketrgb = WorldBucketHeadClipRGB;
01613 else bucketrgb = WorldBucketHeadRGB;
01614 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
01615
01616 if (count > BUCKET_VERT_END)
01617 {
01618 SET_TPAGE(-1);
01619 FlushOneBucketTEX0(bucketrgb, clip);
01620 count = 0;
01621 }
01622
01623 bucketrgb->CurrentIndex[0] = count;
01624 bucketrgb->CurrentIndex[1] = count + 1;
01625 bucketrgb->CurrentIndex[2] = count + 2;
01626 bucketrgb->CurrentIndex[3] = count;
01627 bucketrgb->CurrentIndex[4] = count + 2;
01628 bucketrgb->CurrentIndex[5] = count + 3;
01629 bucketrgb->CurrentIndex += 6;
01630
01631 vertrgb = bucketrgb->CurrentVerts;
01632 bucketrgb->CurrentVerts += 4;
01633 }
01634
01635
01636
01637 COPY_QUAD_XYZRHW(vertrgb);
01638
01639 if (lit)
01640 {
01641 COPY_WORLD_QUAD_COLOR_LIT(vertrgb);
01642 }
01643 else
01644 {
01645 COPY_WORLD_QUAD_COLOR(vertrgb);
01646 }
01647
01648 if (WorldFog)
01649 COPY_QUAD_SPECULAR(vertrgb);
01650
01651
01652
01653 if (mp->Type & WorldEnvMask)
01654 {
01655 INC_POLY_COUNT(WorldDrawnCount, 2);
01656
01657
01658
01659 if (clip) envbucket = WorldBucketHeadEnvClip;
01660 else envbucket = WorldBucketHeadEnv;
01661 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01662
01663 if (count > ENV_VERT_END)
01664 continue;
01665
01666 envbucket->CurrentIndex[0] = count;
01667 envbucket->CurrentIndex[1] = count + 1;
01668 envbucket->CurrentIndex[2] = count + 2;
01669 envbucket->CurrentIndex[3] = count;
01670 envbucket->CurrentIndex[4] = count + 2;
01671 envbucket->CurrentIndex[5] = count + 3;
01672 envbucket->CurrentIndex += 6;
01673
01674 vert = envbucket->CurrentVerts;
01675 envbucket->CurrentVerts += 4;
01676
01677
01678
01679 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01680 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01681 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01682 *(MEM32*)&vert[3] = *(MEM32*)&mp->v3->sx;
01683 }
01684 }
01685
01686
01687
01688 for (i = m->TriNumRGB ; i ; i--, mp++)
01689 {
01690
01691
01692
01693 REJECT_WORLD_POLY();
01694 CLIP_TRI();
01695 INC_POLY_COUNT(WorldDrawnCount, 1);
01696
01697
01698
01699 if (mp->Type & POLY_SEMITRANS)
01700 {
01701 if (!SEMI_POLY_FREE()) continue;
01702 SEMI_POLY_SETUP_RGB(vertrgb, WorldFog, 3, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01703 }
01704 else
01705 {
01706 if (clip) bucketrgb = WorldBucketHeadClipRGB;
01707 else bucketrgb = WorldBucketHeadRGB;
01708 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
01709
01710 if (count > BUCKET_VERT_END)
01711 {
01712 SET_TPAGE(-1);
01713 FlushOneBucketTEX0(bucketrgb, clip);
01714 count = 0;
01715 }
01716
01717 bucketrgb->CurrentIndex[0] = count;
01718 bucketrgb->CurrentIndex[1] = count + 1;
01719 bucketrgb->CurrentIndex[2] = count + 2;
01720 bucketrgb->CurrentIndex += 3;
01721
01722 vertrgb = bucketrgb->CurrentVerts;
01723 bucketrgb->CurrentVerts += 3;
01724 }
01725
01726
01727
01728 COPY_TRI_XYZRHW(vertrgb);
01729
01730 if (lit)
01731 {
01732 COPY_WORLD_TRI_COLOR_LIT(vertrgb);
01733 }
01734 else
01735 {
01736 COPY_WORLD_TRI_COLOR(vertrgb);
01737 }
01738
01739 if (WorldFog)
01740 COPY_TRI_SPECULAR(vertrgb);
01741
01742
01743
01744 if (mp->Type & WorldEnvMask)
01745 {
01746 INC_POLY_COUNT(WorldDrawnCount, 1);
01747
01748
01749
01750 if (clip) envbucket = WorldBucketHeadEnvClip;
01751 else envbucket = WorldBucketHeadEnv;
01752 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01753
01754 if (count > ENV_VERT_END)
01755 continue;
01756
01757 envbucket->CurrentIndex[0] = count;
01758 envbucket->CurrentIndex[1] = count + 1;
01759 envbucket->CurrentIndex[2] = count + 2;
01760 envbucket->CurrentIndex += 3;
01761
01762 vert = envbucket->CurrentVerts;
01763 envbucket->CurrentVerts += 3;
01764
01765
01766
01767 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01768 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01769 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01770 }
01771 }
01772 }
01773
01775
01777
01778 void DrawCubePolys(WORLD_MODEL *m, long lit)
01779 {
01780 long i;
01781 WORLD_POLY *mp;
01782 VERTEX_TEX1 *vert;
01783 BUCKET_TEX1 *bucket;
01784 VERTEX_TEX0 *vertrgb;
01785 BUCKET_TEX0 *bucketrgb;
01786 BUCKET_ENV *envbucket = WorldBucketHeadEnv;
01787 short count;
01788
01789
01790
01791 mp = m->PolyPtr;
01792
01793 for (i = m->QuadNumTex ; i ; i--, mp++)
01794 {
01795
01796
01797
01798 REJECT_WORLD_POLY();
01799 INC_POLY_COUNT(WorldDrawnCount, 2);
01800
01801
01802
01803 if (mp->Type & POLY_SEMITRANS)
01804 {
01805 if (!SEMI_POLY_FREE()) continue;
01806 SEMI_POLY_SETUP(vert, WorldFog, 4, mp->Tpage, FALSE, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01807 }
01808 else
01809 {
01810 bucket = &WorldBucketHead[mp->Tpage];
01811 count = (short)(bucket->CurrentVerts - bucket->Verts);
01812
01813 if (count > BUCKET_VERT_END)
01814 {
01815 SET_TPAGE(mp->Tpage);
01816 FlushOneBucketTEX1(bucket, FALSE);
01817 count = 0;
01818 }
01819
01820 bucket->CurrentIndex[0] = count;
01821 bucket->CurrentIndex[1] = count + 1;
01822 bucket->CurrentIndex[2] = count + 2;
01823 bucket->CurrentIndex[3] = count;
01824 bucket->CurrentIndex[4] = count + 2;
01825 bucket->CurrentIndex[5] = count + 3;
01826 bucket->CurrentIndex += 6;
01827
01828 vert = bucket->CurrentVerts;
01829 bucket->CurrentVerts += 4;
01830 }
01831
01832
01833
01834 COPY_QUAD_XYZRHW(vert);
01835 COPY_QUAD_UV(vert);
01836
01837 if (lit)
01838 {
01839 COPY_WORLD_QUAD_COLOR_LIT(vert);
01840 }
01841 else
01842 {
01843 COPY_WORLD_QUAD_COLOR(vert);
01844 }
01845
01846 if (WorldFog)
01847 COPY_QUAD_SPECULAR(vert);
01848
01849
01850
01851 if (mp->Type & WorldEnvMask)
01852 {
01853 INC_POLY_COUNT(WorldDrawnCount, 2);
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] = count;
01866 envbucket->CurrentIndex[4] = count + 2;
01867 envbucket->CurrentIndex[5] = count + 3;
01868 envbucket->CurrentIndex += 6;
01869
01870 vert = envbucket->CurrentVerts;
01871 envbucket->CurrentVerts += 4;
01872
01873
01874
01875 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01876 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01877 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01878 *(MEM32*)&vert[3] = *(MEM32*)&mp->v3->sx;
01879 }
01880 }
01881
01882
01883
01884 for (i = m->TriNumTex ; i ; i--, mp++)
01885 {
01886
01887
01888
01889 REJECT_WORLD_POLY();
01890 INC_POLY_COUNT(WorldDrawnCount, 1);
01891
01892
01893
01894 if (mp->Type & POLY_SEMITRANS)
01895 {
01896 if (!SEMI_POLY_FREE()) continue;
01897 SEMI_POLY_SETUP(vert, WorldFog, 3, mp->Tpage, FALSE, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01898 }
01899 else
01900 {
01901 bucket = &WorldBucketHead[mp->Tpage];
01902 count = (short)(bucket->CurrentVerts - bucket->Verts);
01903
01904 if (count > BUCKET_VERT_END)
01905 {
01906 SET_TPAGE(mp->Tpage);
01907 FlushOneBucketTEX1(bucket, FALSE);
01908 count = 0;
01909 }
01910
01911 bucket->CurrentIndex[0] = count;
01912 bucket->CurrentIndex[1] = count + 1;
01913 bucket->CurrentIndex[2] = count + 2;
01914 bucket->CurrentIndex += 3;
01915
01916 vert = bucket->CurrentVerts;
01917 bucket->CurrentVerts += 3;
01918 }
01919
01920
01921
01922 COPY_TRI_XYZRHW(vert);
01923 COPY_TRI_UV(vert);
01924
01925 if (lit)
01926 {
01927 COPY_WORLD_TRI_COLOR_LIT(vert);
01928 }
01929 else
01930 {
01931 COPY_WORLD_TRI_COLOR(vert);
01932 }
01933
01934 if (WorldFog)
01935 COPY_TRI_SPECULAR(vert);
01936
01937
01938
01939 if (mp->Type & WorldEnvMask)
01940 {
01941 INC_POLY_COUNT(WorldDrawnCount, 1);
01942
01943
01944
01945 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
01946
01947 if (count > ENV_VERT_END)
01948 continue;
01949
01950 envbucket->CurrentIndex[0] = count;
01951 envbucket->CurrentIndex[1] = count + 1;
01952 envbucket->CurrentIndex[2] = count + 2;
01953 envbucket->CurrentIndex += 3;
01954
01955 vert = envbucket->CurrentVerts;
01956 envbucket->CurrentVerts += 3;
01957
01958
01959
01960 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
01961 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
01962 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
01963 }
01964 }
01965
01966
01967
01968 for (i = m->QuadNumRGB ; i ; i--, mp++)
01969 {
01970
01971
01972
01973 REJECT_WORLD_POLY();
01974 INC_POLY_COUNT(WorldDrawnCount, 2);
01975
01976
01977
01978 if (mp->Type & POLY_SEMITRANS)
01979 {
01980 if (!SEMI_POLY_FREE()) continue;
01981 SEMI_POLY_SETUP_RGB(vertrgb, WorldFog, 4, FALSE, (mp->Type & POLY_SEMITRANS_ONE) != 0);
01982 }
01983 else
01984 {
01985 bucketrgb = WorldBucketHeadRGB;
01986 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
01987
01988 if (count > BUCKET_VERT_END)
01989 {
01990 SET_TPAGE(-1);
01991 FlushOneBucketTEX0(bucketrgb, FALSE);
01992 count = 0;
01993 }
01994
01995 bucketrgb->CurrentIndex[0] = count;
01996 bucketrgb->CurrentIndex[1] = count + 1;
01997 bucketrgb->CurrentIndex[2] = count + 2;
01998 bucketrgb->CurrentIndex[3] = count;
01999 bucketrgb->CurrentIndex[4] = count + 2;
02000 bucketrgb->CurrentIndex[5] = count + 3;
02001 bucketrgb->CurrentIndex += 6;
02002
02003 vertrgb = bucketrgb->CurrentVerts;
02004 bucketrgb->CurrentVerts += 4;
02005 }
02006
02007
02008
02009 COPY_QUAD_XYZRHW(vertrgb);
02010
02011 if (lit)
02012 {
02013 COPY_WORLD_QUAD_COLOR_LIT(vertrgb);
02014 }
02015 else
02016 {
02017 COPY_WORLD_QUAD_COLOR(vertrgb);
02018 }
02019
02020 if (WorldFog)
02021 COPY_QUAD_SPECULAR(vertrgb);
02022
02023
02024
02025 if (mp->Type & WorldEnvMask)
02026 {
02027 INC_POLY_COUNT(WorldDrawnCount, 2);
02028
02029
02030
02031 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
02032
02033 if (count > ENV_VERT_END)
02034 continue;
02035
02036 envbucket->CurrentIndex[0] = count;
02037 envbucket->CurrentIndex[1] = count + 1;
02038 envbucket->CurrentIndex[2] = count + 2;
02039 envbucket->CurrentIndex[3] = count;
02040 envbucket->CurrentIndex[4] = count + 2;
02041 envbucket->CurrentIndex[5] = count + 3;
02042 envbucket->CurrentIndex += 6;
02043
02044 vert = envbucket->CurrentVerts;
02045 envbucket->CurrentVerts += 4;
02046
02047
02048
02049 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
02050 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
02051 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
02052 *(MEM32*)&vert[3] = *(MEM32*)&mp->v3->sx;
02053 }
02054 }
02055
02056
02057
02058 for (i = m->TriNumRGB ; i ; i--, mp++)
02059 {
02060
02061
02062
02063 REJECT_WORLD_POLY();
02064 INC_POLY_COUNT(WorldDrawnCount, 1);
02065
02066
02067
02068 if (mp->Type & POLY_SEMITRANS)
02069 {
02070 if (!SEMI_POLY_FREE()) continue;
02071 SEMI_POLY_SETUP_RGB(vertrgb, WorldFog, 3, FALSE, (mp->Type & POLY_SEMITRANS_ONE) != 0);
02072 }
02073 else
02074 {
02075 bucketrgb = WorldBucketHeadRGB;
02076 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
02077
02078 if (count > BUCKET_VERT_END)
02079 {
02080 SET_TPAGE(-1);
02081 FlushOneBucketTEX0(bucketrgb, FALSE);
02082 count = 0;
02083 }
02084
02085 bucketrgb->CurrentIndex[0] = count;
02086 bucketrgb->CurrentIndex[1] = count + 1;
02087 bucketrgb->CurrentIndex[2] = count + 2;
02088 bucketrgb->CurrentIndex += 3;
02089
02090 vertrgb = bucketrgb->CurrentVerts;
02091 bucketrgb->CurrentVerts += 3;
02092 }
02093
02094
02095
02096 COPY_TRI_XYZRHW(vertrgb);
02097
02098 if (lit)
02099 {
02100 COPY_WORLD_TRI_COLOR_LIT(vertrgb);
02101 }
02102 else
02103 {
02104 COPY_WORLD_TRI_COLOR(vertrgb);
02105 }
02106
02107 if (WorldFog)
02108 COPY_TRI_SPECULAR(vertrgb);
02109
02110
02111
02112 if (mp->Type & WorldEnvMask)
02113 {
02114 INC_POLY_COUNT(WorldDrawnCount, 1);
02115
02116
02117
02118 count = (short)(envbucket->CurrentVerts - envbucket->Verts);
02119
02120 if (count > ENV_VERT_END)
02121 continue;
02122
02123 envbucket->CurrentIndex[0] = count;
02124 envbucket->CurrentIndex[1] = count + 1;
02125 envbucket->CurrentIndex[2] = count + 2;
02126 envbucket->CurrentIndex += 3;
02127
02128 vert = envbucket->CurrentVerts;
02129 envbucket->CurrentVerts += 3;
02130
02131
02132
02133 *(MEM32*)&vert[0] = *(MEM32*)&mp->v0->sx;
02134 *(MEM32*)&vert[1] = *(MEM32*)&mp->v1->sx;
02135 *(MEM32*)&vert[2] = *(MEM32*)&mp->v2->sx;
02136 }
02137 }
02138 }
02139
02141
02143
02144 void DrawCubePolysMirror(WORLD_MODEL *m, long lit)
02145 {
02146 short count;
02147 long i, clip;
02148 WORLD_MIRROR_POLY *mp;
02149 VERTEX_TEX1 *vert;
02150 BUCKET_TEX1 *bucket;
02151 VERTEX_TEX0 *vertrgb;
02152 BUCKET_TEX0 *bucketrgb;
02153
02154
02155
02156 mp = m->MirrorPolyPtr;
02157
02158 for (i = m->MirrorQuadNumTex ; i ; i--, mp++)
02159 {
02160
02161
02162
02163 REJECT_WORLD_POLY_MIRROR();
02164 CLIP_QUAD();
02165 INC_POLY_COUNT(WorldDrawnCount, 2);
02166
02167
02168
02169 if (mp->Type & POLY_SEMITRANS)
02170 {
02171 if (!SEMI_POLY_FREE()) continue;
02172 SEMI_POLY_SETUP(vert, FALSE, 4, mp->Tpage, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
02173 }
02174 else
02175 {
02176 if (clip) bucket = &BucketClipFog[mp->Tpage];
02177 else bucket = &BucketFog[mp->Tpage];
02178 count = (short)(bucket->CurrentVerts - bucket->Verts);
02179
02180 if (count > BUCKET_VERT_END)
02181 {
02182 SET_TPAGE(mp->Tpage);
02183 FlushOneBucketTEX1(bucket, clip);
02184 count = 0;
02185 }
02186
02187 bucket->CurrentIndex[0] = count;
02188 bucket->CurrentIndex[1] = count + 1;
02189 bucket->CurrentIndex[2] = count + 2;
02190 bucket->CurrentIndex[3] = count;
02191 bucket->CurrentIndex[4] = count + 2;
02192 bucket->CurrentIndex[5] = count + 3;
02193 bucket->CurrentIndex += 6;
02194
02195 vert = bucket->CurrentVerts;
02196 bucket->CurrentVerts += 4;
02197 }
02198
02199
02200
02201 COPY_QUAD_XYZRHW(vert);
02202 COPY_QUAD_UV(vert);
02203
02204 if (lit)
02205 {
02206 COPY_WORLD_QUAD_COLOR_LIT_MIRROR(vert);
02207 }
02208 else
02209 {
02210 COPY_WORLD_QUAD_COLOR(vert);
02211 }
02212
02213 COPY_QUAD_SPECULAR(vert);
02214 }
02215
02216
02217
02218 for (i = m->MirrorTriNumTex ; i ; i--, mp++)
02219 {
02220
02221
02222
02223 REJECT_WORLD_POLY_MIRROR();
02224 CLIP_TRI();
02225 INC_POLY_COUNT(WorldDrawnCount, 1);
02226
02227
02228
02229 if (mp->Type & POLY_SEMITRANS)
02230 {
02231 if (!SEMI_POLY_FREE()) continue;
02232 SEMI_POLY_SETUP(vert, FALSE, 3, mp->Tpage, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
02233 }
02234 else
02235 {
02236 if (clip) bucket = &BucketClipFog[mp->Tpage];
02237 else bucket = &BucketFog[mp->Tpage];
02238 count = (short)(bucket->CurrentVerts - bucket->Verts);
02239
02240 if (count > BUCKET_VERT_END)
02241 {
02242 SET_TPAGE(mp->Tpage);
02243 FlushOneBucketTEX1(bucket, clip);
02244 count = 0;
02245 }
02246
02247 bucket->CurrentIndex[0] = count;
02248 bucket->CurrentIndex[1] = count + 1;
02249 bucket->CurrentIndex[2] = count + 2;
02250 bucket->CurrentIndex += 3;
02251
02252 vert = bucket->CurrentVerts;
02253 bucket->CurrentVerts += 3;
02254 }
02255
02256
02257
02258 COPY_TRI_XYZRHW(vert);
02259 COPY_TRI_UV(vert);
02260
02261 if (lit)
02262 {
02263 COPY_WORLD_TRI_COLOR_LIT_MIRROR(vert);
02264 }
02265 else
02266 {
02267 COPY_WORLD_TRI_COLOR(vert);
02268 }
02269
02270 COPY_TRI_SPECULAR(vert);
02271 }
02272
02273
02274
02275 for (i = m->MirrorQuadNumRGB ; i ; i--, mp++)
02276 {
02277
02278
02279
02280 REJECT_WORLD_POLY_MIRROR();
02281 CLIP_QUAD();
02282 INC_POLY_COUNT(WorldDrawnCount, 2);
02283
02284
02285
02286 if (mp->Type & POLY_SEMITRANS)
02287 {
02288 if (!SEMI_POLY_FREE()) continue;
02289 SEMI_POLY_SETUP_RGB(vertrgb, FALSE, 4, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
02290 }
02291 else
02292 {
02293 if (clip) bucketrgb = &BucketClipFogRGB;
02294 else bucketrgb = &BucketFogRGB;
02295 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
02296
02297 if (count > BUCKET_VERT_END)
02298 {
02299 SET_TPAGE(-1);
02300 FlushOneBucketTEX0(bucketrgb, clip);
02301 count = 0;
02302 }
02303
02304 bucketrgb->CurrentIndex[0] = count;
02305 bucketrgb->CurrentIndex[1] = count + 1;
02306 bucketrgb->CurrentIndex[2] = count + 2;
02307 bucketrgb->CurrentIndex[3] = count;
02308 bucketrgb->CurrentIndex[4] = count + 2;
02309 bucketrgb->CurrentIndex[5] = count + 3;
02310 bucketrgb->CurrentIndex += 6;
02311
02312 vertrgb = bucketrgb->CurrentVerts;
02313 bucketrgb->CurrentVerts += 4;
02314 }
02315
02316
02317
02318 COPY_QUAD_XYZRHW(vertrgb);
02319
02320 if (lit)
02321 {
02322 COPY_WORLD_QUAD_COLOR_LIT_MIRROR(vertrgb);
02323 }
02324 else
02325 {
02326 COPY_WORLD_QUAD_COLOR(vertrgb);
02327 }
02328
02329 COPY_QUAD_SPECULAR(vertrgb);
02330 }
02331
02332
02333
02334 for (i = m->MirrorTriNumRGB ; i ; i--, mp++)
02335 {
02336
02337
02338
02339 REJECT_WORLD_POLY_MIRROR();
02340 CLIP_TRI();
02341 INC_POLY_COUNT(WorldDrawnCount, 1);
02342
02343
02344
02345 if (mp->Type & POLY_SEMITRANS)
02346 {
02347 if (!SEMI_POLY_FREE()) continue;
02348 SEMI_POLY_SETUP_RGB(vertrgb, FALSE, 3, clip, (mp->Type & POLY_SEMITRANS_ONE) != 0);
02349 }
02350 else
02351 {
02352 if (clip) bucketrgb = &BucketClipFogRGB;
02353 else bucketrgb = &BucketFogRGB;
02354 count = (short)(bucketrgb->CurrentVerts - bucketrgb->Verts);
02355
02356 if (count > BUCKET_VERT_END)
02357 {
02358 SET_TPAGE(-1);
02359 FlushOneBucketTEX0(bucketrgb, clip);
02360 count = 0;
02361 }
02362
02363 bucketrgb->CurrentIndex[0] = count;
02364 bucketrgb->CurrentIndex[1] = count + 1;
02365 bucketrgb->CurrentIndex[2] = count + 2;
02366 bucketrgb->CurrentIndex += 3;
02367
02368 vertrgb = bucketrgb->CurrentVerts;
02369 bucketrgb->CurrentVerts += 3;
02370 }
02371
02372
02373
02374 COPY_TRI_XYZRHW(vertrgb);
02375
02376 if (lit)
02377 {
02378 COPY_WORLD_TRI_COLOR_LIT_MIRROR(vertrgb);
02379 }
02380 else
02381 {
02382 COPY_WORLD_TRI_COLOR(vertrgb);
02383 }
02384
02385 COPY_TRI_SPECULAR(vertrgb);
02386 }
02387 }
02388
02390
02392
02393 void ProcessTextureAnimations(void)
02394 {
02395 long i;
02396
02397 for (i = 0 ; i < TexAnimNum ; i++)
02398 {
02399 TexAnim[i].FrameTime += TimeStep;
02400 if (TexAnim[i].FrameTime >= TexAnim[i].CurrentFrame->Time)
02401 {
02402 TexAnim[i].FrameTime -= TexAnim[i].CurrentFrame->Time;
02403 TexAnim[i].CurrentFrameNum = (TexAnim[i].CurrentFrameNum + 1) % TexAnim[i].FrameNum;
02404 TexAnim[i].CurrentFrame = &TexAnim[i].Frame[TexAnim[i].CurrentFrameNum];
02405 }
02406 }
02407 }