#version 450

// Super Sleuth Gamma Ramp
// based on Overload's ramp as implemented in bsnes v073
// ported by hunterk
// license: GPLv2

layout(push_constant) uniform Push
{
	vec4 SourceSize;
	vec4 OriginalSize;
	vec4 OutputSize;
	uint FrameCount;
	float mixer;
} params;

#pragma parameter mixer "Gamma Boost (%)" 150.0 100.0 200.0 1.0

layout(std140, set = 0, binding = 0) uniform UBO
{
	mat4 MVP;
} global;

#pragma stage vertex
layout(location = 0) in vec4 Position;
layout(location = 1) in vec2 TexCoord;
layout(location = 0) out vec2 vTexCoord;

void main()
{
   gl_Position = global.MVP * Position;
   vTexCoord = TexCoord;
}

#pragma stage fragment
layout(location = 0) in vec2 vTexCoord;
layout(location = 0) out vec4 FragColor;
layout(set = 0, binding = 2) uniform sampler2D Source;

// Overload's gamma ramp from Super Sleuth
// Apparently not really based on anything but it looks nice
const uint gammaRamp[32] = {
      0x00, 0x01, 0x03, 0x06, 0x0a, 0x0f, 0x15, 0x1c,
      0x24, 0x2d, 0x37, 0x42, 0x4e, 0x5b, 0x69, 0x78,
      0x88, 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xc0,
      0xc8, 0xd0, 0xd8, 0xe0, 0xe8, 0xf0, 0xf8, 0xff,
    };

#define conv(f) ((f >= 1.0) ? 255 : (f <= 0.0 ? 0 : int(floor(f * 256.0))))

void main()
{
	vec4 img = texture(Source, vTexCoord);

	// convert standard vec4 to uint color values
	uvec4 int_img = uvec4(conv(img.r), conv(img.g), conv(img.b), conv(img.a));

	uint r = (int_img.r) & 0xff;
	uint g = (int_img.g) & 0xff;
	uint b = (int_img.b) & 0xff;

	// apply the ramp
	uint R = gammaRamp[r >> 3];
	uint G = gammaRamp[g >> 3];
	uint B = gammaRamp[b >> 3];

	uvec3 output_i = uvec3(R, G, B);
	vec3  output_f = vec3(output_i) * vec3(1./255.);

	// mix between corrected and uncorrected output
	FragColor.rgb = mix(img.rgb, output_f, (params.mixer / 100.0) - 1.0);
}