diff --git a/Data/TableData/LogicalBodyTypes/Filters.xml b/Data/TableData/LogicalBodyTypes/Filters.xml index 089f37d15..81fc0e1aa 100644 --- a/Data/TableData/LogicalBodyTypes/Filters.xml +++ b/Data/TableData/LogicalBodyTypes/Filters.xml @@ -10,7 +10,7 @@ GUN_PISTOL - 711, 732 + 711, 732, 1352 @@ -32,13 +32,13 @@ GUN_PISTOL GUN_M_PISTOL - 711, 732 + 711, 732, 1352 GUN_PISTOL - 711, 732 + 711, 732, 1352 @@ -2307,12 +2307,12 @@ - 711 + 711, 1352 - 711 + 711, 1352 diff --git a/Shaders/cubic/catmull-rom-bilinear.glsl b/Shaders/interpolation/catmull-rom-bilinear.glsl similarity index 97% rename from Shaders/cubic/catmull-rom-bilinear.glsl rename to Shaders/interpolation/catmull-rom-bilinear.glsl index cfe00bff0..03d5b77ae 100644 --- a/Shaders/cubic/catmull-rom-bilinear.glsl +++ b/Shaders/interpolation/catmull-rom-bilinear.glsl @@ -1,137 +1,137 @@ -/* - The following code is licensed under the MIT license: https://gist.github.com/TheRealMJP/bc503b0b87b643d3505d41eab8b332ae - Ported from code: https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1 - Samples a texture with Catmull-Rom filtering, using 9 texture fetches instead of 16. - See http://vec3.ca/bicubic-filtering-in-fewer-taps/ for more details - ATENTION: This code only work using LINEAR filter sampling set on Retroarch! - Modified to use 5 texture fetches -*/ - -#if defined(VERTEX) - -#if __VERSION__ >= 130 -#define COMPAT_VARYING out -#define COMPAT_ATTRIBUTE in -#define COMPAT_TEXTURE texture -#else -#define COMPAT_VARYING varying -#define COMPAT_ATTRIBUTE attribute -#define COMPAT_TEXTURE texture2D -#endif - -#ifdef GL_ES -#define COMPAT_PRECISION mediump -precision COMPAT_PRECISION float; -#else -#define COMPAT_PRECISION -#endif - -COMPAT_ATTRIBUTE vec4 VertexCoord; -COMPAT_ATTRIBUTE vec4 COLOR; -COMPAT_ATTRIBUTE vec4 TexCoord; -COMPAT_VARYING vec4 COL0; -COMPAT_VARYING vec4 TEX0; - -uniform mat4 MVPMatrix; -uniform COMPAT_PRECISION int FrameDirection; -uniform COMPAT_PRECISION int FrameCount; -uniform COMPAT_PRECISION vec2 OutputSize; -uniform COMPAT_PRECISION vec2 TextureSize; -uniform COMPAT_PRECISION vec2 InputSize; - -void main() -{ - gl_Position = MVPMatrix * VertexCoord; - COL0 = COLOR; - TEX0.xy = TexCoord.xy; -} - -#elif defined(FRAGMENT) - -#if __VERSION__ >= 130 -#define COMPAT_VARYING in -#define COMPAT_TEXTURE texture -out mediump vec4 FragColor; -#else -#define COMPAT_VARYING varying -#define FragColor gl_FragColor -#define COMPAT_TEXTURE texture2D -#endif - -#ifdef GL_ES -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else -precision mediump float; -#endif -#define COMPAT_PRECISION mediump -#else -#define COMPAT_PRECISION -#endif - -uniform COMPAT_PRECISION int FrameDirection; -uniform COMPAT_PRECISION int FrameCount; -uniform COMPAT_PRECISION vec2 OutputSize; -uniform COMPAT_PRECISION vec2 TextureSize; -uniform COMPAT_PRECISION vec2 InputSize; -uniform sampler2D Texture; -COMPAT_VARYING vec4 TEX0; - -// compatibility #defines -#define Source Texture -#define vTexCoord TEX0.xy - -#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize -#define outsize vec4(OutputSize, 1.0 / OutputSize) - -void main() -{ - // We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding - // down the sample location to get the exact center of our "starting" texel. The starting texel will be at - // location [1, 1] in the grid, where [0, 0] is the top left corner. - vec2 samplePos = vTexCoord * SourceSize.xy; - vec2 texPos1 = floor(samplePos - 0.5) + 0.5; - - // Compute the fractional offset from our starting texel to our original sample location, which we'll - // feed into the Catmull-Rom spline function to get our filter weights. - vec2 f = samplePos - texPos1; - - // Compute the Catmull-Rom weights using the fractional offset that we calculated earlier. - // These equations are pre-expanded based on our knowledge of where the texels will be located, - // which lets us avoid having to evaluate a piece-wise function. - vec2 w0 = f * (-0.5 + f * (1.0 - 0.5 * f)); - vec2 w1 = 1.0 + f * f * (-2.5 + 1.5 * f); - vec2 w2 = f * (0.5 + f * (2.0 - 1.5 * f)); - vec2 w3 = f * f * (-0.5 + 0.5 * f); - - // Work out weighting factors and sampling offsets that will let us use bilinear filtering to - // simultaneously evaluate the middle 2 samples from the 4x4 grid. - vec2 w12 = w1 + w2; - vec2 offset12 = w2 / (w1 + w2); - - // Compute the final UV coordinates we'll use for sampling the texture - vec2 texPos0 = texPos1 - 1.; - vec2 texPos3 = texPos1 + 2.; - vec2 texPos12 = texPos1 + offset12; - - texPos0 *= SourceSize.zw; - texPos3 *= SourceSize.zw; - texPos12 *= SourceSize.zw; - - float wtm = w12.x * w0.y; - float wml = w0.x * w12.y; - float wmm = w12.x * w12.y; - float wmr = w3.x * w12.y; - float wbm = w12.x * w3.y; - - vec3 result = vec3(0.0f); - - result += COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos0.y)).rgb * wtm; - result += COMPAT_TEXTURE(Source, vec2(texPos0.x, texPos12.y)).rgb * wml; - result += COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos12.y)).rgb * wmm; - result += COMPAT_TEXTURE(Source, vec2(texPos3.x, texPos12.y)).rgb * wmr; - result += COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos3.y)).rgb * wbm; - - FragColor = vec4(result * (1./(wtm+wml+wmm+wmr+wbm)), 1.0); -} -#endif +/* + The following code is licensed under the MIT license: https://gist.github.com/TheRealMJP/bc503b0b87b643d3505d41eab8b332ae + Ported from code: https://gist.github.com/TheRealMJP/c83b8c0f46b63f3a88a5986f4fa982b1 + Samples a texture with Catmull-Rom filtering, using 9 texture fetches instead of 16. + See http://vec3.ca/bicubic-filtering-in-fewer-taps/ for more details + ATENTION: This code only work using LINEAR filter sampling set on Retroarch! + Modified to use 5 texture fetches +*/ + +#if defined(VERTEX) + +#if __VERSION__ >= 130 +#define COMPAT_VARYING out +#define COMPAT_ATTRIBUTE in +#define COMPAT_TEXTURE texture +#else +#define COMPAT_VARYING varying +#define COMPAT_ATTRIBUTE attribute +#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#define COMPAT_PRECISION mediump +precision COMPAT_PRECISION float; +#else +#define COMPAT_PRECISION +#endif + +COMPAT_ATTRIBUTE vec4 VertexCoord; +COMPAT_ATTRIBUTE vec4 COLOR; +COMPAT_ATTRIBUTE vec4 TexCoord; +COMPAT_VARYING vec4 COL0; +COMPAT_VARYING vec4 TEX0; + +uniform mat4 MVPMatrix; +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; + +void main() +{ + gl_Position = MVPMatrix * VertexCoord; + COL0 = COLOR; + TEX0.xy = TexCoord.xy; +} + +#elif defined(FRAGMENT) + +#if __VERSION__ >= 130 +#define COMPAT_VARYING in +#define COMPAT_TEXTURE texture +out mediump vec4 FragColor; +#else +#define COMPAT_VARYING varying +#define FragColor gl_FragColor +#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; +uniform sampler2D Texture; +COMPAT_VARYING vec4 TEX0; + +// compatibility #defines +#define Source Texture +#define vTexCoord TEX0.xy + +#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize +#define outsize vec4(OutputSize, 1.0 / OutputSize) + +void main() +{ + // We're going to sample a a 4x4 grid of texels surrounding the target UV coordinate. We'll do this by rounding + // down the sample location to get the exact center of our "starting" texel. The starting texel will be at + // location [1, 1] in the grid, where [0, 0] is the top left corner. + vec2 samplePos = vTexCoord * SourceSize.xy; + vec2 texPos1 = floor(samplePos - 0.5) + 0.5; + + // Compute the fractional offset from our starting texel to our original sample location, which we'll + // feed into the Catmull-Rom spline function to get our filter weights. + vec2 f = samplePos - texPos1; + + // Compute the Catmull-Rom weights using the fractional offset that we calculated earlier. + // These equations are pre-expanded based on our knowledge of where the texels will be located, + // which lets us avoid having to evaluate a piece-wise function. + vec2 w0 = f * (-0.5 + f * (1.0 - 0.5 * f)); + vec2 w1 = 1.0 + f * f * (-2.5 + 1.5 * f); + vec2 w2 = f * (0.5 + f * (2.0 - 1.5 * f)); + vec2 w3 = f * f * (-0.5 + 0.5 * f); + + // Work out weighting factors and sampling offsets that will let us use bilinear filtering to + // simultaneously evaluate the middle 2 samples from the 4x4 grid. + vec2 w12 = w1 + w2; + vec2 offset12 = w2 / (w1 + w2); + + // Compute the final UV coordinates we'll use for sampling the texture + vec2 texPos0 = texPos1 - 1.; + vec2 texPos3 = texPos1 + 2.; + vec2 texPos12 = texPos1 + offset12; + + texPos0 *= SourceSize.zw; + texPos3 *= SourceSize.zw; + texPos12 *= SourceSize.zw; + + float wtm = w12.x * w0.y; + float wml = w0.x * w12.y; + float wmm = w12.x * w12.y; + float wmr = w3.x * w12.y; + float wbm = w12.x * w3.y; + + vec3 result = vec3(0.0f); + + result += COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos0.y)).rgb * wtm; + result += COMPAT_TEXTURE(Source, vec2(texPos0.x, texPos12.y)).rgb * wml; + result += COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos12.y)).rgb * wmm; + result += COMPAT_TEXTURE(Source, vec2(texPos3.x, texPos12.y)).rgb * wmr; + result += COMPAT_TEXTURE(Source, vec2(texPos12.x, texPos3.y)).rgb * wbm; + + FragColor = vec4(result * (1./(wtm+wml+wmm+wmr+wbm)), 1.0); +} +#endif diff --git a/Shaders/interpolation/fsr.glsl b/Shaders/interpolation/fsr.glsl new file mode 100644 index 000000000..17e574bc9 --- /dev/null +++ b/Shaders/interpolation/fsr.glsl @@ -0,0 +1,324 @@ +/* + FSR - [EASU] EDGE ADAPTIVE SPATIAL UPSAMPLING + Ported from https://www.shadertoy.com/view/stXSWB, MIT license +*/ + +#if defined(VERTEX) + +#if __VERSION__ >= 130 +#define COMPAT_VARYING out +#define COMPAT_ATTRIBUTE in +#define COMPAT_TEXTURE texture +#else +#define COMPAT_VARYING varying +#define COMPAT_ATTRIBUTE attribute +#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +COMPAT_ATTRIBUTE vec4 VertexCoord; +COMPAT_ATTRIBUTE vec4 COLOR; +COMPAT_ATTRIBUTE vec4 TexCoord; +COMPAT_VARYING vec4 COL0; +COMPAT_VARYING vec4 TEX0; + +uniform mat4 MVPMatrix; +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; + +void main() +{ + gl_Position = MVPMatrix * VertexCoord; + COL0 = COLOR; + TEX0.xy = TexCoord.xy; +} + +#elif defined(FRAGMENT) + +#if __VERSION__ >= 130 +#define COMPAT_VARYING in +#define COMPAT_TEXTURE texture +out vec4 FragColor; +#else +#define COMPAT_VARYING varying +#define FragColor gl_FragColor +#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; +uniform sampler2D Texture; +COMPAT_VARYING vec4 TEX0; + +// compatibility #defines +#define Source Texture +#define vTexCoord TEX0.xy + +#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize +#define outsize vec4(OutputSize, 1.0 / OutputSize) + +vec3 FsrEasuCF(vec2 p) { + return COMPAT_TEXTURE(Source,p).rgb; +} + +/**** EASU ****/ +void FsrEasuCon( + out vec4 con0, + out vec4 con1, + out vec4 con2, + out vec4 con3, + // This the rendered image resolution being upscaled + vec2 inputViewportInPixels, + // This is the resolution of the resource containing the input image (useful for dynamic resolution) + vec2 inputSizeInPixels, + // This is the display resolution which the input image gets upscaled to + vec2 outputSizeInPixels +) +{ + // Output integer position to a pixel position in viewport. + con0 = vec4( + inputViewportInPixels.x/outputSizeInPixels.x, + inputViewportInPixels.y/outputSizeInPixels.y, + .5*inputViewportInPixels.x/outputSizeInPixels.x-.5, + .5*inputViewportInPixels.y/outputSizeInPixels.y-.5 + ); + // Viewport pixel position to normalized image space. + // This is used to get upper-left of 'F' tap. + con1 = vec4(1,1,1,-1)/inputSizeInPixels.xyxy; + // Centers of gather4, first offset from upper-left of 'F'. + // +---+---+ + // | | | + // +--(0)--+ + // | b | c | + // +---F---+---+---+ + // | e | f | g | h | + // +--(1)--+--(2)--+ + // | i | j | k | l | + // +---+---+---+---+ + // | n | o | + // +--(3)--+ + // | | | + // +---+---+ + // These are from (0) instead of 'F'. + con2 = vec4(-1,2,1,2)/inputSizeInPixels.xyxy; + con3 = vec4(0,4,0,0)/inputSizeInPixels.xyxy; +} + +// Filtering for a given tap for the scalar. +void FsrEasuTapF( + inout vec3 aC, // Accumulated color, with negative lobe. + inout float aW, // Accumulated weight. + vec2 off, // Pixel offset from resolve position to tap. + vec2 dir, // Gradient direction. + vec2 len, // Length. + float lob, // Negative lobe strength. + float clp, // Clipping point. + vec3 c +) +{ + // Tap color. + // Rotate offset by direction. + vec2 v = vec2(dot(off, dir), dot(off,vec2(-dir.y,dir.x))); + // Anisotropy. + v *= len; + // Compute distance^2. + float d2 = min(dot(v,v),clp); + // Limit to the window as at corner, 2 taps can easily be outside. + // Approximation of lancos2 without sin() or rcp(), or sqrt() to get x. + // (25/16 * (2/5 * x^2 - 1)^2 - (25/16 - 1)) * (1/4 * x^2 - 1)^2 + // |_______________________________________| |_______________| + // base window + // The general form of the 'base' is, + // (a*(b*x^2-1)^2-(a-1)) + // Where 'a=1/(2*b-b^2)' and 'b' moves around the negative lobe. + float wB = .4 * d2 - 1.; + float wA = lob * d2 -1.; + wB *= wB; + wA *= wA; + wB = 1.5625*wB-.5625; + float w= wB * wA; + // Do weighted average. + aC += c*w; + aW += w; +} + +//------------------------------------------------------------------------------------------------------------------------------ +// Accumulate direction and length. +void FsrEasuSetF( + inout vec2 dir, + inout float len, + float w, + float lA,float lB,float lC,float lD,float lE +) +{ + // Direction is the '+' diff. + // a + // b c d + // e + // Then takes magnitude from abs average of both sides of 'c'. + // Length converts gradient reversal to 0, smoothly to non-reversal at 1, shaped, then adding horz and vert terms. + float lenX = max(abs(lD - lC), abs(lC - lB)); + float dirX = lD - lB; + dir.x += dirX * w; + lenX = clamp(abs(dirX)/lenX,0.,1.); + lenX *= lenX; + len += lenX * w; + // Repeat for the y axis. + float lenY = max(abs(lE - lC), abs(lC - lA)); + float dirY = lE - lA; + dir.y += dirY * w; + lenY = clamp(abs(dirY) / lenY,0.,1.); + lenY *= lenY; + len += lenY * w; +} + +//------------------------------------------------------------------------------------------------------------------------------ +void FsrEasuF( + out vec3 pix, + vec2 ip, // Integer pixel position in output. + // Constants generated by FsrEasuCon(). + vec4 con0, // xy = output to input scale, zw = first pixel offset correction + vec4 con1, + vec4 con2, + vec4 con3 +) +{ + //------------------------------------------------------------------------------------------------------------------------------ + // Get position of 'f'. + vec2 pp = ip * con0.xy + con0.zw; // Corresponding input pixel/subpixel + vec2 fp = floor(pp);// fp = source nearest pixel + pp -= fp; // pp = source subpixel + + //------------------------------------------------------------------------------------------------------------------------------ + // 12-tap kernel. + // b c + // e f g h + // i j k l + // n o + // Gather 4 ordering. + // a b + // r g + vec2 p0 = fp * con1.xy + con1.zw; + + // These are from p0 to avoid pulling two constants on pre-Navi hardware. + vec2 p1 = p0 + con2.xy; + vec2 p2 = p0 + con2.zw; + vec2 p3 = p0 + con3.xy; + + // TextureGather is not available on WebGL2 + vec4 off = vec4(-.5,.5,-.5,.5)*con1.xxyy; + // textureGather to texture offsets + // x=west y=east z=north w=south + vec3 bC = FsrEasuCF(p0 + off.xw); float bL = bC.g + 0.5 *(bC.r + bC.b); + vec3 cC = FsrEasuCF(p0 + off.yw); float cL = cC.g + 0.5 *(cC.r + cC.b); + vec3 iC = FsrEasuCF(p1 + off.xw); float iL = iC.g + 0.5 *(iC.r + iC.b); + vec3 jC = FsrEasuCF(p1 + off.yw); float jL = jC.g + 0.5 *(jC.r + jC.b); + vec3 fC = FsrEasuCF(p1 + off.yz); float fL = fC.g + 0.5 *(fC.r + fC.b); + vec3 eC = FsrEasuCF(p1 + off.xz); float eL = eC.g + 0.5 *(eC.r + eC.b); + vec3 kC = FsrEasuCF(p2 + off.xw); float kL = kC.g + 0.5 *(kC.r + kC.b); + vec3 lC = FsrEasuCF(p2 + off.yw); float lL = lC.g + 0.5 *(lC.r + lC.b); + vec3 hC = FsrEasuCF(p2 + off.yz); float hL = hC.g + 0.5 *(hC.r + hC.b); + vec3 gC = FsrEasuCF(p2 + off.xz); float gL = gC.g + 0.5 *(gC.r + gC.b); + vec3 oC = FsrEasuCF(p3 + off.yz); float oL = oC.g + 0.5 *(oC.r + oC.b); + vec3 nC = FsrEasuCF(p3 + off.xz); float nL = nC.g + 0.5 *(nC.r + nC.b); + + //------------------------------------------------------------------------------------------------------------------------------ + // Simplest multi-channel approximate luma possible (luma times 2, in 2 FMA/MAD). + // Accumulate for bilinear interpolation. + vec2 dir = vec2(0); + float len = 0.; + + FsrEasuSetF(dir, len, (1.-pp.x)*(1.-pp.y), bL, eL, fL, gL, jL); + FsrEasuSetF(dir, len, pp.x *(1.-pp.y), cL, fL, gL, hL, kL); + FsrEasuSetF(dir, len, (1.-pp.x)* pp.y , fL, iL, jL, kL, nL); + FsrEasuSetF(dir, len, pp.x * pp.y , gL, jL, kL, lL, oL); + + //------------------------------------------------------------------------------------------------------------------------------ + // Normalize with approximation, and cleanup close to zero. + vec2 dir2 = dir * dir; + float dirR = dir2.x + dir2.y; + bool zro = dirR < (1.0/32768.0); + dirR = inversesqrt(dirR); + dirR = zro ? 1.0 : dirR; + dir.x = zro ? 1.0 : dir.x; + dir *= vec2(dirR); + // Transform from {0 to 2} to {0 to 1} range, and shape with square. + len = len * 0.5; + len *= len; + // Stretch kernel {1.0 vert|horz, to sqrt(2.0) on diagonal}. + float stretch = dot(dir,dir) / (max(abs(dir.x), abs(dir.y))); + // Anisotropic length after rotation, + // x := 1.0 lerp to 'stretch' on edges + // y := 1.0 lerp to 2x on edges + vec2 len2 = vec2(1. +(stretch-1.0)*len, 1. -.5 * len); + // Based on the amount of 'edge', + // the window shifts from +/-{sqrt(2.0) to slightly beyond 2.0}. + float lob = .5 - .29 * len; + // Set distance^2 clipping point to the end of the adjustable window. + float clp = 1./lob; + + //------------------------------------------------------------------------------------------------------------------------------ + // Accumulation mixed with min/max of 4 nearest. + // b c + // e f g h + // i j k l + // n o + vec3 min4 = min(min(fC,gC),min(jC,kC)); + vec3 max4 = max(max(fC,gC),max(jC,kC)); + // Accumulation. + vec3 aC = vec3(0); + float aW = 0.; + FsrEasuTapF(aC, aW, vec2( 0,-1)-pp, dir, len2, lob, clp, bC); + FsrEasuTapF(aC, aW, vec2( 1,-1)-pp, dir, len2, lob, clp, cC); + FsrEasuTapF(aC, aW, vec2(-1, 1)-pp, dir, len2, lob, clp, iC); + FsrEasuTapF(aC, aW, vec2( 0, 1)-pp, dir, len2, lob, clp, jC); + FsrEasuTapF(aC, aW, vec2( 0, 0)-pp, dir, len2, lob, clp, fC); + FsrEasuTapF(aC, aW, vec2(-1, 0)-pp, dir, len2, lob, clp, eC); + FsrEasuTapF(aC, aW, vec2( 1, 1)-pp, dir, len2, lob, clp, kC); + FsrEasuTapF(aC, aW, vec2( 2, 1)-pp, dir, len2, lob, clp, lC); + FsrEasuTapF(aC, aW, vec2( 2, 0)-pp, dir, len2, lob, clp, hC); + FsrEasuTapF(aC, aW, vec2( 1, 0)-pp, dir, len2, lob, clp, gC); + FsrEasuTapF(aC, aW, vec2( 1, 2)-pp, dir, len2, lob, clp, oC); + FsrEasuTapF(aC, aW, vec2( 0, 2)-pp, dir, len2, lob, clp, nC); + //------------------------------------------------------------------------------------------------------------------------------ + // Normalize and dering. + pix=min(max4,max(min4,aC/aW)); +} + +void main() +{ + vec3 c; + vec4 con0,con1,con2,con3; + + vec2 fragCoord = vTexCoord.xy * OutputSize.xy; + + FsrEasuCon( + con0, con1, con2, con3, SourceSize.xy, SourceSize.xy, OutputSize.xy + ); + FsrEasuF(c, fragCoord, con0, con1, con2, con3); + FragColor = vec4(c.xyz, 1); +} + +#endif diff --git a/Shaders/interpolation/fsr.glsl.pass1 b/Shaders/interpolation/fsr.glsl.pass1 new file mode 100644 index 000000000..d9ce74fc6 --- /dev/null +++ b/Shaders/interpolation/fsr.glsl.pass1 @@ -0,0 +1,178 @@ +/* + FSR - [RCAS] ROBUST CONTRAST ADAPTIVE SHARPENING + Ported from https://www.shadertoy.com/view/stXSWB, MIT license +*/ + +#pragma parameter FSR_SHARPENING "FSR RCAS Sharpening Amount (Lower = Sharper)" 0.6 0.0 2.0 0.1 + +#if defined(VERTEX) + +#if __VERSION__ >= 130 +#define COMPAT_VARYING out +#define COMPAT_ATTRIBUTE in +#define COMPAT_TEXTURE texture +#else +#define COMPAT_VARYING varying +#define COMPAT_ATTRIBUTE attribute +#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +COMPAT_ATTRIBUTE vec4 VertexCoord; +COMPAT_ATTRIBUTE vec4 COLOR; +COMPAT_ATTRIBUTE vec4 TexCoord; +COMPAT_VARYING vec4 COL0; +COMPAT_VARYING vec4 TEX0; + +uniform mat4 MVPMatrix; +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; + +void main() +{ + gl_Position = MVPMatrix * VertexCoord; + COL0 = COLOR; + TEX0.xy = TexCoord.xy; +} + +#elif defined(FRAGMENT) + +#if __VERSION__ >= 130 +#define COMPAT_VARYING in +#define COMPAT_TEXTURE texture +out vec4 FragColor; +#else +#define COMPAT_VARYING varying +#define FragColor gl_FragColor +#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; +uniform sampler2D Texture; +COMPAT_VARYING vec4 TEX0; + +// compatibility #defines +#define Source Texture +#define vTexCoord TEX0.xy + +#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize +#define outsize vec4(OutputSize, 1.0 / OutputSize) + +#ifdef PARAMETER_UNIFORM +uniform COMPAT_PRECISION float FSR_SHARPENING; +#else +#define FSR_SHARPENING 0.6 +#endif + +#define FSR_RCAS_LIMIT (0.25-(1.0/16.0)) +//#define FSR_RCAS_DENOISE + +// Input callback prototypes that need to be implemented by calling shader +vec4 FsrRcasLoadF(vec2 p); +//------------------------------------------------------------------------------------------------------------------------------ +void FsrRcasCon( + out float con, + // The scale is {0.0 := maximum, to N>0, where N is the number of stops (halving) of the reduction of sharpness}. + float sharpness +){ + // Transform from stops to linear value. + con = exp2(-sharpness); +} + +vec3 FsrRcasF( + vec2 ip, // Integer pixel position in output. + float con +) +{ + // Constant generated by RcasSetup(). + // Algorithm uses minimal 3x3 pixel neighborhood. + // b + // d e f + // h + vec2 sp = vec2(ip); + vec3 b = FsrRcasLoadF(sp + vec2( 0,-1)).rgb; + vec3 d = FsrRcasLoadF(sp + vec2(-1, 0)).rgb; + vec3 e = FsrRcasLoadF(sp).rgb; + vec3 f = FsrRcasLoadF(sp+vec2( 1, 0)).rgb; + vec3 h = FsrRcasLoadF(sp+vec2( 0, 1)).rgb; + // Luma times 2. + float bL = b.g + .5 * (b.b + b.r); + float dL = d.g + .5 * (d.b + d.r); + float eL = e.g + .5 * (e.b + e.r); + float fL = f.g + .5 * (f.b + f.r); + float hL = h.g + .5 * (h.b + h.r); + // Noise detection. + float nz = .25 * (bL + dL + fL + hL) - eL; + nz=clamp( + abs(nz) + /( + max(max(bL,dL),max(eL,max(fL,hL))) + -min(min(bL,dL),min(eL,min(fL,hL))) + ), + 0., 1. + ); + nz=1.-.5*nz; + // Min and max of ring. + vec3 mn4 = min(b, min(f, h)); + vec3 mx4 = max(b, max(f, h)); + // Immediate constants for peak range. + vec2 peakC = vec2(1., -4.); + // Limiters, these need to be high precision RCPs. + vec3 hitMin = mn4 / (4. * mx4); + vec3 hitMax = (peakC.x - mx4) / (4.* mn4 + peakC.y); + vec3 lobeRGB = max(-hitMin, hitMax); + float lobe = max( + -FSR_RCAS_LIMIT, + min(max(lobeRGB.r, max(lobeRGB.g, lobeRGB.b)), 0.) + )*con; + // Apply noise removal. + #ifdef FSR_RCAS_DENOISE + lobe *= nz; + #endif + // Resolve, which needs the medium precision rcp approximation to avoid visible tonality changes. + return (lobe * (b + d + h + f) + e) / (4. * lobe + 1.); +} + + +vec4 FsrRcasLoadF(vec2 p) { + return COMPAT_TEXTURE(Source,p/OutputSize.xy); +} + +void main() +{ + vec2 fragCoord = vTexCoord.xy * OutputSize.xy; + + // Set up constants + float con; + FsrRcasCon(con, FSR_SHARPENING); + + // Perform RCAS pass + vec3 col = FsrRcasF(fragCoord, con); + + FragColor = vec4(col,1); +} + +#endif diff --git a/Shaders/interpolation/jinc2-dedither.glsl b/Shaders/interpolation/jinc2-dedither.glsl new file mode 100644 index 000000000..32235e056 --- /dev/null +++ b/Shaders/interpolation/jinc2-dedither.glsl @@ -0,0 +1,202 @@ +/* + Hyllian's jinc windowed-jinc 2-lobe sharper with anti-ringing Shader + + Copyright (C) 2011-2016 Hyllian/Jararaca - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#define JINC2_WINDOW_SINC 0.405 +#define JINC2_SINC 0.79 +#define JINC2_AR_STRENGTH 0.8 + +#define texCoord TEX0 + +#if defined(VERTEX) + +#if __VERSION__ >= 130 +#define OUT out +#define IN in +#define tex2D texture +#else +#define OUT varying +#define IN attribute +#define tex2D texture2D +#endif + +#ifdef GL_ES +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + + +IN vec4 VertexCoord; +IN vec4 Color; +IN vec2 TexCoord; +OUT vec4 color; +OUT vec2 texCoord; + +uniform mat4 MVPMatrix; +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; + +void main() +{ + gl_Position = MVPMatrix * VertexCoord; + color = Color; + texCoord = TexCoord * 1.0001; +} + +#elif defined(FRAGMENT) + +#if __VERSION__ >= 130 +#define IN in +#define tex2D texture +out vec4 FragColor; +#else +#define IN varying +#define FragColor gl_FragColor +#define tex2D texture2D +#endif + +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; +uniform sampler2D s_p; +IN vec2 texCoord; + +const float halfpi = 1.5707963267948966192313216916398; +const float pi = 3.1415926535897932384626433832795; +const float wa = JINC2_WINDOW_SINC*pi; +const float wb = JINC2_SINC*pi; + +// Calculates the distance between two points +float d(vec2 pt1, vec2 pt2) +{ + vec2 v = pt2 - pt1; + return sqrt(dot(v,v)); +} + +vec3 min4(vec3 a, vec3 b, vec3 c, vec3 d) +{ + return min(a, min(b, min(c, d))); +} + +vec3 max4(vec3 a, vec3 b, vec3 c, vec3 d) +{ + return max(a, max(b, max(c, d))); +} + +vec4 resampler(vec4 x) +{ + vec4 res; + + res = (x==vec4(0.0, 0.0, 0.0, 0.0)) ? vec4(wa*wb) : sin(x*wa)*sin(x*wb)/(x*x); + + return res; +} + +void main() +{ + + vec3 color; + vec4 weights[4]; + + vec2 dx = vec2(1.0, 0.0); + vec2 dy = vec2(0.0, 1.0); + + vec2 pc = texCoord*TextureSize; + + vec2 tc = (floor(pc-vec2(0.5,0.5))+vec2(0.5,0.5)); + + weights[0] = resampler(vec4(d(pc, tc -dx -dy), d(pc, tc -dy), d(pc, tc +dx -dy), d(pc, tc+2.0*dx -dy))); + weights[1] = resampler(vec4(d(pc, tc -dx ), d(pc, tc ), d(pc, tc +dx ), d(pc, tc+2.0*dx ))); + weights[2] = resampler(vec4(d(pc, tc -dx +dy), d(pc, tc +dy), d(pc, tc +dx +dy), d(pc, tc+2.0*dx +dy))); + weights[3] = resampler(vec4(d(pc, tc -dx+2.0*dy), d(pc, tc +2.0*dy), d(pc, tc +dx+2.0*dy), d(pc, tc+2.0*dx+2.0*dy))); + + dx = dx/TextureSize; + dy = dy/TextureSize; + tc = tc/TextureSize; + + vec3 c00 = tex2D(s_p, tc -dx -dy).xyz; + vec3 c10 = tex2D(s_p, tc -dy).xyz; + vec3 c20 = tex2D(s_p, tc +dx -dy).xyz; + vec3 c30 = tex2D(s_p, tc+2.0*dx -dy).xyz; + vec3 c01 = tex2D(s_p, tc -dx ).xyz; + vec3 c11 = tex2D(s_p, tc ).xyz; + vec3 c21 = tex2D(s_p, tc +dx ).xyz; + vec3 c31 = tex2D(s_p, tc+2.0*dx ).xyz; + vec3 c02 = tex2D(s_p, tc -dx +dy).xyz; + vec3 c12 = tex2D(s_p, tc +dy).xyz; + vec3 c22 = tex2D(s_p, tc +dx +dy).xyz; + vec3 c32 = tex2D(s_p, tc+2.0*dx +dy).xyz; + vec3 c03 = tex2D(s_p, tc -dx+2.0*dy).xyz; + vec3 c13 = tex2D(s_p, tc +2.0*dy).xyz; + vec3 c23 = tex2D(s_p, tc +dx+2.0*dy).xyz; + vec3 c33 = tex2D(s_p, tc+2.0*dx+2.0*dy).xyz; + + color = tex2D(s_p, texCoord).xyz; + + // Get min/max samples + vec3 min_sample = min4(c11, c21, c12, c22); + vec3 max_sample = max4(c11, c21, c12, c22); +/* + color = mat4x3(c00, c10, c20, c30) * weights[0]; + color+= mat4x3(c01, c11, c21, c31) * weights[1]; + color+= mat4x3(c02, c12, c22, c32) * weights[2]; + color+= mat4x3(c03, c13, c23, c33) * weights[3]; + mat4 wgts = mat4(weights[0], weights[1], weights[2], weights[3]); + vec4 wsum = wgts * vec4(1.0,1.0,1.0,1.0); + color = color/(dot(wsum, vec4(1.0,1.0,1.0,1.0))); +*/ + + + color = vec3(dot(weights[0], vec4(c00.x, c10.x, c20.x, c30.x)), dot(weights[0], vec4(c00.y, c10.y, c20.y, c30.y)), dot(weights[0], vec4(c00.z, c10.z, c20.z, c30.z))); + color+= vec3(dot(weights[1], vec4(c01.x, c11.x, c21.x, c31.x)), dot(weights[1], vec4(c01.y, c11.y, c21.y, c31.y)), dot(weights[1], vec4(c01.z, c11.z, c21.z, c31.z))); + color+= vec3(dot(weights[2], vec4(c02.x, c12.x, c22.x, c32.x)), dot(weights[2], vec4(c02.y, c12.y, c22.y, c32.y)), dot(weights[2], vec4(c02.z, c12.z, c22.z, c32.z))); + color+= vec3(dot(weights[3], vec4(c03.x, c13.x, c23.x, c33.x)), dot(weights[3], vec4(c03.y, c13.y, c23.y, c33.y)), dot(weights[3], vec4(c03.z, c13.z, c23.z, c33.z))); + color = color/(dot(weights[0], vec4(1,1,1,1)) + dot(weights[1], vec4(1,1,1,1)) + dot(weights[2], vec4(1,1,1,1)) + dot(weights[3], vec4(1,1,1,1))); + + // Anti-ringing + vec3 aux = color; + color = clamp(color, min_sample, max_sample); + color = mix(aux, color, JINC2_AR_STRENGTH); + + // final sum and weight normalization + FragColor.xyz = color; +} +#endif diff --git a/Shaders/windowed/lanczos2-sharp.glsl b/Shaders/interpolation/lanczos2-sharp.glsl similarity index 100% rename from Shaders/windowed/lanczos2-sharp.glsl rename to Shaders/interpolation/lanczos2-sharp.glsl diff --git a/Shaders/readme.txt b/Shaders/readme.txt index c262bee6d..abd02a01b 100644 --- a/Shaders/readme.txt +++ b/Shaders/readme.txt @@ -5,3 +5,6 @@ https://github.com/libretro/glsl-shaders Note: Filename must end with "bilinear.glsl" to enable bilinear hardware filtering (GL_LINEAR) + + +Extract shader-package.zip to unlock 100+ additional shaders diff --git a/Shaders/shader-package.zip b/Shaders/shader-package.zip index 2f3e07f7d..21290e21f 100644 Binary files a/Shaders/shader-package.zip and b/Shaders/shader-package.zip differ diff --git a/Shaders/sharpen/fast-sharpen.glsl b/Shaders/sharpen/fast-sharpen.glsl deleted file mode 100644 index 623fd6d58..000000000 --- a/Shaders/sharpen/fast-sharpen.glsl +++ /dev/null @@ -1,148 +0,0 @@ -/* - Fast Sharpen Shader - - Copyright (C) 2005 - 2019 guest(r) - guest.r@gmail.com - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#pragma parameter SHARPEN "Sharpen strength" 1.00 0.0 2.00 0.05 -#pragma parameter CONTR "Ammount of sharpening" 0.07 0.0 0.25 0.01 -#pragma parameter DETAILS "Details sharpened " 1.00 0.0 1.00 0.05 - -#if defined(VERTEX) - -#if __VERSION__ >= 130 -#define COMPAT_VARYING out -#define COMPAT_ATTRIBUTE in -#define COMPAT_TEXTURE texture -#else -#define COMPAT_VARYING varying -#define COMPAT_ATTRIBUTE attribute -#define COMPAT_TEXTURE texture2D -#endif - -#ifdef GL_ES -#define COMPAT_PRECISION mediump -#else -#define COMPAT_PRECISION -#endif - -COMPAT_ATTRIBUTE vec4 VertexCoord; -COMPAT_ATTRIBUTE vec4 TexCoord; -COMPAT_VARYING vec4 TEX0; - -vec4 _oPosition1; -uniform mat4 MVPMatrix; -uniform COMPAT_PRECISION int FrameDirection; -uniform COMPAT_PRECISION int FrameCount; -uniform COMPAT_PRECISION vec2 OutputSize; -uniform COMPAT_PRECISION vec2 TextureSize; -uniform COMPAT_PRECISION vec2 InputSize; -COMPAT_VARYING vec2 g10; -COMPAT_VARYING vec2 g01; -COMPAT_VARYING vec2 g12; -COMPAT_VARYING vec2 g21; - -// compatibility #defines -#define vTexCoord TEX0.xy -#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize -#define OutSize vec4(OutputSize, 1.0 / OutputSize) - -void main() -{ - gl_Position = MVPMatrix * VertexCoord; - TEX0.xy = TexCoord.xy * 1.00001; - g10 = vec2( 0.3333,-1.0)*SourceSize.zw; - g01 = vec2(-1.0,-0.3333)*SourceSize.zw; - g12 = vec2(-0.3333, 1.0)*SourceSize.zw; - g21 = vec2( 1.0, 0.3333)*SourceSize.zw; -} - -#elif defined(FRAGMENT) - -#ifdef GL_ES -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else -precision mediump float; -#endif -#define COMPAT_PRECISION mediump -#else -#define COMPAT_PRECISION -#endif - -#if __VERSION__ >= 130 -#define COMPAT_VARYING in -#define COMPAT_TEXTURE texture -out COMPAT_PRECISION vec4 FragColor; -#else -#define COMPAT_VARYING varying -#define FragColor gl_FragColor -#define COMPAT_TEXTURE texture2D -#endif - -uniform COMPAT_PRECISION int FrameDirection; -uniform COMPAT_PRECISION int FrameCount; -uniform COMPAT_PRECISION vec2 OutputSize; -uniform COMPAT_PRECISION vec2 TextureSize; -uniform COMPAT_PRECISION vec2 InputSize; -uniform sampler2D Texture; -COMPAT_VARYING vec4 TEX0; -COMPAT_VARYING vec2 g10; -COMPAT_VARYING vec2 g01; -COMPAT_VARYING vec2 g12; -COMPAT_VARYING vec2 g21; - -// compatibility #defines -#define Source Texture -#define vTexCoord TEX0.xy - -#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize -#define OutSize vec4(OutputSize, 1.0 / OutputSize) - -#ifdef PARAMETER_UNIFORM -uniform COMPAT_PRECISION float SHARPEN; -uniform COMPAT_PRECISION float CONTR; -uniform COMPAT_PRECISION float DETAILS; -#else -#define SHARPEN 1.2 -#define CONTR 0.08 -#define DETAILS 1.0 -#endif - -void main() -{ - vec3 c10 = COMPAT_TEXTURE(Source, vTexCoord + g10).rgb; - vec3 c01 = COMPAT_TEXTURE(Source, vTexCoord + g01).rgb; - vec3 c21 = COMPAT_TEXTURE(Source, vTexCoord + g21).rgb; - vec3 c12 = COMPAT_TEXTURE(Source, vTexCoord + g12).rgb; - vec3 c11 = COMPAT_TEXTURE(Source, vTexCoord ).rgb; - vec3 b11 = (c10+c01+c12+c21)*0.25; - - float contrast = max(max(c11.r,c11.g),c11.b); - contrast = mix(2.0*CONTR, CONTR, contrast); - - vec3 mn1 = min(min(c10,c01),min(c12,c21)); mn1 = min(mn1,c11*(1.0-contrast)); - vec3 mx1 = max(max(c10,c01),max(c12,c21)); mx1 = max(mx1,c11*(1.0+contrast)); - - vec3 dif = pow(mx1-mn1+0.0001, vec3(0.75,0.75,0.75)); - vec3 sharpen = mix(vec3(SHARPEN*DETAILS), vec3(SHARPEN), dif); - - c11 = clamp(mix(c11,b11,-sharpen), mn1,mx1); - - FragColor = vec4(c11,1.0); -} -#endif diff --git a/Shaders/sharpen/rca-sharpen.glsl b/Shaders/sharpen/rca-sharpen.glsl new file mode 100644 index 000000000..d9ce74fc6 --- /dev/null +++ b/Shaders/sharpen/rca-sharpen.glsl @@ -0,0 +1,178 @@ +/* + FSR - [RCAS] ROBUST CONTRAST ADAPTIVE SHARPENING + Ported from https://www.shadertoy.com/view/stXSWB, MIT license +*/ + +#pragma parameter FSR_SHARPENING "FSR RCAS Sharpening Amount (Lower = Sharper)" 0.6 0.0 2.0 0.1 + +#if defined(VERTEX) + +#if __VERSION__ >= 130 +#define COMPAT_VARYING out +#define COMPAT_ATTRIBUTE in +#define COMPAT_TEXTURE texture +#else +#define COMPAT_VARYING varying +#define COMPAT_ATTRIBUTE attribute +#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +COMPAT_ATTRIBUTE vec4 VertexCoord; +COMPAT_ATTRIBUTE vec4 COLOR; +COMPAT_ATTRIBUTE vec4 TexCoord; +COMPAT_VARYING vec4 COL0; +COMPAT_VARYING vec4 TEX0; + +uniform mat4 MVPMatrix; +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; + +void main() +{ + gl_Position = MVPMatrix * VertexCoord; + COL0 = COLOR; + TEX0.xy = TexCoord.xy; +} + +#elif defined(FRAGMENT) + +#if __VERSION__ >= 130 +#define COMPAT_VARYING in +#define COMPAT_TEXTURE texture +out vec4 FragColor; +#else +#define COMPAT_VARYING varying +#define FragColor gl_FragColor +#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; +uniform sampler2D Texture; +COMPAT_VARYING vec4 TEX0; + +// compatibility #defines +#define Source Texture +#define vTexCoord TEX0.xy + +#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize +#define outsize vec4(OutputSize, 1.0 / OutputSize) + +#ifdef PARAMETER_UNIFORM +uniform COMPAT_PRECISION float FSR_SHARPENING; +#else +#define FSR_SHARPENING 0.6 +#endif + +#define FSR_RCAS_LIMIT (0.25-(1.0/16.0)) +//#define FSR_RCAS_DENOISE + +// Input callback prototypes that need to be implemented by calling shader +vec4 FsrRcasLoadF(vec2 p); +//------------------------------------------------------------------------------------------------------------------------------ +void FsrRcasCon( + out float con, + // The scale is {0.0 := maximum, to N>0, where N is the number of stops (halving) of the reduction of sharpness}. + float sharpness +){ + // Transform from stops to linear value. + con = exp2(-sharpness); +} + +vec3 FsrRcasF( + vec2 ip, // Integer pixel position in output. + float con +) +{ + // Constant generated by RcasSetup(). + // Algorithm uses minimal 3x3 pixel neighborhood. + // b + // d e f + // h + vec2 sp = vec2(ip); + vec3 b = FsrRcasLoadF(sp + vec2( 0,-1)).rgb; + vec3 d = FsrRcasLoadF(sp + vec2(-1, 0)).rgb; + vec3 e = FsrRcasLoadF(sp).rgb; + vec3 f = FsrRcasLoadF(sp+vec2( 1, 0)).rgb; + vec3 h = FsrRcasLoadF(sp+vec2( 0, 1)).rgb; + // Luma times 2. + float bL = b.g + .5 * (b.b + b.r); + float dL = d.g + .5 * (d.b + d.r); + float eL = e.g + .5 * (e.b + e.r); + float fL = f.g + .5 * (f.b + f.r); + float hL = h.g + .5 * (h.b + h.r); + // Noise detection. + float nz = .25 * (bL + dL + fL + hL) - eL; + nz=clamp( + abs(nz) + /( + max(max(bL,dL),max(eL,max(fL,hL))) + -min(min(bL,dL),min(eL,min(fL,hL))) + ), + 0., 1. + ); + nz=1.-.5*nz; + // Min and max of ring. + vec3 mn4 = min(b, min(f, h)); + vec3 mx4 = max(b, max(f, h)); + // Immediate constants for peak range. + vec2 peakC = vec2(1., -4.); + // Limiters, these need to be high precision RCPs. + vec3 hitMin = mn4 / (4. * mx4); + vec3 hitMax = (peakC.x - mx4) / (4.* mn4 + peakC.y); + vec3 lobeRGB = max(-hitMin, hitMax); + float lobe = max( + -FSR_RCAS_LIMIT, + min(max(lobeRGB.r, max(lobeRGB.g, lobeRGB.b)), 0.) + )*con; + // Apply noise removal. + #ifdef FSR_RCAS_DENOISE + lobe *= nz; + #endif + // Resolve, which needs the medium precision rcp approximation to avoid visible tonality changes. + return (lobe * (b + d + h + f) + e) / (4. * lobe + 1.); +} + + +vec4 FsrRcasLoadF(vec2 p) { + return COMPAT_TEXTURE(Source,p/OutputSize.xy); +} + +void main() +{ + vec2 fragCoord = vTexCoord.xy * OutputSize.xy; + + // Set up constants + float con; + FsrRcasCon(con, FSR_SHARPENING); + + // Perform RCAS pass + vec3 col = FsrRcasF(fragCoord, con); + + FragColor = vec4(col,1); +} + +#endif diff --git a/Shaders/xbrz/xbrz-freescale.glsl b/Shaders/xbrz/xbrz-freescale-multipass.glsl similarity index 66% rename from Shaders/xbrz/xbrz-freescale.glsl rename to Shaders/xbrz/xbrz-freescale-multipass.glsl index 3cc9eddec..5a01406d2 100644 --- a/Shaders/xbrz/xbrz-freescale.glsl +++ b/Shaders/xbrz/xbrz-freescale-multipass.glsl @@ -78,12 +78,6 @@ uniform COMPAT_PRECISION vec2 InputSize; #define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize #define OutSize vec4(OutputSize, 1.0 / OutputSize) -#ifdef PARAMETER_UNIFORM -uniform COMPAT_PRECISION float WHATEVER; -#else -#define WHATEVER 0.0 -#endif - void main() { gl_Position = MVPMatrix * VertexCoord; @@ -120,6 +114,7 @@ uniform COMPAT_PRECISION vec2 TextureSize; uniform COMPAT_PRECISION vec2 InputSize; uniform sampler2D Texture; COMPAT_VARYING vec4 TEX0; +// in variables go here as COMPAT_VARYING whatever // compatibility #defines #define Source Texture @@ -181,7 +176,6 @@ void main() // x|G|H|I|x // -|x|x|x|- - vec2 scale = OutputSize.xy * SourceSize.zw; vec2 pos = fract(vTexCoord * SourceSize.xy) - vec2(0.5, 0.5); vec2 coord = vTexCoord - pos * SourceSize.zw; @@ -207,8 +201,8 @@ void main() // -|-|x|x|- if (!((eq(E,F) && eq(H,I)) || (eq(E,H) && eq(F,I)))) { - float dist_H_F = DistYCbCr(G, E) + DistYCbCr(E, C) + DistYCbCr(P(0,2), I) + DistYCbCr(I, P(2.,0.)) + (4.0 * DistYCbCr(H, F)); - float dist_E_I = DistYCbCr(D, H) + DistYCbCr(H, P(1,2)) + DistYCbCr(B, F) + DistYCbCr(F, P(2.,1.)) + (4.0 * DistYCbCr(E, I)); + float dist_H_F = DistYCbCr(G, E) + DistYCbCr(E, C) + DistYCbCr(P(0.,2.), I) + DistYCbCr(I, P(2.,0.)) + (4.0 * DistYCbCr(H, F)); + float dist_E_I = DistYCbCr(D, H) + DistYCbCr(H, P(1.,2.)) + DistYCbCr(B, F) + DistYCbCr(F, P(2.,1.)) + (4.0 * DistYCbCr(E, I)); bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_H_F) < dist_E_I; blendResult.z = ((dist_H_F < dist_E_I) && neq(E,F) && neq(E,H)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; } @@ -234,7 +228,7 @@ void main() // -|-|-|-|- if (!((eq(B,C) && eq(E,F)) || (eq(B,E) && eq(C,F)))) { - float dist_E_C = DistYCbCr(D, B) + DistYCbCr(B, P(1.,-2.)) + DistYCbCr(H, F) + DistYCbCr(F, P(2.,-1.)) + (4.0 * DistYCbCr(E, C)); + float dist_E_C = DistYCbCr(D, B) + DistYCbCr(B, P(1,-2)) + DistYCbCr(H, F) + DistYCbCr(F, P(2.,-1.)) + (4.0 * DistYCbCr(E, C)); float dist_B_F = DistYCbCr(A, E) + DistYCbCr(E, I) + DistYCbCr(P(0.,-2.), C) + DistYCbCr(C, P(2.,0.)) + (4.0 * DistYCbCr(B, F)); bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_B_F) < dist_E_C; blendResult.y = ((dist_E_C > dist_B_F) && neq(E,B) && neq(E,F)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; @@ -253,123 +247,91 @@ void main() blendResult.x = ((dist_D_B < dist_A_E) && neq(E,D) && neq(E,B)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; } - vec3 res = E; + FragColor = vec4(blendResult); // Pixel Tap Mapping: -|-|-|-|- // -|-|B|C|- // -|D|E|F|x // -|G|H|I|x // -|-|x|x|- - if(blendResult.z != BLEND_NONE) - { - float dist_F_G = DistYCbCr(F, G); - float dist_H_C = DistYCbCr(H, C); - bool doLineBlend = (blendResult.z == BLEND_DOMINANT || - !((blendResult.y != BLEND_NONE && !IsPixEqual(E, G)) || (blendResult.w != BLEND_NONE && !IsPixEqual(E, C)) || - (IsPixEqual(G, H) && IsPixEqual(H, I) && IsPixEqual(I, F) && IsPixEqual(F, C) && !IsPixEqual(E, I)))); + if(blendResult.z == BLEND_DOMINANT || (blendResult.z == BLEND_NORMAL && + !((blendResult.y != BLEND_NONE && !IsPixEqual(E, G)) || (blendResult.w != BLEND_NONE && !IsPixEqual(E, C)) || + (IsPixEqual(G, H) && IsPixEqual(H, I) && IsPixEqual(I, F) && IsPixEqual(F, C) && !IsPixEqual(E, I))))) + { + FragColor.z += 4.0; - vec2 origin = vec2(0.0, 1.0 / sqrt(2.0)); - vec2 direction = vec2(1.0, -1.0); - if(doLineBlend) - { - bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_F_G <= dist_H_C) && neq(E,G) && neq(D,G); - bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_H_C <= dist_F_G) && neq(E,C) && neq(B,C); - origin = haveShallowLine? vec2(0.0, 0.25) : vec2(0.0, 0.5); - direction.x += haveShallowLine? 1.0: 0.0; - direction.y -= haveSteepLine? 1.0: 0.0; - } + float dist_F_G = DistYCbCr(F, G); + float dist_H_C = DistYCbCr(H, C); - vec3 blendPix = mix(H,F, step(DistYCbCr(E, F), DistYCbCr(E, H))); - res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale)); - } + if((STEEP_DIRECTION_THRESHOLD * dist_F_G <= dist_H_C) && neq(E,G) && neq(D,G)) + FragColor.z += 16.0; + + if((STEEP_DIRECTION_THRESHOLD * dist_H_C <= dist_F_G) && neq(E,C) && neq(B,C)) + FragColor.z += 64.0; + } // Pixel Tap Mapping: -|-|-|-|- // -|A|B|-|- // x|D|E|F|- // x|G|H|I|- // -|x|x|-|- - if(blendResult.w != BLEND_NONE) - { - float dist_H_A = DistYCbCr(H, A); - float dist_D_I = DistYCbCr(D, I); - bool doLineBlend = (blendResult.w == BLEND_DOMINANT || - !((blendResult.z != BLEND_NONE && !IsPixEqual(E, A)) || (blendResult.x != BLEND_NONE && !IsPixEqual(E, I)) || - (IsPixEqual(A, D) && IsPixEqual(D, G) && IsPixEqual(G, H) && IsPixEqual(H, I) && !IsPixEqual(E, G)))); + if(blendResult.w == BLEND_DOMINANT || (blendResult.w == BLEND_NORMAL && + !((blendResult.z != BLEND_NONE && !IsPixEqual(E, A)) || (blendResult.x != BLEND_NONE && !IsPixEqual(E, I)) || + (IsPixEqual(A, D) && IsPixEqual(D, G) && IsPixEqual(G, H) && IsPixEqual(H, I) && !IsPixEqual(E, G))))) + { + FragColor.w += 4.0; - vec2 origin = vec2(-1.0 / sqrt(2.0), 0.0); - vec2 direction = vec2(1.0, 1.0); - if(doLineBlend) - { - bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_H_A <= dist_D_I) && neq(E,A) && neq(B,A); - bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_D_I <= dist_H_A) && neq(E,I) && neq(F,I); - origin = haveShallowLine? vec2(-0.25, 0.0) : vec2(-0.5, 0.0); - direction.y += haveShallowLine? 1.0: 0.0; - direction.x += haveSteepLine? 1.0: 0.0; - } - origin = origin; - direction = direction; + float dist_H_A = DistYCbCr(H, A); + float dist_D_I = DistYCbCr(D, I); - vec3 blendPix = mix(H,D, step(DistYCbCr(E, D), DistYCbCr(E, H))); - res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale)); - } + if((STEEP_DIRECTION_THRESHOLD * dist_H_A <= dist_D_I) && neq(E,A) && neq(B,A)) + FragColor.w += 16.0; + + if((STEEP_DIRECTION_THRESHOLD * dist_D_I <= dist_H_A) && neq(E,I) && neq(F,I)) + FragColor.w += 64.0; + } // Pixel Tap Mapping: -|-|x|x|- // -|A|B|C|x // -|D|E|F|x // -|-|H|I|- // -|-|-|-|- - if(blendResult.y != BLEND_NONE) - { - float dist_B_I = DistYCbCr(B, I); - float dist_F_A = DistYCbCr(F, A); - bool doLineBlend = (blendResult.y == BLEND_DOMINANT || - !((blendResult.x != BLEND_NONE && !IsPixEqual(E, I)) || (blendResult.z != BLEND_NONE && !IsPixEqual(E, A)) || - (IsPixEqual(I, F) && IsPixEqual(F, C) && IsPixEqual(C, B) && IsPixEqual(B, A) && !IsPixEqual(E, C)))); + if(blendResult.y == BLEND_DOMINANT || (blendResult.y == BLEND_NORMAL && + !((blendResult.x != BLEND_NONE && !IsPixEqual(E, I)) || (blendResult.z != BLEND_NONE && !IsPixEqual(E, A)) || + (IsPixEqual(I, F) && IsPixEqual(F, C) && IsPixEqual(C, B) && IsPixEqual(B, A) && !IsPixEqual(E, C))))) + { + FragColor.y += 4.0; - vec2 origin = vec2(1.0 / sqrt(2.0), 0.0); - vec2 direction = vec2(-1.0, -1.0); + float dist_B_I = DistYCbCr(B, I); + float dist_F_A = DistYCbCr(F, A); - if(doLineBlend) - { - bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_B_I <= dist_F_A) && neq(E,I) && neq(H,I); - bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_F_A <= dist_B_I) && neq(E,A) && neq(D,A); - origin = haveShallowLine? vec2(0.25, 0.0) : vec2(0.5, 0.0); - direction.y -= haveShallowLine? 1.0: 0.0; - direction.x -= haveSteepLine? 1.0: 0.0; - } + if((STEEP_DIRECTION_THRESHOLD * dist_B_I <= dist_F_A) && neq(E,I) && neq(H,I)) + FragColor.y += 16.0; - vec3 blendPix = mix(F,B, step(DistYCbCr(E, B), DistYCbCr(E, F))); - res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale)); - } + if((STEEP_DIRECTION_THRESHOLD * dist_F_A <= dist_B_I) && neq(E,A) && neq(D,A)) + FragColor.y += 64.0; + } // Pixel Tap Mapping: -|x|x|-|- // x|A|B|C|- // x|D|E|F|- // -|G|H|-|- // -|-|-|-|- - if(blendResult.x != BLEND_NONE) - { - float dist_D_C = DistYCbCr(D, C); - float dist_B_G = DistYCbCr(B, G); - bool doLineBlend = (blendResult.x == BLEND_DOMINANT || - !((blendResult.w != BLEND_NONE && !IsPixEqual(E, C)) || (blendResult.y != BLEND_NONE && !IsPixEqual(E, G)) || - (IsPixEqual(C, B) && IsPixEqual(B, A) && IsPixEqual(A, D) && IsPixEqual(D, G) && !IsPixEqual(E, A)))); + if(blendResult.x == BLEND_DOMINANT || (blendResult.x == BLEND_NORMAL && + !((blendResult.w != BLEND_NONE && !IsPixEqual(E, C)) || (blendResult.y != BLEND_NONE && !IsPixEqual(E, G)) || + (IsPixEqual(C, B) && IsPixEqual(B, A) && IsPixEqual(A, D) && IsPixEqual(D, G) && !IsPixEqual(E, A))))) + { + FragColor.x += 4.0; - vec2 origin = vec2(0.0, -1.0 / sqrt(2.0)); - vec2 direction = vec2(-1.0, 1.0); - if(doLineBlend) - { - bool haveShallowLine = (STEEP_DIRECTION_THRESHOLD * dist_D_C <= dist_B_G) && neq(E,C) && neq(F,C); - bool haveSteepLine = (STEEP_DIRECTION_THRESHOLD * dist_B_G <= dist_D_C) && neq(E,G) && neq(H,G); - origin = haveShallowLine? vec2(0.0, -0.25) : vec2(0.0, -0.5); - direction.x -= haveShallowLine? 1.0: 0.0; - direction.y += haveSteepLine? 1.0: 0.0; - } + float dist_D_C = DistYCbCr(D, C); + float dist_B_G = DistYCbCr(B, G); - vec3 blendPix = mix(D,B, step(DistYCbCr(E, B), DistYCbCr(E, D))); - res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale)); - } + if((STEEP_DIRECTION_THRESHOLD * dist_D_C <= dist_B_G) && neq(E,C) && neq(F,C)) + FragColor.x += 16.0; - FragColor = vec4(res, 1.0); + if((STEEP_DIRECTION_THRESHOLD * dist_B_G <= dist_D_C) && neq(E,G) && neq(H,G)) + FragColor.x += 64.0; + } + FragColor /= 255.0; } #endif diff --git a/Shaders/xbrz/xbrz-freescale-multipass.glsl.pass1 b/Shaders/xbrz/xbrz-freescale-multipass.glsl.pass1 new file mode 100644 index 000000000..0001c2dcb --- /dev/null +++ b/Shaders/xbrz/xbrz-freescale-multipass.glsl.pass1 @@ -0,0 +1,277 @@ +/* + Hyllian's xBR-vertex code and texel mapping + + Copyright (C) 2011/2016 Hyllian - sergiogdb@gmail.com + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +// This shader also uses code and/or concepts from xBRZ as it appears +// in the Desmume source code. The license for which is as follows: + +// **************************************************************************** +// * This file is part of the HqMAME project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * +// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved * +// * * +// * Additionally and as a special exception, the author gives permission * +// * to link the code of this program with the MAME library (or with modified * +// * versions of MAME that use the same license as MAME), and distribute * +// * linked combinations including the two. You must obey the GNU General * +// * Public License in all respects for all of the code used other than MAME. * +// * If you modify this file, you may extend this exception to your version * +// * of the file, but you are not obligated to do so. If you do not wish to * +// * do so, delete this exception statement from your version. * +// **************************************************************************** + +#if defined(VERTEX) + +#if __VERSION__ >= 130 +#define COMPAT_VARYING out +#define COMPAT_ATTRIBUTE in +#define COMPAT_TEXTURE texture +#else +#define COMPAT_VARYING varying +#define COMPAT_ATTRIBUTE attribute +#define COMPAT_TEXTURE texture2D +#endif + +#ifdef GL_ES +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +COMPAT_ATTRIBUTE vec4 VertexCoord; +COMPAT_ATTRIBUTE vec4 COLOR; +COMPAT_ATTRIBUTE vec4 TexCoord; +COMPAT_VARYING vec4 COL0; +COMPAT_VARYING vec4 TEX0; + +vec4 _oPosition1; +uniform mat4 MVPMatrix; +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; + +// compatibility #defines +#define vTexCoord TEX0.xy +#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize +#define OutSize vec4(OutputSize, 1.0 / OutputSize) + +void main() +{ + gl_Position = MVPMatrix * VertexCoord; + TEX0.xy = TexCoord.xy * 1.0001; +} + +#elif defined(FRAGMENT) + +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#define COMPAT_PRECISION mediump +#else +#define COMPAT_PRECISION +#endif + +#if __VERSION__ >= 130 +#define COMPAT_VARYING in +#define COMPAT_TEXTURE texture +out COMPAT_PRECISION vec4 FragColor; +#else +#define COMPAT_VARYING varying +#define FragColor gl_FragColor +#define COMPAT_TEXTURE texture2D +#endif + +uniform COMPAT_PRECISION int FrameDirection; +uniform COMPAT_PRECISION int FrameCount; +uniform COMPAT_PRECISION vec2 OutputSize; +uniform COMPAT_PRECISION vec2 TextureSize; +uniform COMPAT_PRECISION vec2 InputSize; +uniform sampler2D Texture; +uniform sampler2D PassPrev2Texture; +uniform COMPAT_PRECISION vec2 PassPrev2TextureSize; +COMPAT_VARYING vec4 TEX0; + +// compatibility #defines +#define Source Texture +#define vTexCoord TEX0.xy + +#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize +#define OutSize vec4(OutputSize, 1.0 / OutputSize) +#define OriginalSize vec4(PassPrev2TextureSize, 1.0 / PassPrev2TextureSize) + +#define BLEND_NONE 0. +#define BLEND_NORMAL 1. +#define BLEND_DOMINANT 2. +#define LUMINANCE_WEIGHT 1.0 +#define EQUAL_COLOR_TOLERANCE 30.0/255.0 +#define STEEP_DIRECTION_THRESHOLD 2.2 +#define DOMINANT_DIRECTION_THRESHOLD 3.6 + +float DistYCbCr(vec3 pixA, vec3 pixB) +{ + const vec3 w = vec3(0.2627, 0.6780, 0.0593); + const float scaleB = 0.5 / (1.0 - w.b); + const float scaleR = 0.5 / (1.0 - w.r); + vec3 diff = pixA - pixB; + float Y = dot(diff.rgb, w); + float Cb = scaleB * (diff.b - Y); + float Cr = scaleR * (diff.r - Y); + + return sqrt(((LUMINANCE_WEIGHT * Y) * (LUMINANCE_WEIGHT * Y)) + (Cb * Cb) + (Cr * Cr)); +} + +bool IsPixEqual(const vec3 pixA, const vec3 pixB) +{ + return (DistYCbCr(pixA, pixB) < EQUAL_COLOR_TOLERANCE); +} + +float get_left_ratio(vec2 center, vec2 origin, vec2 direction, vec2 scale) +{ + vec2 P0 = center - origin; + vec2 proj = direction * (dot(P0, direction) / dot(direction, direction)); + vec2 distv = P0 - proj; + vec2 orth = vec2(-direction.y, direction.x); + float side = sign(dot(P0, orth)); + float v = side * length(distv * scale); + +// return step(0, v); + return smoothstep(-sqrt(2.0)/2.0, sqrt(2.0)/2.0, v); +} + +#define eq(a,b) (a == b) +#define neq(a,b) (a != b) + +#define P(x,y) COMPAT_TEXTURE(PassPrev2Texture, coord + OriginalSize.zw * vec2(x, y)).rgb + +void main() +{ + //--------------------------------------- + // Input Pixel Mapping: -|B|- + // D|E|F + // -|H|- + + vec2 scale = OutputSize.xy * OriginalSize.zw; + vec2 pos = fract(vTexCoord * OriginalSize.xy) - vec2(0.5, 0.5); + vec2 coord = vTexCoord - pos * OriginalSize.zw; + + vec3 B = P( 0.,-1.); + vec3 D = P(-1., 0.); + vec3 E = P( 0., 0.); + vec3 F = P( 1., 0.); + vec3 H = P( 0., 1.); + + vec4 info = floor(COMPAT_TEXTURE(Source, coord) * 255.0 + 0.5); + + // info Mapping: x|y| + // w|z| + + vec4 blendResult = floor(mod(info, 4.0)); + vec4 doLineBlend = floor(mod(info / 4.0, 4.0)); + vec4 haveShallowLine = floor(mod(info / 16.0, 4.0)); + vec4 haveSteepLine = floor(mod(info / 64.0, 4.0)); + + vec3 res = E; + + // Pixel Tap Mapping: -|-|- + // -|E|F + // -|H|- + + if(blendResult.z > BLEND_NONE) + { + vec2 origin = vec2(0.0, 1.0 / sqrt(2.0)); + vec2 direction = vec2(1.0, -1.0); + if(doLineBlend.z > 0.0) + { + origin = haveShallowLine.z > 0.0? vec2(0.0, 0.25) : vec2(0.0, 0.5); + direction.x += haveShallowLine.z; + direction.y -= haveSteepLine.z; + } + + vec3 blendPix = mix(H,F, step(DistYCbCr(E, F), DistYCbCr(E, H))); + res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale)); + } + + // Pixel Tap Mapping: -|-|- + // D|E|- + // -|H|- + if(blendResult.w > BLEND_NONE) + { + vec2 origin = vec2(-1.0 / sqrt(2.0), 0.0); + vec2 direction = vec2(1.0, 1.0); + if(doLineBlend.w > 0.0) + { + origin = haveShallowLine.w > 0.0? vec2(-0.25, 0.0) : vec2(-0.5, 0.0); + direction.y += haveShallowLine.w; + direction.x += haveSteepLine.w; + } + + vec3 blendPix = mix(H,D, step(DistYCbCr(E, D), DistYCbCr(E, H))); + res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale)); + } + + // Pixel Tap Mapping: -|B|- + // -|E|F + // -|-|- + if(blendResult.y > BLEND_NONE) + { + vec2 origin = vec2(1.0 / sqrt(2.0), 0.0); + vec2 direction = vec2(-1.0, -1.0); + + if(doLineBlend.y > 0.0) + { + origin = haveShallowLine.y > 0.0? vec2(0.25, 0.0) : vec2(0.5, 0.0); + direction.y -= haveShallowLine.y; + direction.x -= haveSteepLine.y; + } + + vec3 blendPix = mix(F,B, step(DistYCbCr(E, B), DistYCbCr(E, F))); + res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale)); + } + + // Pixel Tap Mapping: -|B|- + // D|E|- + // -|-|- + if(blendResult.x > BLEND_NONE) + { + vec2 origin = vec2(0.0, -1.0 / sqrt(2.0)); + vec2 direction = vec2(-1.0, 1.0); + if(doLineBlend.x > 0.0) + { + origin = haveShallowLine.x > 0.0? vec2(0.0, -0.25) : vec2(0.0, -0.5); + direction.x -= haveShallowLine.x; + direction.y += haveSteepLine.x; + } + + vec3 blendPix = mix(D,B, step(DistYCbCr(E, B), DistYCbCr(E, D))); + res = mix(res, blendPix, get_left_ratio(pos, origin, direction, scale)); + } + + FragColor = vec4(res, 1.0); +} +#endif diff --git a/cnc-ddraw config.exe b/cnc-ddraw config.exe index 2a5fb8d31..3ad01cd56 100644 Binary files a/cnc-ddraw config.exe and b/cnc-ddraw config.exe differ diff --git a/ddraw.dll b/ddraw.dll index 8ef5eb725..57da59487 100644 Binary files a/ddraw.dll and b/ddraw.dll differ diff --git a/ddraw.ini b/ddraw.ini index aa0540341..159497f89 100644 --- a/ddraw.ini +++ b/ddraw.ini @@ -19,6 +19,9 @@ windowed=true ; Maintain aspect ratio maintas=false +; Use custom aspect ratio - Example values: 4:3, 16:10, 16:9, 21:9 +aspect_ratio= + ; Windowboxing / Integer Scaling boxing=false @@ -36,7 +39,9 @@ adjmouse=true ; Preliminary libretro shader support - (Requires 'renderer=opengl*') https://github.com/libretro/glsl-shaders ; 2x scaling example: https://imgur.com/a/kxsM1oY - 4x scaling example: https://imgur.com/a/wjrhpFV -shader=Shaders\cubic\catmull-rom-bilinear.glsl +; You can specify a full path to a .glsl shader file here or use one of the values listed below +; Possible values: Nearest neighbor, Bilinear, Bicubic, Lanczos, xBR-lv2 +shader=Shaders\interpolation\catmull-rom-bilinear.glsl ; Window position, -32000 = center to screen posX=-32000 @@ -59,24 +64,35 @@ savesettings=1 resizable=true ; Upscaling filter for the direct3d9* renderers -; Possible values: 0 = nearest-neighbor, 1 = bilinear, 2 = bicubic (16/32bit color depth games only) +; Possible values: 0 = nearest-neighbor, 1 = bilinear, 2 = bicubic, 3 = lanczos (bicubic/lanczos only support 16/32bit color depth games) d3d9_filter=2 -; Enable upscale hack for high resolution patches (Supports C&C1, Red Alert 1 and KKND Xtreme) +; Disable font smoothing for fonts that are smaller than size X +anti_aliased_fonts_min_size=13 + +; Raise the size of small fonts to X +min_font_size=0 + +; Center window to screen when game changes the display resolution +; Possible values: 0 = never center, 1 = automatic, 2 = always center +center_window=1 + +; Inject a custom display resolution into the in-game resolution list - Example values: 960x540, 3840x2160 +; Note: This setting can used for downscaling as well, you can insert resolutions higher than your monitor supports +inject_resolution= + +; Enable upscale hack for high resolution patches (Supports C&C1, Red Alert 1, Worms 2 and KKND Xtreme) vhack=false -; cnc-ddraw config program language, possible values: auto, english, chinese, german, spanish, russian, hungarian, french, italian -configlang=auto - -; cnc-ddraw config program theme, possible values: Windows10, Cobalt XEMedia -configtheme=Windows10 - ; Where should screenshots be saved screenshotdir=.\Screenshots\ ; Switch between windowed/borderless modes with alt+enter rather than windowed/fullscreen modes toggle_borderless=true +; Switch between windowed/fullscreen upscaled modes with alt+enter rather than windowed/fullscreen modes +toggle_upscaled=false + ; ### Compatibility settings ### @@ -84,53 +100,61 @@ toggle_borderless=true ; Hide WM_ACTIVATEAPP and WM_NCACTIVATE messages to prevent problems on alt+tab -noactivateapp=true +noactivateapp=false ; Max game ticks per second, possible values: -1 = disabled, -2 = refresh rate, 0 = emulate 60hz vblank, 1-1000 = custom game speed ; Note: Can be used to slow down a too fast running game, fix flickering or too fast animations ; Note: Usually one of the following values will work: 60 / 30 / 25 / 20 / 15 (lower value = slower game speed) maxgameticks=-1 +; Method that should be used to limit game ticks (maxgameticks=): 0 = Automatic, 1 = TestCooperativeLevel, 2 = BltFast, 3 = Unlock, 4 = PeekMessage +limiter_type=0 + ; Force minimum FPS, possible values: 0 = disabled, -1 = use 'maxfps=' value, -2 = same as -1 but force full redraw, 1-1000 = custom FPS ; Note: Set this to a low value such as 5 or 10 if some parts of the game are not being displayed (e.g. menus or loading screens) minfps=0 ; Disable fullscreen-exclusive mode for the direct3d9*/opengl* renderers ; Note: Can be used in case some GUI elements like buttons/textboxes/videos/etc.. are invisible -nonexclusive=false +nonexclusive=true ; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact ; Note: Disable this if the game is not running smooth or there are sound issues singlecpu=false -; Available resolutions, possible values: 0 = Small list, 1 = Very small list, 2 = Full list +; Available display resolutions, possible values: 0 = Small list, 1 = Very small list, 2 = Full list ; Note: Set this to 2 if your chosen resolution is not working or does not show up in the list ; Note: Set this to 1 if the game is crashing on startup resolutions=0 -; Child window handling, possible values: 0 = Disabled, 1 = Display top left, 2 = Display top left + repaint, 3 = Hide +; Child window handling, possible values: 0 = Disabled, 1 = Display top left, 2 = Display top left + repaint, 3 = Hide, 4 = Display top left + hide ; Note: Disables upscaling if a child window was detected (to ensure the game is fully playable, may look weird though) fixchilds=2 -; Enable the following setting if your cursor doesn't work properly when upscaling is enabled +; Enable the following setting if your cursor doesn't lock to the window or it doesn't work properly when upscaling is enabled hook_peekmessage=false -; Undocumented settings - You may or may not change these (You should rather focus on the settings above) -releasealt=true +; Undocumented compatibility settings - These will probably not solve your problem, you should rather focus on the settings above +fix_alt_key_stuck=true game_handles_close=false -fixnotresponding=false -hook=4 +fix_not_responding=false +no_compat_warning=false guard_lines=200 max_resolutions=0 -limit_bltfast=false lock_surfaces=false -allow_wmactivate=false flipclear=false -fixmousehook=true rgb555=false no_dinput_hook=false - +center_cursor_fix=false +;fake_mode=640x480x32 +lock_mouse_top_left=false +;win_version=95 +hook=4 +limit_gdi_handles=false +remove_menu=false +refresh_rate=0 +sirtech_hack=true ; ### Hotkeys ### @@ -141,9 +165,15 @@ no_dinput_hook=false ; Switch between windowed and fullscreen mode = [Alt] + ??? keytogglefullscreen=0x0D +; Switch between windowed and fullscreen mode (single key) = ??? +keytogglefullscreen2=0x00 + ; Maximize window = [Alt] + ??? keytogglemaximize=0x22 +; Maximize window (single key) = ??? +keytogglemaximize2=0x00 + ; Unlock cursor 1 = [Ctrl] + ??? keyunlockcursor1=0x09 @@ -155,16 +185,36 @@ keyscreenshot=0x2C +; ### Config program settings ### +; The following settings are for cnc-ddraw config.exe + + +; cnc-ddraw config program language, possible values: auto, english, chinese, german, spanish, russian, hungarian, french, italian, vietnamese +configlang=auto + +; cnc-ddraw config program theme, possible values: Windows10, Cobalt XEMedia +configtheme=Windows10 + +; Hide the 'Compatibility Settings' tab in cnc-ddraw config +hide_compat_tab=false + +; Allow the users to 'Restore default settings' via cnc-ddraw config +allow_reset=false + + + ; ### Game specific settings ### ; The following settings override all settings shown above, section name = executable name +; 7th Legion +[legion] +maxgameticks=25 +singlecpu=false + ; Atrox [Atrox] -renderer=gdi -hook=2 -fixchilds=0 -allow_wmactivate=true +nonexclusive=true ; Atomic Bomberman [BM] @@ -182,6 +232,12 @@ nonexclusive=true adjmouse=true resolutions=2 +; Age of Empires: The Rise of Rome (RockNRor patch) +[EmpiresX_RockNRor] +nonexclusive=true +adjmouse=true +resolutions=2 + ; Age of Empires II [EMPIRES2] nonexclusive=true @@ -192,22 +248,47 @@ adjmouse=true nonexclusive=true adjmouse=true +; Abomination - The Nemesis Project +[abomb] +singlecpu=false + ; American Conquest / Cossacks [DMCR] resolutions=2 guard_lines=300 minfps=-2 +; American Girls Dress Designer +[Dress Designer] +fake_mode=640x480x32 +nonexclusive=true + +; Age of Wonders +[AoW] +resolutions=2 +nonexclusive=false +singlecpu=false + +; Age of Wonders +[AoWCompat] +resolutions=2 +nonexclusive=false +singlecpu=false + +; Age of Wonders Config Tool +[AoWSetup] +resolutions=2 + ; Age of Wonders 2 [AoW2] resolutions=2 -renderer=opengl +nonexclusive=false singlecpu=false ; Age of Wonders 2 [AoW2Compat] resolutions=2 -renderer=opengl +nonexclusive=false singlecpu=false ; Age of Wonders 2 Config Tool @@ -217,13 +298,13 @@ resolutions=2 ; Age of Wonders: Shadow Magic [AoWSM] resolutions=2 -renderer=opengl +nonexclusive=false singlecpu=false ; Age of Wonders: Shadow Magic [AoWSMCompat] resolutions=2 -renderer=opengl +nonexclusive=false singlecpu=false ; Age of Wonders: Shadow Magic Config Tool @@ -239,24 +320,81 @@ adjmouse=true [1602] adjmouse=true +; Army Men: World War / Army Men: Operation Meltdown +[amww] +maxfps=60 +maxgameticks=120 +minfps=-1 + +; Army Men: Air Tactics +[Amat] +maxfps=60 +maxgameticks=120 +minfps=-1 + +; Army Men: Toys in Space +[ARMYMENTIS] +maxfps=60 +maxgameticks=120 +minfps=-1 + +; Army Men 2 +[ArmyMen2] +maxfps=60 +maxgameticks=120 +minfps=-1 + ; Alien Nations [AN] adjmouse=true +; Another War +[AnotherWar] +singlecpu=false + ; Atlantis [ATLANTIS] renderer=opengl maxgameticks=60 +center_cursor_fix=true ; Airline Tycoon Deluxe [AT] -fixchilds=0 +lock_mouse_top_left=true +fixchilds=3 + +; Arthur's Wilderness Rescue +[Arthur] +renderer=gdi + +; Axis & Allies +[AxisAllies] +hook_peekmessage=true +maxgameticks=60 + +; A Bug's Life Action Game +[bugs] +fix_not_responding=true + +; Barney - Secret of the Rainbow +[Barney] +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false ; Baldur's Gate II ; Note: 'Use 3D Acceleration' must be disabled and 'Full Screen' must be enabled in BGConfig.exe [BGMain] resolutions=2 +; Balls of Steel v1.2 +[bos] +checkfile=.\barbarin.ddp +win_version=95 + ; BALDR FORCE EXE [BaldrForce] noactivateapp=true @@ -271,19 +409,60 @@ fixchilds=3 checkfile=.\SOUND.REZ noactivateapp=true +; Blue's 123 Time Activities +[Blues123Time] +renderer=gdi +hook=3 + +; Blue's Treasure Hunt +[Blue'sTreasureHunt-Disc1] +renderer=gdi + +; Blue's Treasure Hunt +[Blue'sTreasureHunt-Disc2] +renderer=gdi + +; Blue's Reading Time Activities +[Blue's Reading Time] +renderer=gdi + +; Blue's ArtTime Activities +[ArtTime] +renderer=gdi + +; Callus 95 - CPS-1 (Capcom Play System 1) emulator +[CALLUS95] +game_handles_close=true +windowed=true +toggle_borderless=true +devmode=true + +; Callus 95 - CPS-1 (Capcom Play System 1) emulator +[CALLUS95p] +game_handles_close=true +windowed=true +toggle_borderless=true +devmode=true + ; Carmageddon [CARMA95] -noactivateapp=true flipclear=true +carma95_hack=true ; Carmageddon [CARM95] -noactivateapp=true flipclear=true +carma95_hack=true -; Carmageddon 2 -[Carma2_SW] -noactivateapp=true +; Carmen Sandiego's Great Chase - NOT WORKING YET +[TIME32] +renderer=gdi +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false ; Captain Claw [claw] @@ -291,6 +470,10 @@ adjmouse=true noactivateapp=true nonexclusive=true +; Championship Manager 99-00 +[cm9900] +singlecpu=false + ; Command & Conquer: Sole Survivor [SOLE] maxgameticks=120 @@ -330,6 +513,7 @@ minfps=-1 ; Command & Conquer: Tiberian Sun / Command & Conquer: Red Alert 2 [game] +nonexclusive=false checkfile=.\blowfish.dll tshack=true noactivateapp=true @@ -341,6 +525,7 @@ boxing=false ; Command & Conquer: Tiberian Sun Demo [SUN] +nonexclusive=false noactivateapp=true tshack=true adjmouse=true @@ -351,6 +536,7 @@ boxing=false ; Command & Conquer: Tiberian Sun - CnCNet [ts-spawn] +nonexclusive=false noactivateapp=true tshack=true adjmouse=true @@ -361,6 +547,7 @@ boxing=false ; Command & Conquer: Red Alert 2 - XWIS [ra2] +nonexclusive=false noactivateapp=true tshack=true maxfps=60 @@ -370,6 +557,7 @@ boxing=false ; Command & Conquer: Red Alert 2 - XWIS [Red Alert 2] +nonexclusive=false noactivateapp=true tshack=true maxfps=60 @@ -379,6 +567,7 @@ boxing=false ; Command & Conquer: Red Alert 2: Yuri's Revenge [gamemd] +nonexclusive=false noactivateapp=true tshack=true maxfps=60 @@ -388,6 +577,7 @@ boxing=false ; Command & Conquer: Red Alert 2: Yuri's Revenge - ?ModExe? [ra2md] +nonexclusive=false noactivateapp=true tshack=true maxfps=60 @@ -397,6 +587,7 @@ boxing=false ; Command & Conquer: Red Alert 2: Yuri's Revenge - CnCNet [gamemd-spawn] +nonexclusive=false noactivateapp=true tshack=true maxfps=60 @@ -406,6 +597,7 @@ boxing=false ; Command & Conquer: Red Alert 2: Yuri's Revenge - XWIS [Yuri's Revenge] +nonexclusive=false noactivateapp=true tshack=true maxfps=60 @@ -413,13 +605,26 @@ minfps=-1 maintas=false boxing=false +; Commandos +[comandos] +maxgameticks=-1 + +; Commandos +[comandos_w10] +maxgameticks=-1 + +; Constructor +[Game_W95] +noactivateapp=true + ; Caesar III [c3] nonexclusive=true adjmouse=true ; Chris Sawyer's Locomotion -[LOCO] +[LOCO/2] +checkfile=.\LOCO.EXE adjmouse=true ; Cultures 2 @@ -450,6 +655,24 @@ nonexclusive=true adjmouse=true nonexclusive=true +; ClueFinders Math Adventures 1.0 +[TCFM32] +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + +; ClueFinders Math Adventures 1.0 +[cfmath32] +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + ; Call To Power 2 [ctp2] maintas=false @@ -464,11 +687,15 @@ adjmouse=true resolutions=2 singlecpu=false +; Die by the Sword +[windie] +maxgameticks=30 + ; Dragon Throne: Battle of Red Cliffs [AdSanguo] maxgameticks=60 noactivateapp=true -limit_bltfast=true +limiter_type=2 ; Dark Reign: The Future of War [DKReign] @@ -479,6 +706,10 @@ maxgameticks=60 maxgameticks=60 noactivateapp=true +; Dreams to Realty +[windream] +maxgameticks=60 + ; Deadlock 2 [DEADLOCK] fixchilds=0 @@ -494,9 +725,27 @@ devmode=true [hellfire] devmode=true +; Disney Trivia Challenge +[DisneyTr] +fixchilds=3 +lock_mouse_top_left=true +renderer=gdi + +; Discoworld Noir +[dn] +fake_mode=640x480x16 + +; Dominion - Storm Over Gift 3 +[dominion] +flipclear=true + +; Excalibur 2555AD +[_FISH] +singlecpu=false + ; Escape Velocity Nova [EV Nova] -devmode=true +nonexclusive=true hook_peekmessage=true rgb555=true keytogglefullscreen=0x46 @@ -505,25 +754,116 @@ adjmouse=true ; Economic War [EcoW] maxgameticks=60 -fixnotresponding=true +fix_not_responding=true + +; Emperor: Rise of the Middle Kingdom +[Emperor] +nonexclusive=true +adjmouse=true + +; Enemy Infestation +[EI] +hook_peekmessage=true + +; F-16 Agressor +[f-16] +resolutions=1 + +; Fable +[FABLE] +singlecpu=false + +; Fallout Tactics: Brotherhood of Steel +[BOS/2] +checkfile=.\binkw32.dll +hook_peekmessage=true + +; Fallout Tactics: Brotherhood of Steel +[BOS_HR] +hook_peekmessage=true + +; Fallout Tactics: Brotherhood of Steel +[FT Tools] +hook_peekmessage=true + +; Falcon 4.0 (Microprose version) +[falcon4] +singlecpu=false + +; Flight Simulator 98 +[FLTSIM95] +flightsim98_hack=true + +; Flight Simulator 98 +[FLTSIM98] +flightsim98_hack=true ; Fairy Tale About Father Frost, Ivan and Nastya [mrazik] guard_lines=0 +; Final Liberation: Warhammer Epic 40000 +[Epic40k] +hook_peekmessage=true +maxgameticks=125 + ; Future Cop - L.A.P.D. [FCopLAPD] nonexclusive=true adjmouse=true +; Freddi 1 +[Freddi1] +renderer=gdi + +; Freddi Fish : The Case of the Hogfish Rustlers of Briny Gulch +[Freddihrbg] +renderer=gdi + +; Freddi Water Worries +[Water] +renderer=gdi + +; Freddi Fish +[FreddiSCS] +renderer=gdi + +; Freddi Fish +[FREDDI4] +renderer=gdi +hook=3 + +; Freddi Fish's One-Stop Fun Shop +[FreddisFunShop] +renderer=gdi + +; Freddi Fish: The Case of the Creature of Coral Cove +[freddicove] +renderer=gdi + +; Freddi Fish: The Case of the Haunted Schoolhouse +[FreddiCHSH] +renderer=gdi + +; Freddi Fish: Maze Madness +[Maze] +renderer=gdi + +; Glover +[glover] +fix_not_responding=true + ; G-Police [GPOLICE] maxgameticks=60 +singlecpu=false ; Gangsters: Organized Crime [gangsters] adjmouse=true nonexclusive=true +fixchilds=0 +fake_mode=640x480x8 ; Grand Theft Auto [Grand Theft Auto] @@ -537,17 +877,59 @@ singlecpu=false [Gta_61] singlecpu=false +; Gruntz +[GRUNTZ] +adjmouse=true +noactivateapp=true +nonexclusive=true + +; Girl Talk +[GirlTalk] +resolutions=2 +game_handles_close=true + +; Jazz Jackrabbit 2 plus +[Jazz2] +inject_resolution=800x450 + +; Jazz Jackrabbit 2 +[Jazz2_NonPlus] +inject_resolution=800x450 + +; Jungle Storm +[Jstorm] +no_compat_warning=true +win_version=98 + +; Hades Challenge +[HADESCH] +no_compat_warning=true + ; Heroes of Might and Magic II: The Succession Wars [HEROES2W] adjmouse=true ; Heroes of Might and Magic III [Heroes3] +renderer=opengl game_handles_close=true +keytogglefullscreen2=0x73 ; Heroes of Might and Magic III HD Mod [Heroes3 HD] +renderer=opengl game_handles_close=true +keytogglefullscreen2=0x73 + +; Heroes of Might and Magic III - Master of Puppets mod +[MoP] +game_handles_close=true +keytogglefullscreen2=0x73 + +; Heroes of Might and Magic IV +[heroes4] +remove_menu=true +keytogglefullscreen2=0x73 ; Hard Truck: Road to Victory [htruck] @@ -555,6 +937,26 @@ maxgameticks=25 renderer=opengl noactivateapp=true +; Hooligans: Storm over Europe +[hooligans] +limit_gdi_handles=true + +; Imperialism 2: The Age of Exploration +[Imperialism II] +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + +; Icewind Dale 2 +; Note: 'Full Screen' must be enabled in Config.exe +; Note: 1070x602 is the lowest possible 16:9 resolution for the Widescreen patch (600/601 height will crash) +[iwd2] +resolutions=2 +inject_resolution=1070x602 + ; Invictus [Invictus] adjmouse=true @@ -564,9 +966,14 @@ renderer=opengl [i76] adjmouse=true -; Infantry Online +; Infantry [infantry] -devmode=true +resolutions=2 +infantryhack=true +max_resolutions=90 + +; Infantry Steam +[FreeInfantry] resolutions=2 infantryhack=true max_resolutions=90 @@ -574,41 +981,42 @@ max_resolutions=90 ; Jagged Alliance 2 [ja2] singlecpu=false -fixmousehook=true -noactivateapp=true -releasealt=true +sirtech_hack=true +fix_alt_key_stuck=true ; Jagged Alliance 2: Unfinished Business [JA2UB] singlecpu=false -fixmousehook=true -noactivateapp=true -releasealt=true +sirtech_hack=true +fix_alt_key_stuck=true ; Jagged Alliance 2: Wildfire [WF6] singlecpu=false -fixmousehook=true -noactivateapp=true -releasealt=true +sirtech_hack=true +fix_alt_key_stuck=true ; Jagged Alliance 2 - UC mod [JA2_UC] singlecpu=false -fixmousehook=true -noactivateapp=true -releasealt=true +sirtech_hack=true +fix_alt_key_stuck=true ; Jagged Alliance 2 - Vengeance Reloaded mod [JA2_Vengeance] singlecpu=false -fixmousehook=true -noactivateapp=true -releasealt=true +sirtech_hack=true +fix_alt_key_stuck=true -; Kings Quest 8 -[Mask] -renderer=opengl +; Jeopardy! - NOT WORKING YET +[jeoppc] +singlecpu=false + +; Karma Immortal Wrath +[karma] +fix_not_responding=true +maxgameticks=60 +limiter_type=4 ; Konung [konung] @@ -626,10 +1034,129 @@ vhack=true [KKND2] noactivateapp=true +; Knights and Merchants The Shattered Kingdom +[KaM_800] +limiter_type=2 +maxgameticks=60 + +; Knights and Merchants The Shattered Kingdom +[KaM_1024] +limiter_type=2 +maxgameticks=60 + +; Lode Runner 2 +[LR2] +no_dinput_hook=true +fake_mode=640x480x16 + +; Last Bronx +[LB] +maxgameticks=30 + +; Lapis (lapis.mgame.com) +[Lapis] +fixchilds=3 +lock_mouse_top_left=true + +; LEGO LOCO - NOT WORKING YET +[LOCO] +checkfile=.\LEGO.INI +fake_mode=1024x768x16 +posX=0 +posY=0 +border=false +fullscreen=false + +; Little Bear Kindergarten/Preschool Thinking Adventures: Parent's Progress Report +[LBPR] +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + +; Little Bear Kindergarten/Preschool Thinking Adventures +[LBSTART] +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + +; Little Bear Toddler Discovery Adventures +[LBT] +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + ; Lionheart [Lionheart] hook_peekmessage=true +; Links Extreme +[EXTREME] +singlecpu=false + +; Lost Vikings 2 +[LOSTV95] +fake_mode=320x240x16 + +; Nightmare Creatures +[NC] +maxgameticks=30 +singlecpu=false + +; Moto Racer (software mode) +[moto] +maxgameticks=59 + +; Madeline 1st Grade Math +[madmath1] +nonexclusive=true +no_compat_warning=true +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false +renderer=gdi +hook=2 +win_version=nt4 + +; Madeline 1st Grade Math: Progress Report +[madpr] +nonexclusive=true +no_compat_warning=true +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false +renderer=gdi +hook=2 +win_version=nt4 + +; Madeline 2nd Grade Math +[madmath2] +nonexclusive=true +no_compat_warning=true +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false +renderer=gdi +hook=2 +win_version=nt4 + ; Majesty Gold [Majesty] minfps=-2 @@ -648,13 +1175,53 @@ nonexclusive=true ; Moorhuhn 2 [Moorhuhn2] -releasealt=true +fix_alt_key_stuck=true + +; Metal Knight +[mk] +maxgameticks=60 +limiter_type=4 ; New Robinson [ROBY] adjmouse=true hook_peekmessage=true +; Neo Sonic Universe +[nsu] +fake_mode=320x240x32 + +; Neo Sonic Universe - battle mode +[nsu_battle] +fake_mode=320x240x32 + +; Nancy Drew (All games) +[Game/3] +checkfile=.\Nancy.cid +limiter_type=1 +maxgameticks=120 + +; NBA Full Court Press +[NBA_FCP] +fake_mode=640x480x8 + +; Nox +[NOX] +checkfile=.\NOX.ICD +renderer=direct3d9 +nonexclusive=false +windowed=false +maxgameticks=125 + +; Nox Reloaded +[NoxReloaded] +maxgameticks=125 + +; Nox GOG +[Game/2] +checkfile=.\nox.cfg +maxgameticks=125 + ; Outlaws [olwin] noactivateapp=true @@ -662,22 +1229,211 @@ maxgameticks=60 adjmouse=true renderer=gdi +; Pandora's Box Puzzle Game +[Pandora] +fixchilds=0 + +; Paddle Bash Hotshot +[SPAGHSPaddle] +no_compat_warning=true + +; Pajama Sam's Games to Play on Any Day +[PJGAMES] +renderer=gdi + +; Pajama Sam +[PajamaTAL] +renderer=gdi + +; Pajama Sam: No Need to Hide When It's Dark Outside +[PajamaNHD] +renderer=gdi + +; Pajama Sam 3 +[Pajama3] +renderer=gdi + +; Pajama Sam's One-Stop Fun Shop +[SamsFunShop] +renderer=gdi + +; Pajama Sam DON'T FEAR THE DARK +[pjSam] +renderer=gdi + +; Pajama Sam 3: You Are What You Eat From Your Head To Your Feet +[UKpajamaEAT] +renderer=gdi + ; Pharaoh [Pharaoh] adjmouse=true +; Putt-Putt Saves The Zoo +[PUTTZOO] +renderer=gdi +hook=3 + +; Putt-Putt's One-Stop Fun Shop +[PuttsFunShop] +renderer=gdi + +; Putt-Putt and Pep's Dog On A Stick +[DOG] +renderer=gdi + +; Putt-Putt Joins the Circus +[puttcircus] +renderer=gdi + +; Putt-Putt Enters The Race +[UKPuttRace] +renderer=gdi + +; Putt-Putt: Travels Through Time +[PuttTTT] +renderer=gdi + +; Putt-Putt and Pep's Balloon-o-Rama +[Balloon] +renderer=gdi + +; Putt-Putt Travels Through Time +[PUTTPUTTTTT] +renderer=gdi + +; Putt-Putt Joins the Circus +[puttputtjtc] +renderer=gdi + +; Pizza Syndicate +[Pizza2] +renderer=opengl + +; Pizza Syndicate - Mehr Biss (Mission CD) +[Pizza_Mission] +renderer=opengl + ; Pax Imperia [Pax Imperia] nonexclusive=true +; Panzer Dragoon +[PANZERDG] +singlecpu=false + +; Play with the Teletubbies +[PlayWTT] +hook=3 + +; Populous - The Beginning +[popTB] +singlecpu=false + +; Rage of Mages +[rom] +maxgameticks=60 +limiter_type=4 +singlecpu=true + ; Railroad Tycoon II [RT2] -adjmouse=true +maxgameticks=60adjmouse=true + +; Reader Rabbit Thinking Ages 4-6 (US) +[rrta32] +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + +; Reader Rabbit Reading Ages 4-6 +[rrirjw32] +renderer=gdi +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + +; Reader Rabbit Reading Ages 6-9 +[irj2w32] +renderer=gdi +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + +; Real War +[RealWar] +maxgameticks=60 +limiter_type=3 + +; Return to Krondor +[RtK] +fixchilds=3 +lock_mouse_top_left=true +singlecpu=false +limiter_type=2 +game_handles_close=true +maxgameticks=59 +anti_aliased_fonts_min_size=99 + +; Rent-A-Hero +[Rent-A-Hero] +singlecpu=false ; ROAD RASH [RoadRash] adjmouse=true -fixchilds=1 +nonexclusive=true + +; Rising Lands (patched) +[Rising] +singlecpu=false + +; Robin Hood - The Legend of Sherwood (GOG) +[Game/4] +checkfile=.\Robin Hood.exe +singlecpu=false +fix_not_responding=true + +; Roland Garros 98 (software mode) +[rg98] +singlecpu=false + +; Robin Hood - The Legend of Sherwood (Steam) +[_rh] +singlecpu=false +fix_not_responding=true + +; Robin Hood - The Legend of Sherwood +[Robin Hood] +singlecpu=false +fix_not_responding=true + +; Scooby-Doo(TM), Case File #1 The Glowing Bug Man - NOT WORKING YET +[Case File #1] +windowed=true +nonexclusive=true +fake_mode=640x480x32 + +; Seven Kingdoms II +[7k2] +fake_mode=352x240x32 +fix_not_responding=true + +; Swarog +[Swarog] +singlecpu=false +maxfps=60 +maxgameticks=60 +minfps=-1 ; Sim Copter [SimCopter] @@ -695,6 +1451,15 @@ adjmouse=true maintas=false boxing=false +; Star Wars Rebellion +[REBEXE] +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + ; Star Wars: Galactic Battlegrounds [battlegrounds] nonexclusive=true @@ -713,6 +1478,34 @@ game_handles_close=true [Rangers] hook_peekmessage=true +; SPYFox: Hold the Mustard +[mustard] +renderer=gdi + +; SPY Fox: Some Assembly Required +[Spyfox2] +renderer=gdi + +; SPY Fox in Dry Cereal (2008) +[SpyFox] +renderer=gdi + +; SPY Fox in Dry Cereal (2001) +[SPYFOXDC] +renderer=gdi + +; SPY Fox : Some Assembly Required +[SPYFOXSR] +renderer=gdi + +; SPY Fox: Operation Ozone +[spyozon] +renderer=gdi + +; SPY Fox: Operation Ozone +[spyfoxozu] +renderer=gdi + ; Stronghold Crusader HD [Stronghold Crusader] resolutions=2 @@ -734,35 +1527,95 @@ adjmouse=true ; Sim City 3000 [SC3] minfps=-2 - +maxgameticks=60 ; Shadow Watch [sw] adjmouse=true - +maxgameticks=30 ; Shadow Flare [ShadowFlare] nonexclusive=true adjmouse=true -maintas=false -boxing=false + +; Squad Leader +[SquadLeader] +maxgameticks=30 +limiter_type=4 + +; Soldiers At War +[SAW_Game] +maxgameticks=30 +limiter_type=4 + +; The Curse Of Monkey Island +[COMI] +singlecpu=false + +; The Tone Rebellion +[Float] +hook_peekmessage=true ; Total Annihilation (Unofficial Beta Patch v3.9.02) [TotalA] -resolutions=2 +max_resolutions=32 lock_surfaces=true singlecpu=false ; Total Annihilation Replay Viewer (Unofficial Beta Patch v3.9.02) [Viewer] -resolutions=2 +max_resolutions=32 lock_surfaces=true singlecpu=false +; Virtual Springfield +[VIRTUAL] +game_handles_close=true +singlecpu=false + +; Total Annihilation: Kingdoms +[Kingdoms] +game_handles_close=true +max_resolutions=32 + +; The Missing on Lost Island +[Island] +lock_mouse_top_left=true +fixchilds=3 + +; The Neverhood +[nhc] +singlecpu=false + +; The X-Files DVD +[XFiles] +windowed=true +fullscreen=true +toggle_borderless=true + +; The Learning Company Launcher +[TLCLauncher] +tlc_hack=true +adjmouse=false +width=0 +height=0 +resizable=false +maintas=false +boxing=false + +; The Jungle Book Groove Party +[Jungle_vr] +fix_not_responding=true + ; Three Kingdoms: Fate of the Dragon [sanguo] maxgameticks=60 noactivateapp=true -limit_bltfast=true +limiter_type=2 + +; Thomas & Friends - The Great Festival Adventure +[Thomas] +no_compat_warning=true +noactivateapp=true ; RollerCoaster Tycoon [rct] @@ -791,6 +1644,12 @@ boxing=false [Tzar] adjmouse=true +; Unreal +[Unreal] +adjmouse=false +lock_mouse_top_left=true +center_cursor_fix=true + ; Uprising [uprising] adjmouse=true @@ -800,24 +1659,75 @@ adjmouse=true renderer=opengl adjmouse=true +; Unreal +[Unreal] +noactivateapp=true + +; Vermeer +[vermeer] +adjmouse=true +fake_mode=640x480x32 + +; Virtua Fighter 2 +[VF2] +fake_mode=640x480x8 + +; Wall Street Trader 2000 - NOT WORKING YET +[WSTrader] +nonexclusive=false +windowed=false + +; WarCraft 2000: Nuclear Epidemic +[war2000] +resolutions=2 +guard_lines=600 +minfps=-2 + +; Warhammer 40000: Chaos Gate +[WH40K] +maxgameticks=250 + +; Weird War +[WeirdWar] +singlecpu=false + ; Wizardry 8 [Wiz8] -fixmousehook=true -noactivateapp=true -releasealt=true +sirtech_hack=true +fix_alt_key_stuck=true + +; Worms 2 +[worms2] +vhack=true +flipclear=true +game_handles_close=true +center_cursor_fix=true ; Worms Armageddon [WA] -adjmouse=true -width=0 -height=0 -resizable=false +lock_mouse_top_left=true + +; Wheel Of Fortune +[WHEEL] +singlecpu=false ; War Wind [WW] minfps=-1 +; Jeff Wayne's 'The War Of The Worlds' +[WoW] +singlecpu=false +minfps=-1 + ; Zeus and Poseidon [Zeus] adjmouse=true +; Zork Nemesis +[znemesis] +fix_not_responding=true +singlecpu=false +maxgameticks=60 +limiter_type=4 +