diff --git a/Cocoa/GBApp.m b/Cocoa/GBApp.m index b2be7b71..4cafbb58 100644 --- a/Cocoa/GBApp.m +++ b/Cocoa/GBApp.m @@ -80,7 +80,7 @@ static uint32_t color_to_int(NSColor *color) @"GBRewind": @(kVK_Tab), @"GBSlow-Motion": @(kVK_Shift), - @"GBFilter": @"NearestNeighbor", + @"GBFilter": @"Pixelated", @"GBColorCorrection": @(GB_COLOR_CORRECTION_MODERN_BALANCED), @"GBHighpassFilter": @(GB_HIGHPASS_ACCURATE), @"GBRewindLength": @(120), diff --git a/Cocoa/Preferences.xib b/Cocoa/Preferences.xib index 8efe997c..0bda2c17 100644 --- a/Cocoa/Preferences.xib +++ b/Cocoa/Preferences.xib @@ -116,17 +116,23 @@ - + - + + + + + + + diff --git a/SDL/gui.c b/SDL/gui.c index 46397902..db677df1 100644 --- a/SDL/gui.c +++ b/SDL/gui.c @@ -1531,6 +1531,7 @@ struct shader_name { } shaders[] = { {"NearestNeighbor", "Nearest Neighbor"}, + {"Pixelated", "Pixelated"}, {"Bilinear", "Bilinear"}, {"SmoothBilinear", "Smooth Bilinear"}, {"MonoLCD", "Monochrome LCD"}, @@ -1557,7 +1558,6 @@ static void cycle_filter(unsigned index) } } - i += 1; if (i >= sizeof(shaders) / sizeof(shaders[0])) { i -= sizeof(shaders) / sizeof(shaders[0]); @@ -1566,7 +1566,7 @@ static void cycle_filter(unsigned index) strcpy(configuration.filter, shaders[i].file_name); free_shader(&shader); if (!init_shader_with_name(&shader, configuration.filter)) { - init_shader_with_name(&shader, "NearestNeighbor"); + init_shader_with_name(&shader, "Pixelated"); } } @@ -1588,7 +1588,7 @@ static void cycle_filter_backwards(unsigned index) strcpy(configuration.filter, shaders[i].file_name); free_shader(&shader); if (!init_shader_with_name(&shader, configuration.filter)) { - init_shader_with_name(&shader, "NearestNeighbor"); + init_shader_with_name(&shader, "Pixelated"); } } @@ -1603,7 +1603,7 @@ static const char *current_filter_name(unsigned index) } if (i == sizeof(shaders) / sizeof(shaders[0])) { - i = 0; + i = 1; // Pixelated } return shaders[i].display_name; diff --git a/SDL/main.c b/SDL/main.c index 4238e2ea..26e474a8 100644 --- a/SDL/main.c +++ b/SDL/main.c @@ -1596,7 +1596,7 @@ int main(int argc, char **argv) SDL_EventState(SDL_DROPFILE, SDL_ENABLE); if (!init_shader_with_name(&shader, configuration.filter)) { - init_shader_with_name(&shader, "NearestNeighbor"); + init_shader_with_name(&shader, "Pixelated"); } update_viewport(); diff --git a/Shaders/Pixelated.fsh b/Shaders/Pixelated.fsh new file mode 100644 index 00000000..e258cdd6 --- /dev/null +++ b/Shaders/Pixelated.fsh @@ -0,0 +1,18 @@ +STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution) +{ + vec2 scale_factor = output_resolution / input_resolution; + vec2 pixel = position * input_resolution - vec2(0.5, 0.5); + + vec4 q11 = texture(image, (floor(pixel) + 0.5) / input_resolution); + vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / input_resolution); + vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution); + vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution); + + vec2 t = fract(pixel); + vec2 w = clamp((t - 0.5) * scale_factor + 0.5, 0.0, 1.0); + + vec4 r1 = mix(q11, q21, w.x); + vec4 r2 = mix(q12, q22, w.x); + + return mix(r1, r2, w.y); +}