commit aa8eed94fba87c00dcc2f5e058bab60475c530a0 Author: sma11case Date: Sat Jan 3 12:00:01 2026 +0800 傲世三国之三分天下-高清HD加强版 diff --git a/RegSetup.exe b/RegSetup.exe new file mode 100644 index 0000000..15b1abe Binary files /dev/null and b/RegSetup.exe differ diff --git a/SDL2.dll b/SDL2.dll new file mode 100644 index 0000000..49d566b Binary files /dev/null and b/SDL2.dll differ diff --git a/SDL2_mixer.dll b/SDL2_mixer.dll new file mode 100644 index 0000000..67c76d2 Binary files /dev/null and b/SDL2_mixer.dll differ diff --git a/Shaders/crt/crt-lottes-fast-no-warp-bilinear.glsl b/Shaders/crt/crt-lottes-fast-no-warp-bilinear.glsl new file mode 100644 index 0000000..449b9be --- /dev/null +++ b/Shaders/crt/crt-lottes-fast-no-warp-bilinear.glsl @@ -0,0 +1,701 @@ +//_____________________________/\_______________________________ +//============================================================== +// +// +// [CRTS] PUBLIC DOMAIN CRT-STYLED SCALAR - 20180120b +// +// by Timothy Lottes +// https://www.shadertoy.com/view/MtSfRK +// adapted for RetroArch by hunterk +// +// +//============================================================== +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//_____________________________/\_______________________________ +//============================================================== +// +// WHAT'S NEW +// +//-------------------------------------------------------------- +// Evolution of prior shadertoy example +//-------------------------------------------------------------- +// This one is semi-optimized +// - Less texture fetches +// - Didn't get to instruction level optimization +// - Could likely use texture fetch to generate phosphor mask +//-------------------------------------------------------------- +// Added options to disable unused features +//-------------------------------------------------------------- +// Added in exposure matching +// - Given scan-line effect and mask always darkens image +// - Uses generalized tonemapper to boost mid-level +// - Note this can compress highlights +// - And won't get back peak brightness +// - But best option if one doesn't want as much darkening +//-------------------------------------------------------------- +// Includes option saturation and contrast controls +//-------------------------------------------------------------- +// Added in subtractive aperture grille +// - This is a bit brighter than prior +//-------------------------------------------------------------- +// Make sure input to this filter is already low-resolution +// - This is not designed to work on titles doing the following +// - Rendering to hi-res with nearest sampling +//-------------------------------------------------------------- +// Added a fast and more pixely option for 2 tap/pixel +//-------------------------------------------------------------- +// Improved the vignette when WARP is enabled +//-------------------------------------------------------------- +// Didn't test HLSL or CPU options +// - Will incorportate patches if they are broken +// - But out of time to try them myself +//============================================================== +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//_____________________________/\_______________________________ +//============================================================== +// +// LICENSE = UNLICENSE (aka PUBLIC DOMAIN) +// +//-------------------------------------------------------------- +// This is free and unencumbered software released into the +// public domain. +//-------------------------------------------------------------- +// Anyone is free to copy, modify, publish, use, compile, sell, +// or distribute this software, either in source code form or as +// a compiled binary, for any purpose, commercial or +// non-commercial, and by any means. +//-------------------------------------------------------------- +// In jurisdictions that recognize copyright laws, the author or +// authors of this software dedicate any and all copyright +// interest in the software to the public domain. We make this +// dedication for the benefit of the public at large and to the +// detriment of our heirs and successors. We intend this +// dedication to be an overt act of relinquishment in perpetuity +// of all present and future rights to this software under +// copyright law. +//-------------------------------------------------------------- +// 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 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. +//-------------------------------------------------------------- +// For more information, please refer to +// +//============================================================== +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// + +#pragma parameter MASK "Mask Type" 1.0 0.0 3.0 1.0 +#pragma parameter MASK_INTENSITY "Mask Intensity" 0.5 0.0 1.0 0.05 +#pragma parameter SCANLINE_THINNESS "Scanline Intensity" 0.5 0.0 1.0 0.1 +#pragma parameter SCAN_BLUR "Sharpness" 2.5 1.0 3.0 0.1 +#pragma parameter CURVATURE "Curvature" 0.02 0.0 0.25 0.01 +#pragma parameter TRINITRON_CURVE "Trinitron-style Curve" 0.0 0.0 1.0 1.0 +#pragma parameter CORNER "Corner Round" 3.0 0.0 11.0 1.0 +#pragma parameter CRT_GAMMA "CRT Gamma" 2.4 0.0 51.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; + +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; +} + +#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; + +// 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 CRT_GAMMA; +uniform COMPAT_PRECISION float SCANLINE_THINNESS; +uniform COMPAT_PRECISION float SCAN_BLUR; +uniform COMPAT_PRECISION float MASK_INTENSITY; +uniform COMPAT_PRECISION float CURVATURE; +uniform COMPAT_PRECISION float CORNER; +uniform COMPAT_PRECISION float MASK; +uniform COMPAT_PRECISION float TRINITRON_CURVE; +#else +#define CRT_GAMMA 2.4 +#define SCANLINE_THINNESS 0.5 +#define SCAN_BLUR 2.5 +#define MASK_INTENSITY 0.54 +#define CURVATURE 0.00 +#define CORNER 3.0 +#define MASK 1.0 +#define TRINITRON_CURVE 0.0 +#endif + +//_____________________________/\_______________________________ +//============================================================== +// +// GAMMA FUNCTIONS +// +//-------------------------------------------------------------- +//-------------------------------------------------------------- +// Since shadertoy doesn't have sRGB textures +// And we need linear input into shader +// Don't do this in your code + float FromSrgb1(float c){ + return (c<=0.04045)?c*(1.0/12.92): + pow(c*(1.0/1.055)+(0.055/1.055),CRT_GAMMA);} +//-------------------------------------------------------------- +vec3 FromSrgb(vec3 c){return vec3( + FromSrgb1(c.r),FromSrgb1(c.g),FromSrgb1(c.b));} + +// Convert from linear to sRGB +// Since shader toy output is not linear +float ToSrgb1(float c){ + return(c<0.0031308?c*12.92:1.055*pow(c,0.41666)-0.055);} +//-------------------------------------------------------------- +vec3 ToSrgb(vec3 c){return vec3( + ToSrgb1(c.r),ToSrgb1(c.g),ToSrgb1(c.b));} +//-------------------------------------------------------------- + +//_____________________________/\_______________________________ +//============================================================== +// +// DEFINES +// +//-------------------------------------------------------------- +// CRTS_CPU - CPU code +// CRTS_GPU - GPU code +//-------------------------------------------------------------- +// CRTS_GLSL - GLSL +// CRTS_HLSL - HLSL (not tested yet) +//-------------------------------------------------------------- +// CRTS_DEBUG - Define to see on/off split screen +//-------------------------------------------------------------- +// CRTS_WARP - Apply screen warp +//-------------------------------------------------------------- +// CRTS_2_TAP - Faster very pixely 2-tap filter (off is 8) +//-------------------------------------------------------------- +// CRTS_MASK_GRILLE - Aperture grille (aka Trinitron) +// CRTS_MASK_GRILLE_LITE - Brighter (subtractive channels) +// CRTS_MASK_NONE - No mask +// CRTS_MASK_SHADOW - Horizontally stretched shadow mask +//-------------------------------------------------------------- +// CRTS_TONE - Normalize mid-level and process color +// CRTS_CONTRAST - Process color - enable contrast control +// CRTS_SATURATION - Process color - enable saturation control +//-------------------------------------------------------------- +#define CRTS_STATIC +#define CrtsPow +#define CRTS_RESTRICT +//============================================================== +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// + +//============================================================== +// SETUP FOR CRTS +//-------------------------------------------------------------- +//============================================================== +//#define CRTS_DEBUG 1 +#define CRTS_GPU 1 +#define CRTS_GLSL 1 +//-------------------------------------------------------------- +//#define CRTS_2_TAP 1 +//-------------------------------------------------------------- +#define CRTS_TONE 1 +#define CRTS_CONTRAST 0 +#define CRTS_SATURATION 0 +//-------------------------------------------------------------- +#define CRTS_WARP 1 +//-------------------------------------------------------------- +// Try different masks -> moved to runtime parameters +//#define CRTS_MASK_GRILLE 1 +//#define CRTS_MASK_GRILLE_LITE 1 +//#define CRTS_MASK_NONE 1 +//#define CRTS_MASK_SHADOW 1 +//-------------------------------------------------------------- +// Scanline thinness +// 0.50 = fused scanlines +// 0.70 = recommended default +// 1.00 = thinner scanlines (too thin) +#define INPUT_THIN 0.5 + (0.5 * SCANLINE_THINNESS) +//-------------------------------------------------------------- +// Horizonal scan blur +// -3.0 = pixely +// -2.5 = default +// -2.0 = smooth +// -1.0 = too blurry +#define INPUT_BLUR -1.0 * SCAN_BLUR +//-------------------------------------------------------------- +// Shadow mask effect, ranges from, +// 0.25 = large amount of mask (not recommended, too dark) +// 0.50 = recommended default +// 1.00 = no shadow mask +#define INPUT_MASK 1.0 - MASK_INTENSITY +//-------------------------------------------------------------- +#define INPUT_X InputSize.x +#define INPUT_Y InputSize.y +//-------------------------------------------------------------- +// Setup the function which returns input image color +vec3 CrtsFetch(vec2 uv){ + // For shadertoy, scale to get native texels in the image + uv*=vec2(INPUT_X,INPUT_Y)/TextureSize.xy; + // Move towards intersting parts +// uv+=vec2(0.5,0.5); + // Non-shadertoy case would not have the color conversion + return FromSrgb(COMPAT_TEXTURE(Texture,uv.xy,-16.0).rgb);} +#endif + +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +//_____________________________/\_______________________________ +//============================================================== +// +// GPU CODE +// +//============================================================== +#ifdef CRTS_GPU +//_____________________________/\_______________________________ +//============================================================== +// PORTABILITY +//============================================================== + #ifdef CRTS_GLSL + #define CrtsF1 float + #define CrtsF2 vec2 + #define CrtsF3 vec3 + #define CrtsF4 vec4 + #define CrtsFractF1 fract + #define CrtsRcpF1(x) (1.0/(x)) + #define CrtsSatF1(x) clamp((x),0.0,1.0) +//-------------------------------------------------------------- + CrtsF1 CrtsMax3F1(CrtsF1 a,CrtsF1 b,CrtsF1 c){ + return max(a,max(b,c));} + #endif +//============================================================== + #ifdef CRTS_HLSL + #define CrtsF1 float + #define CrtsF2 float2 + #define CrtsF3 float3 + #define CrtsF4 float4 + #define CrtsFractF1 frac + #define CrtsRcpF1(x) (1.0/(x)) + #define CrtsSatF1(x) saturate(x) +//-------------------------------------------------------------- + CrtsF1 CrtsMax3F1(CrtsF1 a,CrtsF1 b,CrtsF1 c){ + return max(a,max(b,c));} + #endif +//_____________________________/\_______________________________ +//============================================================== +// TONAL CONTROL CONSTANT GENERATION +//-------------------------------------------------------------- +// This is in here for rapid prototyping +// Please use the CPU code and pass in as constants +//============================================================== + CrtsF4 CrtsTone( + CrtsF1 contrast, + CrtsF1 saturation, + CrtsF1 thin, + CrtsF1 mask){ +//-------------------------------------------------------------- + if(MASK == 0.0) mask=1.0; +//-------------------------------------------------------------- + if(MASK == 1.0){ + // Normal R mask is {1.0,mask,mask} + // LITE R mask is {mask,1.0,1.0} + mask=0.5+mask*0.5; + } +//-------------------------------------------------------------- + CrtsF4 ret; + CrtsF1 midOut=0.18/((1.5-thin)*(0.5*mask+0.5)); + CrtsF1 pMidIn=pow(0.18,contrast); + ret.x=contrast; + ret.y=((-pMidIn)+midOut)/((1.0-pMidIn)*midOut); + ret.z=((-pMidIn)*midOut+pMidIn)/(midOut*(-pMidIn)+midOut); + ret.w=contrast+saturation; + return ret;} +//_____________________________/\_______________________________ +//============================================================== +// MASK +//-------------------------------------------------------------- +// Letting LCD/OLED pixel elements function like CRT phosphors +// So "phosphor" resolution scales with display resolution +//-------------------------------------------------------------- +// Not applying any warp to the mask (want high frequency) +// Real aperture grille has a mask which gets wider on ends +// Not attempting to be "real" but instead look the best +//-------------------------------------------------------------- +// Shadow mask is stretched horizontally +// RRGGBB +// GBBRRG +// RRGGBB +// This tends to look better on LCDs than vertical +// Also 2 pixel width is required to get triad centered +//-------------------------------------------------------------- +// The LITE version of the Aperture Grille is brighter +// Uses {dark,1.0,1.0} for R channel +// Non LITE version uses {1.0,dark,dark} +//-------------------------------------------------------------- +// 'pos' - This is 'fragCoord.xy' +// Pixel {0,0} should be {0.5,0.5} +// Pixel {1,1} should be {1.5,1.5} +//-------------------------------------------------------------- +// 'dark' - Exposure of of masked channel +// 0.0=fully off, 1.0=no effect +//============================================================== + CrtsF3 CrtsMask(CrtsF2 pos,CrtsF1 dark){ + if(MASK == 2.0){ + CrtsF3 m=CrtsF3(dark,dark,dark); + CrtsF1 x=CrtsFractF1(pos.x*(1.0/3.0)); + if(x<(1.0/3.0))m.r=1.0; + else if(x<(2.0/3.0))m.g=1.0; + else m.b=1.0; + return m; + } +//-------------------------------------------------------------- + if(MASK == 1.0){ + CrtsF3 m=CrtsF3(1.0,1.0,1.0); + CrtsF1 x=CrtsFractF1(pos.x*(1.0/3.0)); + if(x<(1.0/3.0))m.r=dark; + else if(x<(2.0/3.0))m.g=dark; + else m.b=dark; + return m; + } +//-------------------------------------------------------------- + if(MASK == 0.0){ + return CrtsF3(1.0,1.0,1.0); + } +//-------------------------------------------------------------- + if(MASK == 3.0){ + pos.x+=pos.y*2.9999; + CrtsF3 m=CrtsF3(dark,dark,dark); + CrtsF1 x=CrtsFractF1(pos.x*(1.0/6.0)); + if(x<(1.0/3.0))m.r=1.0; + else if(x<(2.0/3.0))m.g=1.0; + else m.b=1.0; + return m; + } + } +//_____________________________/\_______________________________ +//============================================================== +// FILTER ENTRY +//-------------------------------------------------------------- +// Input must be linear +// Output color is linear +//-------------------------------------------------------------- +// Must have fetch function setup: CrtsF3 CrtsFetch(CrtsF2 uv) +// - The 'uv' range is {0.0 to 1.0} for input texture +// - Output of this must be linear color +//-------------------------------------------------------------- +// SCANLINE MATH & AUTO-EXPOSURE NOTES +// =================================== +// Each output line has contribution from at most 2 scanlines +// Scanlines are shaped by a windowed cosine function +// This shape blends together well with only 2 lines of overlap +//-------------------------------------------------------------- +// Base scanline intensity is as follows +// which leaves output intensity range from {0 to 1.0} +// -------- +// thin := range {thick 0.5 to thin 1.0} +// off := range {0.0 to <1.0}, +// sub-pixel offset between two scanlines +// -------- +// a0=cos(min(0.5, off *thin)*2pi)*0.5+0.5; +// a1=cos(min(0.5,(1.0-off)*thin)*2pi)*0.5+0.5; +//-------------------------------------------------------------- +// This leads to a image darkening factor of roughly: +// {(1.5-thin)/1.0} +// This is further reduced by the mask: +// {1.0/2.0+mask*1.0/2.0} +// Reciprocal of combined effect is used for auto-exposure +// to scale up the mid-level in the tonemapper +//============================================================== + CrtsF3 CrtsFilter( +//-------------------------------------------------------------- + // SV_POSITION, fragCoord.xy + CrtsF2 ipos, +//-------------------------------------------------------------- + // inputSize / outputSize (in pixels) + CrtsF2 inputSizeDivOutputSize, +//-------------------------------------------------------------- + // 0.5 * inputSize (in pixels) + CrtsF2 halfInputSize, +//-------------------------------------------------------------- + // 1.0 / inputSize (in pixels) + CrtsF2 rcpInputSize, +//-------------------------------------------------------------- + // 1.0 / outputSize (in pixels) + CrtsF2 rcpOutputSize, +//-------------------------------------------------------------- + // 2.0 / outputSize (in pixels) + CrtsF2 twoDivOutputSize, +//-------------------------------------------------------------- + // inputSize.y + CrtsF1 inputHeight, +//-------------------------------------------------------------- + // Warp scanlines but not phosphor mask + // 0.0 = no warp + // 1.0/64.0 = light warping + // 1.0/32.0 = more warping + // Want x and y warping to be different (based on aspect) + CrtsF2 warp, +//-------------------------------------------------------------- + // Scanline thinness + // 0.50 = fused scanlines + // 0.70 = recommended default + // 1.00 = thinner scanlines (too thin) + // Shared with CrtsTone() function + CrtsF1 thin, +//-------------------------------------------------------------- + // Horizonal scan blur + // -3.0 = pixely + // -2.5 = default + // -2.0 = smooth + // -1.0 = too blurry + CrtsF1 blur, +//-------------------------------------------------------------- + // Shadow mask effect, ranges from, + // 0.25 = large amount of mask (not recommended, too dark) + // 0.50 = recommended default + // 1.00 = no shadow mask + // Shared with CrtsTone() function + CrtsF1 mask, +//-------------------------------------------------------------- + // Tonal curve parameters generated by CrtsTone() + CrtsF4 tone +//-------------------------------------------------------------- + ){ +//-------------------------------------------------------------- + #ifdef CRTS_DEBUG + CrtsF2 uv=ipos*rcpOutputSize; + // Show second half processed, and first half un-processed + if(uv.x<0.5){ + // Force nearest to get squares + uv*=1.0/rcpInputSize; + uv=floor(uv)+CrtsF2(0.5,0.5); + uv*=rcpInputSize; + CrtsF3 color=CrtsFetch(uv); + return color;} + #endif +//-------------------------------------------------------------- + // Optional apply warp + CrtsF2 pos; + #ifdef CRTS_WARP + // Convert to {-1 to 1} range + pos=ipos*twoDivOutputSize-CrtsF2(1.0,1.0); + // Distort pushes image outside {-1 to 1} range + pos*=CrtsF2( + 1.0+(pos.y*pos.y)*warp.x, + 1.0+(pos.x*pos.x)*warp.y); + // TODO: Vignette needs optimization + CrtsF1 vin=(1.0-( + (1.0-CrtsSatF1(pos.x*pos.x))*(1.0-CrtsSatF1(pos.y*pos.y)))) * (0.998 + (0.001 * CORNER)); + vin=CrtsSatF1((-vin)*inputHeight+inputHeight); + // Leave in {0 to inputSize} + pos=pos*halfInputSize+halfInputSize; + #else + pos=ipos*inputSizeDivOutputSize; + #endif +//-------------------------------------------------------------- + // Snap to center of first scanline + CrtsF1 y0=floor(pos.y-0.5)+0.5; + #ifdef CRTS_2_TAP + // Using Inigo's "Improved Texture Interpolation" + // http://iquilezles.org/www/articles/texture/texture.htm + pos.x+=0.5; + CrtsF1 xi=floor(pos.x); + CrtsF1 xf=pos.x-xi; + xf=xf*xf*xf*(xf*(xf*6.0-15.0)+10.0); + CrtsF1 x0=xi+xf-0.5; + CrtsF2 p=CrtsF2(x0*rcpInputSize.x,y0*rcpInputSize.y); + // Coordinate adjusted bilinear fetch from 2 nearest scanlines + CrtsF3 colA=CrtsFetch(p); + p.y+=rcpInputSize.y; + CrtsF3 colB=CrtsFetch(p); + #else + // Snap to center of one of four pixels + CrtsF1 x0=floor(pos.x-1.5)+0.5; + // Inital UV position + CrtsF2 p=CrtsF2(x0*rcpInputSize.x,y0*rcpInputSize.y); + // Fetch 4 nearest texels from 2 nearest scanlines + CrtsF3 colA0=CrtsFetch(p); + p.x+=rcpInputSize.x; + CrtsF3 colA1=CrtsFetch(p); + p.x+=rcpInputSize.x; + CrtsF3 colA2=CrtsFetch(p); + p.x+=rcpInputSize.x; + CrtsF3 colA3=CrtsFetch(p); + p.y+=rcpInputSize.y; + CrtsF3 colB3=CrtsFetch(p); + p.x-=rcpInputSize.x; + CrtsF3 colB2=CrtsFetch(p); + p.x-=rcpInputSize.x; + CrtsF3 colB1=CrtsFetch(p); + p.x-=rcpInputSize.x; + CrtsF3 colB0=CrtsFetch(p); + #endif +//-------------------------------------------------------------- + // Vertical filter + // Scanline intensity is using sine wave + // Easy filter window and integral used later in exposure + CrtsF1 off=pos.y-y0; + CrtsF1 pi2=6.28318530717958; + CrtsF1 hlf=0.5; + CrtsF1 scanA=cos(min(0.5, off *thin )*pi2)*hlf+hlf; + CrtsF1 scanB=cos(min(0.5,(-off)*thin+thin)*pi2)*hlf+hlf; +//-------------------------------------------------------------- + #ifdef CRTS_2_TAP + #ifdef CRTS_WARP + // Get rid of wrong pixels on edge + scanA*=vin; + scanB*=vin; + #endif + // Apply vertical filter + CrtsF3 color=(colA*scanA)+(colB*scanB); + #else + // Horizontal kernel is simple gaussian filter + CrtsF1 off0=pos.x-x0; + CrtsF1 off1=off0-1.0; + CrtsF1 off2=off0-2.0; + CrtsF1 off3=off0-3.0; + CrtsF1 pix0=exp2(blur*off0*off0); + CrtsF1 pix1=exp2(blur*off1*off1); + CrtsF1 pix2=exp2(blur*off2*off2); + CrtsF1 pix3=exp2(blur*off3*off3); + CrtsF1 pixT=CrtsRcpF1(pix0+pix1+pix2+pix3); + #ifdef CRTS_WARP + // Get rid of wrong pixels on edge + pixT*=vin; + #endif + scanA*=pixT; + scanB*=pixT; + // Apply horizontal and vertical filters + CrtsF3 color= + (colA0*pix0+colA1*pix1+colA2*pix2+colA3*pix3)*scanA + + (colB0*pix0+colB1*pix1+colB2*pix2+colB3*pix3)*scanB; + #endif +//-------------------------------------------------------------- + // Apply phosphor mask + color*=CrtsMask(ipos,mask); +//-------------------------------------------------------------- + // Optional color processing + #ifdef CRTS_TONE + // Tonal control, start by protecting from /0 + CrtsF1 peak=max(1.0/(256.0*65536.0), + CrtsMax3F1(color.r,color.g,color.b)); + // Compute the ratios of {R,G,B} + CrtsF3 ratio=color*CrtsRcpF1(peak); + // Apply tonal curve to peak value + #ifdef CRTS_CONTRAST + peak=pow(peak,tone.x); + #endif + peak=peak*CrtsRcpF1(peak*tone.y+tone.z); + // Apply saturation + #ifdef CRTS_SATURATION + ratio=pow(ratio,CrtsF3(tone.w,tone.w,tone.w)); + #endif + // Reconstruct color + return ratio*peak; + #else + return color; + #endif +//-------------------------------------------------------------- + } + + +void main() +{ + vec2 warp_factor; + warp_factor.x = CURVATURE; + warp_factor.y = (3.0 / 4.0) * warp_factor.x; // assume 4:3 aspect + warp_factor.x *= (1.0 - TRINITRON_CURVE); + FragColor.rgb = CrtsFilter(vTexCoord.xy * OutputSize.xy*(TextureSize.xy / InputSize.xy), + InputSize.xy / OutputSize.xy, + InputSize.xy * vec2(0.5,0.5), + 1.0/InputSize.xy, + 1.0/OutputSize.xy, + 2.0/OutputSize.xy, + InputSize.y, + warp_factor, + INPUT_THIN, + INPUT_BLUR, + INPUT_MASK, + CrtsTone(1.0,0.0,INPUT_THIN,INPUT_MASK)); + + // Shadertoy outputs non-linear color + FragColor.rgb=ToSrgb(FragColor.rgb); +} +#endif diff --git a/Shaders/interpolation/bilinear.glsl b/Shaders/interpolation/bilinear.glsl new file mode 100644 index 0000000..aa7bee6 --- /dev/null +++ b/Shaders/interpolation/bilinear.glsl @@ -0,0 +1,73 @@ +#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 = VertexCoord.x * MVPMatrix[0] + VertexCoord.y * MVPMatrix[1] + VertexCoord.z * MVPMatrix[2] + VertexCoord.w * MVPMatrix[3]; + 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; + +void main() +{ + FragColor = COMPAT_TEXTURE(Texture, TEX0.xy); +} +#endif \ No newline at end of file diff --git a/Shaders/interpolation/catmull-rom-bilinear.glsl b/Shaders/interpolation/catmull-rom-bilinear.glsl new file mode 100644 index 0000000..cfe00bf --- /dev/null +++ b/Shaders/interpolation/catmull-rom-bilinear.glsl @@ -0,0 +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 diff --git a/Shaders/interpolation/fsr.glsl b/Shaders/interpolation/fsr.glsl new file mode 100644 index 0000000..17e574b --- /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 0000000..d9ce74f --- /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 0000000..32235e0 --- /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/interpolation/lanczos2-sharp.glsl b/Shaders/interpolation/lanczos2-sharp.glsl new file mode 100644 index 0000000..5f83af3 --- /dev/null +++ b/Shaders/interpolation/lanczos2-sharp.glsl @@ -0,0 +1,205 @@ +/* + 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.5 +#define JINC2_SINC 1.0 +#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; +} + +#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 = (x.x==0.0) ? wa*wb : sin(x.x*wa)*sin(x.x*wb)/(x.x*x.x); + res.y = (x.y==0.0) ? wa*wb : sin(x.y*wa)*sin(x.y*wb)/(x.y*x.y); + res.z = (x.z==0.0) ? wa*wb : sin(x.z*wa)*sin(x.z*wb)/(x.z*x.z); + res.w = (x.w==0.0) ? wa*wb : sin(x.w*wa)*sin(x.w*wb)/(x.w*x.w); + + 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/nearest-neighbor.glsl b/Shaders/nearest-neighbor.glsl new file mode 100644 index 0000000..aa7bee6 --- /dev/null +++ b/Shaders/nearest-neighbor.glsl @@ -0,0 +1,73 @@ +#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 = VertexCoord.x * MVPMatrix[0] + VertexCoord.y * MVPMatrix[1] + VertexCoord.z * MVPMatrix[2] + VertexCoord.w * MVPMatrix[3]; + 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; + +void main() +{ + FragColor = COMPAT_TEXTURE(Texture, TEX0.xy); +} +#endif \ No newline at end of file diff --git a/Shaders/readme.txt b/Shaders/readme.txt new file mode 100644 index 0000000..431d12e --- /dev/null +++ b/Shaders/readme.txt @@ -0,0 +1,10 @@ +This is a package of pixel shaders intended for old school emulators. +Copyrights are held by the respective authors. + +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/scanlines/scanline.glsl b/Shaders/scanlines/scanline.glsl new file mode 100644 index 0000000..7c8423b --- /dev/null +++ b/Shaders/scanlines/scanline.glsl @@ -0,0 +1,106 @@ +// Parameter lines go here: +#pragma parameter SCANLINE_BASE_BRIGHTNESS "Scanline Base Brightness" 0.95 0.0 1.0 0.01 +#pragma parameter SCANLINE_SINE_COMP_A "Scanline Sine Comp A" 0.0 0.0 0.10 0.01 +#pragma parameter SCANLINE_SINE_COMP_B "Scanline Sine Comp B" 0.15 0.0 1.0 0.05 + +#define pi 3.141592654 + +#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; +COMPAT_VARYING vec2 omega; + +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; + +void main() +{ + gl_Position = MVPMatrix * VertexCoord; + COL0 = COLOR; + TEX0.xy = TexCoord.xy; + omega = vec2(pi * OutputSize.x, 2.0 * pi * TextureSize.y); +} + +#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; +COMPAT_VARYING vec2 omega; + +// compatibility #defines +#define Source Texture +#define vTexCoord TEX0.xy + +#define SourceSize vec4(TextureSize, 1.0 / TextureSize) //either TextureSize or InputSize +#define OutputSize vec4(OutputSize, 1.0 / OutputSize) + +#ifdef PARAMETER_UNIFORM +// All parameter floats need to have COMPAT_PRECISION in front of them +uniform COMPAT_PRECISION float SCANLINE_BASE_BRIGHTNESS; +uniform COMPAT_PRECISION float SCANLINE_SINE_COMP_A; +uniform COMPAT_PRECISION float SCANLINE_SINE_COMP_B; +#else +#define SCANLINE_BASE_BRIGHTNESS 0.95 +#define SCANLINE_SINE_COMP_A 0.0 +#define SCANLINE_SINE_COMP_B 0.15 +#endif + +void main() +{ + vec2 sine_comp = vec2(SCANLINE_SINE_COMP_A, SCANLINE_SINE_COMP_B); + vec3 res = COMPAT_TEXTURE(Source, vTexCoord).xyz; + vec3 scanline = res * (SCANLINE_BASE_BRIGHTNESS + dot(sine_comp * sin(vTexCoord * omega), vec2(1.0, 1.0))); + FragColor = vec4(scanline.x, scanline.y, scanline.z, 1.0); +} +#endif diff --git a/Shaders/shader-package.zip b/Shaders/shader-package.zip new file mode 100644 index 0000000..21290e2 Binary files /dev/null and b/Shaders/shader-package.zip differ diff --git a/Shaders/sharpen/rca-sharpen.glsl b/Shaders/sharpen/rca-sharpen.glsl new file mode 100644 index 0000000..d9ce74f --- /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/xbr/xbr-lv2-noblend.glsl b/Shaders/xbr/xbr-lv2-noblend.glsl new file mode 100644 index 0000000..bbc2aae --- /dev/null +++ b/Shaders/xbr/xbr-lv2-noblend.glsl @@ -0,0 +1,300 @@ +#version 130 + +/* + Hyllian's xBR-lv2-noblend Shader + + 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. + + Incorporates some of the ideas from SABR shader. Thanks to Joshua Street. +*/ + +#pragma parameter XBR_EQ_THRESHOLD "Eq Threshold" 0.6 0.0 2.0 0.1 +#pragma parameter XBR_LV2_COEFFICIENT "Lv2 Coefficient" 2.0 1.0 3.0 0.1 + +#define mul(a,b) (b*a) + +// Uncomment just one of the three params below to choose the corner detection +#define CORNER_A +//#define CORNER_B +//#define CORNER_C +//#define CORNER_D + +#define lv2_cf XBR_LV2_COEFFICIENT + +#define texCoord TEX0 +#define t1 TEX1 +#define t2 TEX2 +#define t3 TEX3 +#define t4 TEX4 +#define t5 TEX5 +#define t6 TEX6 +#define t7 TEX7 + +#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 PRECISION mediump +#else +#define PRECISION +#endif + + +IN vec4 VertexCoord; +IN vec4 Color; +IN vec2 TexCoord; + +OUT vec4 color; +OUT vec2 texCoord; +OUT vec4 t1; +OUT vec4 t2; +OUT vec4 t3; +OUT vec4 t4; +OUT vec4 t5; +OUT vec4 t6; +OUT vec4 t7; + +uniform mat4 MVPMatrix; +uniform PRECISION int FrameDirection; +uniform PRECISION int FrameCount; +uniform PRECISION vec2 OutputSize; +uniform PRECISION vec2 TextureSize; +uniform PRECISION vec2 InputSize; + +void main() +{ + gl_Position = MVPMatrix * VertexCoord; + color = Color; + + float dx = (1.0/TextureSize.x); + float dy = (1.0/TextureSize.y); + + texCoord = TexCoord; + texCoord.x *= 1.00000001; + t1 = TexCoord.xxxy + vec4( -dx, 0, dx,-2.0*dy); // A1 B1 C1 + t2 = TexCoord.xxxy + vec4( -dx, 0, dx, -dy); // A B C + t3 = TexCoord.xxxy + vec4( -dx, 0, dx, 0); // D E F + t4 = TexCoord.xxxy + vec4( -dx, 0, dx, dy); // G H I + t5 = TexCoord.xxxy + vec4( -dx, 0, dx, 2.0*dy); // G5 H5 I5 + t6 = TexCoord.xyyy + vec4(-2.0*dx,-dy, 0, dy); // A0 D0 G0 + t7 = TexCoord.xyyy + vec4( 2.0*dx,-dy, 0, dy); // C4 F4 I4 +} + + +#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 PRECISION mediump +#else +#define PRECISION +#endif + +uniform PRECISION int FrameDirection; +uniform PRECISION int FrameCount; +uniform PRECISION vec2 OutputSize; +uniform PRECISION vec2 TextureSize; +uniform PRECISION vec2 InputSize; +uniform sampler2D decal; +IN vec2 texCoord; +IN vec4 t1; +IN vec4 t2; +IN vec4 t3; +IN vec4 t4; +IN vec4 t5; +IN vec4 t6; +IN vec4 t7; + +#ifdef PARAMETER_UNIFORM +uniform PRECISION float XBR_EQ_THRESHOLD; +uniform PRECISION float XBR_LV2_COEFFICIENT; +#else +#define XBR_EQ_THRESHOLD 0.6 +#define XBR_LV2_COEFFICIENT 2.0 +#endif +// END PARAMETERS // + +const vec3 Y = vec3(0.2126, 0.7152, 0.0722); + +// Difference between vector components. +vec4 df(vec4 A, vec4 B) +{ + return vec4(abs(A-B)); +} + +// Compare two vectors and return their components are different. +vec4 diff(vec4 A, vec4 B) +{ + return vec4(notEqual(A, B)); +} + +// Determine if two vector components are equal based on a threshold. +vec4 eq(vec4 A, vec4 B) +{ + return (step(df(A, B), vec4(XBR_EQ_THRESHOLD))); +} + +// Determine if two vector components are NOT equal based on a threshold. +vec4 neq(vec4 A, vec4 B) +{ + return (vec4(1.0, 1.0, 1.0, 1.0) - eq(A, B)); +} + +// Weighted distance. +vec4 wd(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h) +{ + return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + 4.0*df(g,h)); +} + +vec4 weighted_distance(vec4 a, vec4 b, vec4 c, vec4 d, vec4 e, vec4 f, vec4 g, vec4 h, vec4 i, vec4 j, vec4 k, vec4 l) +{ + return (df(a,b) + df(a,c) + df(d,e) + df(d,f) + df(i,j) + df(k,l) + 2.0*df(g,h)); +} + +float c_df(vec3 c1, vec3 c2) +{ + vec3 df = abs(c1 - c2); + return df.r + df.g + df.b; +} + +void main() +{ + vec4 edri, edr, edr_l, edr_u; // px = pixel, edr = edge detection rule + vec4 irlv1, irlv2l, irlv2u, block_3d; + bvec4 nc, px; + vec4 fx, fx_l, fx_u; // inequations of straight lines. + + vec2 fp = fract(texCoord*TextureSize); + + vec3 A1 = tex2D(decal, t1.xw ).xyz; + vec3 B1 = tex2D(decal, t1.yw ).xyz; + vec3 C1 = tex2D(decal, t1.zw ).xyz; + vec3 A = tex2D(decal, t2.xw ).xyz; + vec3 B = tex2D(decal, t2.yw ).xyz; + vec3 C = tex2D(decal, t2.zw ).xyz; + vec3 D = tex2D(decal, t3.xw ).xyz; + vec3 E = tex2D(decal, t3.yw ).xyz; + vec3 F = tex2D(decal, t3.zw ).xyz; + vec3 G = tex2D(decal, t4.xw ).xyz; + vec3 H = tex2D(decal, t4.yw ).xyz; + vec3 I = tex2D(decal, t4.zw ).xyz; + vec3 G5 = tex2D(decal, t5.xw ).xyz; + vec3 H5 = tex2D(decal, t5.yw ).xyz; + vec3 I5 = tex2D(decal, t5.zw ).xyz; + vec3 A0 = tex2D(decal, t6.xy ).xyz; + vec3 D0 = tex2D(decal, t6.xz ).xyz; + vec3 G0 = tex2D(decal, t6.xw ).xyz; + vec3 C4 = tex2D(decal, t7.xy ).xyz; + vec3 F4 = tex2D(decal, t7.xz ).xyz; + vec3 I4 = tex2D(decal, t7.xw ).xyz; + + vec4 b = mul( mat4x3(B, D, H, F), Y ); + vec4 c = mul( mat4x3(C, A, G, I), Y ); + vec4 e = mul( mat4x3(E, E, E, E), Y ); + vec4 d = b.yzwx; + vec4 f = b.wxyz; + vec4 g = c.zwxy; + vec4 h = b.zwxy; + vec4 i = c.wxyz; + + vec4 i4 = mul( mat4x3(I4, C1, A0, G5), Y ); + vec4 i5 = mul( mat4x3(I5, C4, A1, G0), Y ); + vec4 h5 = mul( mat4x3(H5, F4, B1, D0), Y ); + vec4 f4 = h5.yzwx; + + vec4 Ao = vec4( 1.0, -1.0, -1.0, 1.0 ); + vec4 Bo = vec4( 1.0, 1.0, -1.0,-1.0 ); + vec4 Co = vec4( 1.5, 0.5, -0.5, 0.5 ); + vec4 Ax = vec4( 1.0, -1.0, -1.0, 1.0 ); + vec4 Bx = vec4( 0.5, 2.0, -0.5,-2.0 ); + vec4 Cx = vec4( 1.0, 1.0, -0.5, 0.0 ); + vec4 Ay = vec4( 1.0, -1.0, -1.0, 1.0 ); + vec4 By = vec4( 2.0, 0.5, -2.0,-0.5 ); + vec4 Cy = vec4( 2.0, 0.0, -1.0, 0.5 ); + + // These inequations define the line below which interpolation occurs. + fx = vec4(greaterThan(Ao*fp.y+Bo*fp.x, Co)); + fx_l = vec4(greaterThan(Ax*fp.y+Bx*fp.x, Cx)); + fx_u = vec4(greaterThan(Ay*fp.y+By*fp.x, Cy)); + +#ifdef CORNER_A + irlv1 = diff(e,f) * diff(e,h); +#endif +#ifdef CORNER_B + irlv1 = (neq(f,b) * neq(h,d) + eq(e,i) * neq(f,i4) * neq(h,i5) + eq(e,g) + eq(e,c)); +#endif +#ifdef CORNER_D + vec4 c1 = i4.yzwx; + vec4 g0 = i5.wxyz; + irlv1 = (neq(f,b) * neq(h,d) + eq(e,i) * neq(f,i4) * neq(h,i5) + eq(e,g) + eq(e,c) ) * (diff(f,f4) * diff(f,i) + diff(h,h5) * diff(h,i) + diff(h,g) + diff(f,c) + eq(b,c1) * eq(d,g0)); +#endif +#ifdef CORNER_C + irlv1 = (neq(f,b) * neq(f,c) + neq(h,d) * neq(h,g) + eq(e,i) * (neq(f,f4) * neq(f,i4) + neq(h,h5) * neq(h,i5)) + eq(e,g) + eq(e,c)); +#endif + + irlv2l = diff(e,g) * diff(d,g); + irlv2u = diff(e,c) * diff(b,c); + + vec4 wd1 = wd( e, c, g, i, h5, f4, h, f); + vec4 wd2 = wd( h, d, i5, f, i4, b, e, i); + + edri = step(wd1, wd2) * irlv1; + edr = step(wd1 + vec4(0.1, 0.1, 0.1, 0.1), wd2) * step(vec4(0.5, 0.5, 0.5, 0.5), irlv1); + edr_l = step( lv2_cf*df(f,g), df(h,c) ) * irlv2l * edr; + edr_u = step( lv2_cf*df(h,c), df(f,g) ) * irlv2u * edr; + + nc = bvec4( edr * ( fx + edr_l * (fx_l)) + edr_u * fx_u); + + px = lessThanEqual(df(e, f), df(e, h)); + + vec3 res1 = nc.x ? px.x ? F : H : nc.y ? px.y ? B : F : nc.z ? px.z ? D : B : E; + vec3 res2 = nc.w ? px.w ? H : D : nc.z ? px.z ? D : B : nc.y ? px.y ? B : F : E; + + vec2 df12 = abs( mul( mat2x3(res1, res2), Y ) - e.xy); + + vec3 res = mix(res1, res2, step(df12.x, df12.y)); + + FragColor.xyz = res; +} +#endif diff --git a/Shaders/xbrz/xbrz-freescale-multipass.glsl b/Shaders/xbrz/xbrz-freescale-multipass.glsl new file mode 100644 index 0000000..5a01406 --- /dev/null +++ b/Shaders/xbrz/xbrz-freescale-multipass.glsl @@ -0,0 +1,337 @@ +/* + 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; +COMPAT_VARYING vec4 TEX0; +// in variables go here as COMPAT_VARYING whatever + +// 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 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(Source, coord + SourceSize.zw * vec2(x, y)).rgb + +void main() +{ + //--------------------------------------- + // Input Pixel Mapping: -|x|x|x|- + // x|A|B|C|x + // x|D|E|F|x + // x|G|H|I|x + // -|x|x|x|- + + vec2 pos = fract(vTexCoord * SourceSize.xy) - vec2(0.5, 0.5); + vec2 coord = vTexCoord - pos * SourceSize.zw; + + vec3 A = P(-1.,-1.); + vec3 B = P( 0.,-1.); + vec3 C = P( 1.,-1.); + vec3 D = P(-1., 0.); + vec3 E = P( 0., 0.); + vec3 F = P( 1., 0.); + vec3 G = P(-1., 1.); + vec3 H = P( 0., 1.); + vec3 I = P( 1., 1.); + + // blendResult Mapping: x|y| + // w|z| + ivec4 blendResult = ivec4(BLEND_NONE,BLEND_NONE,BLEND_NONE,BLEND_NONE); + + // Preprocess corners + // Pixel Tap Mapping: -|-|-|-|- + // -|-|B|C|- + // -|D|E|F|x + // -|G|H|I|x + // -|-|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)); + 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; + } + + + // Pixel Tap Mapping: -|-|-|-|- + // -|A|B|-|- + // x|D|E|F|- + // x|G|H|I|- + // -|x|x|-|- + if (!((eq(D,E) && eq(G,H)) || (eq(D,G) && eq(E,H)))) + { + float dist_G_E = DistYCbCr(P(-2.,1.) , D) + DistYCbCr(D, B) + DistYCbCr(P(-1.,2.), H) + DistYCbCr(H, F) + (4.0 * DistYCbCr(G, E)); + float dist_D_H = DistYCbCr(P(-2.,0.) , G) + DistYCbCr(G, P(0.,2.)) + DistYCbCr(A, E) + DistYCbCr(E, I) + (4.0 * DistYCbCr(D, H)); + bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_D_H) < dist_G_E; + blendResult.w = ((dist_G_E > dist_D_H) && neq(E,D) && neq(E,H)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; + } + + // Pixel Tap Mapping: -|-|x|x|- + // -|A|B|C|x + // -|D|E|F|x + // -|-|H|I|- + // -|-|-|-|- + 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_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; + } + + // Pixel Tap Mapping: -|x|x|-|- + // x|A|B|C|- + // x|D|E|F|- + // -|G|H|-|- + // -|-|-|-|- + if (!((eq(A,B) && eq(D,E)) || (eq(A,D) && eq(B,E)))) + { + float dist_D_B = DistYCbCr(P(-2.,0.), A) + DistYCbCr(A, P(0.,-2.)) + DistYCbCr(G, E) + DistYCbCr(E, C) + (4.0 * DistYCbCr(D, B)); + float dist_A_E = DistYCbCr(P(-2.,-1.), D) + DistYCbCr(D, H) + DistYCbCr(P(-1.,-2.), B) + DistYCbCr(B, F) + (4.0 * DistYCbCr(A, E)); + bool dominantGradient = (DOMINANT_DIRECTION_THRESHOLD * dist_D_B) < dist_A_E; + blendResult.x = ((dist_D_B < dist_A_E) && neq(E,D) && neq(E,B)) ? ((dominantGradient) ? BLEND_DOMINANT : BLEND_NORMAL) : BLEND_NONE; + } + + FragColor = vec4(blendResult); + + // Pixel Tap Mapping: -|-|-|-|- + // -|-|B|C|- + // -|D|E|F|x + // -|G|H|I|x + // -|-|x|x|- + 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; + + float dist_F_G = DistYCbCr(F, G); + float dist_H_C = DistYCbCr(H, C); + + 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_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; + + float dist_H_A = DistYCbCr(H, A); + float dist_D_I = DistYCbCr(D, I); + + 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_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; + + float dist_B_I = DistYCbCr(B, I); + float dist_F_A = DistYCbCr(F, A); + + if((STEEP_DIRECTION_THRESHOLD * dist_B_I <= dist_F_A) && neq(E,I) && neq(H,I)) + FragColor.y += 16.0; + + 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_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; + + float dist_D_C = DistYCbCr(D, C); + float dist_B_G = DistYCbCr(B, G); + + if((STEEP_DIRECTION_THRESHOLD * dist_D_C <= dist_B_G) && neq(E,C) && neq(F,C)) + FragColor.x += 16.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 0000000..0001c2d --- /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 new file mode 100644 index 0000000..3ad01cd Binary files /dev/null and b/cnc-ddraw config.exe differ diff --git a/ddraw.dll b/ddraw.dll new file mode 100644 index 0000000..57da594 Binary files /dev/null and b/ddraw.dll differ diff --git a/ddraw.ini b/ddraw.ini new file mode 100644 index 0000000..b615976 --- /dev/null +++ b/ddraw.ini @@ -0,0 +1,1754 @@ +; cnc-ddraw - https://github.com/FunkyFr3sh/cnc-ddraw + +[ddraw] +; ### Optional settings ### +; Use the following settings to adjust the look and feel to your liking + + +; Stretch to custom resolution, 0 = defaults to the size game requests +width=1024 +height=768 + +; Override the width/height settings shown above and always stretch to fullscreen +; Note: Can be combined with 'windowed=true' to get windowed-fullscreen aka borderless mode +fullscreen=false + +; Run in windowed mode rather than going fullscreen +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 + +; Real rendering rate, -1 = screen rate, 0 = unlimited, n = cap +; Note: Does not have an impact on the game speed, to limit your game speed use 'maxgameticks=' +maxfps=-1 + +; Vertical synchronization, enable if you get tearing - (Requires 'renderer=auto/opengl*/direct3d9*') +; Note: vsync=true can fix tearing but it will cause input lag +vsync=false + +; Automatic mouse sensitivity scaling +; Note: Only works if stretching is enabled. Sensitivity will be adjusted according to the size of the window +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 +; 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 +posY=-32000 + +; Renderer, possible values: auto, opengl, openglcore, gdi, direct3d9, direct3d9on12 (auto = try direct3d9/opengl, fallback = gdi) +renderer=auto + +; Developer mode (don't lock the cursor) +devmode=false + +; Show window borders in windowed mode +border=true + +; Save window position/size/state on game exit and restore it automatically on next game start +; Possible values: 0 = disabled, 1 = save to global 'ddraw' section, 2 = save to game specific section +savesettings=0 + +; Should the window be resizable by the user in windowed mode? +resizable=true + +; Upscaling filter for the direct3d9* renderers +; Possible values: 0 = nearest-neighbor, 1 = bilinear, 2 = bicubic, 3 = lanczos (bicubic/lanczos only support 16/32bit color depth games) +d3d9_filter=2 + +; 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 + +; Where should screenshots be saved +screenshotdir=.\Screenshots\ + +; Switch between windowed/borderless modes with alt+enter rather than windowed/fullscreen modes +toggle_borderless=false + +; Switch between windowed/fullscreen upscaled modes with alt+enter rather than windowed/fullscreen modes +toggle_upscaled=false + + + +; ### Compatibility settings ### +; Use the following settings in case there are any issues with the game + + +; Hide WM_ACTIVATEAPP and WM_NCACTIVATE messages to prevent problems on alt+tab +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=0 + +; 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=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=true + +; 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, 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 lock to the window or it doesn't work properly when upscaling is enabled +hook_peekmessage=false + + +; Undocumented compatibility settings - These will probably not solve your problem, you should rather focus on the settings above +fix_alt_key_stuck=false +game_handles_close=false +fix_not_responding=false +no_compat_warning=false +guard_lines=200 +max_resolutions=0 +lock_surfaces=false +flipclear=false +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 + + + +; ### Hotkeys ### +; Use the following settings to configure your hotkeys, 0x00 = disabled +; Virtual-Key Codes: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes + + +; 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 + +; Unlock cursor 2 = [Right Alt] + ??? +keyunlockcursor2=0xA3 + +; Screenshot +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=true + + + +; ### Game specific settings ### +; The following settings override all settings shown above, section name = executable name + + +; 7th Legion +[legion] +maxgameticks=25 +singlecpu=false + +; Atrox +[Atrox] +nonexclusive=true + +; Atomic Bomberman +[BM] +maxgameticks=60 + +; Age of Empires +[empires] +nonexclusive=true +adjmouse=true +resolutions=2 + +; Age of Empires: The Rise of Rome +[empiresx] +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 +adjmouse=true + +; Age of Empires II: The Conquerors +[age2_x1] +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 +nonexclusive=false +singlecpu=false + +; Age of Wonders 2 +[AoW2Compat] +resolutions=2 +nonexclusive=false +singlecpu=false + +; Age of Wonders 2 Config Tool +[aow2Setup] +resolutions=2 + +; Age of Wonders: Shadow Magic +[AoWSM] +resolutions=2 +nonexclusive=false +singlecpu=false + +; Age of Wonders: Shadow Magic +[AoWSMCompat] +resolutions=2 +nonexclusive=false +singlecpu=false + +; Age of Wonders: Shadow Magic Config Tool +[AoWSMSetup] +resolutions=2 + +; Anstoss 3 +[anstoss3] +renderer=gdi +adjmouse=true + +; Anno 1602 +[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] +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 + +; Blade & Sword +[comeon] +maxgameticks=60 +fixchilds=3 + +; Blood II - The Chosen / Shogo - Mobile Armor Division +[Client] +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] +flipclear=true +carma95_hack=true + +; Carmageddon +[CARM95] +flipclear=true +carma95_hack=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] +adjmouse=true +noactivateapp=true +nonexclusive=true + +; Championship Manager 99-00 +[cm9900] +singlecpu=false + +; Command & Conquer: Sole Survivor +[SOLE] +maxgameticks=120 +maxfps=60 +minfps=-1 + +; Command & Conquer Gold - CnCNet +[cnc95] +maxfps=125 + +; Command & Conquer Gold +[C&C95] +maxgameticks=120 +maxfps=60 +minfps=-1 + +; Command & Conquer: Red Alert - CnCNet +[ra95-spawn] +maxfps=125 + +; Command & Conquer: Red Alert +[ra95] +maxgameticks=120 +maxfps=60 +minfps=-1 + +; Command & Conquer: Red Alert +[ra95_Mod-Launcher] +maxgameticks=120 +maxfps=60 +minfps=-1 + +; Command & Conquer: Red Alert +[ra95p] +maxfps=60 +minfps=-1 + +; Command & Conquer: Tiberian Sun / Command & Conquer: Red Alert 2 +[game] +nonexclusive=false +checkfile=.\blowfish.dll +tshack=true +noactivateapp=true +adjmouse=true +maxfps=60 +minfps=-1 +maintas=false +boxing=false + +; Command & Conquer: Tiberian Sun Demo +[SUN] +nonexclusive=false +noactivateapp=true +tshack=true +adjmouse=true +maxfps=60 +minfps=-1 +maintas=false +boxing=false + +; Command & Conquer: Tiberian Sun - CnCNet +[ts-spawn] +nonexclusive=false +noactivateapp=true +tshack=true +adjmouse=true +maxfps=60 +minfps=-1 +maintas=false +boxing=false + +; Command & Conquer: Red Alert 2 - XWIS +[ra2] +nonexclusive=false +noactivateapp=true +tshack=true +maxfps=60 +minfps=-1 +maintas=false +boxing=false + +; Command & Conquer: Red Alert 2 - XWIS +[Red Alert 2] +nonexclusive=false +noactivateapp=true +tshack=true +maxfps=60 +minfps=-1 +maintas=false +boxing=false + +; Command & Conquer: Red Alert 2: Yuri's Revenge +[gamemd] +nonexclusive=false +noactivateapp=true +tshack=true +maxfps=60 +minfps=-1 +maintas=false +boxing=false + +; Command & Conquer: Red Alert 2: Yuri's Revenge - ?ModExe? +[ra2md] +nonexclusive=false +noactivateapp=true +tshack=true +maxfps=60 +minfps=-1 +maintas=false +boxing=false + +; Command & Conquer: Red Alert 2: Yuri's Revenge - CnCNet +[gamemd-spawn] +nonexclusive=false +noactivateapp=true +tshack=true +maxfps=60 +minfps=-1 +maintas=false +boxing=false + +; Command & Conquer: Red Alert 2: Yuri's Revenge - XWIS +[Yuri's Revenge] +nonexclusive=false +noactivateapp=true +tshack=true +maxfps=60 +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/2] +checkfile=.\LOCO.EXE +adjmouse=true + +; Cultures 2 +[Cultures2] +adjmouse=true + +; Cultures 2 MP +[Cultures2MP] +adjmouse=true + +; Close Combat 2: A Bridge Too Far +[cc2] +adjmouse=true +nonexclusive=true + +; Close Combat 3: The Russian Front +[cc3] +adjmouse=true +nonexclusive=true + +; Close Combat 4: The Battle of the Bulge +[cc4] +adjmouse=true +nonexclusive=true + +; Close Combat 5: Invasion: Normandy +[cc5] +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 +boxing=false + +; Corsairs Gold +[corsairs] +adjmouse=true + +; Divine Divinity +[div] +resolutions=2 +singlecpu=false + +; Die by the Sword +[windie] +maxgameticks=30 + +; Three Kingdoms: Fate of the Dragon +[sanguo] +maxgameticks=60 +noactivateapp=true +limiter_type=2 + +; Dragon Throne: Battle of Red Cliffs +[AdSanguo] +maxgameticks=60 +noactivateapp=true +limiter_type=2 + +; Dragon Throne: Battle of Red Cliffs +[AdSanguo2] +maxgameticks=60 +noactivateapp=true +limiter_type=2 + +; Dragon Throne: Battle of Red Cliffs +[AdSanguoHD] +maxgameticks=60 +noactivateapp=true +limiter_type=2 + +; Dragon Throne: Battle of Red Cliffs +[dragonthrone] +maxgameticks=60 +noactivateapp=true +limiter_type=2 + +; Dark Reign: The Future of War +[DKReign] +maxgameticks=60 + +; Dungeon Keeper 2 +[DKII] +maxgameticks=60 +noactivateapp=true + +; Dreams to Realty +[windream] +maxgameticks=60 + +; Deadlock 2 +[DEADLOCK] +fixchilds=0 +adjmouse=false +maintas=false +boxing=false + +; Diablo +[Diablo] +devmode=true + +; Diablo: Hellfire +[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] +nonexclusive=true +hook_peekmessage=true +rgb555=true +keytogglefullscreen=0x46 +adjmouse=true + +; Economic War +[EcoW] +maxgameticks=60 +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] +singlecpu=false + +; Grand Theft Auto: London 1969 +[gta_uk] +singlecpu=false + +; Grand Theft Auto: London 1961 +[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] +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 +renderer=opengl + +; Interstate 76 +[i76] +adjmouse=true + +; Infantry +[infantry] +resolutions=2 +infantryhack=true +max_resolutions=90 + +; Infantry Steam +[FreeInfantry] +resolutions=2 +infantryhack=true +max_resolutions=90 + +; Jagged Alliance 2 +[ja2] +singlecpu=false +sirtech_hack=true +fix_alt_key_stuck=true + +; Jagged Alliance 2: Unfinished Business +[JA2UB] +singlecpu=false +sirtech_hack=true +fix_alt_key_stuck=true + +; Jagged Alliance 2: Wildfire +[WF6] +singlecpu=false +sirtech_hack=true +fix_alt_key_stuck=true + +; Jagged Alliance 2 - UC mod +[JA2_UC] +singlecpu=false +sirtech_hack=true +fix_alt_key_stuck=true + +; Jagged Alliance 2 - Vengeance Reloaded mod +[JA2_Vengeance] +singlecpu=false +sirtech_hack=true +fix_alt_key_stuck=true + +; Jeopardy! - NOT WORKING YET +[jeoppc] +singlecpu=false + +; Karma Immortal Wrath +[karma] +fix_not_responding=true +maxgameticks=60 +limiter_type=4 + +; Konung +[konung] +fixchilds=0 + +; Konung 2 +[Konung2] +fixchilds=0 + +; KKND Xtreme (With high resolution patch) +[KKNDgame] +vhack=true + +; KKND2: Krossfire +[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 + +; Majesty Gold HD +[MajestyHD] +adjmouse=true + +; Majesty Gold HD +[MajestyHD - Old] +adjmouse=true + +; Mech Warrior 3 +[Mech3] +nonexclusive=true + +; Moorhuhn 2 +[Moorhuhn2] +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 +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] +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 +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] +nonexclusive=true + +; Settlers 3 +[s3] +nonexclusive=true + +; Star Trek - Armada +[Armada] +armadahack=true +nonexclusive=true +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 +adjmouse=true + +; Star Wars: Galactic Battlegrounds: Clone Campaigns +[battlegrounds_x1] +nonexclusive=true +adjmouse=true + +; Starcraft +[StarCraft] +game_handles_close=true + +; Space Rangers +[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 +stronghold_hack=true +adjmouse=true + +; Stronghold Crusader Extreme HD +[Stronghold_Crusader_Extreme] +resolutions=2 +stronghold_hack=true +adjmouse=true + +; Stronghold HD +[Stronghold] +resolutions=2 +stronghold_hack=true +adjmouse=true + +; Sim City 3000 +[SC3] +minfps=-2 +maxgameticks=60 +; Shadow Watch +[sw] +adjmouse=true +maxgameticks=30 +; Shadow Flare +[ShadowFlare] +nonexclusive=true +adjmouse=true + +; 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] +max_resolutions=32 +lock_surfaces=true +singlecpu=false + +; Total Annihilation Replay Viewer (Unofficial Beta Patch v3.9.02) +[Viewer] +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 + + + +; Thomas & Friends - The Great Festival Adventure +[Thomas] +no_compat_warning=true +noactivateapp=true + +; RollerCoaster Tycoon +[rct] +no_dinput_hook=true +singlecpu=false +maxfps=0 +adjmouse=true + +; Twisted Metal +[TWISTED] +nonexclusive=true +maxgameticks=25 +minfps=5 + +; Twisted Metal 2 +[Tm2] +nonexclusive=true +maxgameticks=60 +adjmouse=true +fixchilds=1 +maintas=false +boxing=false + +; Tzar: The Burden of the Crown +; Note: Must set 'DIRECTXDEVICE=0' in 'Tzar.ini' +[Tzar] +adjmouse=true + +; Unreal +[Unreal] +adjmouse=false +lock_mouse_top_left=true +center_cursor_fix=true + +; Uprising +[uprising] +adjmouse=true + +; Uprising 2 +[Uprising 2] +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] +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] +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 + + diff --git a/dplay-setup.exe b/dplay-setup.exe new file mode 100644 index 0000000..0b787ec Binary files /dev/null and b/dplay-setup.exe differ diff --git a/dpwsockx.dll b/dpwsockx.dll new file mode 100644 index 0000000..07c8507 Binary files /dev/null and b/dpwsockx.dll differ diff --git a/dsound.dll b/dsound.dll new file mode 100644 index 0000000..a5721d0 Binary files /dev/null and b/dsound.dll differ diff --git a/ipxconfig.exe b/ipxconfig.exe new file mode 100644 index 0000000..82a8674 Binary files /dev/null and b/ipxconfig.exe differ diff --git a/ipxwrapper.dll b/ipxwrapper.dll new file mode 100644 index 0000000..bf4f0e6 Binary files /dev/null and b/ipxwrapper.dll differ diff --git a/mswsock.dll b/mswsock.dll new file mode 100644 index 0000000..0af4d5e Binary files /dev/null and b/mswsock.dll differ diff --git a/setup.cmd b/setup.cmd new file mode 100644 index 0000000..9d71bb6 --- /dev/null +++ b/setup.cmd @@ -0,0 +1,9 @@ +@echo off + +DISM /online /enable-feature /featurename:DirectPlay /all + +start /wait "" RegSetup.exe + +start /wait "" dplay-setup.exe + +exit diff --git a/vcredist_x86.exe b/vcredist_x86.exe new file mode 100644 index 0000000..9e78e26 Binary files /dev/null and b/vcredist_x86.exe differ diff --git a/winmm.dll b/winmm.dll new file mode 100644 index 0000000..47bc840 Binary files /dev/null and b/winmm.dll differ diff --git a/wsock32.dll b/wsock32.dll new file mode 100644 index 0000000..d0a19aa Binary files /dev/null and b/wsock32.dll differ diff --git a/加强版说明.txt b/加强版说明.txt new file mode 100644 index 0000000..5f0d9a6 --- /dev/null +++ b/加强版说明.txt @@ -0,0 +1,184 @@ + +《傲世三国之三分天下 威力加强版 支持联机 修复黑屏bug 卷轴速度过快bug》 + +0. 右键点击setup.cmd,选择管理员运行,修复注册表 + +1. 启动adsanguo.exe开始游戏(已集成加强版补丁) + +备注:少部分电脑环境依然可能黑屏,不断按CTRL+SHIFT一般可解决 + + + +单电脑模拟多人联机步骤(用于测试联机环境): +1. 启动adsanguo.exe,点多人游戏,选IPX联机方式,修改玩家名,创建游戏,设置地图和电脑数量 +2. 启动adsanguoHD.exe点多人游戏,选IPX联机方式,加入游戏 +3. 返回第一个adsanguo.exe开始游戏 + + +修改版改动的数据: + 1.仓库可以在任意位置建造 + 2.每民居8人口修改为12人口,单机模式人口上限修改为120 + 3.寺庙复活所需金钱降为半价(50%) + 4.每次税收额外随机增加80-200金钱 + 5.马匹生命额外增加50点,所需金钱降为1/3 + 6.马厩有10%概率产出白马,有1/1000概率产出无敌白马(白色血条,无视所有伤害) + 7.刀兵,枪兵,弓兵训练所需金钱降为1/3 + 8.武将有5%概率躲避伤害,有15%概率格挡15%-35%伤害 + 9.人员作战单位(武将和小兵)有15%概率被暴击,造成额外15%-35%伤害 + 10.速度最大上限修改为10,小兵单位每点移速效果增加10%,武将每点移速效果增加15% + 11.杀敌经验改为随机8-12点(原版为固定10点) + 12.稻田产量额外增加300(节省城池空间) + 13.猪圈产量额外增加300(节省城池空间) + 14.矿洞产量额外增加20000(持久战时有充足镔铁) + 15.作坊的包子和酒水产量翻倍(民夫产出1个,实际增加2个) + 16.武将升级有额外成长,如下: + a.最大生命随机提升100-200点(原版为每级固定80点),取消升级回复满血,改为回复40%最大生命 + b.攻击武将攻击额外提升(每次升级有8%概率额外提升) + c.防御武将防御额外提升(每次升级有8%概率额外提升) + d.智力武将最大HP额外随机提升30-80点 + e.异人武将最大MP额外随机提升15-35点 + 17.加入定时器系统,规则如下: + a.攻击武将每秒回复1点HP/2点MP + b.防御武将每秒回复2点HP/1点MP + c.智力武将每秒回复1点HP/2点MP + d.异人武将每秒回复1点HP/1点MP + e.所有武将每15秒获得1点经验 + + 特别说明!! 以上修改全体生效(敌方我方均有效)!! + + +史诗级增强: + 1.增加高清HD支持,分辨率提升至1920x1080 + 2.兼容STEAM版本! 补丁复制到游戏目录覆盖即可生效!! + + + +游戏秘籍: + {dayandnight_ex} 黑白夜交替 + {fps} 显示刷新率 + {hlylevelup} 翰林院升级 + {ineedclear} 清除所有在视口内的敌人 + {ineedhelpme} 电脑控制玩家 + {ineedopenallstory} 打开所有剧情关 + {ineedopenfog} 取消战雾 + {Ineedsuperpower} 所有资源最大化,武将一起全升到9级. + {ineedwin} 过关 + {ineedwine} 增加1000单位酒 + {ineedrice} 增加1000单位谷物 + {ineedwine} 增加1000单位酒水 + {ineedwood} 增加1000单位木头 + {ineediron} 增加1000单位镔铁 + {ineedmeat} 增加1000单位生肉 + {ineedfood} 增加1000单位食物 + {ineedall} 所有城市资源增加50000单位 + {levelmax} 将士或士兵升级到最高等级 + {levelup} 武士或士兵提升一个等级 + {speed_ex} 加速 + {superman_ex} 选中的人无敌(建筑物也可) + {ver} 获得版本号 + + +特殊技能说明: + +勇武:增加己方将士攻击力 + +激励:提高己方将士士气 + +分影:幻化影身,协助攻击 + +急行:加快己方将士行走速度 + +化身:复制武将,具备物理攻击能力 + +巨喝:使敌方落马,并受到伤害 + +誓死:大幅提高己方将士攻击力,防御力下降 + +狂暴:使敌人不分敌我进行攻击 + +地火:召唤地火攻击 + +天甲:增加己方将士防御力 + +缓行:降低敌人行走速度 + +辟谷:增加己方将士体力 + +动摇:降低敌人士气 + +困龙:使敌人失去移动能力 + +落石:召唤落石攻击 + +坚壁:增加己方将士攻击力,防御力,失去移动能力 + +气盾:为己方将士增加魔法护盾 + +冰封:使敌人完全失去任何行动能力,同时受到伤害 + +医疗:增加己方将士生命 + +失蹄:使敌人骑兵落马 + +破甲:降低敌人防御力 + +烈斩:进行直线范围攻击 + +反目:使敌人自相残杀 + +埋伏:隐藏一队士兵 + +激怒:使敌人攻击力增加,不顾一切追杀施用者 + +陷阱:布置陷阱 + +飓风:召唤飓风攻击 + +柔弱:降低敌人攻击力,防御力 + +兵偶:幻化一队士兵,无攻击能力 + +疲劳:降低敌人体力 + +气箭:聚气成箭,攻击敌人 + +毒雾:布下有毒气体 + +结界:布下魔法结界,隔断内外通路 + +瞬移:将己方将士瞬间移动至施法者身旁 + +招魂:从尸体上召唤鬼魂 + +天雷:召唤天雷攻击 + +神武:增加己方将士攻击力 + +神佑:增加己方将士防御力 + +精骑:增加己方将士马上攻击力 + +神射:增加己方弓兵、弩兵攻击力 + +战歌:将己方士兵士气提至最高 + +神行:加快己方所有将士行走速度 + +天鼓:己方所有兵将攻击频率最高 + +仙韵:持续增加己方将士体力 + +永生:持续增加己方将士生命 + +突斩:增加己方将士死亡打击的能力 + +迟钝:降低敌方将士攻击速度 + +开天:打开黑雾 + +采精:吸取敌人体力 + +吸血:吸取敌人生命 + + + diff --git a/安装说明.txt b/安装说明.txt new file mode 100644 index 0000000..b82b6b2 Binary files /dev/null and b/安装说明.txt differ diff --git a/获取激活码.txt b/获取激活码.txt new file mode 100644 index 0000000..cba7a01 Binary files /dev/null and b/获取激活码.txt differ