From 85cab5c47e8d455d559809e118c9f4d045674418 Mon Sep 17 00:00:00 2001 From: ABelliqueux Date: Fri, 25 Jun 2021 17:01:35 +0200 Subject: [PATCH] Break drawPoly() in smaller functions --- include/graphics.h | 13 + src/graphics.c | 701 ++++++++++++++++++++++++--------------------- 2 files changed, 387 insertions(+), 327 deletions(-) diff --git a/include/graphics.h b/include/graphics.h index bc67110..7946234 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -6,4 +6,17 @@ // Drawing void transformMesh(CAMERA * camera, MESH * meshes); void drawPoly(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw); +// Tri drawing +void set3VertexLerPos(MESH * mesh, long t); +void set3Prism(POLY_GT3 * poly, MESH * mesh, DRAWENV * draw, int i); +void set3Tex(POLY_GT3 * poly, MESH * mesh, DRAWENV * draw, long t, int i); +long interpolateTri(POLY_GT3 * poly, MESH * mesh, long t, long * Flag); +void drawTri(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw); +//Quad drawing +void drawQuad(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw); +void set4VertexLerPos(MESH * mesh, long t); +void set4Prism(POLY_GT4 * poly4, MESH * mesh, DRAWENV * draw, int i); +void set4Tex(POLY_GT4 * poly4, MESH * mesh, DRAWENV * draw, long t, int i); +long interpolateQuad(POLY_GT4 * poly4, MESH * mesh, long t, long * Flag); +//2D drawing void drawBG(CAMANGLE * camPtr, char ** nextpri, u_long * otdisc, char * db); diff --git a/src/graphics.c b/src/graphics.c index 6134d2a..dde7c71 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -18,345 +18,392 @@ void drawPoly(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpr long nclip, t = 0; // mesh is POLY_GT3 ( triangle ) if (mesh->index[t].code == 4) { - POLY_GT3 * poly; - // len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ... - for ( int i = 0; i < (mesh->tmesh->len * 3); i += 3 ) { - // If mesh is not part of precalculated background, draw them, else, discard - if ( !( mesh->isBG ) || *camMode != 2) { - poly = (POLY_GT3 *)*nextpri; - // If Vertex Anim flag is set, use it - if (mesh->isAnim){ - // If interpolation flag is set, use it - if(mesh->anim->interpolate){ - // Ping pong - //~ //if (mesh->anim->cursor > 4096 || mesh->anim->cursor < 0){ - //~ // mesh->anim->dir *= -1; - //~ //} - // Fixed point math precision - short precision = 12; - // Find next keyframe - if (mesh->anim->cursor > (1 << precision)) { - // There are still keyframes to interpolate between - if ( mesh->anim->lerpCursor < mesh->anim->nframes - 1 ) { - mesh->anim->lerpCursor ++; - mesh->anim->cursor = 0; - } - // We've reached last frame, go back to first frame - if ( mesh->anim->lerpCursor == mesh->anim->nframes - 1 ) { - mesh->anim->lerpCursor = 0; - mesh->anim->cursor = 0; - } - } - // Let's lerp between keyframes - // TODO : Finish lerped animation implementation - // Vertex 1 - mesh->tmesh->v[ mesh->index[ t ].order.vx ].vx = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vx].vx << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vx].vx << precision, mesh->anim->cursor << precision) >> precision; - mesh->tmesh->v[ mesh->index[ t ].order.vx ].vz = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vx].vz << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vx].vz << precision, mesh->anim->cursor << precision) >> precision; - mesh->tmesh->v[ mesh->index[ t ].order.vx ].vy = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vx].vy << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vx].vy << precision, mesh->anim->cursor << precision) >> precision; - // Vertex 2 - mesh->tmesh->v[ mesh->index[ t ].order.vz ].vx = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vz].vx << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vz].vx << precision, mesh->anim->cursor << precision) >> precision; - mesh->tmesh->v[ mesh->index[ t ].order.vz ].vz = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vz].vz << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vz].vz << precision, mesh->anim->cursor << precision) >> precision; - mesh->tmesh->v[ mesh->index[ t ].order.vz ].vy = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vz].vy << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vz].vy << precision, mesh->anim->cursor << precision) >> precision; - // Vertex 3 - mesh->tmesh->v[ mesh->index[ t ].order.vy ].vx = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vy].vx << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vy].vx << precision, mesh->anim->cursor << precision) >> precision; - mesh->tmesh->v[ mesh->index[ t ].order.vy ].vz = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vy].vz << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vy].vz << precision, mesh->anim->cursor << precision) >> precision; - mesh->tmesh->v[ mesh->index[ t ].order.vy ].vy = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vy].vy << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vy].vy << precision, mesh->anim->cursor << precision) >> precision; - mesh->anim->cursor += 24 * mesh->anim->dir; - // Coord transformation from world space to screen space - nclip = RotAverageNclip3( - &mesh->tmesh->v[ mesh->index[t].order.vx ], - &mesh->tmesh->v[ mesh->index[t].order.vz ], - &mesh->tmesh->v[ mesh->index[t].order.vy ], - ( long* ) &poly->x0, ( long* ) &poly->x1, ( long* ) &poly->x2, - &mesh->p, - &mesh->OTz, - Flag - ); - } else { - // No interpolation - // Use the pre-calculated vertices coordinates from the animation data - nclip = RotAverageNclip3( - &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vx ], - &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vz ], - &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vy ], - ( long* ) &poly->x0, ( long* ) &poly->x1, ( long* ) &poly->x2, - &mesh->p, - &mesh->OTz, - Flag - ); - } - } else { - // No animation - // Use model's regular vertex coordinates - nclip = RotAverageNclip3( - &mesh->tmesh->v[ mesh->index[t].order.vx ], - &mesh->tmesh->v[ mesh->index[t].order.vz ], - &mesh->tmesh->v[ mesh->index[t].order.vy ], - ( long * ) &poly->x0, ( long * ) &poly->x1, ( long * ) &poly->x2, - &mesh->p, - &mesh->OTz, - Flag - ); - } - // Do not draw invisible meshes - if ( nclip > 0 && mesh->OTz > 0 && (mesh->p < 4096) ) { - SetPolyGT3( poly ); - // If isPrism flag is set, use it - // FIXME : Doesn't work with pre-rendered BGs - if ( mesh->isPrism ) { - // Transparency effect : - // Use current DRAWENV clip as TPAGE instead of regular textures - ( (POLY_GT3 *) poly )->tpage = getTPage( mesh->tim->mode&0x3, 0, - draw->clip.x, - draw->clip.y - ); - // Use projected coordinates (results from RotAverage...) as UV coords and clamp them to 0-255,0-224 Why 224 though ? - setUV3(poly, (poly->x0 < 0 ? 0 : poly->x0 > 255 ? 255 : poly->x0), - (poly->y0 < 0 ? 0 : poly->y0 > 240 ? 240 : poly->y0), - (poly->x1 < 0 ? 0 : poly->x1 > 255 ? 255 : poly->x1), - (poly->y1 < 0 ? 0 : poly->y1 > 240 ? 240 : poly->y1), - (poly->x2 < 0 ? 0 : poly->x2 > 255 ? 255 : poly->x2), - (poly->y2 < 0 ? 0 : poly->y2 > 240 ? 240 : poly->y2) - ); - } else { - // No transparency effect - // Use regular TPAGE - ( (POLY_GT3 *) poly )->tpage = getTPage(mesh->tim->mode&0x3, 0, - mesh->tim->prect->x, - mesh->tim->prect->y - ); - setUV3(poly, mesh->tmesh->u[i].vx , mesh->tmesh->u[i].vy + mesh->tim->prect->y, - mesh->tmesh->u[i+2].vx, mesh->tmesh->u[i+2].vy + mesh->tim->prect->y, - mesh->tmesh->u[i+1].vx, mesh->tmesh->u[i+1].vy + mesh->tim->prect->y); - } - // CLUT setup - // If tim mode == 0 | 1 (4bits/8bits image), set CLUT coordinates - if ( (mesh->tim->mode & 0x3 ) < 2){ - setClut(poly, - mesh->tim->crect->x, - mesh->tim->crect->y); - } - if ( mesh->isSprite ) { - SetShadeTex( poly, 1 ); - } - // Init to 0 - CVECTOR outCol = { 0,0,0,0 }; - CVECTOR outCol1 = { 0,0,0,0 }; - CVECTOR outCol2 = { 0,0,0,0 }; - NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vx ], &mesh->tmesh->c[ i+0 ], mesh->p, &outCol); - NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vz ], &mesh->tmesh->c[ i+2 ], mesh->p, &outCol1); - NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vy ], &mesh->tmesh->c[ i+1 ], mesh->p, &outCol2); - // If transparent effect is in use, inhibit shadows - if (mesh->isPrism){ - // Use un-interpolated (i.e: no light, no fog) colors - setRGB0(poly, mesh->tmesh->c[i].r, mesh->tmesh->c[i].g, mesh->tmesh->c[i].b); - setRGB1(poly, mesh->tmesh->c[i+2].r, mesh->tmesh->c[i+2].g, mesh->tmesh->c[i+2].b); - setRGB2(poly, mesh->tmesh->c[i+1].r, mesh->tmesh->c[i+1].g, mesh->tmesh->c[i+1].b); - } else { - setRGB0(poly, outCol.r, outCol.g , outCol.b); - setRGB1(poly, outCol1.r, outCol1.g, outCol1.b); - setRGB2(poly, outCol2.r, outCol2.g, outCol2.b); - } - if ( (mesh->OTz > 0) /*&& (*mesh->OTz < OTLEN)*/ && (mesh->p < 4096) ) { - AddPrim(&ot[ mesh->OTz-2 ], poly); - } - //~ mesh->pos2D.vx = *(&poly->x0); - //~ mesh->pos2D.vy = *(&poly->x0 + 1); - // mesh->pos2D.vy = poly->x0; - // FntPrint("%d %d\n", *(&poly->x0), *(&poly->x0 + 1)); - *nextpri += sizeof(POLY_GT3); - } - t+=1; - } - } + drawTri(mesh, Flag, atime, camMode, nextpri, ot, db, draw); } // If mesh is quad if (mesh->index[t].code == 8) { - POLY_GT4 * poly4; - for (int i = 0; i < (mesh->tmesh->len * 4); i += 4) { - // if mesh is not part of BG, draw them, else, discard - if ( !(mesh->isBG) || *camMode != 2 ) { - poly4 = (POLY_GT4 *)*nextpri; - // Vertex Anim - if (mesh->isAnim){ - // with interpolation - if ( mesh->anim->interpolate ){ - // ping pong - //~ if (mesh->anim->cursor > 4096 || mesh->anim->cursor < 0){ - //~ mesh->anim->dir *= -1; - //~ } - short precision = 12; - if ( mesh->anim->cursor > 1<anim->lerpCursor < mesh->anim->nframes - 1 ) { - mesh->anim->lerpCursor ++; - mesh->anim->cursor = 0; - } - if ( mesh->anim->lerpCursor == mesh->anim->nframes - 1 ) { - mesh->anim->lerpCursor = 0; - mesh->anim->cursor = 0; - } - } - // Vertex 1 - mesh->tmesh->v[ mesh->index[ t ].order.vx ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vx ].vx << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vx ].vx << 12, mesh->anim->cursor << 12) >> 12; - mesh->tmesh->v[ mesh->index[ t ].order.vx ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vx ].vz << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vx ].vz << 12, mesh->anim->cursor << 12) >> 12; - mesh->tmesh->v[ mesh->index[ t ].order.vx ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vx ].vy << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vx ].vy << 12, mesh->anim->cursor << 12) >> 12; - // Vertex 2 - mesh->tmesh->v[ mesh->index[ t ].order.vz ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vz ].vx << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vz ].vx << 12, mesh->anim->cursor << 12) >> 12; - mesh->tmesh->v[ mesh->index[ t ].order.vz ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vz ].vz << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vz ].vz << 12, mesh->anim->cursor << 12) >> 12; - mesh->tmesh->v[ mesh->index[ t ].order.vz ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vz ].vy << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vz ].vy << 12, mesh->anim->cursor << 12) >> 12; - // Vertex 3 - mesh->tmesh->v[ mesh->index[ t ].order.vy ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vy ].vx << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vy ].vx << 12, mesh->anim->cursor << 12) >> 12; - mesh->tmesh->v[ mesh->index[ t ].order.vy ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vy ].vz << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vy ].vz << 12, mesh->anim->cursor << 12) >> 12; - mesh->tmesh->v[ mesh->index[ t ].order.vy ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vy ].vy << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vy ].vy << 12, mesh->anim->cursor << 12) >> 12; - // Vertex 4 - mesh->tmesh->v[ mesh->index[ t ].order.pad ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.pad ].vx << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.pad ].vx << 12, mesh->anim->cursor << 12) >> 12; - mesh->tmesh->v[ mesh->index[ t ].order.pad ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.pad ].vz << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.pad ].vz << 12, mesh->anim->cursor << 12) >> 12; - mesh->tmesh->v[ mesh->index[ t ].order.pad ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.pad ].vy << 12 , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.pad ].vy << 12, mesh->anim->cursor << 12) >> 12; - mesh->anim->cursor += 2 * mesh->anim->dir; - // Coord transformations - nclip = RotAverageNclip4( - &mesh->tmesh->v[ mesh->index[t].order.pad ], - &mesh->tmesh->v[ mesh->index[t].order.vz], - &mesh->tmesh->v[ mesh->index[t].order.vx ], - &mesh->tmesh->v[ mesh->index[t].order.vy ], - ( long* )&poly4->x0, ( long* )&poly4->x1, ( long* )&poly4->x2, ( long* )&poly4->x3, - &mesh->p, - &mesh->OTz, - Flag - ); - } else { - // No interpolation, use all vertices coordinates in anim data - nclip = RotAverageNclip4( - &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.pad ], - &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vz ], - &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vx ], - &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vy ], - ( long* )&poly4->x0, ( long* )&poly4->x1, ( long* )&poly4->x2, ( long* )&poly4->x3, - &mesh->p, - &mesh->OTz, - Flag - ); - } - } else { - // No animation - // Use regulare vertex coords + drawQuad(mesh, Flag, atime, camMode, nextpri, ot, db, draw); + } +}; +void set3VertexLerPos(MESH * mesh, long t){ + // Find and set 3 interpolated vertex value + // TODO : Finish lerp anim implementation + // Fixed point math precision + short precision = 12; + // Vertex 1 + mesh->tmesh->v[ mesh->index[ t ].order.vx ].vx = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vx].vx << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vx].vx << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vx ].vz = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vx].vz << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vx].vz << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vx ].vy = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vx].vy << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vx].vy << precision, mesh->anim->cursor << precision) >> precision; + // Vertex 2 + mesh->tmesh->v[ mesh->index[ t ].order.vz ].vx = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vz].vx << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vz].vx << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vz ].vz = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vz].vz << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vz].vz << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vz ].vy = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vz].vy << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vz].vy << precision, mesh->anim->cursor << precision) >> precision; + // Vertex 3 + mesh->tmesh->v[ mesh->index[ t ].order.vy ].vx = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vy].vx << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vy].vx << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vy ].vz = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vy].vz << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vy].vz << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vy ].vy = lerpD( mesh->anim->data[mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[t].order.vy].vy << precision , mesh->anim->data[(mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[t].order.vy].vy << precision, mesh->anim->cursor << precision) >> precision; + mesh->anim->cursor += 24 * mesh->anim->dir; +}; +void set4VertexLerPos(MESH * mesh, long t){ + // Find and set 4 interpolated vertex value + short precision = 12; + // Vertex 1 + mesh->tmesh->v[ mesh->index[ t ].order.vx ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vx ].vx << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vx ].vx << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vx ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vx ].vz << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vx ].vz << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vx ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vx ].vy << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vx ].vy << precision, mesh->anim->cursor << precision) >> precision; + // Vertex 2 + mesh->tmesh->v[ mesh->index[ t ].order.vz ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vz ].vx << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vz ].vx << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vz ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vz ].vz << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vz ].vz << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vz ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vz ].vy << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vz ].vy << precision, mesh->anim->cursor << precision) >> precision; + // Vertex 3 + mesh->tmesh->v[ mesh->index[ t ].order.vy ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vy ].vx << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vy ].vx << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vy ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vy ].vz << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vy ].vz << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.vy ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.vy ].vy << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.vy ].vy << precision, mesh->anim->cursor << precision) >> precision; + // Vertex 4 + mesh->tmesh->v[ mesh->index[ t ].order.pad ].vx = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.pad ].vx << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.pad ].vx << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.pad ].vz = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.pad ].vz << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.pad ].vz << precision, mesh->anim->cursor << precision) >> precision; + mesh->tmesh->v[ mesh->index[ t ].order.pad ].vy = lerpD( mesh->anim->data[ mesh->anim->lerpCursor * mesh->anim->nvert + mesh->index[ t ].order.pad ].vy << precision , mesh->anim->data[ (mesh->anim->lerpCursor + 1) * mesh->anim->nvert + mesh->index[ t ].order.pad ].vy << precision, mesh->anim->cursor << precision) >> precision; + mesh->anim->cursor += 2 * mesh->anim->dir; +} +long interpolateTri(POLY_GT3 * poly, MESH * mesh, long t, long * Flag){ + long nclip = 0; + // Ping pong + //~ //if (mesh->anim->cursor > 4096 || mesh->anim->cursor < 0){ + //~ // mesh->anim->dir *= -1; + //~ //} + // Find next keyframe + if (mesh->anim->cursor > (1 << 12)) { + // There are still keyframes to interpolate between + if ( mesh->anim->lerpCursor < mesh->anim->nframes - 1 ) { + mesh->anim->lerpCursor ++; + mesh->anim->cursor = 0; + } + // We've reached last frame, go back to first frame + if ( mesh->anim->lerpCursor == mesh->anim->nframes - 1 ) { + mesh->anim->lerpCursor = 0; + mesh->anim->cursor = 0; + } + } + // Find and set interpolated vertex value + set3VertexLerPos(mesh, t); + // Coord transformation from world space to screen space + nclip = RotAverageNclip3( + &mesh->tmesh->v[ mesh->index[t].order.vx ], + &mesh->tmesh->v[ mesh->index[t].order.vz ], + &mesh->tmesh->v[ mesh->index[t].order.vy ], + ( long* ) &poly->x0, ( long* ) &poly->x1, ( long* ) &poly->x2, + &mesh->p, + &mesh->OTz, + Flag + ); + return nclip; +}; +long interpolateQuad(POLY_GT4 * poly4, MESH * mesh, long t, long * Flag){ + long nclip = 0; + // ping pong + //~ if (mesh->anim->cursor > 4096 || mesh->anim->cursor < 0){ + //~ mesh->anim->dir *= -1; + //~ } + short precision = 12; + if ( mesh->anim->cursor > 1<anim->lerpCursor < mesh->anim->nframes - 1 ) { + mesh->anim->lerpCursor ++; + mesh->anim->cursor = 0; + } + if ( mesh->anim->lerpCursor == mesh->anim->nframes - 1 ) { + mesh->anim->lerpCursor = 0; + mesh->anim->cursor = 0; + } + } + // Find and set interpolated vertex value + set4VertexLerPos(mesh, t); + // Coord transformations + nclip = RotAverageNclip4( + &mesh->tmesh->v[ mesh->index[t].order.pad ], + &mesh->tmesh->v[ mesh->index[t].order.vz], + &mesh->tmesh->v[ mesh->index[t].order.vx ], + &mesh->tmesh->v[ mesh->index[t].order.vy ], + ( long* )&poly4->x0, ( long* )&poly4->x1, ( long* )&poly4->x2, ( long* )&poly4->x3, + &mesh->p, + &mesh->OTz, + Flag + ); + return nclip; +}; +void set3Prism(POLY_GT3 * poly, MESH * mesh, DRAWENV * draw, int i){ + // Transparency effect : + // Use current DRAWENV clip as TPAGE instead of regular textures + ( (POLY_GT3 *) poly )->tpage = getTPage( 2, 0, + 0, + 256 + ); + // Use projected coordinates (results from RotAverage...) as UV coords and clamp them to 0-255,0-224 -> 240 - 16 + setUV3( poly, + (poly->x0 < 0 ? 0 : poly->x0 > 255 ? 255 : poly->x0), + (poly->y0 < 0 ? 0 : poly->y0 > 224 ? 224 : poly->y0), + (poly->x1 < 0 ? 0 : poly->x1 > 255 ? 255 : poly->x1), + (poly->y1 < 0 ? 0 : poly->y1 > 224 ? 224 : poly->y1), + (poly->x2 < 0 ? 0 : poly->x2 > 255 ? 255 : poly->x2), + (poly->y2 < 0 ? 0 : poly->y2 > 224 ? 224 : poly->y2) + ); + + setRGB0(poly, mesh->tmesh->c[i].r, mesh->tmesh->c[i].g, mesh->tmesh->c[i].b); + setRGB1(poly, mesh->tmesh->c[i+2].r, mesh->tmesh->c[i+2].g, mesh->tmesh->c[i+2].b); + setRGB2(poly, mesh->tmesh->c[i+1].r, mesh->tmesh->c[i+1].g, mesh->tmesh->c[i+1].b); +}; +void set4Prism(POLY_GT4 * poly4, MESH * mesh, DRAWENV * draw, int i){ + ( (POLY_GT4 *) poly4)->tpage = getTPage( 2, 0, + 0, + 256 + ); + // Use projected coordinates + setUV4( poly4, + (poly4->x0 < 0? 0 : poly4->x0 > 255? 255 : poly4->x0), + (poly4->y0 < 0? 0 : poly4->y0 > 224? 224 : poly4->y0), + (poly4->x1 < 0? 0 : poly4->x1 > 255? 255 : poly4->x1), + (poly4->y1 < 0? 0 : poly4->y1 > 224? 224 : poly4->y1), + (poly4->x2 < 0? 0 : poly4->x2 > 255? 255 : poly4->x2), + (poly4->y2 < 0? 0 : poly4->y2 > 224? 224 : poly4->y2), + (poly4->x3 < 0? 0 : poly4->x3 > 255? 255 : poly4->x3), + (poly4->y3 < 0? 0 : poly4->y3 > 224? 224 : poly4->y3) + ); + + setRGB0(poly4, mesh->tmesh->c[i+3].r, mesh->tmesh->c[i+3].g, mesh->tmesh->c[i+3].b); + setRGB1(poly4, mesh->tmesh->c[i+2].r, mesh->tmesh->c[i+2].g, mesh->tmesh->c[i+2].b); + setRGB2(poly4, mesh->tmesh->c[i+0].r, mesh->tmesh->c[i+0].g, mesh->tmesh->c[i+0].b); + setRGB3(poly4, mesh->tmesh->c[i+1].r, mesh->tmesh->c[i+1].g, mesh->tmesh->c[i+1].b); +}; +void set3Tex(POLY_GT3 * poly, MESH * mesh, DRAWENV * draw, long t, int i){ + CVECTOR outCol = { 0,0,0,0 }; + CVECTOR outCol1 = { 0,0,0,0 }; + CVECTOR outCol2 = { 0,0,0,0 }; + // No transparency effect + // Use regular TPAGE + ( (POLY_GT3 *) poly )->tpage = getTPage(mesh->tim->mode&0x3, 0, + mesh->tim->prect->x, + mesh->tim->prect->y + ); + setUV3(poly, mesh->tmesh->u[i].vx , mesh->tmesh->u[i].vy + mesh->tim->prect->y, + mesh->tmesh->u[i+2].vx, mesh->tmesh->u[i+2].vy + mesh->tim->prect->y, + mesh->tmesh->u[i+1].vx, mesh->tmesh->u[i+1].vy + mesh->tim->prect->y); + + NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vx ], &mesh->tmesh->c[ i+0 ], mesh->p, &outCol); + NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vz ], &mesh->tmesh->c[ i+2 ], mesh->p, &outCol1); + NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vy ], &mesh->tmesh->c[ i+1 ], mesh->p, &outCol2); + setRGB0(poly, outCol.r, outCol.g , outCol.b); + setRGB1(poly, outCol1.r, outCol1.g, outCol1.b); + setRGB2(poly, outCol2.r, outCol2.g, outCol2.b); +}; +void set4Tex(POLY_GT4 * poly4, MESH * mesh, DRAWENV * draw, long t, int i){ + + CVECTOR outCol = {0,0,0,0}; + CVECTOR outCol1 = {0,0,0,0}; + CVECTOR outCol2 = {0,0,0,0}; + CVECTOR outCol3 = {0,0,0,0}; + // Use regular TPAGE + ( (POLY_GT4 *) poly4)->tpage = getTPage( + mesh->tim->mode&0x3, 0, + mesh->tim->prect->x, + mesh->tim->prect->y + ); + // Use model UV coordinates + setUV4( poly4, + mesh->tmesh->u[i+3].vx, mesh->tmesh->u[i+3].vy + mesh->tim->prect->y, + mesh->tmesh->u[i+2].vx, mesh->tmesh->u[i+2].vy + mesh->tim->prect->y, + mesh->tmesh->u[i+0].vx, mesh->tmesh->u[i+0].vy + mesh->tim->prect->y, + mesh->tmesh->u[i+1].vx, mesh->tmesh->u[i+1].vy + mesh->tim->prect->y + ); + NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.pad ] , &mesh->tmesh->c[ i+3 ], mesh->p, &outCol); + NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vz ] , &mesh->tmesh->c[ i+2 ], mesh->p, &outCol1); + NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vx ] , &mesh->tmesh->c[ i+0 ], mesh->p, &outCol2); + NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vy ] , &mesh->tmesh->c[ i+1 ], mesh->p, &outCol3); + setRGB0(poly4, outCol.r, outCol.g , outCol.b); + setRGB1(poly4, outCol1.r, outCol1.g, outCol1.b); + setRGB2(poly4, outCol2.r, outCol2.g, outCol2.b); + setRGB3(poly4, outCol3.r, outCol3.g, outCol3.b); +}; +void set4Subdiv(void){ + //(MESH * mesh, char ** nextpri, u_long * ot, long t, int i) + // FIXME : Polygon subdiv - is it working ? + // In main.c, l.141 + //~ DIVPOLYGON4 div4 = { 0 }; + //~ div4.pih = SCREENXRES; + //~ div4.piv = SCREENYRES; + //~ div4.ndiv = 2; + //~ long OTc = 0; + //~ DIVPOLYGON3 div3 = { 0 }; + //~ div3.pih = SCREENXRES; + //~ div3.piv = SCREENYRES; + //~ div3.ndiv = 1; + // + //~ long OTc = *mesh->OTz >> 4; + //~ FntPrint("OTC:%d", OTc); + //~ if (OTc < 4) { + //~ if (OTc > 1) div4.ndiv = 1; else div4.ndiv = 2; + //~ DivideGT4( + //~ // Vertex coord + //~ &mesh->tmesh->v[ mesh->index[t].order.pad ], + //~ &mesh->tmesh->v[ mesh->index[t].order.vz ], + //~ &mesh->tmesh->v[ mesh->index[t].order.vx ], + //~ &mesh->tmesh->v[ mesh->index[t].order.vy ], + //~ // UV coord + //~ mesh->tmesh->u[i+3], + //~ mesh->tmesh->u[i+2], + //~ mesh->tmesh->u[i+0], + //~ mesh->tmesh->u[i+1], + //~ // Color + //~ mesh->tmesh->c[i], + //~ mesh->tmesh->c[i+1], + //~ mesh->tmesh->c[i+2], + //~ mesh->tmesh->c[i+3], + //~ // Gpu packet + //~ poly4, + //~ &ot[db][*mesh->OTz], + //~ &div4); + //~ // Increment primitive list pointer + //~ *nextpri += ( (sizeof(POLY_GT4) + 3) / 4 ) * (( 1 << ( div4.ndiv )) << ( div4.ndiv )); + //~ triCount = ((1<<(div4.ndiv))<<(div4.ndiv)); + //~ } else if (OTc < 48) { + //~ return 0; + //~ } + +}; +void drawQuad(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw) { + long nclip, t = 0; + // If mesh is quad + POLY_GT4 * poly4; + for (int i = 0; i < (mesh->tmesh->len * 4); i += 4) { + // if mesh is not part of BG, draw them, else, discard + if ( !(mesh->isBG) || *camMode != 2 ) { + poly4 = (POLY_GT4 *)*nextpri; + + // Vertex Anim + if (mesh->isAnim){ + // with interpolation + if ( mesh->anim->interpolate ){ + interpolateQuad(poly4, mesh, t, Flag); + } else { + // No interpolation, use all vertices coordinates in anim data nclip = RotAverageNclip4( - &mesh->tmesh->v[ mesh->index[t].order.pad ], - &mesh->tmesh->v[ mesh->index[t].order.vz], - &mesh->tmesh->v[ mesh->index[t].order.vx ], - &mesh->tmesh->v[ mesh->index[t].order.vy ], - (long*)&poly4->x0, (long*)&poly4->x1, (long*)&poly4->x2, (long*)&poly4->x3, + &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.pad ], + &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vz ], + &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vx ], + &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vy ], + ( long* )&poly4->x0, ( long* )&poly4->x1, ( long* )&poly4->x2, ( long* )&poly4->x3, &mesh->p, &mesh->OTz, Flag ); } - if (nclip > 0 && mesh->OTz > 0 && (mesh->p < 4096)) { - SetPolyGT4(poly4); - // FIXME : Polygon subdiv - is it working ? - //~ OTc = *mesh->OTz >> 4; - //~ FntPrint("OTC:%d", OTc); - //~ if (OTc < 4) { - //~ if (OTc > 1) div4.ndiv = 1; else div4.ndiv = 2; - //~ DivideGT4( - //~ // Vertex coord - //~ &mesh->tmesh->v[ mesh->index[t].order.pad ], - //~ &mesh->tmesh->v[ mesh->index[t].order.vz ], - //~ &mesh->tmesh->v[ mesh->index[t].order.vx ], - //~ &mesh->tmesh->v[ mesh->index[t].order.vy ], - //~ // UV coord - //~ mesh->tmesh->u[i+3], - //~ mesh->tmesh->u[i+2], - //~ mesh->tmesh->u[i+0], - //~ mesh->tmesh->u[i+1], - //~ // Color - //~ mesh->tmesh->c[i], - //~ mesh->tmesh->c[i+1], - //~ mesh->tmesh->c[i+2], - //~ mesh->tmesh->c[i+3], - //~ // Gpu packet - //~ poly4, - //~ &ot[db][*mesh->OTz], - //~ &div4); - //~ // Increment primitive list pointer - //~ *nextpri += ( (sizeof(POLY_GT4) + 3) / 4 ) * (( 1 << ( div4.ndiv )) << ( div4.ndiv )); - //~ triCount = ((1<<(div4.ndiv))<<(div4.ndiv)); - //~ } else if (OTc < 48) { - // Transparency effect - if (mesh->isPrism){ - // Use current DRAWENV clip as TPAGE - ( (POLY_GT4 *) poly4)->tpage = getTPage(mesh->tim->mode&0x3, 0, - draw->clip.x, - draw->clip.y - ); - // Use projected coordinates - setUV4( poly4, - (poly4->x0 < 0? 0 : poly4->x0 > 255? 255 : poly4->x0), - (poly4->y0 < 0? 0 : poly4->y0 > 224? 224 : poly4->y0), - (poly4->x1 < 0? 0 : poly4->x1 > 255? 255 : poly4->x1), - (poly4->y1 < 0? 0 : poly4->y1 > 224? 224 : poly4->y1), - (poly4->x2 < 0? 0 : poly4->x2 > 255? 255 : poly4->x2), - (poly4->y2 < 0? 0 : poly4->y2 > 224? 224 : poly4->y2), - (poly4->x3 < 0? 0 : poly4->x3 > 255? 255 : poly4->x3), - (poly4->y3 < 0? 0 : poly4->y3 > 224? 224 : poly4->y3) + } else { + // No animation + // Use regular vertex coords + nclip = RotAverageNclip4( + &mesh->tmesh->v[ mesh->index[t].order.pad ], + &mesh->tmesh->v[ mesh->index[t].order.vz], + &mesh->tmesh->v[ mesh->index[t].order.vx ], + &mesh->tmesh->v[ mesh->index[t].order.vy ], + (long*)&poly4->x0, (long*)&poly4->x1, (long*)&poly4->x2, (long*)&poly4->x3, + &mesh->p, + &mesh->OTz, + Flag ); - } else { - // Use regular TPAGE - ( (POLY_GT4 *) poly4)->tpage = getTPage( - mesh->tim->mode&0x3, 0, - mesh->tim->prect->x, - mesh->tim->prect->y - ); - // Use model UV coordinates - setUV4( poly4, - mesh->tmesh->u[i+3].vx, mesh->tmesh->u[i+3].vy + mesh->tim->prect->y, - mesh->tmesh->u[i+2].vx, mesh->tmesh->u[i+2].vy + mesh->tim->prect->y, - mesh->tmesh->u[i+0].vx, mesh->tmesh->u[i+0].vy + mesh->tim->prect->y, - mesh->tmesh->u[i+1].vx, mesh->tmesh->u[i+1].vy + mesh->tim->prect->y - ); - } - if (mesh->isSprite){ - SetShadeTex( poly4, 1 ); - } - // If tim mode == 0 | 1, set CLUT coordinates - if ( (mesh->tim->mode & 0x3) < 2 ) { - setClut(poly4, - mesh->tim->crect->x, - mesh->tim->crect->y - ); - } - CVECTOR outCol = {0,0,0,0}; - CVECTOR outCol1 = {0,0,0,0}; - CVECTOR outCol2 = {0,0,0,0}; - CVECTOR outCol3 = {0,0,0,0}; - NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.pad ] , &mesh->tmesh->c[ i+3 ], mesh->p, &outCol); - NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vz ] , &mesh->tmesh->c[ i+2 ], mesh->p, &outCol1); - NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vx ] , &mesh->tmesh->c[ i+0 ], mesh->p, &outCol2); - NormalColorDpq(&mesh->tmesh->n[ mesh->index[t].order.vy ] , &mesh->tmesh->c[ i+1 ], mesh->p, &outCol3); - if (mesh->isPrism){ - setRGB0(poly4, mesh->tmesh->c[i+3].r, mesh->tmesh->c[i+3].g, mesh->tmesh->c[i+3].b); - setRGB1(poly4, mesh->tmesh->c[i+2].r, mesh->tmesh->c[i+2].g, mesh->tmesh->c[i+2].b); - setRGB2(poly4, mesh->tmesh->c[i+0].r, mesh->tmesh->c[i+0].g, mesh->tmesh->c[i+0].b); - setRGB3(poly4, mesh->tmesh->c[i+1].r, mesh->tmesh->c[i+1].g, mesh->tmesh->c[i+1].b); - } else { - setRGB0(poly4, outCol.r, outCol.g , outCol.b); - setRGB1(poly4, outCol1.r, outCol1.g, outCol1.b); - setRGB2(poly4, outCol2.r, outCol2.g, outCol2.b); - setRGB3(poly4, outCol3.r, outCol3.g, outCol3.b); - //~ setRGB0(poly4, mesh->tmesh->c[i+3].r, mesh->tmesh->c[i+3].g, mesh->tmesh->c[i+3].b); - //~ setRGB1(poly4, mesh->tmesh->c[i+2].r, mesh->tmesh->c[i+2].g, mesh->tmesh->c[i+2].b); - //~ setRGB2(poly4, mesh->tmesh->c[i+0].r, mesh->tmesh->c[i+0].g, mesh->tmesh->c[i+0].b); - //~ setRGB3(poly4, mesh->tmesh->c[i+1].r, mesh->tmesh->c[i+1].g, mesh->tmesh->c[i+1].b); - } - if ( (mesh->OTz > 0) /*&& (*mesh->OTz < OTLEN)*/ && (mesh->p < 4096) ) { - AddPrim( &ot[ mesh->OTz-3 ], poly4 ); - } - *nextpri += sizeof( POLY_GT4 ); - } - t += 1; } + if (nclip > 0 && mesh->OTz > 0 && (mesh->p < 4096)) { + SetPolyGT4(poly4); + // If tim mode == 0 | 1, set CLUT coordinates + if ( (mesh->tim->mode & 0x3) < 2 ) { + setClut(poly4, + mesh->tim->crect->x, + mesh->tim->crect->y + ); + } + if (mesh->isSprite){ + SetShadeTex( poly4, 1 ); + } + // Transparency effect + if (mesh->isPrism){ + set4Prism(poly4, mesh, draw, i); + } else { + set4Tex(poly4, mesh, draw, t, i); + } + if ( (mesh->OTz > 0) /*&& (*mesh->OTz < OTLEN)*/ && (mesh->p < 4096) ) { + AddPrim( &ot[ mesh->OTz-3 ], poly4 ); + } + *nextpri += sizeof( POLY_GT4 ); + } + t += 1; } - } + } +}; +void drawTri(MESH * mesh, long * Flag, int atime, int * camMode, char ** nextpri, u_long * ot, char * db, DRAWENV * draw) { + long nclip, t = 0; + // mesh is POLY_GT3 ( triangle ) + POLY_GT3 * poly; + // len member == # vertices, but here it's # of triangle... So, for each tri * 3 vertices ... + for ( int i = 0; i < (mesh->tmesh->len * 3); i += 3 ) { + // If mesh is not part of precalculated background, draw them, else, discard + if ( !( mesh->isBG ) || *camMode != 2) { + poly = (POLY_GT3 *)*nextpri; + // If Vertex Anim flag is set, use it + if (mesh->isAnim){ + // If interpolation flag is set, use it + if(mesh->anim->interpolate){ + nclip = interpolateTri(poly, mesh, t, Flag); + } else { + // No interpolation + // Use the pre-calculated vertices coordinates from the animation data + nclip = RotAverageNclip3( + &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vx ], + &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vz ], + &mesh->anim->data[ atime % mesh->anim->nframes * mesh->anim->nvert + mesh->index[t].order.vy ], + ( long* ) &poly->x0, ( long* ) &poly->x1, ( long* ) &poly->x2, + &mesh->p, + &mesh->OTz, + Flag + ); + } + } else { + // No animation + // Use model's regular vertex coordinates + nclip = RotAverageNclip3( + &mesh->tmesh->v[ mesh->index[t].order.vx ], + &mesh->tmesh->v[ mesh->index[t].order.vz ], + &mesh->tmesh->v[ mesh->index[t].order.vy ], + ( long * ) &poly->x0, ( long * ) &poly->x1, ( long * ) &poly->x2, + &mesh->p, + &mesh->OTz, + Flag + ); + } + // Do not draw invisible meshes + if ( nclip > 0 && mesh->OTz > 0 && (mesh->p < 4096) ) { + SetPolyGT3( poly ); + // CLUT setup + // If tim mode == 0 | 1 (4bits/8bits image), set CLUT coordinates + if ( (mesh->tim->mode & 0x3 ) < 2){ + setClut(poly, + mesh->tim->crect->x, + mesh->tim->crect->y); + } + if ( mesh->isSprite ) { + SetShadeTex( poly, 1 ); + } + // If isPrism flag is set, use it + // FIXME : Doesn't work with pre-rendered BGs + if ( mesh->isPrism ) { + set3Prism(poly, mesh, draw, i); + } else { + set3Tex(poly, mesh, draw, t, i); + } + if ( (mesh->OTz > 0) /*&& (*mesh->OTz < OTLEN)*/ && (mesh->p < 4096) ) { + AddPrim(&ot[ mesh->OTz-2 ], poly); + } + *nextpri += sizeof(POLY_GT3); + } + t+=1; + } + } }; void drawBG(CAMANGLE * camPtr, char ** nextpri, u_long * otdisc, char * db) { // Draw BG image in two SPRT since max width == 256 px