From e93c27579585393b183fbc7e9f9d3911b60cc285 Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:52:25 +0100 Subject: [PATCH] Add option for CRT shader (#314) * add CRT shader * more * more * update type * more * more * more * more --- data/shader/crt-aperture.frag | 135 ++++++++++ data/shader/frag.spv | 453 +++++++++++++++++++++++++++++++++ data/shader/output.sh | 3 + parallel-rdp/interface.cpp | 84 +++++-- parallel-rdp/interface.hpp | 8 +- parallel-rdp/spirv.hpp | 2 +- parallel-rdp/spirv_crt.hpp | 456 ++++++++++++++++++++++++++++++++++ src/ui/config.rs | 2 + src/ui/gui.rs | 14 +- src/ui/video.rs | 20 +- 10 files changed, 1136 insertions(+), 41 deletions(-) create mode 100644 data/shader/crt-aperture.frag create mode 100644 data/shader/frag.spv create mode 100755 data/shader/output.sh create mode 100644 parallel-rdp/spirv_crt.hpp diff --git a/data/shader/crt-aperture.frag b/data/shader/crt-aperture.frag new file mode 100644 index 0000000..5e1571b --- /dev/null +++ b/data/shader/crt-aperture.frag @@ -0,0 +1,135 @@ +#version 450 + +/* + CRT Shader by EasyMode + License: GPL +*/ + +layout(push_constant) uniform Push +{ + vec4 SourceSize; + vec4 OutputSize; +} params; + +#define SHARPNESS_IMAGE 1.0 +#define SHARPNESS_EDGES 3.0 +#define GLOW_WIDTH 0.5 +#define GLOW_HEIGHT 0.5 +#define GLOW_HALATION 0.1 +#define GLOW_DIFFUSION 0.05 +#define MASK_COLORS 2.0 +#define MASK_STRENGTH 0.3 +#define MASK_SIZE 1.0 +#define SCANLINE_SIZE_MIN 0.5 +#define SCANLINE_SIZE_MAX 1.5 +#define SCANLINE_SHAPE 2.5 +#define SCANLINE_OFFSET 1.0 +#define GAMMA_INPUT 2.4 +#define GAMMA_OUTPUT 2.4 +#define BRIGHTNESS 1.5 + +layout(std140, set = 0, binding = 0) uniform UBO +{ + mat4 MVP; +} global; + +#define FIX(c) max(abs(c), 1e-5) +#define PI 3.141592653589 +#define TEX2D(c) pow(texture(tex, c).rgb, vec3(GAMMA_INPUT)) +#define saturate(c) clamp(c, 0.0, 1.0) + +mat3x3 get_color_matrix(sampler2D tex, vec2 co, vec2 dx) +{ + return mat3x3(TEX2D(co - dx), TEX2D(co), TEX2D(co + dx)); +} + +vec3 blur(mat3 m, float dist, float rad) +{ + vec3 x = vec3(dist - 1.0, dist, dist + 1.0) / rad; + vec3 w = exp2(x * x * -1.0); + + return (m[0] * w.x + m[1] * w.y + m[2] * w.z) / (w.x + w.y + w.z); +} + +vec3 filter_gaussian(sampler2D tex, vec2 co, vec2 tex_size) +{ + vec2 dx = vec2(1.0 / tex_size.x, 0.0); + vec2 dy = vec2(0.0, 1.0 / tex_size.y); + vec2 pix_co = co * tex_size; + vec2 tex_co = (floor(pix_co) + 0.5) / tex_size; + vec2 dist = (fract(pix_co) - 0.5) * -1.0; + + mat3x3 line0 = get_color_matrix(tex, tex_co - dy, dx); + mat3x3 line1 = get_color_matrix(tex, tex_co, dx); + mat3x3 line2 = get_color_matrix(tex, tex_co + dy, dx); + mat3x3 column = mat3x3(blur(line0, dist.x, GLOW_WIDTH), + blur(line1, dist.x, GLOW_WIDTH), + blur(line2, dist.x, GLOW_WIDTH)); + + return blur(column, dist.y, GLOW_HEIGHT); +} + +vec3 filter_lanczos(sampler2D tex, vec2 co, vec2 tex_size, float sharp) +{ + tex_size.x *= sharp; + + vec2 dx = vec2(1.0 / tex_size.x, 0.0); + vec2 pix_co = co * tex_size - vec2(0.5, 0.0); + vec2 tex_co = (floor(pix_co) + vec2(0.5, 0.001)) / tex_size; + vec2 dist = fract(pix_co); + vec4 coef = PI * vec4(dist.x + 1.0, dist.x, dist.x - 1.0, dist.x - 2.0); + + coef = FIX(coef); + coef = 2.0 * sin(coef) * sin(coef / 2.0) / (coef * coef); + coef /= dot(coef, vec4(1.0)); + + vec4 col1 = vec4(TEX2D(tex_co), 1.0); + vec4 col2 = vec4(TEX2D(tex_co + dx), 1.0); + + return (mat4x4(col1, col1, col2, col2) * coef).rgb; +} + +vec3 get_scanline_weight(float x, vec3 col) +{ + vec3 beam = mix(vec3(SCANLINE_SIZE_MIN), vec3(SCANLINE_SIZE_MAX), pow(col, vec3(1.0 / SCANLINE_SHAPE))); + vec3 x_mul = 2.0 / beam; + vec3 x_offset = x_mul * 0.5; + + return smoothstep(0.0, 1.0, 1.0 - abs(x * x_mul - x_offset)) * x_offset; +} + +vec3 get_mask_weight(float x) +{ + float i = mod(floor(x * params.OutputSize.x * params.SourceSize.x / (params.SourceSize.x * MASK_SIZE)), MASK_COLORS); + + if (i == 0.0) return mix(vec3(1.0, 0.0, 1.0), vec3(1.0, 0.0, 0.0), MASK_COLORS - 2.0); + else if (i == 1.0) return vec3(0.0, 1.0, 0.0); + else return vec3(0.0, 0.0, 1.0); +} + +#pragma stage fragment +layout(location = 0) in vec2 vTexCoord; +layout(location = 0) out vec4 FragColor; +layout(set = 0, binding = 0) uniform sampler2D Source; + +void main() +{ + float scale = floor(params.OutputSize.y * params.SourceSize.w); + float offset = 1.0 / scale * 0.5; + + if (bool(mod(scale, 2.0))) offset = 0.0; + + vec2 co = (vTexCoord * params.SourceSize.xy - vec2(0.0, offset * SCANLINE_OFFSET)) * params.SourceSize.zw; + vec3 col_glow = filter_gaussian(Source, co, params.SourceSize.xy); + vec3 col_soft = filter_lanczos(Source, co, params.SourceSize.xy, SHARPNESS_IMAGE); + vec3 col_sharp = filter_lanczos(Source, co, params.SourceSize.xy, SHARPNESS_EDGES); + vec3 col = sqrt(col_sharp * col_soft); + + col *= get_scanline_weight(fract(co.y * params.SourceSize.y), col_soft); + col_glow = saturate(col_glow - col); + col += col_glow * col_glow * GLOW_HALATION; + col = mix(col, col * get_mask_weight(vTexCoord.x) * MASK_COLORS, MASK_STRENGTH); + col += col_glow * GLOW_DIFFUSION; + col = pow(col * BRIGHTNESS, vec3(1.0 / GAMMA_OUTPUT)); + FragColor = vec4(col, 1.0); +} diff --git a/data/shader/frag.spv b/data/shader/frag.spv new file mode 100644 index 0000000..681734c --- /dev/null +++ b/data/shader/frag.spv @@ -0,0 +1,453 @@ +{0x07230203,0x00010300,0x000d000b,0x000004fd, +0x00000000,0x00020011,0x00000001,0x0006000b, +0x00000001,0x4c534c47,0x6474732e,0x3035342e, +0x00000000,0x0003000e,0x00000000,0x00000001, +0x0007000f,0x00000004,0x00000004,0x6e69616d, +0x00000000,0x000001ba,0x0000021a,0x00030010, +0x00000004,0x00000007,0x00030047,0x00000185, +0x00000002,0x00050048,0x00000185,0x00000000, +0x00000023,0x00000000,0x00050048,0x00000185, +0x00000001,0x00000023,0x00000010,0x00040047, +0x000001ba,0x0000001e,0x00000000,0x00040047, +0x000001ca,0x00000021,0x00000000,0x00040047, +0x000001ca,0x00000022,0x00000000,0x00040047, +0x0000021a,0x0000001e,0x00000000,0x00020013, +0x00000002,0x00030021,0x00000003,0x00000002, +0x00030016,0x00000006,0x00000020,0x00090019, +0x00000007,0x00000006,0x00000001,0x00000000, +0x00000000,0x00000000,0x00000001,0x00000000, +0x0003001b,0x00000008,0x00000007,0x00040020, +0x00000009,0x00000000,0x00000008,0x00040017, +0x0000000a,0x00000006,0x00000002,0x00040017, +0x0000000c,0x00000006,0x00000003,0x00040017, +0x00000037,0x00000006,0x00000004,0x0004002b, +0x00000006,0x0000003a,0x4019999a,0x0006002c, +0x0000000c,0x0000003b,0x0000003a,0x0000003a, +0x0000003a,0x0004002b,0x00000006,0x00000049, +0x3f800000,0x0004002b,0x00000006,0x0000004a, +0x00000000,0x0004002b,0x00000006,0x00000068, +0xbf800000,0x00040015,0x0000006b,0x00000020, +0x00000001,0x0004002b,0x0000006b,0x0000006c, +0x00000000,0x00040015,0x0000006f,0x00000020, +0x00000000,0x0004002b,0x0000006f,0x00000070, +0x00000000,0x0004002b,0x0000006b,0x00000074, +0x00000001,0x0004002b,0x0000006f,0x00000077, +0x00000001,0x0004002b,0x00000006,0x000000a1, +0x3f000000,0x0005002c,0x0000000a,0x000000fc, +0x000000a1,0x0000004a,0x0004002b,0x00000006, +0x00000101,0x3a83126f,0x0005002c,0x0000000a, +0x00000102,0x000000a1,0x00000101,0x0004002b, +0x00000006,0x0000010b,0x40490fdb,0x0004002b, +0x00000006,0x00000116,0x40000000,0x0004002b, +0x00000006,0x0000011c,0x3727c5ac,0x0007002c, +0x00000037,0x0000012c,0x00000049,0x00000049, +0x00000049,0x00000049,0x00040018,0x00000149, +0x00000037,0x00000004,0x0006002c,0x0000000c, +0x00000165,0x000000a1,0x000000a1,0x000000a1, +0x0004002b,0x00000006,0x00000166,0x3fc00000, +0x0006002c,0x0000000c,0x00000167,0x00000166, +0x00000166,0x00000166,0x0004002b,0x00000006, +0x00000169,0x3ecccccd,0x0006002c,0x0000000c, +0x0000016a,0x00000169,0x00000169,0x00000169, +0x0004001e,0x00000185,0x00000037,0x00000037, +0x00040020,0x00000186,0x00000009,0x00000185, +0x0004003b,0x00000186,0x00000187,0x00000009, +0x00040020,0x00000188,0x00000009,0x00000006, +0x00020014,0x00000196,0x0006002c,0x0000000c, +0x0000019a,0x00000049,0x0000004a,0x00000049, +0x0006002c,0x0000000c,0x000001a1,0x0000004a, +0x00000049,0x0000004a,0x0006002c,0x0000000c, +0x000001a4,0x0000004a,0x0000004a,0x00000049, +0x0004002b,0x0000006f,0x000001aa,0x00000003, +0x00040020,0x000001b9,0x00000001,0x0000000a, +0x0004003b,0x000001b9,0x000001ba,0x00000001, +0x00040020,0x000001bc,0x00000009,0x00000037, +0x0004003b,0x00000009,0x000001ca,0x00000000, +0x0004002b,0x00000006,0x000001dc,0x40400000, +0x0004002b,0x00000006,0x000001ff,0x3dcccccd, +0x00040020,0x00000206,0x00000001,0x00000006, +0x0004002b,0x00000006,0x0000020c,0x3e99999a, +0x0004002b,0x00000006,0x00000210,0x3d4ccccd, +0x0004002b,0x00000006,0x00000216,0x3ed55555, +0x0006002c,0x0000000c,0x00000217,0x00000216, +0x00000216,0x00000216,0x00040020,0x00000219, +0x00000003,0x00000037,0x0004003b,0x00000219, +0x0000021a,0x00000003,0x0005002c,0x0000000a, +0x000004f3,0x000000a1,0x000000a1,0x0007002c, +0x00000037,0x000004f4,0x0000011c,0x0000011c, +0x0000011c,0x0000011c,0x0006002c,0x0000000c, +0x000004f6,0x00000116,0x00000116,0x00000116, +0x0006002c,0x0000000c,0x000004f7,0x00000049, +0x00000049,0x00000049,0x0006002c,0x0000000c, +0x000004f8,0x0000004a,0x0000004a,0x0000004a, +0x0006002c,0x0000000c,0x000004f9,0x0000020c, +0x0000020c,0x0000020c,0x0007002c,0x00000037, +0x000004fa,0x000000a1,0x000000a1,0x000000a1, +0x000000a1,0x0004002b,0x00000006,0x000004fb, +0x3eaaaaab,0x00050036,0x00000002,0x00000004, +0x00000000,0x00000003,0x000200f8,0x00000005, +0x00060041,0x00000188,0x000001a8,0x00000187, +0x00000074,0x00000077,0x0004003d,0x00000006, +0x000001a9,0x000001a8,0x00060041,0x00000188, +0x000001ab,0x00000187,0x0000006c,0x000001aa, +0x0004003d,0x00000006,0x000001ac,0x000001ab, +0x00050085,0x00000006,0x000001ad,0x000001a9, +0x000001ac,0x0006000c,0x00000006,0x000001ae, +0x00000001,0x00000008,0x000001ad,0x00050088, +0x00000006,0x000001b2,0x000000a1,0x000001ae, +0x0005008d,0x00000006,0x000001b4,0x000001ae, +0x00000116,0x000500b7,0x00000196,0x000001b5, +0x000001b4,0x0000004a,0x000600a9,0x00000006, +0x000004fc,0x000001b5,0x0000004a,0x000001b2, +0x0004003d,0x0000000a,0x000001bb,0x000001ba, +0x00050041,0x000001bc,0x000001bd,0x00000187, +0x0000006c,0x0004003d,0x00000037,0x000001be, +0x000001bd,0x0007004f,0x0000000a,0x000001bf, +0x000001be,0x000001be,0x00000000,0x00000001, +0x00050085,0x0000000a,0x000001c0,0x000001bb, +0x000001bf,0x00050050,0x0000000a,0x000001c3, +0x0000004a,0x000004fc,0x00050083,0x0000000a, +0x000001c4,0x000001c0,0x000001c3,0x0007004f, +0x0000000a,0x000001c7,0x000001be,0x000001be, +0x00000002,0x00000003,0x00050085,0x0000000a, +0x000001c8,0x000001c4,0x000001c7,0x00050051, +0x00000006,0x00000249,0x000001be,0x00000000, +0x00050088,0x00000006,0x0000024a,0x00000049, +0x00000249,0x00050050,0x0000000a,0x0000024b, +0x0000024a,0x0000004a,0x00050051,0x00000006, +0x0000024d,0x000001be,0x00000001,0x00050088, +0x00000006,0x0000024e,0x00000049,0x0000024d, +0x00050050,0x0000000a,0x0000024f,0x0000004a, +0x0000024e,0x00050085,0x0000000a,0x00000252, +0x000001c8,0x000001bf,0x0006000c,0x0000000a, +0x00000254,0x00000001,0x00000008,0x00000252, +0x00050081,0x0000000a,0x00000256,0x00000254, +0x000004f3,0x00050088,0x0000000a,0x00000258, +0x00000256,0x000001bf,0x0006000c,0x0000000a, +0x0000025a,0x00000001,0x0000000a,0x00000252, +0x00050083,0x0000000a,0x0000025c,0x0000025a, +0x000004f3,0x0005008e,0x0000000a,0x0000025d, +0x0000025c,0x00000068,0x00050083,0x0000000a, +0x00000260,0x00000258,0x0000024f,0x0004003d, +0x00000008,0x0000028a,0x000001ca,0x00050083, +0x0000000a,0x0000028d,0x00000260,0x0000024b, +0x00050057,0x00000037,0x0000028e,0x0000028a, +0x0000028d,0x0008004f,0x0000000c,0x0000028f, +0x0000028e,0x0000028e,0x00000000,0x00000001, +0x00000002,0x0007000c,0x0000000c,0x00000290, +0x00000001,0x0000001a,0x0000028f,0x0000003b, +0x00050057,0x00000037,0x00000293,0x0000028a, +0x00000260,0x0008004f,0x0000000c,0x00000294, +0x00000293,0x00000293,0x00000000,0x00000001, +0x00000002,0x0007000c,0x0000000c,0x00000295, +0x00000001,0x0000001a,0x00000294,0x0000003b, +0x00050081,0x0000000a,0x00000299,0x00000260, +0x0000024b,0x00050057,0x00000037,0x0000029a, +0x0000028a,0x00000299,0x0008004f,0x0000000c, +0x0000029b,0x0000029a,0x0000029a,0x00000000, +0x00000001,0x00000002,0x0007000c,0x0000000c, +0x0000029c,0x00000001,0x0000001a,0x0000029b, +0x0000003b,0x00050083,0x0000000a,0x000002af, +0x00000258,0x0000024b,0x00050057,0x00000037, +0x000002b0,0x0000028a,0x000002af,0x0008004f, +0x0000000c,0x000002b1,0x000002b0,0x000002b0, +0x00000000,0x00000001,0x00000002,0x0007000c, +0x0000000c,0x000002b2,0x00000001,0x0000001a, +0x000002b1,0x0000003b,0x00050057,0x00000037, +0x000002b5,0x0000028a,0x00000258,0x0008004f, +0x0000000c,0x000002b6,0x000002b5,0x000002b5, +0x00000000,0x00000001,0x00000002,0x0007000c, +0x0000000c,0x000002b7,0x00000001,0x0000001a, +0x000002b6,0x0000003b,0x00050081,0x0000000a, +0x000002bb,0x00000258,0x0000024b,0x00050057, +0x00000037,0x000002bc,0x0000028a,0x000002bb, +0x0008004f,0x0000000c,0x000002bd,0x000002bc, +0x000002bc,0x00000000,0x00000001,0x00000002, +0x0007000c,0x0000000c,0x000002be,0x00000001, +0x0000001a,0x000002bd,0x0000003b,0x00050081, +0x0000000a,0x00000268,0x00000258,0x0000024f, +0x00050083,0x0000000a,0x000002d1,0x00000268, +0x0000024b,0x00050057,0x00000037,0x000002d2, +0x0000028a,0x000002d1,0x0008004f,0x0000000c, +0x000002d3,0x000002d2,0x000002d2,0x00000000, +0x00000001,0x00000002,0x0007000c,0x0000000c, +0x000002d4,0x00000001,0x0000001a,0x000002d3, +0x0000003b,0x00050057,0x00000037,0x000002d7, +0x0000028a,0x00000268,0x0008004f,0x0000000c, +0x000002d8,0x000002d7,0x000002d7,0x00000000, +0x00000001,0x00000002,0x0007000c,0x0000000c, +0x000002d9,0x00000001,0x0000001a,0x000002d8, +0x0000003b,0x00050081,0x0000000a,0x000002dd, +0x00000268,0x0000024b,0x00050057,0x00000037, +0x000002de,0x0000028a,0x000002dd,0x0008004f, +0x0000000c,0x000002df,0x000002de,0x000002de, +0x00000000,0x00000001,0x00000002,0x0007000c, +0x0000000c,0x000002e0,0x00000001,0x0000001a, +0x000002df,0x0000003b,0x00050051,0x00000006, +0x0000026d,0x0000025d,0x00000000,0x00050083, +0x00000006,0x000002f3,0x0000026d,0x00000049, +0x00050081,0x00000006,0x000002f6,0x0000026d, +0x00000049,0x00060050,0x0000000c,0x000002f7, +0x000002f3,0x0000026d,0x000002f6,0x00050085, +0x0000000c,0x000002fa,0x000002f7,0x000004f6, +0x00050085,0x0000000c,0x000002fd,0x000002fa, +0x000002fa,0x0005008e,0x0000000c,0x000002fe, +0x000002fd,0x00000068,0x0006000c,0x0000000c, +0x000002ff,0x00000001,0x0000001d,0x000002fe, +0x00050051,0x00000006,0x00000303,0x000002ff, +0x00000000,0x0005008e,0x0000000c,0x00000304, +0x00000290,0x00000303,0x00050051,0x00000006, +0x00000308,0x000002ff,0x00000001,0x0005008e, +0x0000000c,0x00000309,0x00000295,0x00000308, +0x00050081,0x0000000c,0x0000030a,0x00000304, +0x00000309,0x00050051,0x00000006,0x0000030e, +0x000002ff,0x00000002,0x0005008e,0x0000000c, +0x0000030f,0x0000029c,0x0000030e,0x00050081, +0x0000000c,0x00000310,0x0000030a,0x0000030f, +0x00050081,0x00000006,0x00000315,0x00000303, +0x00000308,0x00050081,0x00000006,0x00000318, +0x00000315,0x0000030e,0x00060050,0x0000000c, +0x00000319,0x00000318,0x00000318,0x00000318, +0x00050088,0x0000000c,0x0000031a,0x00000310, +0x00000319,0x0005008e,0x0000000c,0x00000331, +0x000002b2,0x00000303,0x0005008e,0x0000000c, +0x00000336,0x000002b7,0x00000308,0x00050081, +0x0000000c,0x00000337,0x00000331,0x00000336, +0x0005008e,0x0000000c,0x0000033c,0x000002be, +0x0000030e,0x00050081,0x0000000c,0x0000033d, +0x00000337,0x0000033c,0x00050088,0x0000000c, +0x00000347,0x0000033d,0x00000319,0x0005008e, +0x0000000c,0x0000035e,0x000002d4,0x00000303, +0x0005008e,0x0000000c,0x00000363,0x000002d9, +0x00000308,0x00050081,0x0000000c,0x00000364, +0x0000035e,0x00000363,0x0005008e,0x0000000c, +0x00000369,0x000002e0,0x0000030e,0x00050081, +0x0000000c,0x0000036a,0x00000364,0x00000369, +0x00050088,0x0000000c,0x00000374,0x0000036a, +0x00000319,0x00050051,0x00000006,0x00000286, +0x0000025d,0x00000001,0x00050083,0x00000006, +0x0000037a,0x00000286,0x00000049,0x00050081, +0x00000006,0x0000037d,0x00000286,0x00000049, +0x00060050,0x0000000c,0x0000037e,0x0000037a, +0x00000286,0x0000037d,0x00050085,0x0000000c, +0x00000381,0x0000037e,0x000004f6,0x00050085, +0x0000000c,0x00000384,0x00000381,0x00000381, +0x0005008e,0x0000000c,0x00000385,0x00000384, +0x00000068,0x0006000c,0x0000000c,0x00000386, +0x00000001,0x0000001d,0x00000385,0x00050051, +0x00000006,0x0000038a,0x00000386,0x00000000, +0x0005008e,0x0000000c,0x0000038b,0x0000031a, +0x0000038a,0x00050051,0x00000006,0x0000038f, +0x00000386,0x00000001,0x0005008e,0x0000000c, +0x00000390,0x00000347,0x0000038f,0x00050081, +0x0000000c,0x00000391,0x0000038b,0x00000390, +0x00050051,0x00000006,0x00000395,0x00000386, +0x00000002,0x0005008e,0x0000000c,0x00000396, +0x00000374,0x00000395,0x00050081,0x0000000c, +0x00000397,0x00000391,0x00000396,0x00050081, +0x00000006,0x0000039c,0x0000038a,0x0000038f, +0x00050081,0x00000006,0x0000039f,0x0000039c, +0x00000395,0x00060050,0x0000000c,0x000003a0, +0x0000039f,0x0000039f,0x0000039f,0x00050088, +0x0000000c,0x000003a1,0x00000397,0x000003a0, +0x00060052,0x0000000a,0x000004e1,0x00000249, +0x000001bf,0x00000000,0x00050085,0x0000000a, +0x000003b6,0x000001c8,0x000004e1,0x00050083, +0x0000000a,0x000003b7,0x000003b6,0x000000fc, +0x0006000c,0x0000000a,0x000003b9,0x00000001, +0x00000008,0x000003b7,0x00050081,0x0000000a, +0x000003ba,0x000003b9,0x00000102,0x00050088, +0x0000000a,0x000003bc,0x000003ba,0x000004e1, +0x0006000c,0x0000000a,0x000003be,0x00000001, +0x0000000a,0x000003b7,0x00050051,0x00000006, +0x000003c0,0x000003be,0x00000000,0x00050081, +0x00000006,0x000003c1,0x000003c0,0x00000049, +0x00050083,0x00000006,0x000003c6,0x000003c0, +0x00000049,0x00050083,0x00000006,0x000003c9, +0x000003c0,0x00000116,0x00070050,0x00000037, +0x000003ca,0x000003c1,0x000003c0,0x000003c6, +0x000003c9,0x0005008e,0x00000037,0x000003cb, +0x000003ca,0x0000010b,0x0006000c,0x00000037, +0x000003cd,0x00000001,0x00000004,0x000003cb, +0x0007000c,0x00000037,0x000003cf,0x00000001, +0x00000028,0x000003cd,0x000004f4,0x0006000c, +0x00000037,0x000003d1,0x00000001,0x0000000d, +0x000003cf,0x0005008e,0x00000037,0x000003d2, +0x000003d1,0x00000116,0x00050085,0x00000037, +0x000003d5,0x000003cf,0x000004fa,0x0006000c, +0x00000037,0x000003d6,0x00000001,0x0000000d, +0x000003d5,0x00050085,0x00000037,0x000003d7, +0x000003d2,0x000003d6,0x00050085,0x00000037, +0x000003da,0x000003cf,0x000003cf,0x00050088, +0x00000037,0x000003db,0x000003d7,0x000003da, +0x00050094,0x00000006,0x000003dd,0x000003db, +0x0000012c,0x00070050,0x00000037,0x000003df, +0x000003dd,0x000003dd,0x000003dd,0x000003dd, +0x00050088,0x00000037,0x000003e0,0x000003db, +0x000003df,0x00050057,0x00000037,0x000003e3, +0x0000028a,0x000003bc,0x0008004f,0x0000000c, +0x000003e4,0x000003e3,0x000003e3,0x00000000, +0x00000001,0x00000002,0x0007000c,0x0000000c, +0x000003e5,0x00000001,0x0000001a,0x000003e4, +0x0000003b,0x00050051,0x00000006,0x000003e6, +0x000003e5,0x00000000,0x00050051,0x00000006, +0x000003e7,0x000003e5,0x00000001,0x00050051, +0x00000006,0x000003e8,0x000003e5,0x00000002, +0x00050081,0x0000000a,0x000003ed,0x000003bc, +0x0000024b,0x00050057,0x00000037,0x000003ee, +0x0000028a,0x000003ed,0x0008004f,0x0000000c, +0x000003ef,0x000003ee,0x000003ee,0x00000000, +0x00000001,0x00000002,0x0007000c,0x0000000c, +0x000003f0,0x00000001,0x0000001a,0x000003ef, +0x0000003b,0x00050051,0x00000006,0x000003f1, +0x000003f0,0x00000000,0x00050051,0x00000006, +0x000003f2,0x000003f0,0x00000001,0x00050051, +0x00000006,0x000003f3,0x000003f0,0x00000002, +0x00070050,0x00000037,0x00000407,0x000003e6, +0x000003e7,0x000003e8,0x00000049,0x00070050, +0x00000037,0x00000409,0x000003f1,0x000003f2, +0x000003f3,0x00000049,0x00070050,0x00000149, +0x0000040b,0x00000407,0x00000407,0x00000409, +0x00000409,0x00050091,0x00000037,0x0000040d, +0x0000040b,0x000003e0,0x0008004f,0x0000000c, +0x0000040e,0x0000040d,0x0000040d,0x00000000, +0x00000001,0x00000002,0x00050085,0x00000006, +0x0000041b,0x00000249,0x000001dc,0x00060052, +0x0000000a,0x000004e9,0x0000041b,0x000001bf, +0x00000000,0x00050088,0x00000006,0x0000041f, +0x000004fb,0x00000249,0x00050050,0x0000000a, +0x00000420,0x0000041f,0x0000004a,0x00050085, +0x0000000a,0x00000423,0x000001c8,0x000004e9, +0x00050083,0x0000000a,0x00000424,0x00000423, +0x000000fc,0x0006000c,0x0000000a,0x00000426, +0x00000001,0x00000008,0x00000424,0x00050081, +0x0000000a,0x00000427,0x00000426,0x00000102, +0x00050088,0x0000000a,0x00000429,0x00000427, +0x000004e9,0x0006000c,0x0000000a,0x0000042b, +0x00000001,0x0000000a,0x00000424,0x00050051, +0x00000006,0x0000042d,0x0000042b,0x00000000, +0x00050081,0x00000006,0x0000042e,0x0000042d, +0x00000049,0x00050083,0x00000006,0x00000433, +0x0000042d,0x00000049,0x00050083,0x00000006, +0x00000436,0x0000042d,0x00000116,0x00070050, +0x00000037,0x00000437,0x0000042e,0x0000042d, +0x00000433,0x00000436,0x0005008e,0x00000037, +0x00000438,0x00000437,0x0000010b,0x0006000c, +0x00000037,0x0000043a,0x00000001,0x00000004, +0x00000438,0x0007000c,0x00000037,0x0000043c, +0x00000001,0x00000028,0x0000043a,0x000004f4, +0x0006000c,0x00000037,0x0000043e,0x00000001, +0x0000000d,0x0000043c,0x0005008e,0x00000037, +0x0000043f,0x0000043e,0x00000116,0x00050085, +0x00000037,0x00000442,0x0000043c,0x000004fa, +0x0006000c,0x00000037,0x00000443,0x00000001, +0x0000000d,0x00000442,0x00050085,0x00000037, +0x00000444,0x0000043f,0x00000443,0x00050085, +0x00000037,0x00000447,0x0000043c,0x0000043c, +0x00050088,0x00000037,0x00000448,0x00000444, +0x00000447,0x00050094,0x00000006,0x0000044a, +0x00000448,0x0000012c,0x00070050,0x00000037, +0x0000044c,0x0000044a,0x0000044a,0x0000044a, +0x0000044a,0x00050088,0x00000037,0x0000044d, +0x00000448,0x0000044c,0x00050057,0x00000037, +0x00000450,0x0000028a,0x00000429,0x0008004f, +0x0000000c,0x00000451,0x00000450,0x00000450, +0x00000000,0x00000001,0x00000002,0x0007000c, +0x0000000c,0x00000452,0x00000001,0x0000001a, +0x00000451,0x0000003b,0x00050051,0x00000006, +0x00000453,0x00000452,0x00000000,0x00050051, +0x00000006,0x00000454,0x00000452,0x00000001, +0x00050051,0x00000006,0x00000455,0x00000452, +0x00000002,0x00050081,0x0000000a,0x0000045a, +0x00000429,0x00000420,0x00050057,0x00000037, +0x0000045b,0x0000028a,0x0000045a,0x0008004f, +0x0000000c,0x0000045c,0x0000045b,0x0000045b, +0x00000000,0x00000001,0x00000002,0x0007000c, +0x0000000c,0x0000045d,0x00000001,0x0000001a, +0x0000045c,0x0000003b,0x00050051,0x00000006, +0x0000045e,0x0000045d,0x00000000,0x00050051, +0x00000006,0x0000045f,0x0000045d,0x00000001, +0x00050051,0x00000006,0x00000460,0x0000045d, +0x00000002,0x00070050,0x00000037,0x00000474, +0x00000453,0x00000454,0x00000455,0x00000049, +0x00070050,0x00000037,0x00000476,0x0000045e, +0x0000045f,0x00000460,0x00000049,0x00070050, +0x00000149,0x00000478,0x00000474,0x00000474, +0x00000476,0x00000476,0x00050091,0x00000037, +0x0000047a,0x00000478,0x0000044d,0x0008004f, +0x0000000c,0x0000047b,0x0000047a,0x0000047a, +0x00000000,0x00000001,0x00000002,0x00050085, +0x0000000c,0x000001e8,0x0000047b,0x0000040e, +0x0006000c,0x0000000c,0x000001e9,0x00000001, +0x0000001f,0x000001e8,0x00050051,0x00000006, +0x000001eb,0x000001c8,0x00000001,0x00060041, +0x00000188,0x000001ec,0x00000187,0x0000006c, +0x00000077,0x0004003d,0x00000006,0x000001ed, +0x000001ec,0x00050085,0x00000006,0x000001ee, +0x000001eb,0x000001ed,0x0006000c,0x00000006, +0x000001ef,0x00000001,0x0000000a,0x000001ee, +0x0007000c,0x0000000c,0x00000482,0x00000001, +0x0000001a,0x0000040e,0x0000016a,0x0008000c, +0x0000000c,0x00000483,0x00000001,0x0000002e, +0x00000165,0x00000167,0x00000482,0x00050088, +0x0000000c,0x00000486,0x000004f6,0x00000483, +0x0005008e,0x0000000c,0x00000488,0x00000486, +0x000000a1,0x0005008e,0x0000000c,0x0000048b, +0x00000486,0x000001ef,0x00050083,0x0000000c, +0x0000048d,0x0000048b,0x00000488,0x0006000c, +0x0000000c,0x0000048e,0x00000001,0x00000004, +0x0000048d,0x00050083,0x0000000c,0x00000490, +0x000004f7,0x0000048e,0x0008000c,0x0000000c, +0x00000493,0x00000001,0x00000031,0x000004f8, +0x000004f7,0x00000490,0x00050085,0x0000000c, +0x00000495,0x00000493,0x00000488,0x00050085, +0x0000000c,0x000001f5,0x000001e9,0x00000495, +0x00050083,0x0000000c,0x000001f8,0x000003a1, +0x000001f5,0x0008000c,0x0000000c,0x000001fb, +0x00000001,0x0000002b,0x000001f8,0x000004f8, +0x000004f7,0x00050085,0x0000000c,0x000001fe, +0x000001fb,0x000001fb,0x0005008e,0x0000000c, +0x00000200,0x000001fe,0x000001ff,0x00050081, +0x0000000c,0x00000202,0x000001f5,0x00000200, +0x00050041,0x00000206,0x00000207,0x000001ba, +0x00000070,0x0004003d,0x00000006,0x00000208, +0x00000207,0x000300f7,0x000004b3,0x00000000, +0x000300fb,0x00000070,0x0000049b,0x000200f8, +0x0000049b,0x00060041,0x00000188,0x0000049d, +0x00000187,0x00000074,0x00000070,0x0004003d, +0x00000006,0x0000049e,0x0000049d,0x00050085, +0x00000006,0x0000049f,0x00000208,0x0000049e, +0x0006000c,0x00000006,0x000004a7,0x00000001, +0x00000008,0x0000049f,0x0005008d,0x00000006, +0x000004a8,0x000004a7,0x00000116,0x000500b4, +0x00000196,0x000004aa,0x000004a8,0x0000004a, +0x000300f7,0x000004b2,0x00000000,0x000400fa, +0x000004aa,0x000004ab,0x000004ac,0x000200f8, +0x000004ac,0x000500b4,0x00000196,0x000004ae, +0x000004a8,0x00000049,0x000300f7,0x000004b1, +0x00000000,0x000400fa,0x000004ae,0x000004af, +0x000004b0,0x000200f8,0x000004b0,0x000200f9, +0x000004b3,0x000200f8,0x000004af,0x000200f9, +0x000004b3,0x000200f8,0x000004b1,0x000100ff, +0x000200f8,0x000004ab,0x000200f9,0x000004b3, +0x000200f8,0x000004b2,0x000100ff,0x000200f8, +0x000004b3,0x000900f5,0x0000000c,0x000004f1, +0x0000019a,0x000004ab,0x000001a1,0x000004af, +0x000001a4,0x000004b0,0x00050085,0x0000000c, +0x0000020a,0x00000202,0x000004f1,0x0005008e, +0x0000000c,0x0000020b,0x0000020a,0x00000116, +0x0008000c,0x0000000c,0x0000020e,0x00000001, +0x0000002e,0x00000202,0x0000020b,0x000004f9, +0x0005008e,0x0000000c,0x00000211,0x000001fb, +0x00000210,0x00050081,0x0000000c,0x00000213, +0x0000020e,0x00000211,0x0005008e,0x0000000c, +0x00000215,0x00000213,0x00000166,0x0007000c, +0x0000000c,0x00000218,0x00000001,0x0000001a, +0x00000215,0x00000217,0x00050051,0x00000006, +0x0000021c,0x00000218,0x00000000,0x00050051, +0x00000006,0x0000021d,0x00000218,0x00000001, +0x00050051,0x00000006,0x0000021e,0x00000218, +0x00000002,0x00070050,0x00000037,0x0000021f, +0x0000021c,0x0000021d,0x0000021e,0x00000049, +0x0003003e,0x0000021a,0x0000021f,0x000100fd, +0x00010038} diff --git a/data/shader/output.sh b/data/shader/output.sh new file mode 100755 index 0000000..749c9c2 --- /dev/null +++ b/data/shader/output.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +glslc -O crt-aperture.frag -o frag.spv --target-env=vulkan1.1 -mfmt=c diff --git a/parallel-rdp/interface.cpp b/parallel-rdp/interface.cpp index 5a950df..977cdbf 100644 --- a/parallel-rdp/interface.cpp +++ b/parallel-rdp/interface.cpp @@ -3,6 +3,7 @@ #include "rdp_device.hpp" #include "interface.hpp" #include "spirv.hpp" +#include "spirv_crt.hpp" #include using namespace Vulkan; @@ -51,8 +52,6 @@ enum vi_registers VI_REGS_COUNT }; -static bool fullscreen; -static bool integer_scaling; static SDL_Window *window; static RDP::CommandProcessor *processor; static SDL_WSIPlatform *wsi_platform; @@ -64,6 +63,8 @@ static CALL_BACK callback; static GFX_INFO gfx_info; static uint32_t region; static bool crop_letterbox; +static const uint32_t *fragment_spirv; +static size_t fragment_size; typedef struct { @@ -77,6 +78,12 @@ typedef struct uint8_t depthbuffer_enabled; } FrameBufferInfo; +typedef struct +{ + float SourceSize[4]; + float OutputSize[4]; +} Push; + static uint8_t *rdram_dirty; static uint64_t sync_signal; static FrameBufferInfo frame_buffer_info; @@ -165,8 +172,8 @@ bool sdl_event_filter(void *userdata, SDL_Event *event) case SDL_SCANCODE_RETURN: if (event->key.mod & SDL_KMOD_ALT) { - fullscreen = !fullscreen; - SDL_SetWindowFullscreen(window, fullscreen); + gfx_info.fullscreen = !gfx_info.fullscreen; + SDL_SetWindowFullscreen(window, gfx_info.fullscreen); } break; case SDL_SCANCODE_F: @@ -176,7 +183,7 @@ bool sdl_event_filter(void *userdata, SDL_Event *event) } break; case SDL_SCANCODE_ESCAPE: - if (fullscreen) + if (gfx_info.fullscreen) callback.emu_running = false; break; case SDL_SCANCODE_F4: @@ -196,7 +203,7 @@ bool sdl_event_filter(void *userdata, SDL_Event *event) return 0; } -void rdp_new_processor(GFX_INFO _gfx_info, uint32_t upscale) +void rdp_new_processor(GFX_INFO _gfx_info) { memset(&frame_buffer_info, 0, sizeof(FrameBufferInfo)); sync_signal = 0; @@ -209,12 +216,12 @@ void rdp_new_processor(GFX_INFO _gfx_info, uint32_t upscale) } RDP::CommandProcessorFlags flags = 0; - if (upscale == 2) + if (gfx_info.upscale == 2) { flags |= RDP::COMMAND_PROCESSOR_FLAG_SUPER_SAMPLED_DITHER_BIT; flags |= RDP::COMMAND_PROCESSOR_FLAG_UPSCALING_2X_BIT; } - else if (upscale == 4) + else if (gfx_info.upscale == 4) { flags |= RDP::COMMAND_PROCESSOR_FLAG_SUPER_SAMPLED_DITHER_BIT; flags |= RDP::COMMAND_PROCESSOR_FLAG_UPSCALING_4X_BIT; @@ -223,7 +230,7 @@ void rdp_new_processor(GFX_INFO _gfx_info, uint32_t upscale) processor = new RDP::CommandProcessor(wsi->get_device(), gfx_info.RDRAM, 0, gfx_info.RDRAM_SIZE, gfx_info.RDRAM_SIZE / 2, flags); } -void rdp_init(void *_window, GFX_INFO _gfx_info, uint32_t _upscale, bool _integer_scaling, bool _fullscreen) +void rdp_init(void *_window, GFX_INFO _gfx_info) { window = (SDL_Window *)_window; bool result = SDL_AddEventWatch(sdl_event_filter, nullptr); @@ -234,8 +241,18 @@ void rdp_init(void *_window, GFX_INFO _gfx_info, uint32_t _upscale, bool _intege } gfx_info = _gfx_info; - fullscreen = _fullscreen; - integer_scaling = _integer_scaling; + + if (gfx_info.crt) + { + fragment_spirv = crt_fragment_spirv; + fragment_size = sizeof(crt_fragment_spirv); + } + else + { + fragment_spirv = plain_fragment_spirv; + fragment_size = sizeof(plain_fragment_spirv); + } + bool window_vsync = 0; wsi = new WSI; wsi_platform = new SDL_WSIPlatform; @@ -254,7 +271,7 @@ void rdp_init(void *_window, GFX_INFO _gfx_info, uint32_t _upscale, bool _intege } rdram_dirty = (uint8_t *)malloc(gfx_info.RDRAM_SIZE / 8); - rdp_new_processor(gfx_info, _upscale); + rdp_new_processor(gfx_info); if (!processor->device_is_supported()) { @@ -297,15 +314,14 @@ void rdp_close() } } -static void calculate_viewport(float *x, float *y, float *width, float *height) +static void calculate_viewport(float *x, float *y, float *width, float *height, uint32_t display_height) { - const int32_t display_width = gfx_info.widescreen ? (gfx_info.PAL ? 512 : 426) : (gfx_info.PAL ? 384 : 320); - const int32_t display_height = gfx_info.PAL ? 288 : 240; + uint32_t display_width = gfx_info.widescreen ? display_height * 16 / 9 : display_height * 4 / 3; int w, h; SDL_GetWindowSize(window, &w, &h); - if (integer_scaling) + if (gfx_info.integer_scaling) { // Integer scaling path int scale_x = w / display_width; @@ -320,6 +336,13 @@ static void calculate_viewport(float *x, float *y, float *width, float *height) *width = scaled_width; *height = scaled_height; + + // Center the viewport + int integer_x = (w - *width) / 2.0f; + int integer_y = (h - *height) / 2.0f; + + *x = integer_x; + *y = integer_y; } else { @@ -330,11 +353,11 @@ static void calculate_viewport(float *x, float *y, float *width, float *height) *width = display_width * scale; *height = display_height * scale; - } - // Center the viewport - *x = (w - *width) / 2.0f; - *y = (h - *height) / 2.0f; + // Center the viewport + *x = (w - *width) / 2.0f; + *y = (h - *height) / 2.0f; + } } static void render_frame(Vulkan::Device &device) @@ -361,15 +384,16 @@ static void render_frame(Vulkan::Device &device) Vulkan::ImageHandle image = processor->scanout(options); - // Normally reflection is automated. Vulkan::ResourceLayout vertex_layout = {}; Vulkan::ResourceLayout fragment_layout = {}; fragment_layout.output_mask = 1 << 0; fragment_layout.sets[0].sampled_image_mask = 1 << 0; + if (gfx_info.crt) + fragment_layout.push_constant_size = sizeof(Push); // This request is cached. auto *program = device.request_program(vertex_spirv, sizeof(vertex_spirv), - fragment_spirv, sizeof(fragment_spirv), + fragment_spirv, fragment_size, &vertex_layout, &fragment_layout); @@ -379,9 +403,6 @@ static void render_frame(Vulkan::Device &device) auto rp = device.get_swapchain_render_pass(Vulkan::SwapchainRenderPass::ColorOnly); cmd->begin_render_pass(rp); - VkViewport vp = cmd->get_viewport(); - calculate_viewport(&vp.x, &vp.y, &vp.width, &vp.height); - cmd->set_program(program); // Basic default render state. @@ -392,6 +413,19 @@ static void render_frame(Vulkan::Device &device) // If we don't have an image, we just get a cleared screen in the render pass. if (image) { + VkViewport vp = cmd->get_viewport(); + calculate_viewport(&vp.x, &vp.y, &vp.width, &vp.height, image->get_height()); + + if (gfx_info.crt) + { + // Set shader parameters + Push push = { + {float(image->get_width()), float(image->get_height()), 1.0f / float(image->get_width()), 1.0f / float(image->get_height())}, + {vp.width, vp.height, 1.0f / vp.width, 1.0f / vp.height}, + }; + cmd->push_constants(&push, 0, sizeof(push)); + } + cmd->set_texture(0, 0, image->get_view(), Vulkan::StockSampler::LinearClamp); cmd->set_viewport(vp); // The vertices are constants in the shader. diff --git a/parallel-rdp/interface.hpp b/parallel-rdp/interface.hpp index 583625e..5a0323e 100644 --- a/parallel-rdp/interface.hpp +++ b/parallel-rdp/interface.hpp @@ -18,6 +18,10 @@ extern "C" uint32_t *DPC_STATUS_REG; bool PAL; bool widescreen; + bool fullscreen; + bool integer_scaling; + uint32_t upscale; + bool crt; } GFX_INFO; typedef struct @@ -28,13 +32,13 @@ extern "C" bool enable_speedlimiter; } CALL_BACK; - void rdp_init(void *_window, GFX_INFO _gfx_info, uint32_t _upscale, bool _integer_scaling, bool _fullscreen); + void rdp_init(void *_window, GFX_INFO _gfx_info); void rdp_close(); void rdp_set_vi_register(uint32_t reg, uint32_t value); void rdp_update_screen(); CALL_BACK rdp_check_callback(); uint64_t rdp_process_commands(); - void rdp_new_processor(GFX_INFO _gfx_info, uint32_t _upscale); + void rdp_new_processor(GFX_INFO _gfx_info); void rdp_check_framebuffers(uint32_t address); void rdp_full_sync(); diff --git a/parallel-rdp/spirv.hpp b/parallel-rdp/spirv.hpp index 50619fc..f227353 100644 --- a/parallel-rdp/spirv.hpp +++ b/parallel-rdp/spirv.hpp @@ -74,7 +74,7 @@ static const uint32_t vertex_spirv[] = 0x00000030, 0x00000033, 0x0003003e, 0x0000002b, 0x00000032, 0x000100fd, 0x00010038}; -static const uint32_t fragment_spirv[] = +static const uint32_t plain_fragment_spirv[] = {0x07230203, 0x00010000, 0x000d000a, 0x00000015, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, diff --git a/parallel-rdp/spirv_crt.hpp b/parallel-rdp/spirv_crt.hpp new file mode 100644 index 0000000..fdcf4ce --- /dev/null +++ b/parallel-rdp/spirv_crt.hpp @@ -0,0 +1,456 @@ +#pragma once + +static const uint32_t crt_fragment_spirv[] = + {0x07230203, 0x00010300, 0x000d000b, 0x000004fd, + 0x00000000, 0x00020011, 0x00000001, 0x0006000b, + 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, + 0x00000000, 0x0003000e, 0x00000000, 0x00000001, + 0x0007000f, 0x00000004, 0x00000004, 0x6e69616d, + 0x00000000, 0x000001ba, 0x0000021a, 0x00030010, + 0x00000004, 0x00000007, 0x00030047, 0x00000185, + 0x00000002, 0x00050048, 0x00000185, 0x00000000, + 0x00000023, 0x00000000, 0x00050048, 0x00000185, + 0x00000001, 0x00000023, 0x00000010, 0x00040047, + 0x000001ba, 0x0000001e, 0x00000000, 0x00040047, + 0x000001ca, 0x00000021, 0x00000000, 0x00040047, + 0x000001ca, 0x00000022, 0x00000000, 0x00040047, + 0x0000021a, 0x0000001e, 0x00000000, 0x00020013, + 0x00000002, 0x00030021, 0x00000003, 0x00000002, + 0x00030016, 0x00000006, 0x00000020, 0x00090019, + 0x00000007, 0x00000006, 0x00000001, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0x00000000, + 0x0003001b, 0x00000008, 0x00000007, 0x00040020, + 0x00000009, 0x00000000, 0x00000008, 0x00040017, + 0x0000000a, 0x00000006, 0x00000002, 0x00040017, + 0x0000000c, 0x00000006, 0x00000003, 0x00040017, + 0x00000037, 0x00000006, 0x00000004, 0x0004002b, + 0x00000006, 0x0000003a, 0x4019999a, 0x0006002c, + 0x0000000c, 0x0000003b, 0x0000003a, 0x0000003a, + 0x0000003a, 0x0004002b, 0x00000006, 0x00000049, + 0x3f800000, 0x0004002b, 0x00000006, 0x0000004a, + 0x00000000, 0x0004002b, 0x00000006, 0x00000068, + 0xbf800000, 0x00040015, 0x0000006b, 0x00000020, + 0x00000001, 0x0004002b, 0x0000006b, 0x0000006c, + 0x00000000, 0x00040015, 0x0000006f, 0x00000020, + 0x00000000, 0x0004002b, 0x0000006f, 0x00000070, + 0x00000000, 0x0004002b, 0x0000006b, 0x00000074, + 0x00000001, 0x0004002b, 0x0000006f, 0x00000077, + 0x00000001, 0x0004002b, 0x00000006, 0x000000a1, + 0x3f000000, 0x0005002c, 0x0000000a, 0x000000fc, + 0x000000a1, 0x0000004a, 0x0004002b, 0x00000006, + 0x00000101, 0x3a83126f, 0x0005002c, 0x0000000a, + 0x00000102, 0x000000a1, 0x00000101, 0x0004002b, + 0x00000006, 0x0000010b, 0x40490fdb, 0x0004002b, + 0x00000006, 0x00000116, 0x40000000, 0x0004002b, + 0x00000006, 0x0000011c, 0x3727c5ac, 0x0007002c, + 0x00000037, 0x0000012c, 0x00000049, 0x00000049, + 0x00000049, 0x00000049, 0x00040018, 0x00000149, + 0x00000037, 0x00000004, 0x0006002c, 0x0000000c, + 0x00000165, 0x000000a1, 0x000000a1, 0x000000a1, + 0x0004002b, 0x00000006, 0x00000166, 0x3fc00000, + 0x0006002c, 0x0000000c, 0x00000167, 0x00000166, + 0x00000166, 0x00000166, 0x0004002b, 0x00000006, + 0x00000169, 0x3ecccccd, 0x0006002c, 0x0000000c, + 0x0000016a, 0x00000169, 0x00000169, 0x00000169, + 0x0004001e, 0x00000185, 0x00000037, 0x00000037, + 0x00040020, 0x00000186, 0x00000009, 0x00000185, + 0x0004003b, 0x00000186, 0x00000187, 0x00000009, + 0x00040020, 0x00000188, 0x00000009, 0x00000006, + 0x00020014, 0x00000196, 0x0006002c, 0x0000000c, + 0x0000019a, 0x00000049, 0x0000004a, 0x00000049, + 0x0006002c, 0x0000000c, 0x000001a1, 0x0000004a, + 0x00000049, 0x0000004a, 0x0006002c, 0x0000000c, + 0x000001a4, 0x0000004a, 0x0000004a, 0x00000049, + 0x0004002b, 0x0000006f, 0x000001aa, 0x00000003, + 0x00040020, 0x000001b9, 0x00000001, 0x0000000a, + 0x0004003b, 0x000001b9, 0x000001ba, 0x00000001, + 0x00040020, 0x000001bc, 0x00000009, 0x00000037, + 0x0004003b, 0x00000009, 0x000001ca, 0x00000000, + 0x0004002b, 0x00000006, 0x000001dc, 0x40400000, + 0x0004002b, 0x00000006, 0x000001ff, 0x3dcccccd, + 0x00040020, 0x00000206, 0x00000001, 0x00000006, + 0x0004002b, 0x00000006, 0x0000020c, 0x3e99999a, + 0x0004002b, 0x00000006, 0x00000210, 0x3d4ccccd, + 0x0004002b, 0x00000006, 0x00000216, 0x3ed55555, + 0x0006002c, 0x0000000c, 0x00000217, 0x00000216, + 0x00000216, 0x00000216, 0x00040020, 0x00000219, + 0x00000003, 0x00000037, 0x0004003b, 0x00000219, + 0x0000021a, 0x00000003, 0x0005002c, 0x0000000a, + 0x000004f3, 0x000000a1, 0x000000a1, 0x0007002c, + 0x00000037, 0x000004f4, 0x0000011c, 0x0000011c, + 0x0000011c, 0x0000011c, 0x0006002c, 0x0000000c, + 0x000004f6, 0x00000116, 0x00000116, 0x00000116, + 0x0006002c, 0x0000000c, 0x000004f7, 0x00000049, + 0x00000049, 0x00000049, 0x0006002c, 0x0000000c, + 0x000004f8, 0x0000004a, 0x0000004a, 0x0000004a, + 0x0006002c, 0x0000000c, 0x000004f9, 0x0000020c, + 0x0000020c, 0x0000020c, 0x0007002c, 0x00000037, + 0x000004fa, 0x000000a1, 0x000000a1, 0x000000a1, + 0x000000a1, 0x0004002b, 0x00000006, 0x000004fb, + 0x3eaaaaab, 0x00050036, 0x00000002, 0x00000004, + 0x00000000, 0x00000003, 0x000200f8, 0x00000005, + 0x00060041, 0x00000188, 0x000001a8, 0x00000187, + 0x00000074, 0x00000077, 0x0004003d, 0x00000006, + 0x000001a9, 0x000001a8, 0x00060041, 0x00000188, + 0x000001ab, 0x00000187, 0x0000006c, 0x000001aa, + 0x0004003d, 0x00000006, 0x000001ac, 0x000001ab, + 0x00050085, 0x00000006, 0x000001ad, 0x000001a9, + 0x000001ac, 0x0006000c, 0x00000006, 0x000001ae, + 0x00000001, 0x00000008, 0x000001ad, 0x00050088, + 0x00000006, 0x000001b2, 0x000000a1, 0x000001ae, + 0x0005008d, 0x00000006, 0x000001b4, 0x000001ae, + 0x00000116, 0x000500b7, 0x00000196, 0x000001b5, + 0x000001b4, 0x0000004a, 0x000600a9, 0x00000006, + 0x000004fc, 0x000001b5, 0x0000004a, 0x000001b2, + 0x0004003d, 0x0000000a, 0x000001bb, 0x000001ba, + 0x00050041, 0x000001bc, 0x000001bd, 0x00000187, + 0x0000006c, 0x0004003d, 0x00000037, 0x000001be, + 0x000001bd, 0x0007004f, 0x0000000a, 0x000001bf, + 0x000001be, 0x000001be, 0x00000000, 0x00000001, + 0x00050085, 0x0000000a, 0x000001c0, 0x000001bb, + 0x000001bf, 0x00050050, 0x0000000a, 0x000001c3, + 0x0000004a, 0x000004fc, 0x00050083, 0x0000000a, + 0x000001c4, 0x000001c0, 0x000001c3, 0x0007004f, + 0x0000000a, 0x000001c7, 0x000001be, 0x000001be, + 0x00000002, 0x00000003, 0x00050085, 0x0000000a, + 0x000001c8, 0x000001c4, 0x000001c7, 0x00050051, + 0x00000006, 0x00000249, 0x000001be, 0x00000000, + 0x00050088, 0x00000006, 0x0000024a, 0x00000049, + 0x00000249, 0x00050050, 0x0000000a, 0x0000024b, + 0x0000024a, 0x0000004a, 0x00050051, 0x00000006, + 0x0000024d, 0x000001be, 0x00000001, 0x00050088, + 0x00000006, 0x0000024e, 0x00000049, 0x0000024d, + 0x00050050, 0x0000000a, 0x0000024f, 0x0000004a, + 0x0000024e, 0x00050085, 0x0000000a, 0x00000252, + 0x000001c8, 0x000001bf, 0x0006000c, 0x0000000a, + 0x00000254, 0x00000001, 0x00000008, 0x00000252, + 0x00050081, 0x0000000a, 0x00000256, 0x00000254, + 0x000004f3, 0x00050088, 0x0000000a, 0x00000258, + 0x00000256, 0x000001bf, 0x0006000c, 0x0000000a, + 0x0000025a, 0x00000001, 0x0000000a, 0x00000252, + 0x00050083, 0x0000000a, 0x0000025c, 0x0000025a, + 0x000004f3, 0x0005008e, 0x0000000a, 0x0000025d, + 0x0000025c, 0x00000068, 0x00050083, 0x0000000a, + 0x00000260, 0x00000258, 0x0000024f, 0x0004003d, + 0x00000008, 0x0000028a, 0x000001ca, 0x00050083, + 0x0000000a, 0x0000028d, 0x00000260, 0x0000024b, + 0x00050057, 0x00000037, 0x0000028e, 0x0000028a, + 0x0000028d, 0x0008004f, 0x0000000c, 0x0000028f, + 0x0000028e, 0x0000028e, 0x00000000, 0x00000001, + 0x00000002, 0x0007000c, 0x0000000c, 0x00000290, + 0x00000001, 0x0000001a, 0x0000028f, 0x0000003b, + 0x00050057, 0x00000037, 0x00000293, 0x0000028a, + 0x00000260, 0x0008004f, 0x0000000c, 0x00000294, + 0x00000293, 0x00000293, 0x00000000, 0x00000001, + 0x00000002, 0x0007000c, 0x0000000c, 0x00000295, + 0x00000001, 0x0000001a, 0x00000294, 0x0000003b, + 0x00050081, 0x0000000a, 0x00000299, 0x00000260, + 0x0000024b, 0x00050057, 0x00000037, 0x0000029a, + 0x0000028a, 0x00000299, 0x0008004f, 0x0000000c, + 0x0000029b, 0x0000029a, 0x0000029a, 0x00000000, + 0x00000001, 0x00000002, 0x0007000c, 0x0000000c, + 0x0000029c, 0x00000001, 0x0000001a, 0x0000029b, + 0x0000003b, 0x00050083, 0x0000000a, 0x000002af, + 0x00000258, 0x0000024b, 0x00050057, 0x00000037, + 0x000002b0, 0x0000028a, 0x000002af, 0x0008004f, + 0x0000000c, 0x000002b1, 0x000002b0, 0x000002b0, + 0x00000000, 0x00000001, 0x00000002, 0x0007000c, + 0x0000000c, 0x000002b2, 0x00000001, 0x0000001a, + 0x000002b1, 0x0000003b, 0x00050057, 0x00000037, + 0x000002b5, 0x0000028a, 0x00000258, 0x0008004f, + 0x0000000c, 0x000002b6, 0x000002b5, 0x000002b5, + 0x00000000, 0x00000001, 0x00000002, 0x0007000c, + 0x0000000c, 0x000002b7, 0x00000001, 0x0000001a, + 0x000002b6, 0x0000003b, 0x00050081, 0x0000000a, + 0x000002bb, 0x00000258, 0x0000024b, 0x00050057, + 0x00000037, 0x000002bc, 0x0000028a, 0x000002bb, + 0x0008004f, 0x0000000c, 0x000002bd, 0x000002bc, + 0x000002bc, 0x00000000, 0x00000001, 0x00000002, + 0x0007000c, 0x0000000c, 0x000002be, 0x00000001, + 0x0000001a, 0x000002bd, 0x0000003b, 0x00050081, + 0x0000000a, 0x00000268, 0x00000258, 0x0000024f, + 0x00050083, 0x0000000a, 0x000002d1, 0x00000268, + 0x0000024b, 0x00050057, 0x00000037, 0x000002d2, + 0x0000028a, 0x000002d1, 0x0008004f, 0x0000000c, + 0x000002d3, 0x000002d2, 0x000002d2, 0x00000000, + 0x00000001, 0x00000002, 0x0007000c, 0x0000000c, + 0x000002d4, 0x00000001, 0x0000001a, 0x000002d3, + 0x0000003b, 0x00050057, 0x00000037, 0x000002d7, + 0x0000028a, 0x00000268, 0x0008004f, 0x0000000c, + 0x000002d8, 0x000002d7, 0x000002d7, 0x00000000, + 0x00000001, 0x00000002, 0x0007000c, 0x0000000c, + 0x000002d9, 0x00000001, 0x0000001a, 0x000002d8, + 0x0000003b, 0x00050081, 0x0000000a, 0x000002dd, + 0x00000268, 0x0000024b, 0x00050057, 0x00000037, + 0x000002de, 0x0000028a, 0x000002dd, 0x0008004f, + 0x0000000c, 0x000002df, 0x000002de, 0x000002de, + 0x00000000, 0x00000001, 0x00000002, 0x0007000c, + 0x0000000c, 0x000002e0, 0x00000001, 0x0000001a, + 0x000002df, 0x0000003b, 0x00050051, 0x00000006, + 0x0000026d, 0x0000025d, 0x00000000, 0x00050083, + 0x00000006, 0x000002f3, 0x0000026d, 0x00000049, + 0x00050081, 0x00000006, 0x000002f6, 0x0000026d, + 0x00000049, 0x00060050, 0x0000000c, 0x000002f7, + 0x000002f3, 0x0000026d, 0x000002f6, 0x00050085, + 0x0000000c, 0x000002fa, 0x000002f7, 0x000004f6, + 0x00050085, 0x0000000c, 0x000002fd, 0x000002fa, + 0x000002fa, 0x0005008e, 0x0000000c, 0x000002fe, + 0x000002fd, 0x00000068, 0x0006000c, 0x0000000c, + 0x000002ff, 0x00000001, 0x0000001d, 0x000002fe, + 0x00050051, 0x00000006, 0x00000303, 0x000002ff, + 0x00000000, 0x0005008e, 0x0000000c, 0x00000304, + 0x00000290, 0x00000303, 0x00050051, 0x00000006, + 0x00000308, 0x000002ff, 0x00000001, 0x0005008e, + 0x0000000c, 0x00000309, 0x00000295, 0x00000308, + 0x00050081, 0x0000000c, 0x0000030a, 0x00000304, + 0x00000309, 0x00050051, 0x00000006, 0x0000030e, + 0x000002ff, 0x00000002, 0x0005008e, 0x0000000c, + 0x0000030f, 0x0000029c, 0x0000030e, 0x00050081, + 0x0000000c, 0x00000310, 0x0000030a, 0x0000030f, + 0x00050081, 0x00000006, 0x00000315, 0x00000303, + 0x00000308, 0x00050081, 0x00000006, 0x00000318, + 0x00000315, 0x0000030e, 0x00060050, 0x0000000c, + 0x00000319, 0x00000318, 0x00000318, 0x00000318, + 0x00050088, 0x0000000c, 0x0000031a, 0x00000310, + 0x00000319, 0x0005008e, 0x0000000c, 0x00000331, + 0x000002b2, 0x00000303, 0x0005008e, 0x0000000c, + 0x00000336, 0x000002b7, 0x00000308, 0x00050081, + 0x0000000c, 0x00000337, 0x00000331, 0x00000336, + 0x0005008e, 0x0000000c, 0x0000033c, 0x000002be, + 0x0000030e, 0x00050081, 0x0000000c, 0x0000033d, + 0x00000337, 0x0000033c, 0x00050088, 0x0000000c, + 0x00000347, 0x0000033d, 0x00000319, 0x0005008e, + 0x0000000c, 0x0000035e, 0x000002d4, 0x00000303, + 0x0005008e, 0x0000000c, 0x00000363, 0x000002d9, + 0x00000308, 0x00050081, 0x0000000c, 0x00000364, + 0x0000035e, 0x00000363, 0x0005008e, 0x0000000c, + 0x00000369, 0x000002e0, 0x0000030e, 0x00050081, + 0x0000000c, 0x0000036a, 0x00000364, 0x00000369, + 0x00050088, 0x0000000c, 0x00000374, 0x0000036a, + 0x00000319, 0x00050051, 0x00000006, 0x00000286, + 0x0000025d, 0x00000001, 0x00050083, 0x00000006, + 0x0000037a, 0x00000286, 0x00000049, 0x00050081, + 0x00000006, 0x0000037d, 0x00000286, 0x00000049, + 0x00060050, 0x0000000c, 0x0000037e, 0x0000037a, + 0x00000286, 0x0000037d, 0x00050085, 0x0000000c, + 0x00000381, 0x0000037e, 0x000004f6, 0x00050085, + 0x0000000c, 0x00000384, 0x00000381, 0x00000381, + 0x0005008e, 0x0000000c, 0x00000385, 0x00000384, + 0x00000068, 0x0006000c, 0x0000000c, 0x00000386, + 0x00000001, 0x0000001d, 0x00000385, 0x00050051, + 0x00000006, 0x0000038a, 0x00000386, 0x00000000, + 0x0005008e, 0x0000000c, 0x0000038b, 0x0000031a, + 0x0000038a, 0x00050051, 0x00000006, 0x0000038f, + 0x00000386, 0x00000001, 0x0005008e, 0x0000000c, + 0x00000390, 0x00000347, 0x0000038f, 0x00050081, + 0x0000000c, 0x00000391, 0x0000038b, 0x00000390, + 0x00050051, 0x00000006, 0x00000395, 0x00000386, + 0x00000002, 0x0005008e, 0x0000000c, 0x00000396, + 0x00000374, 0x00000395, 0x00050081, 0x0000000c, + 0x00000397, 0x00000391, 0x00000396, 0x00050081, + 0x00000006, 0x0000039c, 0x0000038a, 0x0000038f, + 0x00050081, 0x00000006, 0x0000039f, 0x0000039c, + 0x00000395, 0x00060050, 0x0000000c, 0x000003a0, + 0x0000039f, 0x0000039f, 0x0000039f, 0x00050088, + 0x0000000c, 0x000003a1, 0x00000397, 0x000003a0, + 0x00060052, 0x0000000a, 0x000004e1, 0x00000249, + 0x000001bf, 0x00000000, 0x00050085, 0x0000000a, + 0x000003b6, 0x000001c8, 0x000004e1, 0x00050083, + 0x0000000a, 0x000003b7, 0x000003b6, 0x000000fc, + 0x0006000c, 0x0000000a, 0x000003b9, 0x00000001, + 0x00000008, 0x000003b7, 0x00050081, 0x0000000a, + 0x000003ba, 0x000003b9, 0x00000102, 0x00050088, + 0x0000000a, 0x000003bc, 0x000003ba, 0x000004e1, + 0x0006000c, 0x0000000a, 0x000003be, 0x00000001, + 0x0000000a, 0x000003b7, 0x00050051, 0x00000006, + 0x000003c0, 0x000003be, 0x00000000, 0x00050081, + 0x00000006, 0x000003c1, 0x000003c0, 0x00000049, + 0x00050083, 0x00000006, 0x000003c6, 0x000003c0, + 0x00000049, 0x00050083, 0x00000006, 0x000003c9, + 0x000003c0, 0x00000116, 0x00070050, 0x00000037, + 0x000003ca, 0x000003c1, 0x000003c0, 0x000003c6, + 0x000003c9, 0x0005008e, 0x00000037, 0x000003cb, + 0x000003ca, 0x0000010b, 0x0006000c, 0x00000037, + 0x000003cd, 0x00000001, 0x00000004, 0x000003cb, + 0x0007000c, 0x00000037, 0x000003cf, 0x00000001, + 0x00000028, 0x000003cd, 0x000004f4, 0x0006000c, + 0x00000037, 0x000003d1, 0x00000001, 0x0000000d, + 0x000003cf, 0x0005008e, 0x00000037, 0x000003d2, + 0x000003d1, 0x00000116, 0x00050085, 0x00000037, + 0x000003d5, 0x000003cf, 0x000004fa, 0x0006000c, + 0x00000037, 0x000003d6, 0x00000001, 0x0000000d, + 0x000003d5, 0x00050085, 0x00000037, 0x000003d7, + 0x000003d2, 0x000003d6, 0x00050085, 0x00000037, + 0x000003da, 0x000003cf, 0x000003cf, 0x00050088, + 0x00000037, 0x000003db, 0x000003d7, 0x000003da, + 0x00050094, 0x00000006, 0x000003dd, 0x000003db, + 0x0000012c, 0x00070050, 0x00000037, 0x000003df, + 0x000003dd, 0x000003dd, 0x000003dd, 0x000003dd, + 0x00050088, 0x00000037, 0x000003e0, 0x000003db, + 0x000003df, 0x00050057, 0x00000037, 0x000003e3, + 0x0000028a, 0x000003bc, 0x0008004f, 0x0000000c, + 0x000003e4, 0x000003e3, 0x000003e3, 0x00000000, + 0x00000001, 0x00000002, 0x0007000c, 0x0000000c, + 0x000003e5, 0x00000001, 0x0000001a, 0x000003e4, + 0x0000003b, 0x00050051, 0x00000006, 0x000003e6, + 0x000003e5, 0x00000000, 0x00050051, 0x00000006, + 0x000003e7, 0x000003e5, 0x00000001, 0x00050051, + 0x00000006, 0x000003e8, 0x000003e5, 0x00000002, + 0x00050081, 0x0000000a, 0x000003ed, 0x000003bc, + 0x0000024b, 0x00050057, 0x00000037, 0x000003ee, + 0x0000028a, 0x000003ed, 0x0008004f, 0x0000000c, + 0x000003ef, 0x000003ee, 0x000003ee, 0x00000000, + 0x00000001, 0x00000002, 0x0007000c, 0x0000000c, + 0x000003f0, 0x00000001, 0x0000001a, 0x000003ef, + 0x0000003b, 0x00050051, 0x00000006, 0x000003f1, + 0x000003f0, 0x00000000, 0x00050051, 0x00000006, + 0x000003f2, 0x000003f0, 0x00000001, 0x00050051, + 0x00000006, 0x000003f3, 0x000003f0, 0x00000002, + 0x00070050, 0x00000037, 0x00000407, 0x000003e6, + 0x000003e7, 0x000003e8, 0x00000049, 0x00070050, + 0x00000037, 0x00000409, 0x000003f1, 0x000003f2, + 0x000003f3, 0x00000049, 0x00070050, 0x00000149, + 0x0000040b, 0x00000407, 0x00000407, 0x00000409, + 0x00000409, 0x00050091, 0x00000037, 0x0000040d, + 0x0000040b, 0x000003e0, 0x0008004f, 0x0000000c, + 0x0000040e, 0x0000040d, 0x0000040d, 0x00000000, + 0x00000001, 0x00000002, 0x00050085, 0x00000006, + 0x0000041b, 0x00000249, 0x000001dc, 0x00060052, + 0x0000000a, 0x000004e9, 0x0000041b, 0x000001bf, + 0x00000000, 0x00050088, 0x00000006, 0x0000041f, + 0x000004fb, 0x00000249, 0x00050050, 0x0000000a, + 0x00000420, 0x0000041f, 0x0000004a, 0x00050085, + 0x0000000a, 0x00000423, 0x000001c8, 0x000004e9, + 0x00050083, 0x0000000a, 0x00000424, 0x00000423, + 0x000000fc, 0x0006000c, 0x0000000a, 0x00000426, + 0x00000001, 0x00000008, 0x00000424, 0x00050081, + 0x0000000a, 0x00000427, 0x00000426, 0x00000102, + 0x00050088, 0x0000000a, 0x00000429, 0x00000427, + 0x000004e9, 0x0006000c, 0x0000000a, 0x0000042b, + 0x00000001, 0x0000000a, 0x00000424, 0x00050051, + 0x00000006, 0x0000042d, 0x0000042b, 0x00000000, + 0x00050081, 0x00000006, 0x0000042e, 0x0000042d, + 0x00000049, 0x00050083, 0x00000006, 0x00000433, + 0x0000042d, 0x00000049, 0x00050083, 0x00000006, + 0x00000436, 0x0000042d, 0x00000116, 0x00070050, + 0x00000037, 0x00000437, 0x0000042e, 0x0000042d, + 0x00000433, 0x00000436, 0x0005008e, 0x00000037, + 0x00000438, 0x00000437, 0x0000010b, 0x0006000c, + 0x00000037, 0x0000043a, 0x00000001, 0x00000004, + 0x00000438, 0x0007000c, 0x00000037, 0x0000043c, + 0x00000001, 0x00000028, 0x0000043a, 0x000004f4, + 0x0006000c, 0x00000037, 0x0000043e, 0x00000001, + 0x0000000d, 0x0000043c, 0x0005008e, 0x00000037, + 0x0000043f, 0x0000043e, 0x00000116, 0x00050085, + 0x00000037, 0x00000442, 0x0000043c, 0x000004fa, + 0x0006000c, 0x00000037, 0x00000443, 0x00000001, + 0x0000000d, 0x00000442, 0x00050085, 0x00000037, + 0x00000444, 0x0000043f, 0x00000443, 0x00050085, + 0x00000037, 0x00000447, 0x0000043c, 0x0000043c, + 0x00050088, 0x00000037, 0x00000448, 0x00000444, + 0x00000447, 0x00050094, 0x00000006, 0x0000044a, + 0x00000448, 0x0000012c, 0x00070050, 0x00000037, + 0x0000044c, 0x0000044a, 0x0000044a, 0x0000044a, + 0x0000044a, 0x00050088, 0x00000037, 0x0000044d, + 0x00000448, 0x0000044c, 0x00050057, 0x00000037, + 0x00000450, 0x0000028a, 0x00000429, 0x0008004f, + 0x0000000c, 0x00000451, 0x00000450, 0x00000450, + 0x00000000, 0x00000001, 0x00000002, 0x0007000c, + 0x0000000c, 0x00000452, 0x00000001, 0x0000001a, + 0x00000451, 0x0000003b, 0x00050051, 0x00000006, + 0x00000453, 0x00000452, 0x00000000, 0x00050051, + 0x00000006, 0x00000454, 0x00000452, 0x00000001, + 0x00050051, 0x00000006, 0x00000455, 0x00000452, + 0x00000002, 0x00050081, 0x0000000a, 0x0000045a, + 0x00000429, 0x00000420, 0x00050057, 0x00000037, + 0x0000045b, 0x0000028a, 0x0000045a, 0x0008004f, + 0x0000000c, 0x0000045c, 0x0000045b, 0x0000045b, + 0x00000000, 0x00000001, 0x00000002, 0x0007000c, + 0x0000000c, 0x0000045d, 0x00000001, 0x0000001a, + 0x0000045c, 0x0000003b, 0x00050051, 0x00000006, + 0x0000045e, 0x0000045d, 0x00000000, 0x00050051, + 0x00000006, 0x0000045f, 0x0000045d, 0x00000001, + 0x00050051, 0x00000006, 0x00000460, 0x0000045d, + 0x00000002, 0x00070050, 0x00000037, 0x00000474, + 0x00000453, 0x00000454, 0x00000455, 0x00000049, + 0x00070050, 0x00000037, 0x00000476, 0x0000045e, + 0x0000045f, 0x00000460, 0x00000049, 0x00070050, + 0x00000149, 0x00000478, 0x00000474, 0x00000474, + 0x00000476, 0x00000476, 0x00050091, 0x00000037, + 0x0000047a, 0x00000478, 0x0000044d, 0x0008004f, + 0x0000000c, 0x0000047b, 0x0000047a, 0x0000047a, + 0x00000000, 0x00000001, 0x00000002, 0x00050085, + 0x0000000c, 0x000001e8, 0x0000047b, 0x0000040e, + 0x0006000c, 0x0000000c, 0x000001e9, 0x00000001, + 0x0000001f, 0x000001e8, 0x00050051, 0x00000006, + 0x000001eb, 0x000001c8, 0x00000001, 0x00060041, + 0x00000188, 0x000001ec, 0x00000187, 0x0000006c, + 0x00000077, 0x0004003d, 0x00000006, 0x000001ed, + 0x000001ec, 0x00050085, 0x00000006, 0x000001ee, + 0x000001eb, 0x000001ed, 0x0006000c, 0x00000006, + 0x000001ef, 0x00000001, 0x0000000a, 0x000001ee, + 0x0007000c, 0x0000000c, 0x00000482, 0x00000001, + 0x0000001a, 0x0000040e, 0x0000016a, 0x0008000c, + 0x0000000c, 0x00000483, 0x00000001, 0x0000002e, + 0x00000165, 0x00000167, 0x00000482, 0x00050088, + 0x0000000c, 0x00000486, 0x000004f6, 0x00000483, + 0x0005008e, 0x0000000c, 0x00000488, 0x00000486, + 0x000000a1, 0x0005008e, 0x0000000c, 0x0000048b, + 0x00000486, 0x000001ef, 0x00050083, 0x0000000c, + 0x0000048d, 0x0000048b, 0x00000488, 0x0006000c, + 0x0000000c, 0x0000048e, 0x00000001, 0x00000004, + 0x0000048d, 0x00050083, 0x0000000c, 0x00000490, + 0x000004f7, 0x0000048e, 0x0008000c, 0x0000000c, + 0x00000493, 0x00000001, 0x00000031, 0x000004f8, + 0x000004f7, 0x00000490, 0x00050085, 0x0000000c, + 0x00000495, 0x00000493, 0x00000488, 0x00050085, + 0x0000000c, 0x000001f5, 0x000001e9, 0x00000495, + 0x00050083, 0x0000000c, 0x000001f8, 0x000003a1, + 0x000001f5, 0x0008000c, 0x0000000c, 0x000001fb, + 0x00000001, 0x0000002b, 0x000001f8, 0x000004f8, + 0x000004f7, 0x00050085, 0x0000000c, 0x000001fe, + 0x000001fb, 0x000001fb, 0x0005008e, 0x0000000c, + 0x00000200, 0x000001fe, 0x000001ff, 0x00050081, + 0x0000000c, 0x00000202, 0x000001f5, 0x00000200, + 0x00050041, 0x00000206, 0x00000207, 0x000001ba, + 0x00000070, 0x0004003d, 0x00000006, 0x00000208, + 0x00000207, 0x000300f7, 0x000004b3, 0x00000000, + 0x000300fb, 0x00000070, 0x0000049b, 0x000200f8, + 0x0000049b, 0x00060041, 0x00000188, 0x0000049d, + 0x00000187, 0x00000074, 0x00000070, 0x0004003d, + 0x00000006, 0x0000049e, 0x0000049d, 0x00050085, + 0x00000006, 0x0000049f, 0x00000208, 0x0000049e, + 0x0006000c, 0x00000006, 0x000004a7, 0x00000001, + 0x00000008, 0x0000049f, 0x0005008d, 0x00000006, + 0x000004a8, 0x000004a7, 0x00000116, 0x000500b4, + 0x00000196, 0x000004aa, 0x000004a8, 0x0000004a, + 0x000300f7, 0x000004b2, 0x00000000, 0x000400fa, + 0x000004aa, 0x000004ab, 0x000004ac, 0x000200f8, + 0x000004ac, 0x000500b4, 0x00000196, 0x000004ae, + 0x000004a8, 0x00000049, 0x000300f7, 0x000004b1, + 0x00000000, 0x000400fa, 0x000004ae, 0x000004af, + 0x000004b0, 0x000200f8, 0x000004b0, 0x000200f9, + 0x000004b3, 0x000200f8, 0x000004af, 0x000200f9, + 0x000004b3, 0x000200f8, 0x000004b1, 0x000100ff, + 0x000200f8, 0x000004ab, 0x000200f9, 0x000004b3, + 0x000200f8, 0x000004b2, 0x000100ff, 0x000200f8, + 0x000004b3, 0x000900f5, 0x0000000c, 0x000004f1, + 0x0000019a, 0x000004ab, 0x000001a1, 0x000004af, + 0x000001a4, 0x000004b0, 0x00050085, 0x0000000c, + 0x0000020a, 0x00000202, 0x000004f1, 0x0005008e, + 0x0000000c, 0x0000020b, 0x0000020a, 0x00000116, + 0x0008000c, 0x0000000c, 0x0000020e, 0x00000001, + 0x0000002e, 0x00000202, 0x0000020b, 0x000004f9, + 0x0005008e, 0x0000000c, 0x00000211, 0x000001fb, + 0x00000210, 0x00050081, 0x0000000c, 0x00000213, + 0x0000020e, 0x00000211, 0x0005008e, 0x0000000c, + 0x00000215, 0x00000213, 0x00000166, 0x0007000c, + 0x0000000c, 0x00000218, 0x00000001, 0x0000001a, + 0x00000215, 0x00000217, 0x00050051, 0x00000006, + 0x0000021c, 0x00000218, 0x00000000, 0x00050051, + 0x00000006, 0x0000021d, 0x00000218, 0x00000001, + 0x00050051, 0x00000006, 0x0000021e, 0x00000218, + 0x00000002, 0x00070050, 0x00000037, 0x0000021f, + 0x0000021c, 0x0000021d, 0x0000021e, 0x00000049, + 0x0003003e, 0x0000021a, 0x0000021f, 0x000100fd, + 0x00010038}; diff --git a/src/ui/config.rs b/src/ui/config.rs index cd831ac..a789587 100644 --- a/src/ui/config.rs +++ b/src/ui/config.rs @@ -47,6 +47,7 @@ pub struct Video { pub integer_scaling: bool, pub fullscreen: bool, pub widescreen: bool, + pub crt: bool, } #[derive(serde::Serialize, serde::Deserialize)] @@ -106,6 +107,7 @@ impl Config { integer_scaling: false, fullscreen: false, widescreen: false, + crt: false, }, emulation: Emulation { overclock: false }, } diff --git a/src/ui/gui.rs b/src/ui/gui.rs index 5a05e39..313c035 100644 --- a/src/ui/gui.rs +++ b/src/ui/gui.rs @@ -18,6 +18,7 @@ pub struct GopherEguiApp { integer_scaling: bool, fullscreen: bool, widescreen: bool, + crt: bool, overclock: bool, emulate_vru: bool, dinput: bool, @@ -44,6 +45,7 @@ struct SaveConfig { integer_scaling: bool, fullscreen: bool, widescreen: bool, + crt: bool, emulate_vru: bool, overclock: bool, } @@ -121,6 +123,7 @@ impl GopherEguiApp { integer_scaling: config.video.integer_scaling, fullscreen: config.video.fullscreen, widescreen: config.video.widescreen, + crt: config.video.crt, emulate_vru: config.input.emulate_vru, overclock: config.emulation.overclock, show_vru_dialog: false, @@ -159,6 +162,7 @@ fn save_config( config.video.integer_scaling = save_config_items.integer_scaling; config.video.fullscreen = save_config_items.fullscreen; config.video.widescreen = save_config_items.widescreen; + config.video.crt = save_config_items.crt; config.input.emulate_vru = save_config_items.emulate_vru; config.emulation.overclock = save_config_items.overclock; @@ -175,6 +179,7 @@ impl Drop for GopherEguiApp { integer_scaling: self.integer_scaling, fullscreen: self.fullscreen, widescreen: self.widescreen, + crt: self.crt, emulate_vru: self.emulate_vru, overclock: self.overclock, }; @@ -240,7 +245,7 @@ fn show_vru_dialog(app: &mut GopherEguiApp, ctx: &egui::Context) { } }); - ui.add_space(32.0); + ui.add_space(16.0); if ui.button("Close without saying anything").clicked() { app.vru_word_notifier @@ -303,6 +308,7 @@ pub fn open_rom(app: &mut GopherEguiApp, ctx: &egui::Context, enable_overclock: let integer_scaling = app.integer_scaling; let fullscreen = app.fullscreen; let widescreen = app.widescreen; + let crt = app.crt; let emulate_vru = app.emulate_vru; let overclock = app.overclock; let peer_addr; @@ -399,6 +405,7 @@ pub fn open_rom(app: &mut GopherEguiApp, ctx: &egui::Context, enable_overclock: integer_scaling, fullscreen, widescreen, + crt, emulate_vru, overclock, }; @@ -535,7 +542,7 @@ impl eframe::App for GopherEguiApp { } }); - ui.add_space(32.0); + ui.add_space(16.0); ui.label("Controller Config:"); egui::Grid::new("controller_config").show(ui, |ui| { ui.label("Port"); @@ -599,7 +606,7 @@ impl eframe::App for GopherEguiApp { ui.end_row(); } }); - ui.add_space(32.0); + ui.add_space(16.0); let upscale_values = [1, 2, 4]; let mut slider_value = match self.upscale { 1 => 0, @@ -621,6 +628,7 @@ impl eframe::App for GopherEguiApp { ui.checkbox(&mut self.integer_scaling, "Integer Scaling"); ui.checkbox(&mut self.fullscreen, "Fullscreen (Esc closes game)"); ui.checkbox(&mut self.widescreen, "Widescreen (stretch)"); + ui.checkbox(&mut self.crt, "Apply CRT shader"); ui.add_space(16.0); ui.checkbox(&mut self.overclock, "Overclock N64 CPU (may cause bugs)"); diff --git a/src/ui/video.rs b/src/ui/video.rs index 187aefc..84b19bc 100644 --- a/src/ui/video.rs +++ b/src/ui/video.rs @@ -53,17 +53,13 @@ pub fn init(device: &mut device::Device) { DPC_STATUS_REG: &mut device.rdp.regs_dpc[device::rdp::DPC_STATUS_REG as usize], PAL: device.cart.pal, widescreen: device.ui.config.video.widescreen, + fullscreen: device.ui.video.fullscreen, + integer_scaling: device.ui.config.video.integer_scaling, + upscale: device.ui.config.video.upscale, + crt: device.ui.config.video.crt, }; - unsafe { - rdp_init( - device.ui.video.window as *mut std::ffi::c_void, - gfx_info, - device.ui.config.video.upscale, - device.ui.config.video.integer_scaling, - device.ui.video.fullscreen, - ) - } + unsafe { rdp_init(device.ui.video.window as *mut std::ffi::c_void, gfx_info) } } pub fn close(ui: &ui::Ui) { @@ -97,9 +93,13 @@ pub fn load_state(device: &mut device::Device) { DPC_STATUS_REG: &mut device.rdp.regs_dpc[device::rdp::DPC_STATUS_REG as usize], PAL: device.cart.pal, widescreen: device.ui.config.video.widescreen, + fullscreen: device.ui.video.fullscreen, + integer_scaling: device.ui.config.video.integer_scaling, + upscale: device.ui.config.video.upscale, + crt: device.ui.config.video.crt, }; unsafe { - rdp_new_processor(gfx_info, device.ui.config.video.upscale); + rdp_new_processor(gfx_info); } }