REDRIVER2/src_rebuild/Game/C/shadow.c

907 lines
19 KiB
C

#include "driver2.h"
#include "shadow.h"
#include "texture.h"
#include "system.h"
#include "main.h"
#include "camera.h"
#include "draw.h"
#include "dr2roads.h"
#include "players.h"
#include "debris.h"
#include "handling.h"
#include "convert.h"
#include "mission.h"
#include "tile.h"
#include "INLINE_C.H"
#include "STRINGS.H"
int gShadowTexturePage;
int gShadowTextureNum;
UV shadowuv;
POLYFT4 shadowpoly;
VECTOR tyre_new_positions[4];
VECTOR tyre_save_positions[4];
int tyre_track_offset[4];
int num_tyre_tracks[4];
TYRE_TRACK track_buffer[4][64];
int smoke_count[4];
// [D] [T]
void InitTyreTracks(void)
{
int i;
i = 0;
while (i < 4)
{
num_tyre_tracks[i] = 0;
tyre_track_offset[i] = 0;
i++;
}
}
// [A]
void ResetTyreTracks(CAR_DATA* cp, int player_id)
{
// [A] reset tyre tracks
if (player_id >= 0 && player_id < 2 && cp->controlType != CONTROL_TYPE_NONE)
{
GetTyreTrackPositions(cp, player_id);
SetTyreTrackOldPositions(player_id);
}
}
// [D] [T]
void GetTyreTrackPositions(CAR_DATA *cp, int player_id)
{
int track;
uint loop;
CAR_COSMETICS *car_cos;
VECTOR WheelPos;
VECTOR CarPos;
CarPos.vx = cp->hd.where.t[0];
CarPos.vy = cp->hd.where.t[1];
CarPos.vz = cp->hd.where.t[2];
car_cos = cp->ap.carCos;
SetRotMatrix(&cp->hd.drawCarMat);
loop = 0;
do {
if (loop & 2)
WheelPos.vx = car_cos->wheelDisp[loop].vx + 17;
else
WheelPos.vx = car_cos->wheelDisp[loop].vx - 17;
WheelPos.vy = 0;
WheelPos.vz = -car_cos->wheelDisp[loop + 1 & 3].vz;
_MatrixRotate(&WheelPos);
WheelPos.vx += CarPos.vx;
WheelPos.vy = CarPos.vy;
WheelPos.vz += CarPos.vz;
track = player_id * 2 + (loop / 2);
tyre_new_positions[track].vx = WheelPos.vx;
tyre_new_positions[track].vz = WheelPos.vz;
tyre_new_positions[track].vy = MapHeight(&WheelPos);
loop += 2;
} while (loop < 4);
}
// [D] [T]
void SetTyreTrackOldPositions(int player_id)
{
int idx = player_id * 2;
tyre_save_positions[idx].vx = tyre_new_positions[idx].vx;
tyre_save_positions[idx].vy = tyre_new_positions[idx].vy;
tyre_save_positions[idx].vz = tyre_new_positions[idx].vz;
tyre_save_positions[idx + 1].vx = tyre_new_positions[idx + 1].vx;
tyre_save_positions[idx + 1].vy = tyre_new_positions[idx + 1].vy;
tyre_save_positions[idx + 1].vz = tyre_new_positions[idx + 1].vz;
}
// [D] [T]
void AddTyreTrack(int wheel, int tracksAndSmoke, int padid)
{
static int Cont[4] = { 0, 0, 0, 0 };
short x;
short z;
sdPlane *SurfaceDataPtr;
char trackSurface;
TYRE_TRACK *tt_p;
VECTOR *newtp;
VECTOR *oldtp;
VECTOR New1;
VECTOR New2;
VECTOR New3;
VECTOR New4;
VECTOR SmokeDrift;
VECTOR SmokePosition;
VECTOR grass_vector;
newtp = &tyre_new_positions[wheel];
// [A] disabled due to MP and SP bugs
/*
if (newtp->vx - camera_position.vx + 20480 > 40960)
return;
if (newtp->vz - camera_position.vz + 20480 > 40960)
return;*/
if (tracksAndSmoke == 0)
{
SurfaceDataPtr = sdGetCell(newtp);
trackSurface = 1;
if (SurfaceDataPtr->surface == 6)
return;
if (SurfaceDataPtr->surface == 4)
trackSurface = 2;
}
else
{
oldtp = &tyre_save_positions[wheel];
tt_p = track_buffer[wheel] + (tyre_track_offset[wheel] + num_tyre_tracks[wheel] & 0x3f);
SurfaceDataPtr = sdGetCell(newtp);
// check surface type
if (SurfaceDataPtr != NULL)
{
if (SurfaceDataPtr->surface == 6)
return;
if (SurfaceDataPtr->surface == 4)
{
tt_p->surface = 2;
player[padid].onGrass = 1;
}
else
{
tt_p->surface = 1;
}
}
else
{
tt_p->surface = 1;
}
trackSurface = tt_p->surface;
}
SmokePosition.vx = newtp->vx;
SmokePosition.vz = newtp->vz;
SmokePosition.vy = -50 - newtp->vy;
// make smoke
if ((smoke_count[wheel]++ & 3) == 1)
{
GetSmokeDrift(&SmokeDrift);
if (trackSurface == 2)
{
grass_vector.vx = 0;
grass_vector.vy = 50;
grass_vector.vz = 0;
grass_vector.pad = 0;
Setup_Smoke(&SmokePosition, 50, 500, SMOKE_BROWN, 0, &SmokeDrift, 0);
Setup_Sparks(&SmokePosition, &grass_vector, 5, 2);
}
else if (wetness == 0)
{
Setup_Smoke(&SmokePosition, 50, 500, SMOKE_WHITE, 0, &SmokeDrift, 0);
}
}
// lay down tracks to buffer
if (tracksAndSmoke)
{
int dir;
dir = ratan2(oldtp->vz - newtp->vz, oldtp->vx - newtp->vx);
x = FixHalfRound(rcossin_tbl[(-dir & 0xfffU) * 2] * 35, 13);
z = FixHalfRound(rcossin_tbl[(-dir & 0xfffU) * 2 + 1] * 35, 13);
New1.vy = oldtp->vy + 10;
New3.vy = newtp->vy + 10;
New2.vx = oldtp->vx;
New1.vx = New2.vx + x;
New2.vz = oldtp->vz;
New1.vz = New2.vz + z;
New2.vx = New2.vx - x;
New2.vz = New2.vz - z;
New4.vx = newtp->vx;
New3.vx = New4.vx + x;
New4.vz = newtp->vz;
New3.vz = New4.vz + z;
New4.vx = New4.vx - x;
New4.vz = New4.vz - z;
if (num_tyre_tracks[wheel] == 64)
{
tyre_track_offset[wheel]++;
tyre_track_offset[wheel] &= 63;
}
else
{
num_tyre_tracks[wheel]++;
}
if (Cont[wheel] == 1 && continuous_track == 1)
tt_p->type = 1;
else
tt_p->type = 0;
Cont[wheel] = 1;
tt_p->p1.vx = New1.vx;
tt_p->p1.vy = New1.vy;
tt_p->p1.vz = New1.vz;
tt_p->p2.vx = New2.vx;
tt_p->p2.vy = New1.vy;
tt_p->p2.vz = New2.vz;
tt_p->p3.vx = New3.vx;
tt_p->p3.vy = New3.vy;
tt_p->p3.vz = New3.vz;
tt_p->p4.vx = New4.vx;
tt_p->p4.vy = New3.vy;
tt_p->p4.vz = New4.vz;
}
}
// [D] [T]
void DrawTyreTracks(void)
{
char last_duff;
POLY_FT4 *poly;
TYRE_TRACK *tt_p;
int index;
int loop;
int wheel_loop;
POLY_FT4 *lasttyre;
SVECTOR ps[4];
int z;
gte_SetRotMatrix(&inv_camera_matrix);
gte_SetTransVector(&dummy);
wheel_loop = 0;
do {
lasttyre = NULL;
last_duff = 1;
index = tyre_track_offset[wheel_loop];
for (loop = 0; loop < num_tyre_tracks[wheel_loop]; loop++)
{
tt_p = track_buffer[wheel_loop] + index;
index++;
if (index == 64)
index = 0;
if (tt_p->type == 2)
continue;
ps[0].vx = tt_p->p1.vx - camera_position.vx;
ps[0].vy = -camera_position.vy - tt_p->p1.vy;
ps[0].vz = tt_p->p1.vz - camera_position.vz;
ps[1].vx = tt_p->p2.vx - camera_position.vx;
ps[1].vy = -camera_position.vy - tt_p->p2.vy;
ps[1].vz = tt_p->p2.vz - camera_position.vz;
ps[2].vx = tt_p->p3.vx - camera_position.vx;
ps[2].vy = -camera_position.vy - tt_p->p3.vy;
ps[2].vz = tt_p->p3.vz - camera_position.vz;
ps[3].vx = tt_p->p4.vx - camera_position.vx;
ps[3].vy = -camera_position.vy - tt_p->p4.vy;
ps[3].vz = tt_p->p4.vz - camera_position.vz;
poly = (POLY_FT4 *)current->primptr;
z = 0;
if (lasttyre != NULL && tt_p->type != 0 && !last_duff)
{
last_duff = 1;
if (ps[2].vx + 9000 <= 18000 && ps[2].vz + 9000 <= 18000)
{
gte_ldv0(&ps[2]);
gte_rtps();
gte_stsxy(&poly->x2);
gte_stsz(&z);
gte_ldv0(&ps[3]);
gte_rtps();
*(uint *)&poly->x0 = *(uint *)&lasttyre->x2;
*(uint *)&poly->x1 = *(uint *)&lasttyre->x3;
gte_stsxy(&poly->x3);
}
}
else
{
last_duff = 1;
if (ps[0].vx + 0x5000 <= 0xa000 && ps[0].vz + 0x5000 <= 0xa000)
{
gte_ldv3(&ps[0], &ps[1], &ps[2]);
gte_rtpt();
gte_stsxy3(&poly->x0, &poly->x1, &poly->x2);
gte_stsz(&z);
gte_ldv0(&ps[3]);
gte_rtps();
gte_stsxy(&poly->x3);
}
else
{
tt_p->type = 2;
}
}
if (z > 50)
{
setPolyFT4(poly);
setSemiTrans(poly, 1);
if (tt_p->surface == 1)
{
poly->r0 = poly->g0 = poly->b0 = 26;
}
else
{
poly->r0 = 17;
poly->g0 = poly->b0 = 35;
}
*(ushort *)&poly->u0 = *(ushort *)&gTyreTexture.coords.u0;
*(ushort *)&poly->u1 = *(ushort *)&gTyreTexture.coords.u1;
*(ushort *)&poly->u2 = *(ushort *)&gTyreTexture.coords.u2;
*(ushort *)&poly->u3 = *(ushort *)&gTyreTexture.coords.u3;
poly->tpage = gTyreTexture.tpageid | 0x40;
poly->clut = gTyreTexture.clutid;
addPrim(current->ot + (z >> 3), poly);
current->primptr += sizeof(POLY_FT4);
lasttyre = poly;
last_duff = 0;
}
}
wheel_loop++;
} while (wheel_loop < 4);
}
// [D] [T] [A] now better shadow code
void InitShadow(void)
{
TEXINF *texinf;
TPAN pos;
texinf = GetTextureInfoName("CARSHAD", &pos);
gShadowTexturePage = pos.texture_page;
gShadowTextureNum = pos.texture_number;
shadowuv.u0 = texinf->x;
shadowuv.u1 = texinf->x + texinf->width - 1;
shadowuv.v1 = texinf->y;
shadowuv.u2 = texinf->x;
shadowuv.v2 = texinf->y + texinf->height - 1;
shadowuv.u3 = texinf->x + texinf->width - 1;
shadowuv.v3 = texinf->y + texinf->height - 1;
shadowuv.v0 = texinf->y;
if (GameLevel == 3)
{
shadowuv.v1 += 1;
shadowuv.v0 += 1;
}
shadowpoly.id = 4;
shadowpoly.texture_set = pos.texture_page;
shadowpoly.texture_id = pos.texture_number;
shadowpoly.v0 = 0;
shadowpoly.v1 = 1;
shadowpoly.v2 = 2;
shadowpoly.v3 = 3;
*(ushort*)&shadowpoly.uv0 = *(ushort*)&shadowuv.u0;
*(ushort*)&shadowpoly.uv1 = *(ushort*)&shadowuv.u1;
*(ushort*)&shadowpoly.uv2 = *(ushort*)&shadowuv.u3;
*(ushort*)&shadowpoly.uv3 = *(ushort*)&shadowuv.u2;
}
// [D] [A] - this is a fuckery
void SubdivShadow(long z0, long z1, long z2, long z3, POLY_FT4 *sps)
{
// [A] we already have better car shadow code. This is UNUSED anyway
POLY_FT4 *spd;
spd = (POLY_FT4 *)current->primptr;
current->primptr += sizeof(POLY_FT4);
memcpy((u_char*)spd, (u_char*)sps, sizeof(POLY_FT4));
addPrim(current->ot + (z0 * 2 + z3 * 6 >> 6), spd);
}
extern VECTOR dummy;
extern _pct plotContext; // scratchpad addr: 0x1F8000C0
// [D] [T] [A] better shadow code
void PlaceShadowForCar(VECTOR *shadowPoints, int subdiv, int zOfs, int flag)
{
MVERTEX subdivVerts[5][5];
SVECTOR points[4];
points[0].vx = shadowPoints[0].vx - camera_position.vx;
points[0].vy = -shadowPoints[0].vy - camera_position.vy;
points[0].vz = shadowPoints[0].vz - camera_position.vz;
points[1].vx = shadowPoints[1].vx - camera_position.vx;
points[1].vy = -shadowPoints[1].vy - camera_position.vy;
points[1].vz = shadowPoints[1].vz - camera_position.vz;
points[2].vx = shadowPoints[3].vx - camera_position.vx;
points[2].vy = -shadowPoints[3].vy - camera_position.vy;
points[2].vz = shadowPoints[3].vz - camera_position.vz;
points[3].vx = shadowPoints[2].vx - camera_position.vx;
points[3].vy = -shadowPoints[2].vy - camera_position.vy;
points[3].vz = shadowPoints[2].vz - camera_position.vz;
gte_SetTransVector(&dummy);
gte_SetRotMatrix(&inv_camera_matrix);
plotContext.primptr = current->primptr;
plotContext.ptexture_pages = (ushort(*)[128])texture_pages;
plotContext.ptexture_cluts = (ushort(*)[128][32])texture_cluts;
plotContext.ot = current->ot + 10 + zOfs;
plotContext.flags = flag;
plotContext.colour = 80 | (80 << 8) | (80 << 16) | 0x2e000000;
plotContext.current = current;
POLYFT4* pft4 = &shadowpoly;
plotContext.clut = (uint)(*plotContext.ptexture_cluts)[pft4->texture_set][pft4->texture_id] << 0x10;
plotContext.tpage = ((uint)(*plotContext.ptexture_pages)[pft4->texture_set] | 0x40) << 0x10;
copyVector(&subdivVerts[0][0], &points[pft4->v0]);
subdivVerts[0][0].uv.val = *(ushort*)&pft4->uv0;
copyVector(&subdivVerts[0][1], &points[pft4->v1]);
subdivVerts[0][1].uv.val = *(ushort*)&pft4->uv1;
copyVector(&subdivVerts[0][2], &points[pft4->v3]);
subdivVerts[0][2].uv.val = *(ushort*)&pft4->uv3;
copyVector(&subdivVerts[0][3], &points[pft4->v2]);
subdivVerts[0][3].uv.val = *(ushort*)&pft4->uv2;
makeMesh((MVERTEX(*)[5][5])subdivVerts, subdiv, subdiv);
drawMesh((MVERTEX(*)[5][5])subdivVerts, subdiv, subdiv, &plotContext);
current->primptr = plotContext.primptr;
}
static int numcv;
static int lastcv;
static SVECTOR cv[12];
// [D] - refactored - NOT TESTED YET
int clipAgainstZ(void)
{
SVECTOR *curr;
SVECTOR *prev;
int _tmp;
int temp;
int d;
SVECTOR *dst;
int flags;
int srccount;
int dstcount;
dstcount = 0;
curr = cv + lastcv;
dst = cv + lastcv + 2;
srccount = numcv-1;
flags = ((curr + numcv * 0x1fffffff)[1].vz > 0) << 1;
prev = curr + numcv * 0x1fffffff + 1;
do {
if (srccount < 0)
{
numcv = dstcount;
lastcv = lastcv + 2;
return 0;
}
flags >>= 1;
if (curr->vz > 0)
flags |= 2;
if (flags == 1)
{
d = prev->vz - curr->vz;
dst->vx = (curr->vx * prev->vz - prev->vx * curr->vz) / d;
dst->vy = (curr->vy * prev->vz - prev->vy * curr->vz) / d;
dst->pad = (curr->pad * prev->vz - prev->pad * curr->vz) / d;
dst->vz = 0;
LAB_00076ca4:
dst--;
dstcount++;
}
else if (flags < 2)
{
if (flags != 0)
{
LAB_00076c84:
temp = curr->vz;
dst->vx = prev->vx;
dst->vz = temp;
goto LAB_00076ca4;
}
}
else
{
if (flags != 2)
{
goto LAB_00076c84;
}
d = prev->vz - curr->vz;
dst->vx = (curr->vx * prev->vz - prev->vx * curr->vz) / d;
dst->vy = (curr->vy * prev->vz - prev->vy * curr->vz) / d;
dst->pad = (curr->pad * prev->vz - prev->pad * curr->vz) / d;
dst->vz = 0;
_tmp = curr->vz;
dst[-1].vx = prev->vx;
dst[-1].vz = _tmp;
dst -= 2;
dstcount += 2;
}
srccount--;
prev = curr--;
} while (true);
}
// decompiled code
// original method signature:
// void /*$ra*/ clippedPoly()
// line 1081, offset 0x00076cd4
/* begin block 1 */
// Start line: 1083
// Start offset: 0x00076CD4
// Variables:
// int i; // $a3
// int j; // $t0
// int z1; // $v1
// POLY_G3 *pg3; // $s0
// int z[3]; // stack offset -24
/* end block 1 */
// End offset: 0x00077128
// End Line: 1156
/* begin block 2 */
// Start line: 2993
/* end block 2 */
// End Line: 2994
/* begin block 3 */
// Start line: 2996
/* end block 3 */
// End Line: 2997
/* begin block 4 */
// Start line: 2997
/* end block 4 */
// End Line: 2998
/* begin block 5 */
// Start line: 2999
/* end block 5 */
// End Line: 3000
/* WARNING: Unknown calling convention yet parameter storage is locked */
void clippedPoly(void)
{
UNIMPLEMENTED();
/*
undefined4 uVar1;
int track;
int iVar3;
POLY_F3 *pPVar4;
DB *pDVar5;
undefined4 in_zero;
undefined4 in_at;
int iVar6;
SVECTOR *pSVar7;
short *psVar8;
ulong *in_a1;
short *psVar9;
int iVar10;
int iVar11;
uint *puVar12;
pPVar4 = spolys;
iVar11 = numcv + -1;
if (iVar11 != -1) {
in_a1 = (ulong *)0xffffffff;
psVar8 = &(&cv)[lastcv].vz;
do {
iVar11 = iVar11 + -1;
*psVar8 = *psVar8 * 2 - psVar8[-2];
psVar8 = psVar8 + -4;
} while (iVar11 != -1);
}
clipAgainstZ();
if (2 < numcv) {
iVar11 = numcv + -1;
if (numcv != 0) {
in_a1 = (ulong *)0xffffffff;
pSVar7 = &cv + lastcv;
do {
iVar11 = iVar11 + -1;
pSVar7->vz = pSVar7->vz + pSVar7->vx * 2;
pSVar7 = pSVar7 + -1;
} while (iVar11 != -1);
}
clipAgainstZ();
if (2 < numcv) {
iVar11 = numcv + -1;
if (numcv != 0) {
in_a1 = (ulong *)&(&cv)[lastcv].vy;
do {
iVar11 = iVar11 + -1;
*(short *)((int)in_a1 + 2) =
*(short *)((int)in_a1 + 2) - (*(short *)((int)in_a1 + -2) + *(short *)in_a1 * 2);
in_a1 = in_a1 + -2;
} while (iVar11 != -1);
}
clipAgainstZ();
if (2 < numcv) {
iVar11 = numcv + -1;
if (numcv != 0) {
in_a1 = (ulong *)0xffffffff;
psVar8 = &(&cv)[lastcv].vy;
do {
iVar11 = iVar11 + -1;
psVar8[1] = psVar8[1] + *psVar8 * 4;
psVar8 = psVar8 + -4;
} while (iVar11 != -1);
}
clipAgainstZ();
if (2 < numcv) {
iVar11 = numcv + -1;
if (numcv != 0) {
in_a1 = (ulong *)0xffffffff;
psVar8 = &(&cv)[lastcv].vy;
do {
iVar11 = iVar11 + -1;
psVar8[1] = (short)((int)(((uint)(ushort)psVar8[1] + (int)*psVar8 * -2) * 0x10000) >>
0x11);
psVar8 = psVar8 + -4;
} while (iVar11 != -1);
}
iVar11 = numcv + -3;
iVar3 = lastcv;
spolys = pPVar4;
while (-1 < iVar11) {
iVar6 = iVar3 * 8;
setCopReg(2, in_zero, *(undefined4 *)(&cv + lastcv));
setCopReg(2, in_at, *(undefined4 *)&(&cv)[lastcv].vz);
setCopReg(2, &DAT_000da928 + iVar6, *(undefined4 *)(&DAT_000da928 + iVar6));
setCopReg(2, &Cont_12 + iVar6, *(undefined4 *)(&DAT_000da92c + iVar6));
setCopReg(2, &cv + lastcv, *(undefined4 *)(&Cont_12 + iVar6));
setCopReg(2, in_a1, *(undefined4 *)(&DAT_000da924 + iVar6));
copFunction(2, 0x280030);
*(undefined *)((int)&spolys->tag + 3) = 6;
spolys->code = '2';
spolys->r0 = *(uchar *)&(&cv)[lastcv].pad;
spolys->g0 = *(uchar *)&(&cv)[lastcv].pad;
psVar9 = &(&cv)[iVar3 + -1].pad;
spolys->b0 = *(uchar *)&(&cv)[lastcv].pad;
*(undefined *)&spolys->x1 = *(undefined *)psVar9;
*(undefined *)((int)&spolys->x1 + 1) = *(undefined *)psVar9;
psVar8 = &(&cv)[iVar3 + -2].pad;
*(undefined *)&spolys->y1 = *(undefined *)psVar9;
*(undefined *)&spolys[1].tag = *(undefined *)psVar8;
*(undefined *)((int)&spolys[1].tag + 1) = *(undefined *)psVar8;
*(undefined *)((int)&spolys[1].tag + 2) = *(undefined *)psVar8;
uVar1 = getCopReg(2, 0xc);
*(undefined4 *)&spolys->x0 = uVar1;
uVar1 = getCopReg(2, 0xd);
*(undefined4 *)&spolys->x2 = uVar1;
uVar1 = getCopReg(2, 0xe);
*(undefined4 *)&spolys[1].r0 = uVar1;
pDVar5 = current;
iVar6 = getCopReg(2, 0x11);
iVar10 = getCopReg(2, 0x12);
track = getCopReg(2, 0x13);
iVar6 = (iVar6 + iVar10 + track) / 3 + LightSortCorrect;
iVar10 = iVar6 >> 3;
if (iVar6 < 0x40) {
iVar10 = 8;
}
spolys->tag = spolys->tag & 0xff000000 | current->ot[iVar10] & 0xffffff;
puVar12 = (uint *)&spolys[1].x0;
pDVar5->ot[iVar10] = pDVar5->ot[iVar10] & 0xff000000 | (uint)spolys & 0xffffff;
*(undefined *)((int)&spolys[1].y0 + 1) = 7;
*(undefined *)((int)&spolys[1].y1 + 1) = 0x24;
pDVar5 = current;
spolys[1].x2 = -1;
spolys[1].y2 = -1;
*(undefined2 *)&spolys[2].r0 = 0xffff;
*(undefined2 *)&spolys[2].b0 = 0xffff;
spolys[2].x1 = -1;
spolys[2].y1 = -1;
spolys[2].y0 = 0x20;
*puVar12 = *puVar12 & 0xff000000 | pDVar5->ot[iVar10] & 0xffffff;
iVar11 = iVar11 + -1;
in_a1 = pDVar5->ot + iVar10;
*in_a1 = *in_a1 & 0xff000000 | (uint)puVar12 & 0xffffff;
spolys = (POLY_F3 *)&spolys[2].x2;
pDVar5->primptr = pDVar5->primptr + 0x20;
iVar3 = iVar3 + -1;
}
}
}
}
}
return;*/
}
// [D] [T]
void sQuad(SVECTOR *v0, SVECTOR *v1, SVECTOR *v2, SVECTOR *v3, CVECTOR* light_col, int LightSortCorrect)
{
int z1;
int z[4];
POLY_G4 *poly;
poly = (POLY_G4*)current->primptr;
#if 0
if (v0->vz < 1001 || v1->vz < 1001 || v2->vz < 1001 || v3->vz < 1001)
{
if (v0->vz > 0 || v1->vz > 0 || v2->vz > 0 || v3->vz > 0)
{
cv[0] = *v0;
cv[1] = *v1;
cv[2] = *v3;
cv[1].pad = light_col;
numcv = 3;
lastcv = 2;
clippedPoly();
cv[0] = *v2;
cv[1] = *v1;
cv[2] = *v3;
cv[1].pad = light_col;
numcv = 3;
lastcv = 2;
clippedPoly();
}
}
else
#endif
{
gte_ldv3(v0, v1, v3);
gte_rtpt();
setPolyG4(poly);
setSemiTrans(poly, 1);
poly->r1 = light_col->r;
poly->g1 = light_col->g;
poly->b1 = light_col->b;
poly->r0 = 0;
poly->g0 = 0;
poly->b0 = 0;
poly->r2 = 0;
poly->g2 = 0;
poly->b2 = 0;
poly->r3 = 0;
poly->g3 = 0;
poly->b3 = 0;
gte_stsxy3(&poly->x0, &poly->x1, &poly->x2);
gte_stsz3(&z[0], &z[1], &z[2]);
gte_ldv0(v2);
gte_rtps();
gte_stsxy(&poly->x3);
gte_stsz(&z[3]);
z1 = (z[0] + z[1] + z[2] + z[3] >> 2) + LightSortCorrect;
if (z1 < 0)
z1 = 0;
z1 >>= 3;
addPrim(current->ot + z1, poly);
current->primptr += sizeof(POLY_G4);
POLY_FT3* null = (POLY_FT3*)current->primptr;
setPolyFT3(null);
null->x0 = -1;
null->y0 = -1;
null->x1 = -1;
null->y1 = -1;
null->x2 = -1;
null->y2 = -1;
null->tpage = 0x20;
addPrim(current->ot + z1, null);
current->primptr += sizeof(POLY_FT3);
}
}