diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index d7f42e8f1..4e7bc989f 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -53,7 +53,7 @@ PathInfo path; #endif #endif -//#undef EXPERIMENTAL_WIFI +#undef EXPERIMENTAL_WIFI TCommonSettings CommonSettings; static BaseDriver _stub_driver; @@ -2035,7 +2035,7 @@ static void execHardware_hstart() void NDS_Reschedule() { - DEBUG_statistics.sequencerExecutionCounters[0]++; + IF_DEVELOPER(if(!sequencer.reschedule) DEBUG_statistics.sequencerExecutionCounters[0]++;); sequencer.reschedule = true; } diff --git a/desmume/src/SPU.cpp b/desmume/src/SPU.cpp index a41070972..5c934bca6 100644 --- a/desmume/src/SPU.cpp +++ b/desmume/src/SPU.cpp @@ -1010,15 +1010,17 @@ static void SPU_MixAudio(SPU_struct *SPU, int length) ////////////////////////////////////////////////////////////////////////////// -//emulates one frame of the cpu core. +//emulates one hline of the cpu core. //this will produce a variable number of samples, calculated to keep a 44100hz output //in sync with the emulator framerate -static const double time_per_frame = (double)1.0/((double)ARM7_CLOCK/6/355); //(double)1.0/(double)59.8261; // ((double)ARM7_CLOCK/6/355/263) -static const double samples_per_frame = time_per_frame * 44100; +static const int dots_per_clock = 6; +static const int dots_per_hline = 355; +static const double time_per_hline = (double)1.0/((double)ARM7_CLOCK/dots_per_clock/dots_per_hline); +static const double samples_per_hline = time_per_hline * 44100; int spu_core_samples = 0; void SPU_Emulate_core() { - samples += samples_per_frame; + samples += samples_per_hline; spu_core_samples = (int)(samples); samples -= spu_core_samples; diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 8901e3637..efb9b5467 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -259,6 +259,7 @@ using std::max; using std::min; GFX3D gfx3d; +static GFX3D_Clipper boxtestClipper; //tables that are provided to anyone CACHE_ALIGN u32 color_15bit_to_24bit_reverse[32768]; @@ -1339,26 +1340,15 @@ void gfx3d_glViewPort(u32 v) GFX_DELAY(1); } +int boxcounter = 0; BOOL gfx3d_glBoxTest(u32 v) { -#ifdef TESTS_ENABLED MMU_new.gxstat.tr = 0; // clear boxtest bit MMU_new.gxstat.tb = 1; // busy -#else - MMU_new.gxstat.tr = 1; // HACK!!! - MMU_new.gxstat.tb = 0; -#endif BTcoords[BTind++] = float16table[v & 0xFFFF]; BTcoords[BTind++] = float16table[v >> 16]; - // 0 - X coordinate - // 1 - Y coordinate - // 2 - Z coordinate - // 3 - Width - // 4 - Height - // 5 - Depth - if (BTind < 5) return FALSE; BTind = 0; @@ -1376,76 +1366,101 @@ BOOL gfx3d_glBoxTest(u32 v) INFO("\n");*/ #endif -#ifdef TESTS_ENABLED + //(crafted to be clear, not fast.) - // 0 - X coordinate 1 - Y coordinate 2 - Z coordinate - // 3 - Width 4 - Height 5 - Depth - ALIGN(16) float boxCoords[6][4][4] = { - // near - { {BTcoords[0], BTcoords[1], BTcoords[2], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1], BTcoords[2], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1]+BTcoords[4], BTcoords[2], 1.0f}, - {BTcoords[0], BTcoords[1]+BTcoords[4], BTcoords[2], 1.0f}}, - // far - { {BTcoords[0], BTcoords[1], BTcoords[2]+BTcoords[5], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1], BTcoords[2]+BTcoords[5], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1]+BTcoords[4], BTcoords[2]+BTcoords[5], 1.0f}, - {BTcoords[0], BTcoords[1]+BTcoords[4], BTcoords[2]+BTcoords[5], 1.0f}}, - // left - { {BTcoords[0], BTcoords[1], BTcoords[2]+BTcoords[5], 1.0f}, - {BTcoords[0], BTcoords[1], BTcoords[2], 1.0f}, - {BTcoords[0], BTcoords[1]+BTcoords[4], BTcoords[2], 1.0f}, - {BTcoords[0], BTcoords[1]+BTcoords[4], BTcoords[2]+BTcoords[5], 1.0f}}, - // right - { {BTcoords[0]+BTcoords[3], BTcoords[1], BTcoords[2], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1], BTcoords[2]+BTcoords[5], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1]+BTcoords[4], BTcoords[2]+BTcoords[5], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1]+BTcoords[4], BTcoords[2], 1.0f}}, - // top - { {BTcoords[0], BTcoords[1], BTcoords[2]+BTcoords[5], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1], BTcoords[2]+BTcoords[5], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1], BTcoords[2], 1.0f}, - {BTcoords[0], BTcoords[1], BTcoords[2], 1.0f}}, - // bottom - { {BTcoords[0], BTcoords[1]+BTcoords[4], BTcoords[2]+BTcoords[5], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1]+BTcoords[4], BTcoords[2]+BTcoords[5], 1.0f}, - {BTcoords[0]+BTcoords[3], BTcoords[1]+BTcoords[4], BTcoords[2], 1.0f}, - {BTcoords[0], BTcoords[1]+BTcoords[4], BTcoords[2], 1.0f}} - }; + //there is a still a problem in here. + //nanostray title, ff4, ice age 3 work + //garfields nightmare, strawberry shortcake do not. + //but i think it is a timing issue, since + //1. shortcake can be made to flicker by tweaking btcoords + //2. the flicker can be made to go away by making dma cost todo instead of todo/4 + //the game is probably doing a box test and then dmaing an object to gxfifo, + //and then being sloppy about how long to wait before the next box test. + //(maybe bus lock would fix it) + //this doesnt seem to help garfield. garfield does seem to work better when its + //rendering is being constrained by the box test, but the box test is still failing in that game - for(int face = 0; face < 6; face++) + float x = BTcoords[0]; + float y = BTcoords[1]; + float z = BTcoords[2]; + float w = BTcoords[3]; + float h = BTcoords[4]; + float d = BTcoords[5]; + + //craft the coords by adding extents to startpoint + VERT verts[8]; + verts[0].set_coord(x,y,z,1); + verts[1].set_coord(x+w,y,z,1); + verts[2].set_coord(x+w,y+h,z,1); + verts[3].set_coord(x,y+h,z,1); + verts[4].set_coord(x,y,z+d,1); + verts[5].set_coord(x+w,y,z+d,1); + verts[6].set_coord(x+w,y+h,z+d,1); + verts[7].set_coord(x,y+h,z+d,1); + + //transform all coords + for(int i=0;i<8;i++) { + //MatrixMultVec4x4_M2(mtxCurrent[0], verts[i].coord); + + //yuck.. cant use the sse2 accelerated ones because vert.coords is not cache aligned or something + //i dunno + + void _NOSSE_MatrixMultVec4x4 (const float *matrix, float *vecPtr); + _NOSSE_MatrixMultVec4x4(mtxCurrent[1],verts[i].coord); + _NOSSE_MatrixMultVec4x4(mtxCurrent[0],verts[i].coord); + } + + //craft the faces of the box (clockwise) + POLY polys[6]; + polys[0].setVertIndexes(7,6,5,4); //near + polys[1].setVertIndexes(0,1,2,3); //far + polys[2].setVertIndexes(0,3,7,4); //left + polys[3].setVertIndexes(6,2,1,5); //right + polys[4].setVertIndexes(3,2,6,7); //top + polys[5].setVertIndexes(0,4,5,1); //bottom + + //setup the clipper + GFX3D_Clipper::TClippedPoly tempClippedPoly; + boxtestClipper.clippedPolyCounter = 0; + boxtestClipper.clippedPolys = &tempClippedPoly; + + //clip each poly + for(int i=0;i<6;i++) { - for(int vtx = 0; vtx < 4; vtx++) - { - MatrixMultVec4x4(mtxCurrent[1], boxCoords[face][vtx]); - MatrixMultVec4x4(mtxCurrent[0], boxCoords[face][vtx]); + POLY* poly = &polys[i]; + VERT* vertTable[4] = { + &verts[poly->vertIndexes[0]], + &verts[poly->vertIndexes[1]], + &verts[poly->vertIndexes[2]], + &verts[poly->vertIndexes[3]] + }; - boxCoords[face][vtx][0] = ((boxCoords[face][vtx][0] + boxCoords[face][vtx][3]) / (2.0f * boxCoords[face][vtx][3])); - boxCoords[face][vtx][1] = ((boxCoords[face][vtx][1] + boxCoords[face][vtx][3]) / (2.0f * boxCoords[face][vtx][3])); - boxCoords[face][vtx][2] = ((boxCoords[face][vtx][2] + boxCoords[face][vtx][3]) / (2.0f * boxCoords[face][vtx][3])); - - //if(face==0)INFO("box test: testing face %i, vtx %i: %f %f %f %f\n", face, vtx, - // boxCoords[face][vtx][0], boxCoords[face][vtx][1], boxCoords[face][vtx][2], boxCoords[face][vtx][3]); - - if ((boxCoords[face][vtx][0] >= 0.0f) && (boxCoords[face][vtx][0] <= 1.0f) && - (boxCoords[face][vtx][1] >= 0.0f) && (boxCoords[face][vtx][1] <= 1.0f) && - (boxCoords[face][vtx][2] >= 0.0f) && (boxCoords[face][vtx][2] <= 1.0f)) - { - MMU_new.gxstat.tr = 1; - return TRUE; - } + boxtestClipper.clipPoly(poly,vertTable); + + //if any portion of this poly was retained, then the test passes. + if(boxtestClipper.clippedPolyCounter>0) { + //printf("%06d PASS\n",boxcounter); + MMU_new.gxstat.tr = 1; + break; } } -#else - MMU_new.gxstat.tr = 1; // hack -#endif + if(MMU_new.gxstat.tr == 0) + { + //printf("%06d FAIL\n",boxcounter); + } + + //MMU_new.gxstat.tr = 1; + //MMU_new.gxstat.tr = 0; + + boxcounter++; return TRUE; } BOOL gfx3d_glPosTest(u32 v) { + printf("POSTEST\n"); #ifdef TESTS_ENABLED MMU_new.gxstat.tb = 1; #endif @@ -1470,6 +1485,7 @@ BOOL gfx3d_glPosTest(u32 v) void gfx3d_glVecTest(u32 v) { + printf("VECTEST\n"); GFX_DELAY(5); //INFO("NDS_glVecTest\n"); } @@ -1709,19 +1725,26 @@ void gfx3d_execute3D() if (isSwapBuffers) return; #endif - if(GFX_PIPErecv(&cmd, ¶m)) - { - //if (isSwapBuffers) printf("Executing while swapbuffers is pending: %d:%08X\n",cmd,param); + //this is a SPEED HACK + //fifo is currently emulated more accurately than it probably needs to be. + //without this batch size the emuloop will escape way too often to run fast. + const int HACK_FIFO_BATCH_SIZE = 32; - //since we did anything at all, incur a pipeline motion cost. - //also, we can't let gxfifo sequencer stall until the fifo is empty. - //see... - GFX_DELAY(1); + for(int i=0;i +static T interpolate(const float ratio, const T& x0, const T& x1) { + return (T)(x0 + (float)(x1-x0) * (ratio)); +} + + +//http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/as6/discussion.shtml +static FORCEINLINE VERT clipPoint(VERT* inside, VERT* outside, int coord, int which) +{ + VERT ret; + + float coord_inside = inside->coord[coord]; + float coord_outside = outside->coord[coord]; + float w_inside = inside->coord[3]; + float w_outside = outside->coord[3]; + + float t; + + if(which==-1) { + w_outside = -w_outside; + w_inside = -w_inside; + } + + t = (coord_inside - w_inside)/ ((w_outside-w_inside) - (coord_outside-coord_inside)); + + +#define INTERP(X) ret . X = interpolate(t, inside-> X ,outside-> X ) + + INTERP(coord[0]); INTERP(coord[1]); INTERP(coord[2]); INTERP(coord[3]); + INTERP(texcoord[0]); INTERP(texcoord[1]); + + if(CommonSettings.HighResolutionInterpolateColor) + { + INTERP(fcolor[0]); INTERP(fcolor[1]); INTERP(fcolor[2]); + } + else + { + INTERP(color[0]); INTERP(color[1]); INTERP(color[2]); + ret.color_to_float(); + } + + //this seems like a prudent measure to make sure that math doesnt make a point pop back out + //of the clip volume through interpolation + if(which==-1) + ret.coord[coord] = -ret.coord[3]; + else + ret.coord[coord] = ret.coord[3]; + + return ret; +} + +FORCEINLINE void GFX3D_Clipper::clipSegmentVsPlane(VERT** verts, const int coord, int which) +{ + bool out0, out1; + if(which==-1) + out0 = verts[0]->coord[coord] < -verts[0]->coord[3]; + else + out0 = verts[0]->coord[coord] > verts[0]->coord[3]; + if(which==-1) + out1 = verts[1]->coord[coord] < -verts[1]->coord[3]; + else + out1 = verts[1]->coord[coord] > verts[1]->coord[3]; + + //CONSIDER: should we try and clip things behind the eye? does this code even successfully do it? not sure. + //if(coord==2 && which==1) { + // out0 = verts[0]->coord[2] < 0; + // out1 = verts[1]->coord[2] < 0; + //} + + //both outside: insert no points + if(out0 && out1) { + CLIPLOG(" both outside\n"); + } + + //both inside: insert the first point + if(!out0 && !out1) + { + CLIPLOG(" both inside\n"); + outClippedPoly.clipVerts[outClippedPoly.type++] = *verts[1]; + } + + //exiting volume: insert the clipped point and the first (interior) point + if(!out0 && out1) + { + CLIPLOG(" exiting\n"); + outClippedPoly.clipVerts[outClippedPoly.type++] = clipPoint(verts[0],verts[1], coord, which); + } + + //entering volume: insert clipped point + if(out0 && !out1) { + CLIPLOG(" entering\n"); + outClippedPoly.clipVerts[outClippedPoly.type++] = clipPoint(verts[1],verts[0], coord, which); + outClippedPoly.clipVerts[outClippedPoly.type++] = *verts[1]; + + } +} + +FORCEINLINE void GFX3D_Clipper::clipPolyVsPlane(const int coord, int which) +{ + outClippedPoly.type = 0; + CLIPLOG2("Clipping coord %d against %f\n",coord,x); + for(int i=0;itype; + + CLIPLOG("==Begin poly==\n"); + + tempClippedPoly.clipVerts[0] = *verts[0]; + tempClippedPoly.clipVerts[1] = *verts[1]; + tempClippedPoly.clipVerts[2] = *verts[2]; + if(type==4) + tempClippedPoly.clipVerts[3] = *verts[3]; + + + tempClippedPoly.type = type; + + clipPolyVsPlane(0, -1); + clipPolyVsPlane(0, 1); + clipPolyVsPlane(1, -1); + clipPolyVsPlane(1, 1); + clipPolyVsPlane(2, -1); + clipPolyVsPlane(2, 1); + //TODO - we need to parameterize back plane clipping + + + if(tempClippedPoly.type < 3) + { + //a totally clipped poly. discard it. + //or, a degenerate poly. we're not handling these right now + } + else + { + //TODO - build right in this list instead of copying + clippedPolys[clippedPolyCounter] = tempClippedPoly; + clippedPolys[clippedPolyCounter].poly = poly; + clippedPolyCounter++; + } + +} \ No newline at end of file diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index 4264d0872..e10491283 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -142,6 +142,15 @@ struct POLY { u32 viewport; float miny, maxy; + void setVertIndexes(int a, int b, int c, int d=-1) + { + vertIndexes[0] = a; + vertIndexes[1] = b; + vertIndexes[2] = c; + if(d != -1) { vertIndexes[3] = d; type = 4; } + else type = 3; + } + bool isTranslucent() { //alpha != 31 -> translucent @@ -200,6 +209,18 @@ struct VERT { float u,v; }; }; + void set_coord(float x, float y, float z, float w) { + this->x = x; + this->y = y; + this->z = z; + this->w = w; + } + void set_coord(float* coords) { + x = coords[0]; + y = coords[1]; + z = coords[2]; + w = coords[3]; + } u8 color[3]; float fcolor[3]; void color_to_float() { @@ -236,6 +257,36 @@ struct VIEWPORT { void decode(u32 v); }; +//The worst case we've managed to think of so far would be a viewport zoomed in a little bit +//on a diamond, with cut-out bits in all four corners +#define MAX_CLIPPED_VERTS 8 + +class GFX3D_Clipper +{ +public: + + struct TClippedPoly + { + int type; //otherwise known as "count" of verts + POLY* poly; + VERT clipVerts[MAX_CLIPPED_VERTS]; + }; + + //the entry point for poly clipping + void clipPoly(POLY* poly, VERT** verts); + + //the output of clipping operations goes into here. + //be sure you init it before clipping! + TClippedPoly *clippedPolys; + int clippedPolyCounter; + +private: + TClippedPoly tempClippedPoly; + TClippedPoly outClippedPoly; + FORCEINLINE void clipSegmentVsPlane(VERT** verts, const int coord, int which); + FORCEINLINE void clipPolyVsPlane(const int coord, int which); +}; + //used to communicate state to the renderer struct GFX3D { diff --git a/desmume/src/matrix.cpp b/desmume/src/matrix.cpp index d2eff5a43..7491c6ab1 100644 --- a/desmume/src/matrix.cpp +++ b/desmume/src/matrix.cpp @@ -25,10 +25,7 @@ #include #include "matrix.h" -//------------------------- -//switched SSE functions: implementations for no SSE -#ifndef ENABLE_SSE -void MatrixMultVec4x4 (const float *matrix, float *vecPtr) +void _NOSSE_MatrixMultVec4x4 (const float *matrix, float *vecPtr) { float x = vecPtr[0]; float y = vecPtr[1]; @@ -42,6 +39,15 @@ void MatrixMultVec4x4 (const float *matrix, float *vecPtr) } +//------------------------- +//switched SSE functions: implementations for no SSE +#ifndef ENABLE_SSE +void MatrixMultVec4x4 (const float *matrix, float *vecPtr) +{ + _NOSSE_MatrixMultVec4x4(matrix, vecPtr); +} + + void MatrixMultVec3x3 (const float *matrix, float *vecPtr) { float x = vecPtr[0]; diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index 0108aec83..63f6174dc 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -26,9 +26,6 @@ //the shape rasterizers contained herein are based on code supplied by Chris Hecker from //http://chrishecker.com/Miscellaneous_Technical_Articles -//The worst case we've managed to think of so far would be a viewport zoomed in a little bit -//on a diamond, with cut-out bits in all four corners -#define MAX_CLIPPED_VERTS 8 //TODO - due to a late change of a y-coord flipping, our winding order is wrong //this causes us to have to flip the verts for every front-facing poly. @@ -73,16 +70,11 @@ static u8 decal_table[32][64][64]; static u8 index_lookup_table[65]; static u8 index_start_table[8]; -static struct TClippedPoly -{ - int type; - POLY* poly; - VERT clipVerts[MAX_CLIPPED_VERTS]; -} *clippedPolys = NULL; +static GFX3D_Clipper clipper; +static GFX3D_Clipper::TClippedPoly *clippedPolys = NULL; static int clippedPolyCounter; -TClippedPoly tempClippedPoly; -TClippedPoly outClippedPoly; + ////optimized float floor useful in limited cases ////from http://www.stereopsis.com/FPU.html#convert @@ -252,10 +244,10 @@ struct Fragment static VERT* verts[MAX_CLIPPED_VERTS]; -INLINE static void SubmitVertex(int vert_index, VERT& rawvert) -{ - verts[vert_index] = &rawvert; -} +//INLINE static void SubmitVertex(int vert_index, VERT& rawvert) +//{ +// verts[vert_index] = &rawvert; +//} static Fragment screen[256*192]; static FragmentColor screenColor[256*192]; @@ -922,7 +914,7 @@ static char SoftRastInit(void) { tables_generated = true; - clippedPolys = new TClippedPoly[POLYLIST_SIZE*2]; + clipper.clippedPolys = clippedPolys = new GFX3D_Clipper::TClippedPoly[POLYLIST_SIZE*2]; for(int i=0;i<64;i++) { @@ -1079,167 +1071,6 @@ static void SoftRastConvertFramebuffer() } -template -static T interpolate(const float ratio, const T& x0, const T& x1) { - return (T)(x0 + (float)(x1-x0) * (ratio)); -} - - -//http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/as6/discussion.shtml -static FORCEINLINE VERT clipPoint(VERT* inside, VERT* outside, int coord, int which) -{ - VERT ret; - - float coord_inside = inside->coord[coord]; - float coord_outside = outside->coord[coord]; - float w_inside = inside->coord[3]; - float w_outside = outside->coord[3]; - - float t; - - if(which==-1) { - w_outside = -w_outside; - w_inside = -w_inside; - } - - t = (coord_inside - w_inside)/ ((w_outside-w_inside) - (coord_outside-coord_inside)); - - -#define INTERP(X) ret . X = interpolate(t, inside-> X ,outside-> X ) - - INTERP(coord[0]); INTERP(coord[1]); INTERP(coord[2]); INTERP(coord[3]); - INTERP(texcoord[0]); INTERP(texcoord[1]); - - if(CommonSettings.HighResolutionInterpolateColor) - { - INTERP(fcolor[0]); INTERP(fcolor[1]); INTERP(fcolor[2]); - } - else - { - INTERP(color[0]); INTERP(color[1]); INTERP(color[2]); - ret.color_to_float(); - } - - //this seems like a prudent measure to make sure that math doesnt make a point pop back out - //of the clip volume through interpolation - if(which==-1) - ret.coord[coord] = -ret.coord[3]; - else - ret.coord[coord] = ret.coord[3]; - - return ret; -} - -//#define CLIPLOG(X) printf(X); -//#define CLIPLOG2(X,Y,Z) printf(X,Y,Z); -#define CLIPLOG(X) -#define CLIPLOG2(X,Y,Z) - -static FORCEINLINE void clipSegmentVsPlane(VERT** verts, const int coord, int which) -{ - bool out0, out1; - if(which==-1) - out0 = verts[0]->coord[coord] < -verts[0]->coord[3]; - else - out0 = verts[0]->coord[coord] > verts[0]->coord[3]; - if(which==-1) - out1 = verts[1]->coord[coord] < -verts[1]->coord[3]; - else - out1 = verts[1]->coord[coord] > verts[1]->coord[3]; - - //CONSIDER: should we try and clip things behind the eye? does this code even successfully do it? not sure. - //if(coord==2 && which==1) { - // out0 = verts[0]->coord[2] < 0; - // out1 = verts[1]->coord[2] < 0; - //} - - //both outside: insert no points - if(out0 && out1) { - CLIPLOG(" both outside\n"); - } - - //both inside: insert the first point - if(!out0 && !out1) - { - CLIPLOG(" both inside\n"); - outClippedPoly.clipVerts[outClippedPoly.type++] = *verts[1]; - } - - //exiting volume: insert the clipped point and the first (interior) point - if(!out0 && out1) - { - CLIPLOG(" exiting\n"); - outClippedPoly.clipVerts[outClippedPoly.type++] = clipPoint(verts[0],verts[1], coord, which); - } - - //entering volume: insert clipped point - if(out0 && !out1) { - CLIPLOG(" entering\n"); - outClippedPoly.clipVerts[outClippedPoly.type++] = clipPoint(verts[1],verts[0], coord, which); - outClippedPoly.clipVerts[outClippedPoly.type++] = *verts[1]; - - } -} - -static FORCEINLINE void clipPolyVsPlane(const int coord, int which) -{ - outClippedPoly.type = 0; - CLIPLOG2("Clipping coord %d against %f\n",coord,x); - for(int i=0;itype; - - CLIPLOG("==Begin poly==\n"); - - tempClippedPoly.clipVerts[0] = gfx3d.vertlist->list[poly->vertIndexes[0]]; - tempClippedPoly.clipVerts[1] = gfx3d.vertlist->list[poly->vertIndexes[1]]; - tempClippedPoly.clipVerts[2] = gfx3d.vertlist->list[poly->vertIndexes[2]]; - if(type==4) - tempClippedPoly.clipVerts[3] = gfx3d.vertlist->list[poly->vertIndexes[3]]; - - - tempClippedPoly.type = type; - - clipPolyVsPlane(0, -1); - clipPolyVsPlane(0, 1); - clipPolyVsPlane(1, -1); - clipPolyVsPlane(1, 1); - clipPolyVsPlane(2, -1); - clipPolyVsPlane(2, 1); - //TODO - we need to parameterize back plane clipping - - - if(tempClippedPoly.type < 3) - { - //a totally clipped poly. discard it. - //or, a degenerate poly. we're not handling these right now - } - else - { - //TODO - build right in this list instead of copying - clippedPolys[clippedPolyCounter] = tempClippedPoly; - clippedPolys[clippedPolyCounter].poly = poly; - clippedPolyCounter++; - } - -} static void SoftRastRender() { @@ -1367,11 +1198,23 @@ static void SoftRastRender() gfx3d.vertlist->list[i].color_to_float(); //submit all polys to clipper - clippedPolyCounter = 0; + clipper.clippedPolyCounter = 0; for(int i=0;icount;i++) { - clipPoly(&gfx3d.polylist->list[gfx3d.indexlist[i]]); + POLY* poly = &gfx3d.polylist->list[gfx3d.indexlist[i]]; + VERT* clipVerts[4] = { + &gfx3d.vertlist->list[poly->vertIndexes[0]], + &gfx3d.vertlist->list[poly->vertIndexes[1]], + &gfx3d.vertlist->list[poly->vertIndexes[2]], + poly->type==4 + ?&gfx3d.vertlist->list[poly->vertIndexes[3]] + :NULL + }; + + clipper.clipPoly(poly,clipVerts); + } + clippedPolyCounter = clipper.clippedPolyCounter; //printf("%d %d %d %d\n",gfx3d.viewport.x,gfx3d.viewport.y,gfx3d.viewport.width,gfx3d.viewport.height); // printf("%f\n",vert.coord[0]); @@ -1379,7 +1222,7 @@ static void SoftRastRender() //viewport transforms for(int i=0;i