From d8c7603712ad100f5af0aff377805f985c762186 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Thu, 15 Oct 2015 23:53:54 -0400 Subject: [PATCH] Add scaling simulation script along with output. --- scale/README | 3 + scale/scales.csv | 58 ++++++++++++++ scale/simulated-scale | 173 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 234 insertions(+) create mode 100644 scale/README create mode 100644 scale/scales.csv create mode 100644 scale/simulated-scale diff --git a/scale/README b/scale/README new file mode 100644 index 0000000..9678384 --- /dev/null +++ b/scale/README @@ -0,0 +1,3 @@ +Simulation of scaling when using the sdl2-branch hardware scaling, +calculating estimates of blurriness when using non-integer scale +factors. diff --git a/scale/scales.csv b/scale/scales.csv new file mode 100644 index 0000000..56d5621 --- /dev/null +++ b/scale/scales.csv @@ -0,0 +1,58 @@ +266,200,0.49997,0.99248,n,e +333,250,0.43000,0.69730,n,n +354,266,0.43748,0.74670,n,n +400,300,0.40889,0.60000,n,n +444,333,0.43748,0.74548,n,n +466,350,0.43367,0.71306,n,n +533,400,0.25000,0.49531,n,e +600,450,0.36016,0.58519,n,n +621,466,0.37500,0.66254,n,n +666,500,0.29999,0.46426,n,n +710,533,0.30553,0.54718,n,n +733,550,0.30441,0.51383,n,n +800,600,0.16000,0.20000,n,e +866,650,0.26529,0.48481,n,n +888,666,0.27072,0.49071,n,n +933,700,0.26871,0.42582,n,n +977,733,0.23437,0.43526,n,n +1000,750,0.23371,0.39200,n,n +1066,800,0.12500,0.24765,n,e +1133,849,0.21250,0.39770,n,n +1154,866,0.21250,0.39722,n,n +1200,900,0.21092,0.28889,n,n +1244,933,0.21250,0.39678,n,n +1266,950,0.21226,0.36676,n,n +1333,1000,0.10000,0.19805,n,e +1400,1050,0.17160,0.28980,n,n +1421,1066,0.17499,0.33079,n,n +1466,1100,0.17438,0.27198,n,n +1510,1133,0.17499,0.33164,n,n +1533,1150,0.17486,0.30287,n,n +1600,1200,0.00000,0.00000,e,e +320,240,0.22222,0.33333,e,n +400,300,0.40889,0.60000,n,n +426,320,0.43750,0.68603,n,n +480,360,0.41427,0.62963,n,n +533,400,0.25000,0.49531,n,e +560,420,0.36818,0.59184,n,n +640,480,0.16667,0.25000,e,n +720,540,0.28837,0.45267,n,n +746,560,0.30272,0.52126,n,n +800,600,0.16000,0.20000,n,e +853,640,0.27083,0.45611,n,n +880,660,0.26953,0.44904,n,n +960,720,0.12346,0.22222,e,n +1040,780,0.22848,0.40828,n,n +1066,800,0.12500,0.24765,n,e +1120,840,0.21001,0.30612,n,n +1173,880,0.21178,0.38479,n,n +1200,900,0.21092,0.28889,n,n +1280,960,0.09722,0.16667,e,n +1360,1020,0.17188,0.30565,n,n +1386,1040,0.17455,0.32234,n,n +1440,1080,0.17294,0.24280,n,n +1493,1120,0.17347,0.31279,n,n +1520,1140,0.17454,0.29086,n,n +1600,1200,0.00000,0.00000,e,e +1024,768,0.23438,0.38216,n,n +1440,1080,0.17294,0.24280,n,n diff --git a/scale/simulated-scale b/scale/simulated-scale new file mode 100644 index 0000000..518f8ac --- /dev/null +++ b/scale/simulated-scale @@ -0,0 +1,173 @@ +#!/usr/bin/env python + +import sys + +ASPECT_RATIO = 4.0 / 3 +AUTO_ADJUST = True +SCREENWIDTH = 320 +SCREENHEIGHT = 200 + +def set_screen_size(w, h): + global window_w, window_h, texture_w, texture_h + global scale_horiz, scale_vert + + window_w, window_h = w, h + + if AUTO_ADJUST: + if float(window_w) / window_h > ASPECT_RATIO: + # widescreen + new_window_w = int(window_h * ASPECT_RATIO) + new_window_h = window_h + else: + new_window_w = window_w + new_window_h = int(window_w / ASPECT_RATIO) + + if (window_w, window_h) != (new_window_w, new_window_h): + window_w, window_h = new_window_w, new_window_h + #print "Auto-adjusted to %ix%i" % (window_w, window_h) + + scale_horiz = (window_w + SCREENWIDTH - 1) // SCREENWIDTH + scale_vert = (window_h + SCREENHEIGHT - 1) // SCREENHEIGHT + texture_w = SCREENWIDTH * scale_horiz + texture_h = SCREENHEIGHT * scale_vert + +def texture_pixel_value(x, y): + """Get value at the given texture coordinates.""" + orig_x = x // scale_horiz + orig_y = y // scale_vert + # Black/white checkerboard pattern: + result = (orig_x + orig_y) % 2 + #print "\t(%i, %i) -> %i" % (x, y, result) + return result + +def screen_pixel_value(x, y): + """Get pixel value at given texture coordinates.""" + tx_x = float(x * texture_w) / window_w + tx_y = float(y * texture_h) / window_h + #print "(%i, %i) -> (%.1f, %.1f) in tx" % (x, y, tx_x, tx_y) + + tx_x1 = tx_x // 1 + tx_x2 = tx_x1 + 1 + tx_y1 = tx_y // 1 + tx_y2 = tx_y1 + 1 + + tl = texture_pixel_value(tx_x1, tx_y1) + tr = texture_pixel_value(tx_x2, tx_y1) + bl = texture_pixel_value(tx_x1, tx_y2) + br = texture_pixel_value(tx_x2, tx_y2) + + x_frac = tx_x - tx_x1 + y_frac = tx_y - tx_y1 + + t = tl * (1 - x_frac) + tr * x_frac + #print "\t%.1f between %.1f and %.1f = %.1f" % (x_frac, tl, tr, t) + b = bl * (1 - x_frac) + br * x_frac + #print "\t%.1f between %.1f and %.1f = %.1f" % (y_frac, bl, br, b) + #print "\t%.1f between %.1f and %.1f" % (y_frac, t, b) + + result = t * (1 - y_frac) + b * y_frac + + return result + +def is_exact(v): + frac = min(v, 1 - v) + return frac < (1 / 256.0) + +def bluriness_measure(): + """Calculate a measure for screen blurriness.""" + num_pixels = window_w * window_h + num_blurries = 0 + blurriness = 0 + for y in range(window_h): + for x in range(window_w): + v = screen_pixel_value(x, y) + # Maximum blurriness is frac=0.5: + frac = min(v, 1 - v) + blurriness += frac / 0.5 + + if not is_exact(v): + num_blurries += 1 + + return blurriness / num_pixels, float(num_blurries) / num_pixels + +def draw_ascii(): + output_w, output_h = 80, 50 + + for y in range(output_h): + for x in range(output_w): + v = screen_pixel_value(x, y) + if is_exact(v): + if v < 0.5: + sys.stdout.write(' ') + else: + sys.stdout.write('#') + else: + if v < 0.5: + sys.stdout.write('.') + else: + sys.stdout.write(':') + sys.stdout.write('\n') + +def draw_floats(): + for y in range(output_h): + for x in range(10): + v = screen_pixel_value(x, y) + print "%.3f" % v, + print + +base_screen_sizes = ( + # Integer vertical scales: + (267, 200), + (533, 400), + (800, 600), + (1066, 800), + (1333, 1000), + (1600, 1200), + None, + # Integer horizontal scales: + (320, 240), + (640, 480), + (960, 720), + (1280, 960), + (1600, 1200), + None, + # Other modes we care about: + (1024, 768), None, + (1920, 1080), None, +) + +#set_screen_size(int(sys.argv[1]), int(sys.argv[2])) +#draw_ascii() + +for i in range(len(base_screen_sizes) - 1): + size1, size2 = base_screen_sizes[i:i+2] + if size1 is None: + continue + + def fraction_between_sizes(frac): + return ( + int(size1[0] * (1 - frac) + size2[0] * frac), + int(size1[1] * (1 - frac) + size2[1] * frac), + ) + + sizes = [size1] + if size2 is not None: + sizes.extend(( + fraction_between_sizes(0.25), + fraction_between_sizes(1.0 / 3), + fraction_between_sizes(0.5), + fraction_between_sizes(2.0 / 3), + fraction_between_sizes(0.75), + )) + + for size in sizes: + set_screen_size(size[0] + 1, size[1]) + + int_mul = ((window_w % SCREENWIDTH) == 0 + or (window_h % SCREENHEIGHT) == 0) + blurriness, num_blurries = bluriness_measure() + print "%i,%i,%.5f,%.5f,%s,%s" % ( + window_w, window_h, blurriness, num_blurries, + "e" if (window_w % SCREENWIDTH) == 0 else "n", + "e" if (window_h % SCREENHEIGHT) == 0 else "n") +