]> git.wh0rd.org - ICEs.git/blobdiff - 394889/s_triangle.i.10
more
[ICEs.git] / 394889 / s_triangle.i.10
diff --git a/394889/s_triangle.i.10 b/394889/s_triangle.i.10
new file mode 100644 (file)
index 0000000..17db87e
--- /dev/null
@@ -0,0 +1,214 @@
+typedef union {
+       float f;
+       int i;
+} fi_type;
+static __inline__ int IS_INF_OR_NAN(float x)
+{
+       fi_type tmp;
+       tmp.f = x;
+       return !(int)((unsigned int)((tmp.i & 0x7fffffff) - 0x7f800000) >> 31);
+}
+
+struct gl_texture_image {
+       unsigned int Width;
+       unsigned int Height;
+       unsigned int WidthLog2;
+       void *Data;
+};
+struct gl_texture_object {
+       int BaseLevel;
+       struct gl_texture_image *Image[6][15];
+};
+struct gl_texture_unit {
+       struct gl_texture_object *CurrentTex[9];
+};
+struct gl_texture_attrib {
+       struct gl_texture_unit Unit[(16 + 16)];
+};
+struct gl_renderbuffer {
+       void (*PutRowRGB) (struct gl_context * ctx, struct gl_renderbuffer * rb,
+                          unsigned int count, int x, int y,
+                          const void *values);
+};
+struct gl_framebuffer {
+       struct gl_renderbuffer *_ColorDrawBuffers[8];
+};
+struct gl_context {
+       struct gl_framebuffer *DrawBuffer;
+       struct gl_texture_attrib Texture;
+};
+typedef struct {
+       float attrib[30][4];
+} SWvertex;
+typedef struct sw_span {
+       int x, y;
+       unsigned int end;
+       float attrStepX[30][4];
+       int intTex[2], intTexStep[2];
+} SWspan;
+static void simple_textured_triangle(const SWvertex * v1)
+{
+       struct gl_context *ctx;
+                                    const SWvertex * v0;
+                                    const SWvertex * v2;
+       typedef struct {
+               float dx;
+               float dy;
+               int fsx;
+               int fx0;
+               int lines;
+       } EdgeT;
+       EdgeT eMaj;
+       EdgeT eTop;
+       EdgeT eBot;
+       float oneOverArea;
+       const SWvertex *vMin;
+       const SWvertex *vMid;
+       const SWvertex *vMax;
+       const int snapMask = ~(((1 << 11) / (1 << 4)) - 1);
+       int vMin_fx;
+       int vMin_fy;
+       int vMid_fx;
+       int vMid_fy;
+       int vMax_fx;
+       int vMax_fy;
+       SWspan span;
+       const int fy0 =
+           (((int)
+             ((((v0->attrib[0][1] -
+                 0.5F) * ((float)(1 << 11))) >=
+               0.0F) ? (((v0->attrib[0][1] - 0.5F) *
+                         ((float)(1 << 11))) +
+                        0.5F) : (((v0->attrib[0][1] - 0.5F) *
+                                  ((float)(1 << 11))) - 0.5F)))) & snapMask;
+       const int fy1 =
+           (((int)
+             ((((v1->attrib[0][1] -
+                 0.5F) * ((float)(1 << 11))) >=
+               0.0F) ? (((v1->attrib[0][1] - 0.5F) *
+                         ((float)(1 << 11))) +
+                        0.5F) : (((v1->attrib[0][1] - 0.5F) *
+                                  ((float)(1 << 11))) - 0.5F)))) & snapMask;
+       const int fy2 =
+           (((int)
+             ((((v2->attrib[0][1] -
+                 0.5F) * ((float)(1 << 11))) >=
+               0.0F) ? (((v2->attrib[0][1] - 0.5F) *
+                         ((float)(1 << 11))) +
+                        0.5F) : (((v2->attrib[0][1] - 0.5F) *
+                                  ((float)(1 << 11))) - 0.5F)))) & snapMask;
+       if (fy0 <= fy1) {
+               if (fy1 <= fy2) {
+                       vMin = v0;
+                       vMax = v1;
+                       vMin_fy = fy0;
+               }
+       }
+       vMin_fx =
+           (((int)
+             ((((vMin->attrib[0][0] +
+                 0.5F) * ((float)(1 << 11))) >=
+               0.0F) ? (((vMin->attrib[0][0] + 0.5F) *
+                         ((float)(1 << 11))) +
+                        0.5F) : (((vMin->attrib[0][0] + 0.5F) *
+                                  ((float)(1 << 11))) - 0.5F)))) & snapMask;
+       vMid_fx =
+           (((int)
+             ((((vMid->attrib[0][0] +
+                 0.5F) * ((float)(1 << 11))) >=
+               0.0F) ? (((vMid->attrib[0][0] + 0.5F) *
+                         ((float)(1 << 11))) +
+                        0.5F) : (((vMid->attrib[0][0] + 0.5F) *
+                                  ((float)(1 << 11))) - 0.5F)))) & snapMask;
+       eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / ((float)(1 << 11))));
+       eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / ((float)(1 << 11))));
+       eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / ((float)(1 << 11))));
+       eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / ((float)(1 << 11))));
+       const float area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
+       if (IS_INF_OR_NAN(area) || area == 0.0F)
+               return;
+       oneOverArea = 1.0F / area;
+       if (eBot.lines > 0) {
+               eBot.fx0 = vMin_fx;
+       }
+       int scan_from_left_to_right;
+       struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
+       const struct gl_texture_object *obj =
+           ctx->Texture.Unit[0].CurrentTex[8];
+       const struct gl_texture_image *texImg = obj->Image[0][obj->BaseLevel];
+       const float twidth = (float)texImg->Width;
+       const int twidth_log2 = texImg->WidthLog2;
+       const unsigned char *texture = (const unsigned char *)texImg->Data;
+       const int smask = texImg->Width - 1;
+       const int tmask = texImg->Height - 1;
+       if (!rb || !texture) {
+               return;
+       }
+       float eMaj_ds =
+           (vMax->attrib[4][0] -
+            vMin->attrib[4][0]) * twidth;
+       float eBot_ds =
+           (vMid->attrib[4][0] -
+            vMin->attrib[4][0]) * twidth;
+       span.attrStepX[4][0] =
+           oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
+       span.intTexStep[0] =
+           (((int)
+             ((((span.attrStepX[4][0]) * ((float)(1 << 11))) >=
+               0.0F) ? (((span.attrStepX[4][0]) *
+                         ((float)(1 << 11))) +
+                        0.5F) : (((span.attrStepX[4][0]) *
+                                  ((float)(1 << 11))) - 0.5F))));
+       int subTriangle;
+       int fxLeftEdge = 0;
+       int fxRightEdge = 0;
+       int sLeft = 0;
+       for (subTriangle = 0; subTriangle <= 1; subTriangle++) {
+               EdgeT *eRight;
+               int lines;
+               if (subTriangle == 0) {
+                       if (scan_from_left_to_right) {
+                               eRight = &eBot;
+                               lines = eRight->lines;
+                       } 
+else {
+                               eRight = &eMaj;
+                       }
+               } else {
+                       if (scan_from_left_to_right) 
+{
+                               eRight = &eTop;
+                       }
+                       fxRightEdge = eRight->fsx - 1;
+               }
+               while (lines > 0) {
+                       const int right = fxRightEdge >> 11;
+                       span.x = fxLeftEdge >> 11;
+                       if (right <= span.x)
+                               span.end = 0;
+                       else
+                               span.end = right - span.x;
+                       span.intTex[0] = sLeft;
+                       if (span.end > 0 && span.y >= 0) {
+                               unsigned int i;
+                               unsigned char rgb[16384][3];
+                               for (i = 0; i < span.end; i++) {
+                                       int s =
+                                           ((span.intTex[0]) >> 11) & smask;
+                                       int t =
+                                           ((span.intTex[1]) >> 11) & tmask;
+                                       int pos = (t << twidth_log2) + s;
+                                       rgb[i][0] = texture[pos + 2];
+                                       span.intTex[0] += span.intTexStep[0];
+                               }
+                               rb->PutRowRGB(ctx, rb, span.end, span.x, span.y,
+                                             rgb);
+                       }
+               }
+       }
+}
+
+void *foo()
+{
+       return simple_textured_triangle;
+}