summaryrefslogtreecommitdiff
path: root/osframework/source/SexyAppFramework/SWTri_DrawTriangle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'osframework/source/SexyAppFramework/SWTri_DrawTriangle.cpp')
-rw-r--r--osframework/source/SexyAppFramework/SWTri_DrawTriangle.cpp278
1 files changed, 278 insertions, 0 deletions
diff --git a/osframework/source/SexyAppFramework/SWTri_DrawTriangle.cpp b/osframework/source/SexyAppFramework/SWTri_DrawTriangle.cpp
new file mode 100644
index 0000000..429fec3
--- /dev/null
+++ b/osframework/source/SexyAppFramework/SWTri_DrawTriangle.cpp
@@ -0,0 +1,278 @@
+// This file is included by SWTri.cpp and should not be built directly by the project.
+
+#pragma warning(disable:4101)
+
+#if (TRI0==0)
+ #define PTYPE unsigned long
+ #define PIXEL_INCLUDE "SWTri_Pixel8888.cpp"
+ #define NAME0 8888
+#elif (TRI0==1)
+ #define PTYPE unsigned long
+ #define PIXEL_INCLUDE "SWTri_Pixel888.cpp"
+ #define NAME0 0888
+#elif (TRI0==2)
+ #define PTYPE unsigned short
+ #define PIXEL_INCLUDE "SWTri_Pixel565.cpp"
+ #define NAME0 0565
+#elif (TRI0==3)
+ #define PTYPE unsigned short
+ #define PIXEL_INCLUDE "SWTri_Pixel555.cpp"
+ #define NAME0 0555
+#endif
+
+#if (TRI1==1)
+ #define TEXTURED
+ #define NAME1 TEX1
+#else
+ #define NAME1 TEX0
+#endif
+
+
+#if (TRI2==1)
+ #define TEX_ALPHA
+ #define NAME2 TALPHA1
+#else
+ #define NAME2 TALPHA0
+#endif
+
+#if (TRI3==1)
+ #define MOD_ARGB
+ #define NAME3 MOD1
+#else
+ #define NAME3 MOD0
+#endif
+
+#if (TRI4==1)
+ #define GLOBAL_ARGB
+ #define NAME4 GLOB1
+#else
+ #define NAME4 GLOB0
+#endif
+
+#if (TRI5==1)
+ #define LINEAR_BLEND
+ #define NAME5 BLEND1
+#else
+ #define NAME5 BLEND0
+#endif
+
+#define funcname2(t0,t1,t2,t3,t4,t5) DrawTriangle_##t0##_##t1##_##t2##_##t3##_##t4##_##t5
+#define funcname1(t0,t1,t2,t3,t4,t5) funcname2(t0,t1,t2,t3,t4,t5)
+#define funcname funcname1(NAME0,NAME1,NAME2,NAME3,NAME4,NAME5)
+void Sexy::funcname(SWHelper::SWVertex * pVerts, void * pFrameBuffer, const unsigned int bytepitch, const SWHelper::SWTextureInfo * textureInfo, SWHelper::SWDiffuse & globalDiffuse)
+{
+ const int pitch = bytepitch/sizeof(PTYPE);
+ const int tex_pitch = textureInfo->pitch;
+ const int tex_height = textureInfo->height;
+ const unsigned int tex_endpos = textureInfo->endpos;
+
+ const SWHelper::signed64 bigOne = static_cast<SWHelper::signed64>(1) << 48;
+ #define swap(a,b,type) {type tmp = a; a = b; b = tmp;}
+
+ const unsigned int * pTexture;
+ unsigned int vShift, uMask, vMask;
+
+ #if defined(TEXTURED)
+ {
+ pTexture = textureInfo->pTexture;
+ vShift = textureInfo->vShift;
+ vMask = textureInfo->vMask;
+ uMask = textureInfo->uMask;
+ }
+ #endif
+
+ // Sort vertices by Y component
+
+ SWHelper::SWVertex * v0 = pVerts+0;
+ SWHelper::SWVertex * v1 = pVerts+1;
+ SWHelper::SWVertex * v2 = pVerts+2;
+
+ if (v0->y > v1->y) swap(v0,v1,SWHelper::SWVertex *);
+ if (v1->y > v2->y) swap(v1,v2,SWHelper::SWVertex *);
+ if (v0->y > v1->y) swap(v0,v1,SWHelper::SWVertex *);
+
+ #if defined(MOD_ARGB) && defined(GLOBAL_ARGB)
+ {
+ v0->a = (v0->a * globalDiffuse.a) >> 8;
+ v0->r = (v0->r * globalDiffuse.r) >> 8;
+ v0->g = (v0->g * globalDiffuse.g) >> 8;
+ v0->b = (v0->b * globalDiffuse.b) >> 8;
+ v1->a = (v1->a * globalDiffuse.a) >> 8;
+ v1->r = (v1->r * globalDiffuse.r) >> 8;
+ v1->g = (v1->g * globalDiffuse.g) >> 8;
+ v1->b = (v1->b * globalDiffuse.b) >> 8;
+ v2->a = (v2->a * globalDiffuse.a) >> 8;
+ v2->r = (v2->r * globalDiffuse.r) >> 8;
+ v2->g = (v2->g * globalDiffuse.g) >> 8;
+ v2->b = (v2->b * globalDiffuse.b) >> 8;
+ }
+ #endif
+
+ // Integer Y values (using a quick form of ceil() for positive values)
+
+ int y0 = (v0->y + 0xffff) >> 16;
+ int y2 = (v2->y + 0xffff) >> 16;
+ if (y0 == y2) return; // Null polygon (no height)?
+ int y1 = (v1->y + 0xffff) >> 16;
+
+ // Calculate long-edge deltas
+
+ SWHelper::signed64 oneOverHeight = bigOne / (v2->y - v0->y);
+ int ldx, ldr, ldg, ldb, lda, ldu, ldv;
+ ldx = static_cast<int>(((v2->x - v0->x) * oneOverHeight) >> 32);
+
+ #if defined(MOD_ARGB)
+ lda = static_cast<int>(((v2->a - v0->a) * oneOverHeight) >> 32);
+ ldr = static_cast<int>(((v2->r - v0->r) * oneOverHeight) >> 32);
+ ldg = static_cast<int>(((v2->g - v0->g) * oneOverHeight) >> 32);
+ ldb = static_cast<int>(((v2->b - v0->b) * oneOverHeight) >> 32);
+ #endif
+
+ #if defined(TEXTURED)
+ ldu = static_cast<int>(((v2->u - v0->u) * oneOverHeight) >> 32);
+ ldv = static_cast<int>(((v2->v - v0->v) * oneOverHeight) >> 32);
+ #endif
+
+ // Long-edge midpoint
+
+ SWHelper::signed64 topHeight = v1->y - v0->y;
+ int mid = v0->x + static_cast<int>((topHeight * ldx)>>16);
+
+ if (v1->x == mid) return; // Null polygon (no width)?
+
+ // Edge variables (long)
+
+ SWHelper::signed64 subPix = (y0<<16) - v0->y;
+ int lx, lr, lg, lb, la, lu, lv;
+ lx = v0->x + static_cast<int>((ldx * subPix)>>16);
+
+ #if defined(MOD_ARGB)
+ la = v0->a + static_cast<int>((lda * subPix)>>16);
+ lr = v0->r + static_cast<int>((ldr * subPix)>>16);
+ lg = v0->g + static_cast<int>((ldg * subPix)>>16);
+ lb = v0->b + static_cast<int>((ldb * subPix)>>16);
+ #endif
+
+ #if defined(TEXTURED)
+ lu = v0->u + static_cast<int>((ldu * subPix)>>16);
+ lv = v0->v + static_cast<int>((ldv * subPix)>>16);
+ #endif
+
+ // Scanline deltas
+
+ SWHelper::signed64 oneOverWidth;
+ int dr, dg, db, da, du, dv;
+ #if defined(TEXTURED) || defined(MOD_ARGB)
+ oneOverWidth = bigOne / (v1->x - mid);
+ #endif
+
+ #if defined (MOD_ARGB)
+ da = static_cast<int>(((v1->a - (v0->a + ((topHeight * lda)>>16))) * oneOverWidth)>>32);
+ dr = static_cast<int>(((v1->r - (v0->r + ((topHeight * ldr)>>16))) * oneOverWidth)>>32);
+ dg = static_cast<int>(((v1->g - (v0->g + ((topHeight * ldg)>>16))) * oneOverWidth)>>32);
+ db = static_cast<int>(((v1->b - (v0->b + ((topHeight * ldb)>>16))) * oneOverWidth)>>32);
+ #endif
+
+ #if defined (TEXTURED)
+ du = static_cast<int>(((v1->u - (v0->u + ((topHeight * ldu)>>16))) * oneOverWidth)>>32);
+ dv = static_cast<int>(((v1->v - (v0->v + ((topHeight * ldv)>>16))) * oneOverWidth)>>32);
+ #endif
+
+ // Screen info
+
+ unsigned int offset = y0 * pitch;
+ PTYPE * fb = reinterpret_cast<PTYPE *>(pFrameBuffer) + offset;
+ int iHeight = y1 - y0;
+
+ if (iHeight)
+ {
+ // Short edge delta X
+
+ oneOverHeight = bigOne / topHeight;
+ int sdx = static_cast<int>(((v1->x - v0->x) * oneOverHeight) >> 32);
+
+ // Edge variables (short)
+
+ int sx = v0->x + static_cast<int>((sdx * subPix)>>16);
+
+ // Scan-convert the top half
+
+ if (mid < v1->x)
+ {
+ while(iHeight-- > 0)
+ {
+ // Integer (ceil()) left and right X components
+
+ int x0 = (lx + 0xffff) & 0xffff0000;
+ int x1 = (sx + 0xffff) & 0xffff0000;
+ #include "SWTri_Loop.cpp"
+ }
+ }
+ else if (mid > v1->x)
+ {
+ while(iHeight-- > 0)
+ {
+ // Integer (ceil()) left and right X components
+
+ int x0 = (sx + 0xffff) & 0xffff0000;
+ int x1 = (lx + 0xffff) & 0xffff0000;
+ #include "SWTri_Loop.cpp"
+ }
+ }
+ }
+
+ // Done?
+
+ iHeight = y2 - y1;
+ if (!iHeight) return;
+
+ // Short edge along bottom half
+
+ oneOverHeight = bigOne / (v2->y - v1->y);
+ int sdx = static_cast<int>(((v2->x - v1->x) * oneOverHeight) >> 32);
+
+ subPix = (y1<<16) - v1->y;
+ int sx = v1->x + static_cast<int>((sdx * subPix)>>16);
+
+ // Scan-convert the bottom half
+
+ if (mid < v1->x)
+ {
+ while(iHeight-- > 0)
+ {
+ // Integer (ceil()) left and right X components
+
+ int x0 = (lx + 0xffff) & 0xffff0000;
+ int x1 = (sx + 0xffff) & 0xffff0000;
+ #include "SWTri_Loop.cpp"
+ }
+ }
+ else if (mid > v1->x)
+ {
+ while(iHeight-- > 0)
+ {
+ // Integer (ceil()) left and right X components
+
+ int x0 = (sx + 0xffff) & 0xffff0000;
+ int x1 = (lx + 0xffff) & 0xffff0000;
+ #include "SWTri_Loop.cpp"
+ }
+ }
+}
+#undef funcname2
+#undef funcname1
+#undef funcname
+#undef PTYPE
+#undef PIXEL_INCLUDE
+#undef TEXTURED
+#undef TEX_ALPHA
+#undef MOD_ARGB
+#undef GLOBAL_ARGB
+#undef LINEAR_BLEND
+#undef NAME0
+#undef NAME1
+#undef NAME2
+#undef NAME3
+#undef NAME4
+#undef NAME5
+