+ int c[4], localcolor[4];
+ localcolor[2] = (int)(subcolor[0] * 255.0f);
+ localcolor[1] = (int)(subcolor[1] * 255.0f);
+ localcolor[0] = (int)(subcolor[2] * 255.0f);
+ localcolor[3] = (int)(subcolor[3] * 255.0f);
+ for (x = startx;x < endx;x++)
+ {
+ c[0] = inb4ub[x*4+0] - localcolor[0];if (c[0] < 0) c[0] = 0;
+ c[1] = inb4ub[x*4+1] - localcolor[1];if (c[1] < 0) c[1] = 0;
+ c[2] = inb4ub[x*4+2] - localcolor[2];if (c[2] < 0) c[2] = 0;
+ c[3] = inb4ub[x*4+3] - localcolor[3];if (c[3] < 0) c[3] = 0;
+ c[0] += ina4ub[x*4+0];if (c[0] > 255) c[0] = 255;
+ c[1] += ina4ub[x*4+1];if (c[1] > 255) c[1] = 255;
+ c[2] += ina4ub[x*4+2];if (c[2] > 255) c[2] = 255;
+ c[3] += ina4ub[x*4+3];if (c[3] > 255) c[3] = 255;
+ out4ub[x*4+0] = c[0];
+ out4ub[x*4+1] = c[1];
+ out4ub[x*4+2] = c[2];
+ out4ub[x*4+3] = c[3];
+ }
+}
+
+void DPSOFTRAST_Draw_Span_MultiplyBuffersBGRA8(const DPSOFTRAST_State_Draw_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub)
+{
+ int x, startx = span->startx, endx = span->endx;
+ for (x = startx;x < endx;x++)
+ {
+ out4ub[x*4+0] = (ina4ub[x*4+0] * inb4ub[x*4+0])>>8;
+ out4ub[x*4+1] = (ina4ub[x*4+1] * inb4ub[x*4+1])>>8;
+ out4ub[x*4+2] = (ina4ub[x*4+2] * inb4ub[x*4+2])>>8;
+ out4ub[x*4+3] = (ina4ub[x*4+3] * inb4ub[x*4+3])>>8;
+ }
+}
+
+void DPSOFTRAST_Draw_Span_AddBuffersBGRA8(const DPSOFTRAST_State_Draw_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub)
+{
+ int x, startx = span->startx, endx = span->endx;
+ int d[4];
+ for (x = startx;x < endx;x++)
+ {
+ d[0] = ina4ub[x*4+0] + inb4ub[x*4+0];if (d[0] > 255) d[0] = 255;
+ d[1] = ina4ub[x*4+1] + inb4ub[x*4+1];if (d[1] > 255) d[1] = 255;
+ d[2] = ina4ub[x*4+2] + inb4ub[x*4+2];if (d[2] > 255) d[2] = 255;
+ d[3] = ina4ub[x*4+3] + inb4ub[x*4+3];if (d[3] > 255) d[3] = 255;
+ out4ub[x*4+0] = d[0];
+ out4ub[x*4+1] = d[1];
+ out4ub[x*4+2] = d[2];
+ out4ub[x*4+3] = d[3];
+ }
+}
+
+void DPSOFTRAST_Draw_Span_MixBuffersBGRA8(const DPSOFTRAST_State_Draw_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *ina4ub, const unsigned char *inb4ub)
+{
+ int x, startx = span->startx, endx = span->endx;
+ int a, b;
+ for (x = startx;x < endx;x++)
+ {
+ a = 256 - inb4ub[x*4+3];
+ b = inb4ub[x*4+3];
+ out4ub[x*4+0] = (ina4ub[x*4+0] * a + inb4ub[x*4+0] * b)>>8;
+ out4ub[x*4+1] = (ina4ub[x*4+1] * a + inb4ub[x*4+1] * b)>>8;
+ out4ub[x*4+2] = (ina4ub[x*4+2] * a + inb4ub[x*4+2] * b)>>8;
+ out4ub[x*4+3] = (ina4ub[x*4+3] * a + inb4ub[x*4+3] * b)>>8;
+ }
+}
+
+void DPSOFTRAST_Draw_Span_MixUniformColorBGRA8(const DPSOFTRAST_State_Draw_Span * RESTRICT span, unsigned char *out4ub, const unsigned char *in4ub, const float *color)
+{
+ int x, startx = span->startx, endx = span->endx;
+ int localcolor[4], ilerp, lerp;
+ localcolor[2] = (int)(color[0]*255.0f);
+ localcolor[1] = (int)(color[1]*255.0f);
+ localcolor[0] = (int)(color[2]*255.0f);
+ localcolor[3] = (int)(color[3]*255.0f);
+ ilerp = 256 - localcolor[3];
+ lerp = localcolor[3];
+ for (x = startx;x < endx;x++)
+ {
+ out4ub[x*4+0] = (in4ub[x*4+0] * ilerp + localcolor[0] * lerp)>>8;
+ out4ub[x*4+1] = (in4ub[x*4+1] * ilerp + localcolor[1] * lerp)>>8;
+ out4ub[x*4+2] = (in4ub[x*4+2] * ilerp + localcolor[2] * lerp)>>8;
+ out4ub[x*4+3] = (in4ub[x*4+3] * ilerp + localcolor[3] * lerp)>>8;
+ }
+}
+
+
+
+extern int dpsoftrast_test;
+
+void DPSOFTRAST_VertexShader_Generic(void)
+{
+ DPSOFTRAST_Array_Transform(dpsoftrast.draw.post_array4f[DPSOFTRAST_ARRAY_POSITION], dpsoftrast.draw.in_array4f[DPSOFTRAST_ARRAY_POSITION], dpsoftrast.draw.numvertices, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
+ DPSOFTRAST_Array_Copy(dpsoftrast.draw.post_array4f[DPSOFTRAST_ARRAY_COLOR], dpsoftrast.draw.in_array4f[DPSOFTRAST_ARRAY_COLOR], dpsoftrast.draw.numvertices);
+ DPSOFTRAST_Array_Copy(dpsoftrast.draw.post_array4f[DPSOFTRAST_ARRAY_TEXCOORD0], dpsoftrast.draw.in_array4f[DPSOFTRAST_ARRAY_TEXCOORD0], dpsoftrast.draw.numvertices);
+ if (dpsoftrast.shader_permutation & SHADERPERMUTATION_SPECULAR)
+ DPSOFTRAST_Array_Copy(dpsoftrast.draw.post_array4f[DPSOFTRAST_ARRAY_TEXCOORD1], dpsoftrast.draw.in_array4f[DPSOFTRAST_ARRAY_TEXCOORD1], dpsoftrast.draw.numvertices);
+}
+
+void DPSOFTRAST_PixelShader_Generic(const DPSOFTRAST_State_Draw_Span * RESTRICT span)
+{
+ float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
+ unsigned char buffer_texture_colorbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
+ unsigned char buffer_texture_lightmapbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
+ unsigned char buffer_FragColorbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
+ DPSOFTRAST_Draw_Span_Begin(span, buffer_z);
+ if (dpsoftrast.shader_permutation & SHADERPERMUTATION_DIFFUSE)
+ {
+ DPSOFTRAST_Draw_Span_Texture2DVaryingBGRA8(span, buffer_texture_colorbgra8, GL20TU_FIRST, 2, buffer_z);
+ DPSOFTRAST_Draw_Span_MultiplyVaryingBGRA8(span, buffer_FragColorbgra8, buffer_texture_colorbgra8, 1, buffer_z);
+ if (dpsoftrast.shader_permutation & SHADERPERMUTATION_SPECULAR)
+ {
+ DPSOFTRAST_Draw_Span_Texture2DVaryingBGRA8(span, buffer_texture_lightmapbgra8, GL20TU_SECOND, 2, buffer_z);
+ if (dpsoftrast.shader_permutation & SHADERPERMUTATION_COLORMAPPING)
+ {
+ // multiply
+ DPSOFTRAST_Draw_Span_MultiplyBuffersBGRA8(span, buffer_FragColorbgra8, buffer_FragColorbgra8, buffer_texture_lightmapbgra8);
+ }
+ else if (dpsoftrast.shader_permutation & SHADERPERMUTATION_COLORMAPPING)
+ {
+ // add
+ DPSOFTRAST_Draw_Span_AddBuffersBGRA8(span, buffer_FragColorbgra8, buffer_FragColorbgra8, buffer_texture_lightmapbgra8);
+ }
+ else if (dpsoftrast.shader_permutation & SHADERPERMUTATION_VERTEXTEXTUREBLEND)
+ {
+ // alphablend
+ DPSOFTRAST_Draw_Span_MixBuffersBGRA8(span, buffer_FragColorbgra8, buffer_FragColorbgra8, buffer_texture_lightmapbgra8);
+ }
+ }
+ }
+ else
+ DPSOFTRAST_Draw_Span_VaryingBGRA8(span, buffer_FragColorbgra8, 1, buffer_z);
+ DPSOFTRAST_Draw_Span_FinishBGRA8(span, buffer_FragColorbgra8);
+}
+
+
+
+void DPSOFTRAST_VertexShader_PostProcess(void)
+{
+ DPSOFTRAST_Array_Transform(dpsoftrast.draw.post_array4f[DPSOFTRAST_ARRAY_POSITION], dpsoftrast.draw.in_array4f[DPSOFTRAST_ARRAY_POSITION], dpsoftrast.draw.numvertices, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
+ DPSOFTRAST_Array_Copy(dpsoftrast.draw.post_array4f[DPSOFTRAST_ARRAY_TEXCOORD0], dpsoftrast.draw.in_array4f[DPSOFTRAST_ARRAY_TEXCOORD0], dpsoftrast.draw.numvertices);
+ DPSOFTRAST_Array_Copy(dpsoftrast.draw.post_array4f[DPSOFTRAST_ARRAY_TEXCOORD1], dpsoftrast.draw.in_array4f[DPSOFTRAST_ARRAY_TEXCOORD1], dpsoftrast.draw.numvertices);
+}
+
+void DPSOFTRAST_PixelShader_PostProcess(const DPSOFTRAST_State_Draw_Span * RESTRICT span)
+{
+ // TODO: optimize!! at the very least there is no reason to use texture sampling on the frame texture
+ float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
+ unsigned char buffer_texture_colorbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
+ unsigned char buffer_FragColorbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
+ DPSOFTRAST_Draw_Span_Begin(span, buffer_z);
+ DPSOFTRAST_Draw_Span_Texture2DVaryingBGRA8(span, buffer_FragColorbgra8, GL20TU_FIRST, 2, buffer_z);
+ if (dpsoftrast.shader_permutation & SHADERPERMUTATION_BLOOM)
+ {
+ DPSOFTRAST_Draw_Span_Texture2DVaryingBGRA8(span, buffer_texture_colorbgra8, GL20TU_SECOND, 3, buffer_z);
+ DPSOFTRAST_Draw_Span_AddBloomBGRA8(span, buffer_FragColorbgra8, buffer_FragColorbgra8, buffer_texture_colorbgra8, dpsoftrast.uniform4f + DPSOFTRAST_UNIFORM_BloomColorSubtract * 4);
+ }
+ DPSOFTRAST_Draw_Span_MixUniformColorBGRA8(span, buffer_FragColorbgra8, buffer_FragColorbgra8, dpsoftrast.uniform4f + DPSOFTRAST_UNIFORM_ViewTintColor * 4);
+ if (dpsoftrast.shader_permutation & SHADERPERMUTATION_SATURATION)
+ {
+ // TODO: implement saturation
+ }
+ if (dpsoftrast.shader_permutation & SHADERPERMUTATION_GAMMARAMPS)
+ {
+ // TODO: implement gammaramps
+ }
+ DPSOFTRAST_Draw_Span_FinishBGRA8(span, buffer_FragColorbgra8);
+}
+
+
+
+void DPSOFTRAST_VertexShader_Depth_Or_Shadow(void)
+{
+ DPSOFTRAST_Array_Transform(dpsoftrast.draw.post_array4f[DPSOFTRAST_ARRAY_POSITION], dpsoftrast.draw.in_array4f[DPSOFTRAST_ARRAY_POSITION], dpsoftrast.draw.numvertices, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
+}
+
+void DPSOFTRAST_PixelShader_Depth_Or_Shadow(const DPSOFTRAST_State_Draw_Span * RESTRICT span)
+{
+ // this is never called (because colormask is off when this shader is used)
+ float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
+ unsigned char buffer_FragColorbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
+ DPSOFTRAST_Draw_Span_Begin(span, buffer_z);
+ memset(buffer_FragColorbgra8, 0, span->length*4);
+ DPSOFTRAST_Draw_Span_FinishBGRA8(span, buffer_FragColorbgra8);
+}
+
+
+
+void DPSOFTRAST_VertexShader_FlatColor(void)
+{
+ DPSOFTRAST_Array_Transform(dpsoftrast.draw.post_array4f[DPSOFTRAST_ARRAY_POSITION], dpsoftrast.draw.in_array4f[DPSOFTRAST_ARRAY_POSITION], dpsoftrast.draw.numvertices, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1);
+ DPSOFTRAST_Array_Transform(dpsoftrast.draw.post_array4f[DPSOFTRAST_ARRAY_TEXCOORD0], dpsoftrast.draw.in_array4f[DPSOFTRAST_ARRAY_TEXCOORD0], dpsoftrast.draw.numvertices, dpsoftrast.uniform4f + 4*DPSOFTRAST_UNIFORM_TexMatrixM1);
+}
+
+void DPSOFTRAST_PixelShader_FlatColor(const DPSOFTRAST_State_Draw_Span * RESTRICT span)
+{
+ int x, startx = span->startx, endx = span->endx;
+ int Color_Ambienti[4];
+ float buffer_z[DPSOFTRAST_DRAW_MAXSPANLENGTH];
+ unsigned char buffer_texture_colorbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
+ unsigned char buffer_FragColorbgra8[DPSOFTRAST_DRAW_MAXSPANLENGTH*4];
+ Color_Ambienti[2] = (int)(dpsoftrast.uniform4f[DPSOFTRAST_UNIFORM_Color_Ambient*4+0]*256.0f);
+ Color_Ambienti[1] = (int)(dpsoftrast.uniform4f[DPSOFTRAST_UNIFORM_Color_Ambient*4+1]*256.0f);
+ Color_Ambienti[0] = (int)(dpsoftrast.uniform4f[DPSOFTRAST_UNIFORM_Color_Ambient*4+2]*256.0f);
+ Color_Ambienti[3] = (int)(dpsoftrast.uniform4f[DPSOFTRAST_UNIFORM_Alpha*4+0] *256.0f);
+ DPSOFTRAST_Draw_Span_Begin(span, buffer_z);
+ DPSOFTRAST_Draw_Span_Texture2DVaryingBGRA8(span, buffer_texture_colorbgra8, GL20TU_COLOR, 2, buffer_z);