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 = ~127; 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)2048) >= 0.0F) ? (((v0->attrib[0][1] - 0.5F) * (float)2048) + 0.5F) : (((v0->attrib[0][1] - 0.5F) * (float)2048) - 0.5F)))) & snapMask; const int fy1 = (((int) ((((v1->attrib[0][1] - 0.5F) * (float)2048) >= 0.0F) ? (((v1->attrib[0][1] - 0.5F) * (float)2048) + 0.5F) : (((v1->attrib[0][1] - 0.5F) * (float)2048) - 0.5F)))) & snapMask; const int fy2 = (((int) ((((v2->attrib[0][1] - 0.5F) * (float)2048) >= 0.0F) ? (((v2->attrib[0][1] - 0.5F) * (float)2048) + 0.5F) : (((v2->attrib[0][1] - 0.5F) * (float)2048) - 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)2048) >= 0.0F) ? (((vMin->attrib[0][0] + 0.5F) * (float)2048) + 0.5F) : (((vMin->attrib[0][0] + 0.5F) * (float)2048) - 0.5F)))) & snapMask; vMid_fx = (((int) ((((vMid->attrib[0][0] + 0.5F) * (float)2048) >= 0.0F) ? (((vMid->attrib[0][0] + 0.5F) * (float)2048) + 0.5F) : (((vMid->attrib[0][0] + 0.5F) * (float)2048) - 0.5F)))) & snapMask; eMaj.dx = ((vMax_fx - vMin_fx) * (1.0F / (float)2048)); eMaj.dy = ((vMax_fy - vMin_fy) * (1.0F / (float)2048)); eTop.dx = ((vMax_fx - vMid_fx) * (1.0F / (float)2048)); eBot.dy = ((vMid_fy - vMin_fy) * (1.0F / (float)2048)); 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)2048) >= 0.0F) ? (((span.attrStepX[4][0]) * (float)2048) + 0.5F) : (((span.attrStepX[4][0]) * (float)2048) - 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; }