diff --git a/README.md b/README.md index 837569e5..7bd90e75 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Report problems as issues, following [CONTRIBUTING.md](CONTRIBUTING.md). - Frame generation with AMD FSR 3.1 (any GPU): a generated frame between every two the game draws, with the HUD kept out of it, for about twice the frame rate on a fast display; in a window of another shape than the picture, frames are generated inside the picture only, so the black bars stay clean -- HDR on HDR displays: the game's own native HDR, or an enhanced HDR made from its SDR picture +- HDR on HDR displays: the game's own native HDR, or its SDR picture tone mapped to the display's peak, with exposure, highlights, shadows, contrast, saturation and gamma in the menu - Every shader prepared when the game is built, and the pipelines met in play built again in the background at each start, so play does not stop to compile them; a draw that must wait for its pipeline has it built on worker threads, never on the game's drawing thread diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md index 665d911d..5e6d9ec2 100644 --- a/THIRD_PARTY_NOTICES.md +++ b/THIRD_PARTY_NOTICES.md @@ -37,6 +37,7 @@ Code copied or adapted from another project is listed here with its source, the | libvpx 1.17.0 (MSYS2 `mingw-w64-ucrt-x86_64-libvpx`), static link (`libvpx.a`), no DLL shipped; the release notices must carry its BSD licence text and the WebM Project's `PATENTS` grant | https://chromium.googlesource.com/webm/libvpx, Copyright (c) 2010, The WebM Project authors | BSD-3-Clause | `runtime/ov_movie.c` (VP9 decoding of the `Event/Movie` WebM files) | | MacNativeGames NX2navi resolution patches: output, swapchain and scene size sites and instruction words for 1.2.1 and 1.4.3, the data-page layout, the HeapDef heap names and sizes | https://github.com/ly05010419/MacNativeGames @ `aaf6ba1f494fabaa209d049e528d6f923dfe822a` (`runtime/game_patches.c`, `game_patches_v143.c`, `game_version.h`, `scripts/make_output_res_overlay.py`), Copyright (c) 2026 MacNativeGames contributors | MIT | `recomp/patches-v121.txt`, `recomp/patches-v143.txt`, `runtime/resolution.c` | | AMD FidelityFX Super Resolution 1.0 (`ffx_a.h`, `ffx_fsr1.h`, unmodified; licence text in `runtime/shaders/ffx/LICENSE.txt`) | https://github.com/GPUOpen-Effects/FidelityFX-FSR @ `a21ffb8f6c13233ba336352bdff293894c706575`, Copyright (c) 2021 Advanced Micro Devices, Inc. | MIT | `runtime/shaders/ffx/`, `runtime/shaders/fsr_easu.comp`, `runtime/shaders/fsr_rcas.comp` (compiled into `runtime/fsr_easu_spv.h`, `runtime/fsr_rcas_spv.h`) | +| RenoDX shader library: the RenoDRT tone mapper (Daniele curve, OkLab hue and chrominance, highlights, shadows, contrast, flare, saturation, highlight saturation, blowout), the luminance upgrade of an SDR grade, its colour matrices, and the swap chain pass's gamma correction, gamut compression, peak clamp and PQ encode, ported from HLSL to GLSL | https://github.com/clshortfuse/renodx @ `bc0ead39917634e95c534f7e8cfb59ab82880747` (`src/shaders/tonemap.hlsl`, `tonemap/reno_drt.hlsl`, `tonemap/daniele.hlsl`, `draw.hlsl`, `colorgrade.hlsl`, `colorcorrect.hlsl`, `color/oklab.hlsl`, `color/rgb.hlsl`, `color/pq.hlsl`, `color/srgb.hlsl`, `color/gamma.hlsl`; setting names, ranges and defaults of `src/templates/settings.hpp`), Copyright (c) 2025 Carlos Lopez Jr. | MIT | `runtime/shaders/hdr_tonemap.frag` and `runtime/shaders/hdr_encode.comp` (compiled into `runtime/hdr_tonemap_spv.h`, `runtime/hdr_encode_spv.h`); the HDR settings of `runtime/cfg.c`, `runtime/vk_hdr.c` and `runtime/ui/menu.cpp` | | AMD Display Library (ADL) declarations: `AdapterInfo`, `ADLSingleSensorData`, `ADLPMLogDataOutput`, the `ADL_PMLOG_*` sensor numbers and the `ADL2_*` function signatures | https://github.com/GPUOpen-LibrariesAndSDKs/display-library @ `84c881cb2136f04287eb3af12de00a9e2867aa9e` (`include/adl_structures.h`, `include/adl_defines.h`, `include/adl_sdk.h`), Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc. | MIT | `runtime/perfmon.c` | | Zstandard 1.5.7 (MSYS2 `mingw-w64-ucrt-x86_64-zstd`), static link | https://github.com/facebook/zstd, Copyright (c) Meta Platforms, Inc. and affiliates | BSD-3-Clause | `runtime/resolution.c` (the HeapDef table), `runtime/ov_zstd.c` (the game's zstd frames decoded on the host) | | musl `fma.c`, `fmaf.c` and `scalbn.c`, adapted into one file for the x86-64-v2 build | https://github.com/kraj/musl @ `5a56ad13e1e0790c06122978aad2a14d6b9efc1a` (mirror of https://git.musl-libc.org/cgit/musl), Copyright (c) 2005-2020 Rich Felker and contributors | MIT | `runtime/fma.c` (the correctly rounded fma/fmaf the FP lowering needs on CPUs without FMA3) | diff --git a/docs/README-BuildKit.md b/docs/README-BuildKit.md index d762f517..b48aea06 100644 --- a/docs/README-BuildKit.md +++ b/docs/README-BuildKit.md @@ -66,7 +66,7 @@ When it says `finished`, start `C:\Games\Ocarina\ocarina.exe`. You can delete `C it lasts at most about 20 seconds once the shaders are translated, and the remaining pipelines are built in the background while you play. - **Screen** in the menu has Upscaling (DLSS on NVIDIA RTX cards, FSR 3.1 on any card), Frame generation (FSR 3.1; it - needs DLSS or FSR 3.1 upscaling on), HDR (Native is the game's own HDR; turn HDR on in Windows first) and the + needs DLSS or FSR 3.1 upscaling on), HDR (the game's picture tone mapped to your display, with its own grading rows, or Native, the game's own HDR; turn HDR on in Windows first) and the resolution. Those marked "after restart" take effect when the game starts again. - DLSS needs `nvngx_dlss.dll` from NVIDIA beside `ocarina.exe` (the kit does not include it); FSR 3.1's `amd_fidelityfx_vk.dll` is copied there by the build. diff --git a/docs/architecture.md b/docs/architecture.md index 7036cbca..2f5461ba 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -100,6 +100,12 @@ keeps per-core data without locks and relies on that, so the host models it (`ru are compiled outside the pipeline lock, and one compile serves every thread that needs it. - The game's tensor-core upscaler is replaced by a decode-and-scale pass (`vk_tonemap.c`); `vk_fsr.c` runs AMD FSR 1 (EASU, RCAS) on the present when the window is larger than the picture. +- HDR (`vk_hdr.c`): the game tonemaps its scene into a float target, upscales it, draws the HUD into a second float + target and copies that into the 8-bit sRGB window texture it presents. With `NX2NAVI_HDR=1` the tonemap shader gets + the function of `shaders/hdr_tonemap.frag` spliced in where its SDR curve clamps each channel, so the float picture + holds the HDR picture relative to the HUD's white; the game's FSR 1 pass loses its output clamp; the present reads + the float picture in place of the window texture and `shaders/hdr_encode.comp` writes PQ for an HDR10 swapchain. + `NX2NAVI_HDR=native` reports an HDR10 display to the game, which then renders and presents its own PQ picture. - ASTC textures are uploaded as they are where the device samples ASTC, and decoded by a compute shader everywhere else (`vk_astc.c`); under 20 GiB of video memory the decoder encodes them to BC3. - Occlusion queries never block the CPU; a result that is not ready counts as visible. diff --git a/nx2navi.ini.example b/nx2navi.ini.example index f856bcf7..772df507 100644 --- a/nx2navi.ini.example +++ b/nx2navi.ini.example @@ -265,17 +265,34 @@ # once. # fxaa = 1 -# HDR output: hdr = 1 sends the picture as HDR10 (needs HDR on in Windows, "Use HDR", or a Wayland compositor with -# colour management; without it the picture stays SDR). The game's tonemap keeps highlights up to hdr_peak_nits (your -# display's peak); hdr_game_nits is the picture's white (paper white, 203 is the HDR reference) and hdr_ui_nits the -# HUD's and the menu's. hdr is read at start, the nits at once. +# HDR output: hdr = 1 sends the picture as HDR10 through the HDR tone mapper, hdr = native as the game renders it in +# its own HDR mode (both need HDR on in Windows, "Use HDR", or a Wayland compositor with colour management; without it +# the picture stays SDR, the game's own). hdr_peak_nits is your display's peak; hdr_game_nits the picture's white +# (paper white, 203 is the HDR reference) and hdr_ui_nits the HUD's and the menu's. hdr is read at start, the rest at +# once. # hdr = 0 # hdr_peak_nits = 1000 # hdr_game_nits = 203 # hdr_ui_nits = 203 -# Highlight hue correction in percent (0 to 100): bright colours such as fire turn towards white as in the game's SDR -# picture, matching the light they cast; 0 keeps them fully saturated. Changes take effect at once. -# hdr_hue = 80 +# With hdr = 1: gamma correction (off, 2.2 or 2.4) shows the picture as a display of that power would, as the game was +# made to be seen; off keeps the sRGB curve. The tone mapper: vanilla is the game's own curve at SDR brightness, +# renodrt carries the game's look up to the peak. +# hdr_gamma = 2.2 +# hdr_tonemap = renodrt +# With renodrt: exposure in percent (100 unchanged); highlights, shadows, contrast, saturation and highlight saturation +# from 0 to 100 (50 unchanged); blowout (bright parts towards white) and flare (lifted blacks) from 0 to 100 (0 none); +# hue correction in percent (how much bright colours keep their hue); grade, the percentage of the game's own colour +# grading the picture keeps. +# hdr_exposure = 100 +# hdr_highlights = 50 +# hdr_shadows = 50 +# hdr_contrast = 50 +# hdr_saturation = 50 +# hdr_highlight_sat = 50 +# hdr_blowout = 0 +# hdr_flare = 0 +# hdr_hue = 100 +# hdr_grade = 100 [language] # Language: a Windows locale such as de-DE, or a Switch code (en-US, ja, zh-Hant, ...). Default: the Windows locale. diff --git a/runtime/cfg.c b/runtime/cfg.c index b366fec7..3bf97fd2 100644 --- a/runtime/cfg.c +++ b/runtime/cfg.c @@ -43,8 +43,9 @@ static const char *const known[] = { "DESC_TEMPLATE", "DEVICE_PROFILE", "DISCORD_APP_ID", "DISCORD_IMAGE", "DISCORD_RPC", "DLAA", "DLAA_CAM_KEEP", "DLAA_JITTER", "DLAA_MV", "DLAA_MASKDEBUG", "DLAA_MVDEBUG", "DLAA_OBJMV", "DLAA_SURVEY", "DLAA_TIMES", "DLSS", "DLSS_CHAR_MASK", "DLSS_PRESET", "DLSS_REACTIVE", "DUMP", "DUMP_BUF", "DUMP_DIR", "DUMP_LOG", "LOG_CS_BINDS", "LOG_TEX_FLAGS", "LOG_MESH", "MESH", "POOL", "NATIVE_TENSOR", "LOG_RCOND", "LOG_RT_SIZES", "DUMP_WHITE", "DUMP_AFTER", "DUMP_MOVIE", "SUBMIT_FINISH", "ACQUIRE_WAIT", "CS_FALLBACK", "EXEFS", "FEEDBACK", "FIX_C0", "FIX_ZERO", "FLIGHT", "FLIGHT_AT", "FLIGHT_DIR", "FLIGHT_FRAMES", "FLIGHT_SPIKE_MS", "FLIGHT_THUMBS", "FLUSH_SPAN", "FOLIAGE_SHADOW_CULL", "FOLIAGE_SHADOW_VRS", "FOV", "FOV_PATCH", "FG_HUDLESS_SHOW", "FPS60", "FPS_LIMIT", "FRAMEGEN", "FREEZE_IDLE", "FREE_CORES", - "FULLSCREEN", "FXAA", "GAME_ASPECT", "GAME_RES", "GPA", "GPA_EMPTY", "GPA_TWIN", "GPL", "GPL_DRAW_BUILD", "GPU", "GPU_INDEX", "GPU_PASSES", "GPU_NAME", "HDR", "HDR_GAME_NITS", "HDR_HUE", - "HDR_PEAK_NITS", "HDR_UI_NITS", "HIGHFPS_FIX", "INPUT", "INPUT_RECORD", "INPUT_SCRIPT", "LANG", "LIB_PREBUILD", + "FULLSCREEN", "FXAA", "GAME_ASPECT", "GAME_RES", "GPA", "GPA_EMPTY", "GPA_TWIN", "GPL", "GPL_DRAW_BUILD", "GPU", "GPU_INDEX", "GPU_PASSES", "GPU_NAME", "HDR", "HDR_BLOWOUT", "HDR_CONTRAST", + "HDR_EXPOSURE", "HDR_FLARE", "HDR_GAMMA", "HDR_GAME_NITS", "HDR_GRADE", "HDR_HIGHLIGHT_SAT", "HDR_HIGHLIGHTS", "HDR_HUE", + "HDR_PEAK_NITS", "HDR_SATURATION", "HDR_SHADOWS", "HDR_TONEMAP", "HDR_UI_NITS", "HIGHFPS_FIX", "INPUT", "INPUT_RECORD", "INPUT_SCRIPT", "LANG", "LIB_PREBUILD", "BIG_BUILD_FREE_MB", "BIG_BUILD_MAX_MB", "LIB_PREBUILD_BIG", "LIB_PREBUILD_BIG_BG", "LIB_PREBUILD_KEEP", "LIB_PREBUILD_THREADS", "LOCALE", "LOD_GUARD", "LSTICK_DEADZONE", "MEMORY", "MENU_LANG", "MENU_SOUND_VOLUME", "MENU_TEST", "MENU_CURSOR", "MENU_CURSOR_LOG", "MENU_TEST_DIR", "MENU_TEST_SET", "MINIMAL_LAYOUT", "MIRROR_GAP", "MODS_DIR", "MODS_DISABLED", "MODS_ORDER", "MODS_REBUILD", "MOTION", "MOUSE_MODE", "MOUSE_DIRECT_PATCH", "MOUSE_SENS", "MOVIE_HOST", "MOVIE_PACE", "MVOBJ_ALL", "MVOBJ_BANKS", "MVOBJ_EQUAL", "MVOBJ_EXACT", "MVOBJ_EXEC", "MVOBJ_NOC4", "MVOBJ_ONLY", "MVOBJ_TIMES", "MVPREV_CHECK", "MVPREV_GROW", "MVPREV_SKIP", "MVPREV_TRUST", "MV_CHECK", @@ -77,7 +78,10 @@ static const struct { const char *key, *section; } sections[] = { {"COLOR_PRESET", "display"}, {"COLOR_BRIGHTNESS", "display"}, {"COLOR_CONTRAST", "display"}, {"COLOR_SATURATION", "display"}, {"COLOR_GAMMA", "display"}, {"HDR", "display"}, {"HDR_PEAK_NITS", "display"}, {"HDR_GAME_NITS", "display"}, - {"HDR_UI_NITS", "display"}, {"HDR_HUE", "display"}, {"SHADOW_RES", "display"}, + {"HDR_UI_NITS", "display"}, {"HDR_GAMMA", "display"}, {"HDR_TONEMAP", "display"}, {"HDR_EXPOSURE", "display"}, + {"HDR_HIGHLIGHTS", "display"}, {"HDR_SHADOWS", "display"}, {"HDR_CONTRAST", "display"}, {"HDR_SATURATION", "display"}, + {"HDR_HIGHLIGHT_SAT", "display"}, {"HDR_BLOWOUT", "display"}, {"HDR_FLARE", "display"}, {"HDR_HUE", "display"}, + {"HDR_GRADE", "display"}, {"SHADOW_RES", "display"}, {"DLAA", "display"}, {"DLSS", "display"}, {"DLSS_PRESET", "display"}, {"DLSS_CHAR_MASK", "display"}, {"FXAA", "display"}, {"DEVICE_PROFILE", "display"}, {"ASSUME_FOCUS", "display"}, {"DISCORD_RPC", "discord"}, {"DISCORD_APP_ID", "discord"}, {"DISCORD_IMAGE", "discord"}, @@ -137,9 +141,15 @@ static const CfgMeta metas[] = { {"COLOR_PRESET", "default", "default|vivid|clarity|custom", LIVE}, {"COLOR_BRIGHTNESS", "0", "-30..30", LIVE}, {"COLOR_CONTRAST", "100", "70..150", LIVE}, {"COLOR_SATURATION", "100", "50..200", LIVE}, {"COLOR_GAMMA", "1", "0.8..1.2", LIVE}, - // HDR output (vk_hdr.c): on at start (the tonemap shader is swapped as shaders load); the nits apply at once - {"HDR", "0", "0|1|native", RESTART}, {"HDR_PEAK_NITS", "1000", "400..10000", LIVE}, {"HDR_GAME_NITS", "203", "80..500", LIVE}, - {"HDR_UI_NITS", "203", "80..500", LIVE}, {"HDR_HUE", "80", "0..100", LIVE}, + // HDR output (vk_hdr.c): on at start (the HDR tonemap is spliced into the game's as shaders load); the rest apply at + // once. The grading sliders: 50 leaves the picture as it is, exposure in percent. + {"HDR", "0", "0|1|native", RESTART}, {"HDR_PEAK_NITS", "1000", "400..10000", LIVE}, {"HDR_GAME_NITS", "203", "48..500", LIVE}, + {"HDR_UI_NITS", "203", "48..500", LIVE}, {"HDR_GAMMA", "2.2", "off|2.2|2.4", LIVE}, + {"HDR_TONEMAP", "renodrt", "vanilla|renodrt", LIVE}, {"HDR_EXPOSURE", "100", "0..200", LIVE}, + {"HDR_HIGHLIGHTS", "50", "0..100", LIVE}, {"HDR_SHADOWS", "50", "0..100", LIVE}, {"HDR_CONTRAST", "50", "0..100", LIVE}, + {"HDR_SATURATION", "50", "0..100", LIVE}, {"HDR_HIGHLIGHT_SAT", "50", "0..100", LIVE}, + {"HDR_BLOWOUT", "0", "0..100", LIVE}, {"HDR_FLARE", "0", "0..100", LIVE}, {"HDR_HUE", "100", "0..100", LIVE}, + {"HDR_GRADE", "100", "0..100", LIVE}, {"DEVICE_PROFILE", "auto", "auto|desktop|deck", RESTART}, {"SHADOW_RES", "game", "game|256|512|768|1024|1536|2048", RESTART}, {"SHADOW_SCALE", "1", "1..4", RESTART}, {"SHADOW_COMPARE", "1", "0|1", RESTART}, // vk_texture.c diff --git a/runtime/color_grade_spv.h b/runtime/color_grade_spv.h index 3f45a24e..7e4ba811 100644 --- a/runtime/color_grade_spv.h +++ b/runtime/color_grade_spv.h @@ -1,5 +1,5 @@ // Generated by tools/build_shaders.py from runtime/shaders/color_grade.comp; do not edit. -// source sha256 c93d6ac75667bdee5442d7e94fbf0bd6e7fe7250caa98974424aead10f554106 +// source sha256 664b870a405fe286c9fd5f23c558e1decbf41ea9ef9e1da3383bdb6e81b0bd32 #pragma once #include static const uint32_t color_grade_spv[] = { diff --git a/runtime/gfx.h b/runtime/gfx.h index 3e2de88a..372e86ad 100644 --- a/runtime/gfx.h +++ b/runtime/gfx.h @@ -93,8 +93,8 @@ int gfx_shader_write_code(const GfxShader *s, const char *path); // the guest // A shader of the runtime's own (SPIR-V and a .res.json text as the translator writes them), outside the cache and // never freed; its key is the sha256 of both. NULL when the SPIR-V is malformed. const GfxShader *gfx_shader_own(const uint32_t *spirv, uint64_t words, const char *res_json); -// vk_hdr.c: with NX2NAVI_HDR=1, replaces a fragment shader's SPIR-V (malloc'd, *words long) by the HDR tonemap when it is -// the game's tonemap; gfx_shader.c calls it for every fragment shader entering the cache. +// vk_hdr.c: with NX2NAVI_HDR=1, splices the HDR tonemap into a fragment shader's SPIR-V (malloc'd, *words long) when it +// is the game's tonemap, and unclamps the game's FSR pass; gfx_shader.c calls it for every fragment shader entering the cache. void vk_hdr_shader_swap(uint32_t **spirv, uint64_t *words); uint64_t gfx_shader_failures(void); // failed translations; feeds GfxStats.shader_failures // Reflection: parsed once per shader from the translator's .res.json and the SPIR-V before it enters the cache. diff --git a/runtime/hdr_encode_spv.h b/runtime/hdr_encode_spv.h index d2e5073f..d38b4f14 100644 --- a/runtime/hdr_encode_spv.h +++ b/runtime/hdr_encode_spv.h @@ -1,97 +1,161 @@ // Generated by tools/build_shaders.py from runtime/shaders/hdr_encode.comp; do not edit. -// source sha256 08e1d94f9041b32d4183286db39941eec9cde41412babb197c0303fd64bb07a7 +// source sha256 f79d7e36caf1198a14254a34a739dbca5384af3c62eaa9738b1e1499d8ed6bdd #pragma once #include static const uint32_t hdr_encode_spv[] = { - 0x07230203, 0x00010300, 0x000d000b, 0x000000dd, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, + 0x07230203, 0x00010300, 0x000d000b, 0x000001ff, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, - 0x0006000f, 0x00000005, 0x00000004, 0x6e69616d, 0x00000000, 0x0000004c, 0x00060010, 0x00000004, - 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x0000004c, 0x0000000b, 0x0000001c, - 0x00030047, 0x00000053, 0x00000002, 0x00050048, 0x00000053, 0x00000000, 0x00000023, 0x00000000, - 0x00050048, 0x00000053, 0x00000001, 0x00000023, 0x00000008, 0x00050048, 0x00000053, 0x00000002, - 0x00000023, 0x00000010, 0x00040047, 0x00000064, 0x00000021, 0x00000000, 0x00040047, 0x00000064, - 0x00000022, 0x00000000, 0x00030047, 0x0000009c, 0x00000019, 0x00040047, 0x0000009c, 0x00000021, - 0x00000001, 0x00040047, 0x0000009c, 0x00000022, 0x00000000, 0x00040047, 0x000000a7, 0x0000000b, + 0x0006000f, 0x00000005, 0x00000004, 0x6e69616d, 0x00000000, 0x00000092, 0x00060010, 0x00000004, + 0x00000011, 0x00000008, 0x00000008, 0x00000001, 0x00040047, 0x00000092, 0x0000000b, 0x0000001c, + 0x00030047, 0x00000099, 0x00000002, 0x00050048, 0x00000099, 0x00000000, 0x00000023, 0x00000000, + 0x00050048, 0x00000099, 0x00000001, 0x00000023, 0x00000008, 0x00050048, 0x00000099, 0x00000002, + 0x00000023, 0x00000010, 0x00040047, 0x000000aa, 0x00000021, 0x00000000, 0x00040047, 0x000000aa, + 0x00000022, 0x00000000, 0x00030047, 0x0000013d, 0x00000019, 0x00040047, 0x0000013d, 0x00000021, + 0x00000001, 0x00040047, 0x0000013d, 0x00000022, 0x00000000, 0x00040047, 0x00000149, 0x0000000b, 0x00000019, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, - 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000003, 0x0004002b, 0x00000006, 0x00000015, - 0x3d6147ae, 0x0004002b, 0x00000006, 0x0000001b, 0x4019999a, 0x0006002c, 0x00000007, 0x0000001c, - 0x0000001b, 0x0000001b, 0x0000001b, 0x0004002b, 0x00000006, 0x0000001f, 0x3d25aee6, 0x0006002c, - 0x00000007, 0x00000020, 0x0000001f, 0x0000001f, 0x0000001f, 0x00020014, 0x00000021, 0x00040017, - 0x00000022, 0x00000021, 0x00000003, 0x0004002b, 0x00000006, 0x0000002c, 0x00000000, 0x0004002b, - 0x00000006, 0x0000002d, 0x3f800000, 0x0004002b, 0x00000006, 0x00000031, 0x3e232000, 0x0006002c, - 0x00000007, 0x00000032, 0x00000031, 0x00000031, 0x00000031, 0x0004002b, 0x00000006, 0x00000034, - 0x3f560000, 0x0004002b, 0x00000006, 0x00000035, 0x4196d000, 0x0004002b, 0x00000006, 0x0000003a, - 0x41958000, 0x0004002b, 0x00000006, 0x00000040, 0x429db000, 0x0006002c, 0x00000007, 0x00000041, - 0x00000040, 0x00000040, 0x00000040, 0x00040015, 0x00000045, 0x00000020, 0x00000001, 0x00040017, - 0x00000046, 0x00000045, 0x00000002, 0x00040015, 0x00000049, 0x00000020, 0x00000000, 0x00040017, - 0x0000004a, 0x00000049, 0x00000003, 0x00040020, 0x0000004b, 0x00000001, 0x0000004a, 0x0004003b, - 0x0000004b, 0x0000004c, 0x00000001, 0x00040017, 0x0000004d, 0x00000049, 0x00000002, 0x00040017, - 0x00000052, 0x00000006, 0x00000004, 0x0005001e, 0x00000053, 0x00000046, 0x00000046, 0x00000052, - 0x00040020, 0x00000054, 0x00000009, 0x00000053, 0x0004003b, 0x00000054, 0x00000055, 0x00000009, - 0x0004002b, 0x00000045, 0x00000056, 0x00000001, 0x00040020, 0x00000057, 0x00000009, 0x00000046, - 0x00040017, 0x0000005a, 0x00000021, 0x00000002, 0x00090019, 0x00000061, 0x00000006, 0x00000001, - 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0003001b, 0x00000062, 0x00000061, - 0x00040020, 0x00000063, 0x00000000, 0x00000062, 0x0004003b, 0x00000063, 0x00000064, 0x00000000, - 0x0004002b, 0x00000045, 0x00000067, 0x00000000, 0x0006002c, 0x00000007, 0x0000006e, 0x0000002c, - 0x0000002c, 0x0000002c, 0x0004002b, 0x00000045, 0x00000070, 0x00000002, 0x0004002b, 0x00000049, - 0x00000071, 0x00000002, 0x00040020, 0x00000072, 0x00000009, 0x00000006, 0x0004002b, 0x00000006, - 0x00000075, 0x3f000000, 0x00040018, 0x00000080, 0x00000007, 0x00000003, 0x0004002b, 0x00000006, - 0x00000081, 0x3f209d49, 0x0004002b, 0x00000006, 0x00000082, 0x3d8d844d, 0x0004002b, 0x00000006, - 0x00000083, 0x3c86594b, 0x0006002c, 0x00000007, 0x00000084, 0x00000081, 0x00000082, 0x00000083, - 0x0004002b, 0x00000006, 0x00000085, 0x3ea89a02, 0x0004002b, 0x00000006, 0x00000086, 0x3f6b645a, - 0x0004002b, 0x00000006, 0x00000087, 0x3db43958, 0x0006002c, 0x00000007, 0x00000088, 0x00000085, - 0x00000086, 0x00000087, 0x0004002b, 0x00000006, 0x00000089, 0x3d315b57, 0x0004002b, 0x00000006, - 0x0000008a, 0x3c3ac711, 0x0004002b, 0x00000006, 0x0000008b, 0x3f65460b, 0x0006002c, 0x00000007, - 0x0000008c, 0x00000089, 0x0000008a, 0x0000008b, 0x0006002c, 0x00000080, 0x0000008d, 0x00000084, - 0x00000088, 0x0000008c, 0x0004002b, 0x00000049, 0x00000091, 0x00000000, 0x0004002b, 0x00000049, - 0x00000095, 0x00000001, 0x00090019, 0x0000009a, 0x00000006, 0x00000001, 0x00000000, 0x00000000, - 0x00000000, 0x00000002, 0x00000002, 0x00040020, 0x0000009b, 0x00000000, 0x0000009a, 0x0004003b, - 0x0000009b, 0x0000009c, 0x00000000, 0x0004002b, 0x00000049, 0x000000a6, 0x00000008, 0x0006002c, - 0x0000004a, 0x000000a7, 0x000000a6, 0x000000a6, 0x00000095, 0x0006002c, 0x00000007, 0x000000d1, - 0x0000002d, 0x0000002d, 0x0000002d, 0x0006002c, 0x00000007, 0x000000d3, 0x00000015, 0x00000015, - 0x00000015, 0x0006002c, 0x00000007, 0x000000d6, 0x00000034, 0x00000034, 0x00000034, 0x0004002b, - 0x00000006, 0x000000d7, 0x3d9e8391, 0x0006002c, 0x00000007, 0x000000d8, 0x000000d7, 0x000000d7, - 0x000000d7, 0x0004002b, 0x00000006, 0x000000d9, 0x3f72a76f, 0x0006002c, 0x00000007, 0x000000da, - 0x000000d9, 0x000000d9, 0x000000d9, 0x0004002b, 0x00000006, 0x000000db, 0x38d1b717, 0x0006002c, - 0x00000007, 0x000000dc, 0x000000db, 0x000000db, 0x000000db, 0x00050036, 0x00000002, 0x00000004, - 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x000300f7, 0x000000a8, 0x00000000, 0x000300fb, - 0x00000091, 0x000000a9, 0x000200f8, 0x000000a9, 0x0004003d, 0x0000004a, 0x0000004e, 0x0000004c, - 0x0007004f, 0x0000004d, 0x0000004f, 0x0000004e, 0x0000004e, 0x00000000, 0x00000001, 0x0004007c, - 0x00000046, 0x00000050, 0x0000004f, 0x00050041, 0x00000057, 0x00000058, 0x00000055, 0x00000056, - 0x0004003d, 0x00000046, 0x00000059, 0x00000058, 0x000500af, 0x0000005a, 0x0000005b, 0x00000050, - 0x00000059, 0x0004009a, 0x00000021, 0x0000005c, 0x0000005b, 0x000300f7, 0x0000005e, 0x00000000, - 0x000400fa, 0x0000005c, 0x0000005d, 0x0000005e, 0x000200f8, 0x0000005d, 0x000200f9, 0x000000a8, - 0x000200f8, 0x0000005e, 0x0004003d, 0x00000062, 0x00000065, 0x00000064, 0x00050041, 0x00000057, - 0x00000068, 0x00000055, 0x00000067, 0x0004003d, 0x00000046, 0x00000069, 0x00000068, 0x00050080, - 0x00000046, 0x0000006a, 0x00000050, 0x00000069, 0x00040064, 0x00000061, 0x0000006b, 0x00000065, - 0x0007005f, 0x00000052, 0x0000006c, 0x0000006b, 0x0000006a, 0x00000002, 0x00000067, 0x0008004f, - 0x00000007, 0x0000006d, 0x0000006c, 0x0000006c, 0x00000000, 0x00000001, 0x00000002, 0x0007000c, - 0x00000007, 0x0000006f, 0x00000001, 0x00000028, 0x0000006d, 0x0000006e, 0x00060041, 0x00000072, - 0x00000073, 0x00000055, 0x00000070, 0x00000071, 0x0004003d, 0x00000006, 0x00000074, 0x00000073, - 0x000500ba, 0x00000021, 0x00000076, 0x00000074, 0x00000075, 0x000300f7, 0x00000078, 0x00000000, - 0x000400fa, 0x00000076, 0x00000077, 0x00000078, 0x000200f8, 0x00000077, 0x0008000c, 0x00000007, - 0x0000007c, 0x00000001, 0x0000002b, 0x0000006f, 0x0000006e, 0x000000d1, 0x00050085, 0x00000007, - 0x000000b2, 0x0000007c, 0x000000d8, 0x00050081, 0x00000007, 0x000000b5, 0x0000007c, 0x000000d3, - 0x00050085, 0x00000007, 0x000000b7, 0x000000b5, 0x000000da, 0x0007000c, 0x00000007, 0x000000b8, - 0x00000001, 0x0000001a, 0x000000b7, 0x0000001c, 0x000500ba, 0x00000022, 0x000000ba, 0x0000007c, - 0x00000020, 0x000600a9, 0x00000007, 0x000000bb, 0x000000ba, 0x000000b8, 0x000000b2, 0x000200f9, - 0x00000078, 0x000200f8, 0x00000078, 0x000700f5, 0x00000007, 0x000000d0, 0x0000006f, 0x0000005e, - 0x000000bb, 0x00000077, 0x00050091, 0x00000007, 0x0000008f, 0x0000008d, 0x000000d0, 0x0007000c, - 0x00000007, 0x00000090, 0x00000001, 0x00000028, 0x0000008f, 0x0000006e, 0x00060041, 0x00000072, - 0x00000092, 0x00000055, 0x00000070, 0x00000091, 0x0004003d, 0x00000006, 0x00000093, 0x00000092, - 0x0005008e, 0x00000007, 0x00000094, 0x00000090, 0x00000093, 0x00060041, 0x00000072, 0x00000096, - 0x00000055, 0x00000070, 0x00000095, 0x0004003d, 0x00000006, 0x00000097, 0x00000096, 0x00060050, - 0x00000007, 0x00000098, 0x00000097, 0x00000097, 0x00000097, 0x0007000c, 0x00000007, 0x00000099, - 0x00000001, 0x00000025, 0x00000094, 0x00000098, 0x0004003d, 0x0000009a, 0x0000009d, 0x0000009c, - 0x00050085, 0x00000007, 0x000000c1, 0x00000099, 0x000000dc, 0x0008000c, 0x00000007, 0x000000c4, - 0x00000001, 0x0000002b, 0x000000c1, 0x0000006e, 0x000000d1, 0x0007000c, 0x00000007, 0x000000c5, - 0x00000001, 0x0000001a, 0x000000c4, 0x00000032, 0x0005008e, 0x00000007, 0x000000c7, 0x000000c5, - 0x00000035, 0x00050081, 0x00000007, 0x000000c9, 0x000000d6, 0x000000c7, 0x0005008e, 0x00000007, - 0x000000cb, 0x000000c5, 0x0000003a, 0x00050081, 0x00000007, 0x000000cd, 0x000000d1, 0x000000cb, - 0x00050088, 0x00000007, 0x000000ce, 0x000000c9, 0x000000cd, 0x0007000c, 0x00000007, 0x000000cf, - 0x00000001, 0x0000001a, 0x000000ce, 0x00000041, 0x00050051, 0x00000006, 0x000000a2, 0x000000cf, - 0x00000000, 0x00050051, 0x00000006, 0x000000a3, 0x000000cf, 0x00000001, 0x00050051, 0x00000006, - 0x000000a4, 0x000000cf, 0x00000002, 0x00070050, 0x00000052, 0x000000a5, 0x000000a2, 0x000000a3, - 0x000000a4, 0x0000002d, 0x00040063, 0x0000009d, 0x00000050, 0x000000a5, 0x000200f9, 0x000000a8, - 0x000200f8, 0x000000a8, 0x000100fd, 0x00010038, + 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000003, 0x0004002b, 0x00000006, 0x00000029, + 0x00000000, 0x0006002c, 0x00000007, 0x0000002a, 0x00000029, 0x00000029, 0x00000029, 0x00020014, + 0x0000002b, 0x00040017, 0x0000002c, 0x0000002b, 0x00000003, 0x0004002b, 0x00000006, 0x0000003d, + 0x3d6147ae, 0x0004002b, 0x00000006, 0x00000040, 0x3f870a3d, 0x0004002b, 0x00000006, 0x00000043, + 0x4019999a, 0x0006002c, 0x00000007, 0x00000044, 0x00000043, 0x00000043, 0x00000043, 0x0004002b, + 0x00000006, 0x00000047, 0x414eb852, 0x0004002b, 0x00000006, 0x0000004b, 0x3d25aee6, 0x0006002c, + 0x00000007, 0x0000004c, 0x0000004b, 0x0000004b, 0x0000004b, 0x0004002b, 0x00000006, 0x00000052, + 0x3ed55555, 0x0006002c, 0x00000007, 0x00000053, 0x00000052, 0x00000052, 0x00000052, 0x0004002b, + 0x00000006, 0x0000005b, 0x3b4d2e1c, 0x0006002c, 0x00000007, 0x0000005c, 0x0000005b, 0x0000005b, + 0x0000005b, 0x0004002b, 0x00000006, 0x00000073, 0x3f800000, 0x0004002b, 0x00000006, 0x00000077, + 0x3e232000, 0x0006002c, 0x00000007, 0x00000078, 0x00000077, 0x00000077, 0x00000077, 0x0004002b, + 0x00000006, 0x0000007a, 0x3f560000, 0x0004002b, 0x00000006, 0x0000007b, 0x4196d000, 0x0004002b, + 0x00000006, 0x00000080, 0x41958000, 0x0004002b, 0x00000006, 0x00000086, 0x429db000, 0x0006002c, + 0x00000007, 0x00000087, 0x00000086, 0x00000086, 0x00000086, 0x00040015, 0x0000008b, 0x00000020, + 0x00000001, 0x00040017, 0x0000008c, 0x0000008b, 0x00000002, 0x00040015, 0x0000008f, 0x00000020, + 0x00000000, 0x00040017, 0x00000090, 0x0000008f, 0x00000003, 0x00040020, 0x00000091, 0x00000001, + 0x00000090, 0x0004003b, 0x00000091, 0x00000092, 0x00000001, 0x00040017, 0x00000093, 0x0000008f, + 0x00000002, 0x00040017, 0x00000098, 0x00000006, 0x00000004, 0x0005001e, 0x00000099, 0x0000008c, + 0x0000008c, 0x00000098, 0x00040020, 0x0000009a, 0x00000009, 0x00000099, 0x0004003b, 0x0000009a, + 0x0000009b, 0x00000009, 0x0004002b, 0x0000008b, 0x0000009c, 0x00000001, 0x00040020, 0x0000009d, + 0x00000009, 0x0000008c, 0x00040017, 0x000000a0, 0x0000002b, 0x00000002, 0x00090019, 0x000000a7, + 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0003001b, + 0x000000a8, 0x000000a7, 0x00040020, 0x000000a9, 0x00000000, 0x000000a8, 0x0004003b, 0x000000a9, + 0x000000aa, 0x00000000, 0x0004002b, 0x0000008b, 0x000000ad, 0x00000000, 0x0004002b, 0x0000008b, + 0x000000b4, 0x00000002, 0x0004002b, 0x0000008f, 0x000000b5, 0x00000002, 0x00040020, 0x000000b6, + 0x00000009, 0x00000006, 0x0004002b, 0x00000006, 0x000000b9, 0x3f000000, 0x0004002b, 0x0000008f, + 0x000000c7, 0x00000003, 0x0004002b, 0x00000006, 0x000000cd, 0x400ccccd, 0x0004002b, 0x00000006, + 0x000000d5, 0x40000000, 0x00040018, 0x000000de, 0x00000007, 0x00000003, 0x0004002b, 0x00000006, + 0x000000df, 0x3f209d8b, 0x0004002b, 0x00000006, 0x000000e0, 0x3ea897c9, 0x0004002b, 0x00000006, + 0x000000e1, 0x3d31690b, 0x0006002c, 0x00000007, 0x000000e2, 0x000000df, 0x000000e0, 0x000000e1, + 0x0004002b, 0x00000006, 0x000000e3, 0x3d8d82e1, 0x0004002b, 0x00000006, 0x000000e4, 0x3f6b6700, + 0x0004002b, 0x00000006, 0x000000e5, 0x3c3a2901, 0x0006002c, 0x00000007, 0x000000e6, 0x000000e3, + 0x000000e4, 0x000000e5, 0x0004002b, 0x00000006, 0x000000e7, 0x3c864757, 0x0004002b, 0x00000006, + 0x000000e8, 0x3db44052, 0x0004002b, 0x00000006, 0x000000e9, 0x3f6545bb, 0x0006002c, 0x00000007, + 0x000000ea, 0x000000e7, 0x000000e8, 0x000000e9, 0x0006002c, 0x000000de, 0x000000eb, 0x000000e2, + 0x000000e6, 0x000000ea, 0x0004002b, 0x00000006, 0x000000ef, 0x3e8680a4, 0x0004002b, 0x00000006, + 0x000000f0, 0x3f2d9148, 0x0004002b, 0x00000006, 0x000000f1, 0x3d72e65b, 0x0006002c, 0x00000007, + 0x000000f2, 0x000000ef, 0x000000f0, 0x000000f1, 0x0004002b, 0x00000006, 0x000000f5, 0x3ecd80ce, + 0x0004002b, 0x0000008f, 0x000000ff, 0x00000000, 0x0004002b, 0x0000008f, 0x00000102, 0x00000001, + 0x0004002b, 0x00000006, 0x00000121, 0x401f73da, 0x00090019, 0x0000013b, 0x00000006, 0x00000001, + 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000002, 0x00040020, 0x0000013c, 0x00000000, + 0x0000013b, 0x0004003b, 0x0000013c, 0x0000013d, 0x00000000, 0x0004002b, 0x0000008f, 0x00000148, + 0x00000008, 0x0006002c, 0x00000090, 0x00000149, 0x00000148, 0x00000148, 0x00000102, 0x0006002c, + 0x00000007, 0x000001f0, 0x00000073, 0x00000073, 0x00000073, 0x0006002c, 0x00000007, 0x000001f1, + 0x0000003d, 0x0000003d, 0x0000003d, 0x0006002c, 0x00000007, 0x000001f4, 0x000000cd, 0x000000cd, + 0x000000cd, 0x0006002c, 0x00000007, 0x000001f5, 0x000000f5, 0x000000f5, 0x000000f5, 0x0006002c, + 0x00000007, 0x000001f6, 0x00000121, 0x00000121, 0x00000121, 0x0006002c, 0x00000007, 0x000001f8, + 0x0000007a, 0x0000007a, 0x0000007a, 0x0004002b, 0x00000006, 0x000001f9, 0x3f72a76f, 0x0006002c, + 0x00000007, 0x000001fa, 0x000001f9, 0x000001f9, 0x000001f9, 0x0004002b, 0x00000006, 0x000001fb, + 0x3d9e8391, 0x0006002c, 0x00000007, 0x000001fc, 0x000001fb, 0x000001fb, 0x000001fb, 0x0004002b, + 0x00000006, 0x000001fd, 0x38d1b717, 0x0006002c, 0x00000007, 0x000001fe, 0x000001fd, 0x000001fd, + 0x000001fd, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, + 0x000300f7, 0x0000014a, 0x00000000, 0x000300fb, 0x000000ff, 0x0000014b, 0x000200f8, 0x0000014b, + 0x0004003d, 0x00000090, 0x00000094, 0x00000092, 0x0007004f, 0x00000093, 0x00000095, 0x00000094, + 0x00000094, 0x00000000, 0x00000001, 0x0004007c, 0x0000008c, 0x00000096, 0x00000095, 0x00050041, + 0x0000009d, 0x0000009e, 0x0000009b, 0x0000009c, 0x0004003d, 0x0000008c, 0x0000009f, 0x0000009e, + 0x000500af, 0x000000a0, 0x000000a1, 0x00000096, 0x0000009f, 0x0004009a, 0x0000002b, 0x000000a2, + 0x000000a1, 0x000300f7, 0x000000a4, 0x00000000, 0x000400fa, 0x000000a2, 0x000000a3, 0x000000a4, + 0x000200f8, 0x000000a3, 0x000200f9, 0x0000014a, 0x000200f8, 0x000000a4, 0x0004003d, 0x000000a8, + 0x000000ab, 0x000000aa, 0x00050041, 0x0000009d, 0x000000ae, 0x0000009b, 0x000000ad, 0x0004003d, + 0x0000008c, 0x000000af, 0x000000ae, 0x00050080, 0x0000008c, 0x000000b0, 0x00000096, 0x000000af, + 0x00040064, 0x000000a7, 0x000000b1, 0x000000ab, 0x0007005f, 0x00000098, 0x000000b2, 0x000000b1, + 0x000000b0, 0x00000002, 0x000000ad, 0x0008004f, 0x00000007, 0x000000b3, 0x000000b2, 0x000000b2, + 0x00000000, 0x00000001, 0x00000002, 0x00060041, 0x000000b6, 0x000000b7, 0x0000009b, 0x000000b4, + 0x000000b5, 0x0004003d, 0x00000006, 0x000000b8, 0x000000b7, 0x000500ba, 0x0000002b, 0x000000ba, + 0x000000b8, 0x000000b9, 0x000300f7, 0x000000bc, 0x00000000, 0x000400fa, 0x000000ba, 0x000000bb, + 0x000000bc, 0x000200f8, 0x000000bb, 0x0008000c, 0x00000007, 0x000000c0, 0x00000001, 0x0000002b, + 0x000000b3, 0x0000002a, 0x000001f0, 0x00050081, 0x00000007, 0x00000154, 0x000000c0, 0x000001f1, + 0x00050085, 0x00000007, 0x00000156, 0x00000154, 0x000001fa, 0x0007000c, 0x00000007, 0x00000157, + 0x00000001, 0x0000001a, 0x00000156, 0x00000044, 0x00050085, 0x00000007, 0x0000015a, 0x000000c0, + 0x000001fc, 0x000500bc, 0x0000002c, 0x0000015c, 0x000000c0, 0x0000004c, 0x000600a9, 0x00000007, + 0x0000015d, 0x0000015c, 0x0000015a, 0x00000157, 0x000200f9, 0x000000bc, 0x000200f8, 0x000000bc, + 0x000700f5, 0x00000007, 0x000001ec, 0x000000b3, 0x000000a4, 0x0000015d, 0x000000bb, 0x0004009c, + 0x0000002c, 0x000000c5, 0x000001ec, 0x000600a9, 0x00000007, 0x000000c6, 0x000000c5, 0x0000002a, + 0x000001ec, 0x00060041, 0x000000b6, 0x000000c8, 0x0000009b, 0x000000b4, 0x000000c7, 0x0004003d, + 0x00000006, 0x000000c9, 0x000000c8, 0x000500b4, 0x0000002b, 0x000000ca, 0x000000c9, 0x00000073, + 0x000300f7, 0x000000cc, 0x00000000, 0x000400fa, 0x000000ca, 0x000000cb, 0x000000d2, 0x000200f8, + 0x000000cb, 0x0006000c, 0x00000007, 0x00000164, 0x00000001, 0x00000004, 0x000000c6, 0x0007000c, + 0x00000007, 0x0000016e, 0x00000001, 0x0000001a, 0x00000164, 0x00000053, 0x0005008e, 0x00000007, + 0x0000016f, 0x0000016e, 0x00000040, 0x00050083, 0x00000007, 0x00000171, 0x0000016f, 0x000001f1, + 0x0005008e, 0x00000007, 0x00000173, 0x00000164, 0x00000047, 0x000500bc, 0x0000002c, 0x00000175, + 0x00000164, 0x0000005c, 0x000600a9, 0x00000007, 0x00000176, 0x00000175, 0x00000173, 0x00000171, + 0x0007000c, 0x00000007, 0x00000168, 0x00000001, 0x0000001a, 0x00000176, 0x000001f4, 0x0006000c, + 0x00000007, 0x0000017b, 0x00000001, 0x00000004, 0x00000168, 0x0004007f, 0x00000007, 0x0000017e, + 0x0000017b, 0x000500b8, 0x0000002c, 0x00000180, 0x000000c6, 0x0000002a, 0x000600a9, 0x00000007, + 0x00000181, 0x00000180, 0x0000017e, 0x0000017b, 0x000200f9, 0x000000cc, 0x000200f8, 0x000000d2, + 0x000500b4, 0x0000002b, 0x000000d6, 0x000000c9, 0x000000d5, 0x000300f7, 0x000000d8, 0x00000000, + 0x000400fa, 0x000000d6, 0x000000d7, 0x000000d8, 0x000200f8, 0x000000d7, 0x0006000c, 0x00000007, + 0x00000188, 0x00000001, 0x00000004, 0x000000c6, 0x0007000c, 0x00000007, 0x00000192, 0x00000001, + 0x0000001a, 0x00000188, 0x00000053, 0x0005008e, 0x00000007, 0x00000193, 0x00000192, 0x00000040, + 0x00050083, 0x00000007, 0x00000195, 0x00000193, 0x000001f1, 0x0005008e, 0x00000007, 0x00000197, + 0x00000188, 0x00000047, 0x000500bc, 0x0000002c, 0x00000199, 0x00000188, 0x0000005c, 0x000600a9, + 0x00000007, 0x0000019a, 0x00000199, 0x00000197, 0x00000195, 0x0007000c, 0x00000007, 0x0000018c, + 0x00000001, 0x0000001a, 0x0000019a, 0x00000044, 0x0006000c, 0x00000007, 0x0000019f, 0x00000001, + 0x00000004, 0x0000018c, 0x0004007f, 0x00000007, 0x000001a2, 0x0000019f, 0x000500b8, 0x0000002c, + 0x000001a4, 0x000000c6, 0x0000002a, 0x000600a9, 0x00000007, 0x000001a5, 0x000001a4, 0x000001a2, + 0x0000019f, 0x000200f9, 0x000000d8, 0x000200f8, 0x000000d8, 0x000700f5, 0x00000007, 0x000001ee, + 0x000000c6, 0x000000d2, 0x000001a5, 0x000000d7, 0x000200f9, 0x000000cc, 0x000200f8, 0x000000cc, + 0x000700f5, 0x00000007, 0x000001ed, 0x00000181, 0x000000cb, 0x000001ee, 0x000000d8, 0x00050090, + 0x00000007, 0x000000ec, 0x000001ed, 0x000000eb, 0x00050094, 0x00000006, 0x000000f3, 0x000000ec, + 0x000000f2, 0x0006000c, 0x00000007, 0x000001ab, 0x00000001, 0x00000004, 0x000000ec, 0x0007000c, + 0x00000007, 0x000001ae, 0x00000001, 0x0000001a, 0x000001ab, 0x000001f5, 0x0006000c, 0x00000007, + 0x000001b5, 0x00000001, 0x00000004, 0x000001ae, 0x0004007f, 0x00000007, 0x000001b8, 0x000001b5, + 0x000500b8, 0x0000002c, 0x000001ba, 0x000000ec, 0x0000002a, 0x000600a9, 0x00000007, 0x000001bb, + 0x000001ba, 0x000001b8, 0x000001b5, 0x0007000c, 0x00000006, 0x000000fc, 0x00000001, 0x00000028, + 0x000000f3, 0x00000029, 0x0007000c, 0x00000006, 0x000000fd, 0x00000001, 0x0000001a, 0x000000fc, + 0x000000f5, 0x00050051, 0x00000006, 0x00000101, 0x000001bb, 0x00000000, 0x00050051, 0x00000006, + 0x00000104, 0x000001bb, 0x00000001, 0x00050051, 0x00000006, 0x00000106, 0x000001bb, 0x00000002, + 0x0007000c, 0x00000006, 0x00000107, 0x00000001, 0x00000025, 0x00000104, 0x00000106, 0x0007000c, + 0x00000006, 0x00000108, 0x00000001, 0x00000025, 0x00000101, 0x00000107, 0x0007000c, 0x00000006, + 0x00000109, 0x00000001, 0x00000025, 0x00000029, 0x00000108, 0x00050083, 0x00000006, 0x0000010d, + 0x000000fd, 0x00000109, 0x000500b4, 0x0000002b, 0x00000110, 0x0000010d, 0x00000029, 0x000300f7, + 0x00000113, 0x00000000, 0x000400fa, 0x00000110, 0x00000112, 0x00000114, 0x000200f8, 0x00000112, + 0x000200f9, 0x00000113, 0x000200f8, 0x00000114, 0x0004007f, 0x00000006, 0x00000116, 0x00000109, + 0x00050088, 0x00000006, 0x00000118, 0x00000116, 0x0000010d, 0x000200f9, 0x00000113, 0x000200f8, + 0x00000113, 0x000700f5, 0x00000006, 0x000001ef, 0x00000029, 0x00000112, 0x00000118, 0x00000114, + 0x00060050, 0x00000007, 0x0000011b, 0x000000fd, 0x000000fd, 0x000000fd, 0x00050083, 0x00000006, + 0x0000011e, 0x00000073, 0x000001ef, 0x00060050, 0x00000007, 0x0000011f, 0x0000011e, 0x0000011e, + 0x0000011e, 0x0008000c, 0x00000007, 0x00000120, 0x00000001, 0x0000002e, 0x0000011b, 0x000001bb, + 0x0000011f, 0x0006000c, 0x00000007, 0x000001c1, 0x00000001, 0x00000004, 0x00000120, 0x0007000c, + 0x00000007, 0x000001c4, 0x00000001, 0x0000001a, 0x000001c1, 0x000001f6, 0x0006000c, 0x00000007, + 0x000001cb, 0x00000001, 0x00000004, 0x000001c4, 0x0004007f, 0x00000007, 0x000001ce, 0x000001cb, + 0x000500b8, 0x0000002c, 0x000001d0, 0x00000120, 0x0000002a, 0x000600a9, 0x00000007, 0x000001d1, + 0x000001d0, 0x000001ce, 0x000001cb, 0x00060041, 0x000000b6, 0x00000125, 0x0000009b, 0x000000b4, + 0x000000ff, 0x0004003d, 0x00000006, 0x00000126, 0x00000125, 0x0005008e, 0x00000007, 0x00000128, + 0x000001d1, 0x00000126, 0x00050051, 0x00000006, 0x0000012b, 0x00000128, 0x00000000, 0x00050051, + 0x00000006, 0x0000012d, 0x00000128, 0x00000001, 0x0007000c, 0x00000006, 0x0000012e, 0x00000001, + 0x00000028, 0x0000012b, 0x0000012d, 0x00050051, 0x00000006, 0x00000130, 0x00000128, 0x00000002, + 0x0007000c, 0x00000006, 0x00000131, 0x00000001, 0x00000028, 0x0000012e, 0x00000130, 0x00060041, + 0x000000b6, 0x00000132, 0x0000009b, 0x000000b4, 0x00000102, 0x0004003d, 0x00000006, 0x00000133, + 0x00000132, 0x0007000c, 0x00000006, 0x00000134, 0x00000001, 0x00000028, 0x00000131, 0x00000133, + 0x00050088, 0x00000006, 0x00000138, 0x00000133, 0x00000134, 0x0005008e, 0x00000007, 0x0000013a, + 0x00000128, 0x00000138, 0x0004003d, 0x0000013b, 0x0000013e, 0x0000013d, 0x0007000c, 0x00000007, + 0x00000141, 0x00000001, 0x00000028, 0x0000013a, 0x0000002a, 0x00050085, 0x00000007, 0x000001d7, + 0x00000141, 0x000001fe, 0x0008000c, 0x00000007, 0x000001da, 0x00000001, 0x0000002b, 0x000001d7, + 0x0000002a, 0x000001f0, 0x0007000c, 0x00000007, 0x000001db, 0x00000001, 0x0000001a, 0x000001da, + 0x00000078, 0x0005008e, 0x00000007, 0x000001dd, 0x000001db, 0x0000007b, 0x00050081, 0x00000007, + 0x000001df, 0x000001f8, 0x000001dd, 0x0005008e, 0x00000007, 0x000001e1, 0x000001db, 0x00000080, + 0x00050081, 0x00000007, 0x000001e3, 0x000001f0, 0x000001e1, 0x00050088, 0x00000007, 0x000001e4, + 0x000001df, 0x000001e3, 0x0007000c, 0x00000007, 0x000001e5, 0x00000001, 0x0000001a, 0x000001e4, + 0x00000087, 0x00050051, 0x00000006, 0x00000144, 0x000001e5, 0x00000000, 0x00050051, 0x00000006, + 0x00000145, 0x000001e5, 0x00000001, 0x00050051, 0x00000006, 0x00000146, 0x000001e5, 0x00000002, + 0x00070050, 0x00000098, 0x00000147, 0x00000144, 0x00000145, 0x00000146, 0x00000073, 0x00040063, + 0x0000013e, 0x00000096, 0x00000147, 0x000200f9, 0x0000014a, 0x000200f8, 0x0000014a, 0x000100fd, + 0x00010038, }; diff --git a/runtime/hdr_tonemap_spv.h b/runtime/hdr_tonemap_spv.h index 6a740ef4..d9d7f28a 100644 --- a/runtime/hdr_tonemap_spv.h +++ b/runtime/hdr_tonemap_spv.h @@ -1,290 +1,801 @@ // Generated by tools/build_shaders.py from runtime/shaders/hdr_tonemap.frag; do not edit. -// source sha256 a09ae2b13d844bb6a136d2c3cf38b3ec571191775a4c2f0b43a586bd355381fa +// source sha256 43f8d67ba9658afab0d2e882415fe4adbd46a46787593735c04751e87cf9c007 #pragma once #include static const uint32_t hdr_tonemap_spv[] = { - 0x07230203, 0x00010300, 0x0008000b, 0x0000018a, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, + 0x07230203, 0x00010300, 0x000d000b, 0x00000443, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, - 0x0007000f, 0x00000004, 0x00000004, 0x6e69616d, 0x00000000, 0x00000053, 0x00000181, 0x00030010, - 0x00000004, 0x00000007, 0x00030003, 0x00000002, 0x000001c2, 0x00040005, 0x00000004, 0x6e69616d, - 0x00000000, 0x00050005, 0x0000000a, 0x76727563, 0x31662865, 0x0000003b, 0x00030005, 0x00000009, - 0x00000078, 0x00050005, 0x00000010, 0x76727563, 0x76283365, 0x003b3366, 0x00030005, 0x0000000f, - 0x00000078, 0x00050005, 0x00000014, 0x6378616d, 0x33667628, 0x0000003b, 0x00030005, 0x00000013, - 0x00000063, 0x00030005, 0x00000016, 0x00003079, 0x00040005, 0x0000002e, 0x61726170, 0x0000006d, - 0x00040005, 0x00000034, 0x61726170, 0x0000006d, 0x00040005, 0x00000039, 0x61726170, 0x0000006d, - 0x00030005, 0x0000004b, 0x00000078, 0x00050005, 0x0000004f, 0x745f7066, 0x6263745f, 0x0000385f, - 0x00030005, 0x00000053, 0x00007675, 0x00050005, 0x0000005c, 0x745f7066, 0x6263745f, 0x0000415f, - 0x00030005, 0x00000064, 0x00000077, 0x00030005, 0x00000067, 0x00003143, 0x00040006, 0x00000067, - 0x00000000, 0x00000076, 0x00040005, 0x00000069, 0x635f7066, 0x00000031, 0x00030005, 0x0000006f, - 0x00000067, 0x00030005, 0x00000071, 0x00003343, 0x00040006, 0x00000071, 0x00000000, 0x00000076, - 0x00040005, 0x00000073, 0x635f7066, 0x00000033, 0x00040005, 0x00000076, 0x656d6167, 0x00000000, - 0x00060005, 0x00000079, 0x70707553, 0x4274726f, 0x65666675, 0x00000072, 0x00040006, 0x00000079, - 0x00000000, 0x00646170, 0x00040006, 0x00000079, 0x00000001, 0x00726468, 0x00060005, 0x0000007b, - 0x70707573, 0x5f74726f, 0x66667562, 0x00007265, 0x00040005, 0x00000089, 0x6b616570, 0x00000000, - 0x00030005, 0x00000094, 0x006d756c, 0x00030005, 0x000000a6, 0x00726473, 0x00040005, 0x000000ab, - 0x6c5f7962, 0x00006d75, 0x00040005, 0x000000b2, 0x61726170, 0x0000006d, 0x00030005, 0x000000bb, - 0x00000063, 0x00040005, 0x000000bd, 0x61726170, 0x0000006d, 0x00030005, 0x000000c7, 0x00000073, - 0x00040005, 0x000000c8, 0x61726170, 0x0000006d, 0x00030005, 0x000000cc, 0x0000006e, 0x00030005, - 0x000000d1, 0x0000006d, 0x00040005, 0x000000d2, 0x61726170, 0x0000006d, 0x00030005, 0x000000d5, - 0x00000064, 0x00040005, 0x000000e4, 0x64617267, 0x00000065, 0x00040005, 0x000000fa, 0x5f726473, - 0x00000063, 0x00030005, 0x00000115, 0x00006d73, 0x00040005, 0x00000116, 0x61726170, 0x0000006d, - 0x00030005, 0x00000119, 0x00006473, 0x00030005, 0x00000139, 0x00657568, 0x00030005, 0x0000013d, - 0x00006379, 0x00030005, 0x00000144, 0x00007379, 0x00040005, 0x00000159, 0x61726170, 0x0000006d, - 0x00030005, 0x00000160, 0x00706f74, 0x00040005, 0x00000161, 0x61726170, 0x0000006d, 0x00040005, - 0x00000164, 0x65656e6b, 0x00000000, 0x00030005, 0x0000016c, 0x00000072, 0x00040005, 0x00000181, - 0x6f6c6f63, 0x00000072, 0x00040047, 0x0000004f, 0x00000021, 0x00000001, 0x00040047, 0x0000004f, - 0x00000022, 0x00000000, 0x00040047, 0x00000053, 0x0000001e, 0x00000000, 0x00040047, 0x0000005c, - 0x00000021, 0x00000002, 0x00040047, 0x0000005c, 0x00000022, 0x00000000, 0x00040047, 0x00000066, - 0x00000006, 0x00000010, 0x00030047, 0x00000067, 0x00000002, 0x00050048, 0x00000067, 0x00000000, - 0x00000023, 0x00000000, 0x00040047, 0x00000069, 0x00000021, 0x00000003, 0x00040047, 0x00000069, - 0x00000022, 0x00000000, 0x00040047, 0x00000070, 0x00000006, 0x00000010, 0x00030047, 0x00000071, - 0x00000002, 0x00050048, 0x00000071, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000073, - 0x00000021, 0x00000004, 0x00040047, 0x00000073, 0x00000022, 0x00000000, 0x00040047, 0x00000078, - 0x00000006, 0x00000010, 0x00030047, 0x00000079, 0x00000002, 0x00050048, 0x00000079, 0x00000000, - 0x00000023, 0x00000000, 0x00050048, 0x00000079, 0x00000001, 0x00000023, 0x000005a0, 0x00040047, - 0x0000007b, 0x00000021, 0x00000000, 0x00040047, 0x0000007b, 0x00000022, 0x00000000, 0x00040047, - 0x00000181, 0x0000001e, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, - 0x00030016, 0x00000006, 0x00000020, 0x00040020, 0x00000007, 0x00000007, 0x00000006, 0x00040021, - 0x00000008, 0x00000006, 0x00000007, 0x00040017, 0x0000000c, 0x00000006, 0x00000003, 0x00040020, - 0x0000000d, 0x00000007, 0x0000000c, 0x00040021, 0x0000000e, 0x0000000c, 0x0000000d, 0x00040021, - 0x00000012, 0x00000006, 0x0000000d, 0x0004002b, 0x00000006, 0x00000017, 0x3e28aeed, 0x0004002b, - 0x00000006, 0x00000019, 0x3e3851ec, 0x00020014, 0x0000001a, 0x0004002b, 0x00000006, 0x0000001f, - 0x3f800000, 0x0004002b, 0x00000006, 0x00000026, 0x3f55d445, 0x00040015, 0x0000002f, 0x00000020, - 0x00000000, 0x0004002b, 0x0000002f, 0x00000030, 0x00000000, 0x0004002b, 0x0000002f, 0x00000035, - 0x00000001, 0x0004002b, 0x0000002f, 0x0000003a, 0x00000002, 0x00090019, 0x0000004c, 0x00000006, - 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0003001b, 0x0000004d, - 0x0000004c, 0x00040020, 0x0000004e, 0x00000000, 0x0000004d, 0x0004003b, 0x0000004e, 0x0000004f, - 0x00000000, 0x00040017, 0x00000051, 0x00000006, 0x00000004, 0x00040020, 0x00000052, 0x00000001, - 0x00000051, 0x0004003b, 0x00000052, 0x00000053, 0x00000001, 0x00040017, 0x00000054, 0x00000006, - 0x00000002, 0x0004002b, 0x00000006, 0x00000059, 0x461c4000, 0x0006002c, 0x0000000c, 0x0000005a, - 0x00000059, 0x00000059, 0x00000059, 0x0004003b, 0x0000004e, 0x0000005c, 0x00000000, 0x00040020, - 0x00000063, 0x00000007, 0x00000051, 0x0004002b, 0x0000002f, 0x00000065, 0x00001000, 0x0004001c, - 0x00000066, 0x00000051, 0x00000065, 0x0003001e, 0x00000067, 0x00000066, 0x00040020, 0x00000068, - 0x00000002, 0x00000067, 0x0004003b, 0x00000068, 0x00000069, 0x00000002, 0x00040015, 0x0000006a, - 0x00000020, 0x00000001, 0x0004002b, 0x0000006a, 0x0000006b, 0x00000000, 0x00040020, 0x0000006c, - 0x00000002, 0x00000051, 0x0004001c, 0x00000070, 0x00000051, 0x00000065, 0x0003001e, 0x00000071, - 0x00000070, 0x00040020, 0x00000072, 0x00000002, 0x00000071, 0x0004003b, 0x00000072, 0x00000073, - 0x00000002, 0x0004002b, 0x0000002f, 0x00000077, 0x0000005a, 0x0004001c, 0x00000078, 0x00000051, - 0x00000077, 0x0004001e, 0x00000079, 0x00000078, 0x00000051, 0x00040020, 0x0000007a, 0x00000002, - 0x00000079, 0x0004003b, 0x0000007a, 0x0000007b, 0x00000002, 0x0004002b, 0x0000006a, 0x0000007c, - 0x00000001, 0x00040020, 0x0000007d, 0x00000002, 0x00000006, 0x0004002b, 0x00000006, 0x00000080, - 0x00000000, 0x0004002b, 0x00000006, 0x00000097, 0x3e99096c, 0x0006002c, 0x0000000c, 0x000000c5, - 0x00000080, 0x00000080, 0x00000080, 0x0004002b, 0x00000006, 0x000000d8, 0x3f2aaaab, 0x0006002c, - 0x0000000c, 0x00000108, 0x0000001f, 0x0000001f, 0x0000001f, 0x0004002b, 0x00000006, 0x0000013f, - 0x3e59b3d0, 0x0004002b, 0x00000006, 0x00000140, 0x3f371759, 0x0004002b, 0x00000006, 0x00000141, - 0x3d93dd98, 0x0006002c, 0x0000000c, 0x00000142, 0x0000013f, 0x00000140, 0x00000141, 0x0004002b, - 0x00000006, 0x0000014a, 0x3727c5ac, 0x0004002b, 0x00000006, 0x00000157, 0x3f000000, 0x0004002b, - 0x00000006, 0x00000158, 0x3fc00000, 0x00040020, 0x00000180, 0x00000003, 0x00000051, 0x0004003b, - 0x00000180, 0x00000181, 0x00000003, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, - 0x000200f8, 0x00000005, 0x0004003b, 0x0000000d, 0x0000004b, 0x00000007, 0x0004003b, 0x00000063, - 0x00000064, 0x00000007, 0x0004003b, 0x00000063, 0x0000006f, 0x00000007, 0x0004003b, 0x00000007, - 0x00000076, 0x00000007, 0x0004003b, 0x00000007, 0x00000082, 0x00000007, 0x0004003b, 0x00000007, - 0x00000089, 0x00000007, 0x0004003b, 0x00000007, 0x0000008d, 0x00000007, 0x0004003b, 0x00000007, - 0x00000094, 0x00000007, 0x0004003b, 0x00000007, 0x000000a6, 0x00000007, 0x0004003b, 0x0000000d, - 0x000000ab, 0x00000007, 0x0004003b, 0x0000000d, 0x000000ae, 0x00000007, 0x0004003b, 0x00000007, - 0x000000b2, 0x00000007, 0x0004003b, 0x0000000d, 0x000000bb, 0x00000007, 0x0004003b, 0x0000000d, - 0x000000bd, 0x00000007, 0x0004003b, 0x00000007, 0x000000c7, 0x00000007, 0x0004003b, 0x0000000d, - 0x000000c8, 0x00000007, 0x0004003b, 0x0000000d, 0x000000cc, 0x00000007, 0x0004003b, 0x00000007, - 0x000000d1, 0x00000007, 0x0004003b, 0x0000000d, 0x000000d2, 0x00000007, 0x0004003b, 0x00000007, - 0x000000d5, 0x00000007, 0x0004003b, 0x00000007, 0x000000e4, 0x00000007, 0x0004003b, 0x0000000d, - 0x000000fa, 0x00000007, 0x0004003b, 0x0000000d, 0x000000fd, 0x00000007, 0x0004003b, 0x00000007, - 0x00000115, 0x00000007, 0x0004003b, 0x0000000d, 0x00000116, 0x00000007, 0x0004003b, 0x00000007, - 0x00000119, 0x00000007, 0x0004003b, 0x00000007, 0x00000139, 0x00000007, 0x0004003b, 0x00000007, - 0x0000013d, 0x00000007, 0x0004003b, 0x00000007, 0x00000144, 0x00000007, 0x0004003b, 0x0000000d, - 0x00000159, 0x00000007, 0x0004003b, 0x00000007, 0x00000160, 0x00000007, 0x0004003b, 0x0000000d, - 0x00000161, 0x00000007, 0x0004003b, 0x00000007, 0x00000164, 0x00000007, 0x0004003b, 0x00000007, - 0x0000016c, 0x00000007, 0x0004003d, 0x0000004d, 0x00000050, 0x0000004f, 0x0004003d, 0x00000051, - 0x00000055, 0x00000053, 0x0007004f, 0x00000054, 0x00000056, 0x00000055, 0x00000055, 0x00000000, - 0x00000001, 0x00050057, 0x00000051, 0x00000057, 0x00000050, 0x00000056, 0x0008004f, 0x0000000c, - 0x00000058, 0x00000057, 0x00000057, 0x00000000, 0x00000001, 0x00000002, 0x0007000c, 0x0000000c, - 0x0000005b, 0x00000001, 0x00000025, 0x00000058, 0x0000005a, 0x0004003d, 0x0000004d, 0x0000005d, - 0x0000005c, 0x0004003d, 0x00000051, 0x0000005e, 0x00000053, 0x0007004f, 0x00000054, 0x0000005f, - 0x0000005e, 0x0000005e, 0x00000000, 0x00000001, 0x00050057, 0x00000051, 0x00000060, 0x0000005d, - 0x0000005f, 0x0008004f, 0x0000000c, 0x00000061, 0x00000060, 0x00000060, 0x00000000, 0x00000001, - 0x00000002, 0x00050081, 0x0000000c, 0x00000062, 0x0000005b, 0x00000061, 0x0003003e, 0x0000004b, - 0x00000062, 0x00060041, 0x0000006c, 0x0000006d, 0x00000069, 0x0000006b, 0x0000006b, 0x0004003d, - 0x00000051, 0x0000006e, 0x0000006d, 0x0003003e, 0x00000064, 0x0000006e, 0x00060041, 0x0000006c, - 0x00000074, 0x00000073, 0x0000006b, 0x0000006b, 0x0004003d, 0x00000051, 0x00000075, 0x00000074, - 0x0003003e, 0x0000006f, 0x00000075, 0x00060041, 0x0000007d, 0x0000007e, 0x0000007b, 0x0000007c, - 0x00000030, 0x0004003d, 0x00000006, 0x0000007f, 0x0000007e, 0x000500ba, 0x0000001a, 0x00000081, - 0x0000007f, 0x00000080, 0x000300f7, 0x00000084, 0x00000000, 0x000400fa, 0x00000081, 0x00000083, - 0x00000087, 0x000200f8, 0x00000083, 0x00060041, 0x0000007d, 0x00000085, 0x0000007b, 0x0000007c, - 0x00000030, 0x0004003d, 0x00000006, 0x00000086, 0x00000085, 0x0003003e, 0x00000082, 0x00000086, - 0x000200f9, 0x00000084, 0x000200f8, 0x00000087, 0x0003003e, 0x00000082, 0x0000001f, 0x000200f9, - 0x00000084, 0x000200f8, 0x00000084, 0x0004003d, 0x00000006, 0x00000088, 0x00000082, 0x0003003e, - 0x00000076, 0x00000088, 0x00060041, 0x0000007d, 0x0000008a, 0x0000007b, 0x0000007c, 0x00000035, - 0x0004003d, 0x00000006, 0x0000008b, 0x0000008a, 0x000500ba, 0x0000001a, 0x0000008c, 0x0000008b, - 0x0000001f, 0x000300f7, 0x0000008f, 0x00000000, 0x000400fa, 0x0000008c, 0x0000008e, 0x00000092, - 0x000200f8, 0x0000008e, 0x00060041, 0x0000007d, 0x00000090, 0x0000007b, 0x0000007c, 0x00000035, - 0x0004003d, 0x00000006, 0x00000091, 0x00000090, 0x0003003e, 0x0000008d, 0x00000091, 0x000200f9, - 0x0000008f, 0x000200f8, 0x00000092, 0x0003003e, 0x0000008d, 0x0000001f, 0x000200f9, 0x0000008f, - 0x000200f8, 0x0000008f, 0x0004003d, 0x00000006, 0x00000093, 0x0000008d, 0x0003003e, 0x00000089, - 0x00000093, 0x00050041, 0x00000007, 0x00000095, 0x0000004b, 0x00000030, 0x0004003d, 0x00000006, - 0x00000096, 0x00000095, 0x00050085, 0x00000006, 0x00000098, 0x00000096, 0x00000097, 0x00050041, - 0x00000007, 0x00000099, 0x0000004b, 0x00000035, 0x0004003d, 0x00000006, 0x0000009a, 0x00000099, - 0x00050041, 0x00000007, 0x0000009b, 0x00000064, 0x00000030, 0x0004003d, 0x00000006, 0x0000009c, - 0x0000009b, 0x00050085, 0x00000006, 0x0000009d, 0x0000009a, 0x0000009c, 0x00050081, 0x00000006, - 0x0000009e, 0x00000098, 0x0000009d, 0x00050041, 0x00000007, 0x0000009f, 0x0000004b, 0x0000003a, - 0x0004003d, 0x00000006, 0x000000a0, 0x0000009f, 0x00050041, 0x00000007, 0x000000a1, 0x00000064, - 0x00000035, 0x0004003d, 0x00000006, 0x000000a2, 0x000000a1, 0x00050085, 0x00000006, 0x000000a3, - 0x000000a0, 0x000000a2, 0x00050081, 0x00000006, 0x000000a4, 0x0000009e, 0x000000a3, 0x0007000c, - 0x00000006, 0x000000a5, 0x00000001, 0x00000028, 0x000000a4, 0x00000080, 0x0003003e, 0x00000094, - 0x000000a5, 0x0004003d, 0x00000006, 0x000000a7, 0x00000094, 0x0004007f, 0x00000006, 0x000000a8, - 0x000000a7, 0x0006000c, 0x00000006, 0x000000a9, 0x00000001, 0x0000001b, 0x000000a8, 0x00050083, - 0x00000006, 0x000000aa, 0x0000001f, 0x000000a9, 0x0003003e, 0x000000a6, 0x000000aa, 0x0004003d, - 0x00000006, 0x000000ac, 0x00000094, 0x000500ba, 0x0000001a, 0x000000ad, 0x000000ac, 0x00000080, - 0x000300f7, 0x000000b0, 0x00000000, 0x000400fa, 0x000000ad, 0x000000af, 0x000000b8, 0x000200f8, - 0x000000af, 0x0004003d, 0x0000000c, 0x000000b1, 0x0000004b, 0x0004003d, 0x00000006, 0x000000b3, - 0x00000094, 0x0003003e, 0x000000b2, 0x000000b3, 0x00050039, 0x00000006, 0x000000b4, 0x0000000a, - 0x000000b2, 0x0004003d, 0x00000006, 0x000000b5, 0x00000094, 0x00050088, 0x00000006, 0x000000b6, - 0x000000b4, 0x000000b5, 0x0005008e, 0x0000000c, 0x000000b7, 0x000000b1, 0x000000b6, 0x0003003e, - 0x000000ae, 0x000000b7, 0x000200f9, 0x000000b0, 0x000200f8, 0x000000b8, 0x0004003d, 0x0000000c, - 0x000000b9, 0x0000004b, 0x0003003e, 0x000000ae, 0x000000b9, 0x000200f9, 0x000000b0, 0x000200f8, - 0x000000b0, 0x0004003d, 0x0000000c, 0x000000ba, 0x000000ae, 0x0003003e, 0x000000ab, 0x000000ba, - 0x0004003d, 0x0000000c, 0x000000bc, 0x000000ab, 0x0004003d, 0x0000000c, 0x000000be, 0x0000004b, - 0x0003003e, 0x000000bd, 0x000000be, 0x00050039, 0x0000000c, 0x000000bf, 0x00000010, 0x000000bd, - 0x0004003d, 0x00000006, 0x000000c0, 0x000000a6, 0x0004003d, 0x00000006, 0x000000c1, 0x000000a6, - 0x00050085, 0x00000006, 0x000000c2, 0x000000c0, 0x000000c1, 0x00060050, 0x0000000c, 0x000000c3, - 0x000000c2, 0x000000c2, 0x000000c2, 0x0008000c, 0x0000000c, 0x000000c4, 0x00000001, 0x0000002e, - 0x000000bc, 0x000000bf, 0x000000c3, 0x0007000c, 0x0000000c, 0x000000c6, 0x00000001, 0x00000028, - 0x000000c4, 0x000000c5, 0x0003003e, 0x000000bb, 0x000000c6, 0x0004003d, 0x0000000c, 0x000000c9, - 0x000000bb, 0x0003003e, 0x000000c8, 0x000000c9, 0x00050039, 0x00000006, 0x000000ca, 0x00000014, - 0x000000c8, 0x0007000c, 0x00000006, 0x000000cb, 0x00000001, 0x00000028, 0x000000ca, 0x0000001f, - 0x0003003e, 0x000000c7, 0x000000cb, 0x0004003d, 0x0000000c, 0x000000cd, 0x000000bb, 0x0004003d, - 0x00000006, 0x000000ce, 0x000000c7, 0x00060050, 0x0000000c, 0x000000cf, 0x000000ce, 0x000000ce, - 0x000000ce, 0x00050088, 0x0000000c, 0x000000d0, 0x000000cd, 0x000000cf, 0x0003003e, 0x000000cc, - 0x000000d0, 0x0004003d, 0x0000000c, 0x000000d3, 0x000000cc, 0x0003003e, 0x000000d2, 0x000000d3, - 0x00050039, 0x00000006, 0x000000d4, 0x00000014, 0x000000d2, 0x0003003e, 0x000000d1, 0x000000d4, - 0x00050041, 0x00000007, 0x000000d6, 0x000000cc, 0x00000030, 0x0004003d, 0x00000006, 0x000000d7, - 0x000000d6, 0x00050085, 0x00000006, 0x000000d9, 0x000000d7, 0x000000d8, 0x00050041, 0x00000007, - 0x000000da, 0x000000cc, 0x00000035, 0x0004003d, 0x00000006, 0x000000db, 0x000000da, 0x00050041, - 0x00000007, 0x000000dc, 0x000000cc, 0x0000003a, 0x0004003d, 0x00000006, 0x000000dd, 0x000000dc, - 0x00050081, 0x00000006, 0x000000de, 0x000000db, 0x000000dd, 0x00050041, 0x00000007, 0x000000df, - 0x00000064, 0x0000003a, 0x0004003d, 0x00000006, 0x000000e0, 0x000000df, 0x00050085, 0x00000006, - 0x000000e1, 0x000000de, 0x000000e0, 0x00050081, 0x00000006, 0x000000e2, 0x000000d9, 0x000000e1, - 0x00050083, 0x00000006, 0x000000e3, 0x000000e2, 0x0000001f, 0x0003003e, 0x000000d5, 0x000000e3, - 0x00050041, 0x00000007, 0x000000e5, 0x0000006f, 0x00000035, 0x0004003d, 0x00000006, 0x000000e6, - 0x000000e5, 0x0004003d, 0x00000006, 0x000000e7, 0x000000d5, 0x0004003d, 0x00000006, 0x000000e8, - 0x000000d5, 0x00050085, 0x00000006, 0x000000e9, 0x000000e7, 0x000000e8, 0x00050083, 0x00000006, - 0x000000ea, 0x0000001f, 0x000000e9, 0x00050085, 0x00000006, 0x000000eb, 0x000000e6, 0x000000ea, - 0x00050041, 0x00000007, 0x000000ec, 0x0000006f, 0x00000030, 0x0004003d, 0x00000006, 0x000000ed, - 0x000000ec, 0x00050081, 0x00000006, 0x000000ee, 0x000000eb, 0x000000ed, 0x0003003e, 0x000000e4, - 0x000000ee, 0x0004003d, 0x00000006, 0x000000ef, 0x000000c7, 0x0004003d, 0x0000000c, 0x000000f0, - 0x000000cc, 0x0004003d, 0x00000006, 0x000000f1, 0x000000d1, 0x00060050, 0x0000000c, 0x000000f2, - 0x000000f1, 0x000000f1, 0x000000f1, 0x00050083, 0x0000000c, 0x000000f3, 0x000000f0, 0x000000f2, - 0x0004003d, 0x00000006, 0x000000f4, 0x000000e4, 0x0005008e, 0x0000000c, 0x000000f5, 0x000000f3, - 0x000000f4, 0x0004003d, 0x00000006, 0x000000f6, 0x000000d1, 0x00060050, 0x0000000c, 0x000000f7, - 0x000000f6, 0x000000f6, 0x000000f6, 0x00050081, 0x0000000c, 0x000000f8, 0x000000f5, 0x000000f7, - 0x0005008e, 0x0000000c, 0x000000f9, 0x000000f8, 0x000000ef, 0x0003003e, 0x000000bb, 0x000000f9, - 0x0004003d, 0x00000006, 0x000000fb, 0x00000094, 0x000500ba, 0x0000001a, 0x000000fc, 0x000000fb, - 0x00000080, 0x000300f7, 0x000000ff, 0x00000000, 0x000400fa, 0x000000fc, 0x000000fe, 0x00000105, - 0x000200f8, 0x000000fe, 0x0004003d, 0x0000000c, 0x00000100, 0x0000004b, 0x0004003d, 0x00000006, - 0x00000101, 0x000000a6, 0x0004003d, 0x00000006, 0x00000102, 0x00000094, 0x00050088, 0x00000006, - 0x00000103, 0x00000101, 0x00000102, 0x0005008e, 0x0000000c, 0x00000104, 0x00000100, 0x00000103, - 0x0003003e, 0x000000fd, 0x00000104, 0x000200f9, 0x000000ff, 0x000200f8, 0x00000105, 0x0004003d, - 0x0000000c, 0x00000106, 0x0000004b, 0x0003003e, 0x000000fd, 0x00000106, 0x000200f9, 0x000000ff, - 0x000200f8, 0x000000ff, 0x0004003d, 0x0000000c, 0x00000107, 0x000000fd, 0x0004003d, 0x0000000c, - 0x00000109, 0x0000004b, 0x0004007f, 0x0000000c, 0x0000010a, 0x00000109, 0x0006000c, 0x0000000c, - 0x0000010b, 0x00000001, 0x0000001b, 0x0000010a, 0x00050083, 0x0000000c, 0x0000010c, 0x00000108, - 0x0000010b, 0x0004003d, 0x00000006, 0x0000010d, 0x000000a6, 0x0004003d, 0x00000006, 0x0000010e, - 0x000000a6, 0x00050085, 0x00000006, 0x0000010f, 0x0000010d, 0x0000010e, 0x00060050, 0x0000000c, - 0x00000110, 0x0000010f, 0x0000010f, 0x0000010f, 0x0008000c, 0x0000000c, 0x00000111, 0x00000001, - 0x0000002e, 0x00000107, 0x0000010c, 0x00000110, 0x00060050, 0x0000000c, 0x00000112, 0x00000080, - 0x00000080, 0x00000080, 0x00060050, 0x0000000c, 0x00000113, 0x0000001f, 0x0000001f, 0x0000001f, - 0x0008000c, 0x0000000c, 0x00000114, 0x00000001, 0x0000002b, 0x00000111, 0x00000112, 0x00000113, - 0x0003003e, 0x000000fa, 0x00000114, 0x0004003d, 0x0000000c, 0x00000117, 0x000000fa, 0x0003003e, - 0x00000116, 0x00000117, 0x00050039, 0x00000006, 0x00000118, 0x00000014, 0x00000116, 0x0003003e, - 0x00000115, 0x00000118, 0x00050041, 0x00000007, 0x0000011a, 0x000000fa, 0x00000030, 0x0004003d, - 0x00000006, 0x0000011b, 0x0000011a, 0x00050085, 0x00000006, 0x0000011c, 0x0000011b, 0x000000d8, - 0x00050041, 0x00000007, 0x0000011d, 0x000000fa, 0x00000035, 0x0004003d, 0x00000006, 0x0000011e, - 0x0000011d, 0x00050041, 0x00000007, 0x0000011f, 0x000000fa, 0x0000003a, 0x0004003d, 0x00000006, - 0x00000120, 0x0000011f, 0x00050081, 0x00000006, 0x00000121, 0x0000011e, 0x00000120, 0x00050041, - 0x00000007, 0x00000122, 0x00000064, 0x0000003a, 0x0004003d, 0x00000006, 0x00000123, 0x00000122, - 0x00050085, 0x00000006, 0x00000124, 0x00000121, 0x00000123, 0x00050081, 0x00000006, 0x00000125, - 0x0000011c, 0x00000124, 0x00050083, 0x00000006, 0x00000126, 0x00000125, 0x0000001f, 0x0003003e, - 0x00000119, 0x00000126, 0x0004003d, 0x0000000c, 0x00000127, 0x000000fa, 0x0004003d, 0x00000006, - 0x00000128, 0x00000115, 0x00060050, 0x0000000c, 0x00000129, 0x00000128, 0x00000128, 0x00000128, - 0x00050083, 0x0000000c, 0x0000012a, 0x00000127, 0x00000129, 0x00050041, 0x00000007, 0x0000012b, - 0x0000006f, 0x00000035, 0x0004003d, 0x00000006, 0x0000012c, 0x0000012b, 0x0004003d, 0x00000006, - 0x0000012d, 0x00000119, 0x0004003d, 0x00000006, 0x0000012e, 0x00000119, 0x00050085, 0x00000006, - 0x0000012f, 0x0000012d, 0x0000012e, 0x00050083, 0x00000006, 0x00000130, 0x0000001f, 0x0000012f, - 0x00050085, 0x00000006, 0x00000131, 0x0000012c, 0x00000130, 0x00050041, 0x00000007, 0x00000132, - 0x0000006f, 0x00000030, 0x0004003d, 0x00000006, 0x00000133, 0x00000132, 0x00050081, 0x00000006, - 0x00000134, 0x00000131, 0x00000133, 0x0005008e, 0x0000000c, 0x00000135, 0x0000012a, 0x00000134, - 0x0004003d, 0x00000006, 0x00000136, 0x00000115, 0x00060050, 0x0000000c, 0x00000137, 0x00000136, - 0x00000136, 0x00000136, 0x00050081, 0x0000000c, 0x00000138, 0x00000135, 0x00000137, 0x0003003e, - 0x000000fa, 0x00000138, 0x00060041, 0x0000007d, 0x0000013a, 0x0000007b, 0x0000007c, 0x0000003a, - 0x0004003d, 0x00000006, 0x0000013b, 0x0000013a, 0x0008000c, 0x00000006, 0x0000013c, 0x00000001, - 0x0000002b, 0x0000013b, 0x00000080, 0x0000001f, 0x0003003e, 0x00000139, 0x0000013c, 0x0004003d, - 0x0000000c, 0x0000013e, 0x000000bb, 0x00050094, 0x00000006, 0x00000143, 0x0000013e, 0x00000142, - 0x0003003e, 0x0000013d, 0x00000143, 0x0004003d, 0x0000000c, 0x00000145, 0x000000fa, 0x00050094, - 0x00000006, 0x00000146, 0x00000145, 0x00000142, 0x0003003e, 0x00000144, 0x00000146, 0x0004003d, - 0x00000006, 0x00000147, 0x00000139, 0x000500ba, 0x0000001a, 0x00000148, 0x00000147, 0x00000080, - 0x0004003d, 0x00000006, 0x00000149, 0x00000144, 0x000500ba, 0x0000001a, 0x0000014b, 0x00000149, - 0x0000014a, 0x000500a7, 0x0000001a, 0x0000014c, 0x00000148, 0x0000014b, 0x000300f7, 0x0000014e, - 0x00000000, 0x000400fa, 0x0000014c, 0x0000014d, 0x0000014e, 0x000200f8, 0x0000014d, 0x0004003d, - 0x0000000c, 0x0000014f, 0x000000bb, 0x0004003d, 0x0000000c, 0x00000150, 0x000000fa, 0x0007000c, - 0x0000000c, 0x00000151, 0x00000001, 0x00000028, 0x00000150, 0x000000c5, 0x0004003d, 0x00000006, - 0x00000152, 0x0000013d, 0x0004003d, 0x00000006, 0x00000153, 0x00000144, 0x00050088, 0x00000006, - 0x00000154, 0x00000152, 0x00000153, 0x0005008e, 0x0000000c, 0x00000155, 0x00000151, 0x00000154, - 0x0004003d, 0x00000006, 0x00000156, 0x00000139, 0x0004003d, 0x0000000c, 0x0000015a, 0x000000bb, - 0x0003003e, 0x00000159, 0x0000015a, 0x00050039, 0x00000006, 0x0000015b, 0x00000014, 0x00000159, - 0x0008000c, 0x00000006, 0x0000015c, 0x00000001, 0x00000031, 0x00000157, 0x00000158, 0x0000015b, - 0x00050085, 0x00000006, 0x0000015d, 0x00000156, 0x0000015c, 0x00060050, 0x0000000c, 0x0000015e, - 0x0000015d, 0x0000015d, 0x0000015d, 0x0008000c, 0x0000000c, 0x0000015f, 0x00000001, 0x0000002e, - 0x0000014f, 0x00000155, 0x0000015e, 0x0003003e, 0x000000bb, 0x0000015f, 0x000200f9, 0x0000014e, - 0x000200f8, 0x0000014e, 0x0004003d, 0x0000000c, 0x00000162, 0x000000bb, 0x0003003e, 0x00000161, - 0x00000162, 0x00050039, 0x00000006, 0x00000163, 0x00000014, 0x00000161, 0x0003003e, 0x00000160, - 0x00000163, 0x0004003d, 0x00000006, 0x00000165, 0x00000089, 0x00050085, 0x00000006, 0x00000166, - 0x00000157, 0x00000165, 0x0003003e, 0x00000164, 0x00000166, 0x0004003d, 0x00000006, 0x00000167, - 0x00000160, 0x0004003d, 0x00000006, 0x00000168, 0x00000164, 0x000500ba, 0x0000001a, 0x00000169, - 0x00000167, 0x00000168, 0x000300f7, 0x0000016b, 0x00000000, 0x000400fa, 0x00000169, 0x0000016a, - 0x0000016b, 0x000200f8, 0x0000016a, 0x0004003d, 0x00000006, 0x0000016d, 0x00000089, 0x0004003d, - 0x00000006, 0x0000016e, 0x00000164, 0x00050083, 0x00000006, 0x0000016f, 0x0000016d, 0x0000016e, - 0x0003003e, 0x0000016c, 0x0000016f, 0x0004003d, 0x00000006, 0x00000170, 0x00000164, 0x0004003d, - 0x00000006, 0x00000171, 0x0000016c, 0x0004003d, 0x00000006, 0x00000172, 0x00000160, 0x0004003d, - 0x00000006, 0x00000173, 0x00000164, 0x00050083, 0x00000006, 0x00000174, 0x00000172, 0x00000173, - 0x0004007f, 0x00000006, 0x00000175, 0x00000174, 0x0004003d, 0x00000006, 0x00000176, 0x0000016c, - 0x00050088, 0x00000006, 0x00000177, 0x00000175, 0x00000176, 0x0006000c, 0x00000006, 0x00000178, - 0x00000001, 0x0000001b, 0x00000177, 0x00050083, 0x00000006, 0x00000179, 0x0000001f, 0x00000178, - 0x00050085, 0x00000006, 0x0000017a, 0x00000171, 0x00000179, 0x00050081, 0x00000006, 0x0000017b, - 0x00000170, 0x0000017a, 0x0004003d, 0x00000006, 0x0000017c, 0x00000160, 0x00050088, 0x00000006, - 0x0000017d, 0x0000017b, 0x0000017c, 0x0004003d, 0x0000000c, 0x0000017e, 0x000000bb, 0x0005008e, - 0x0000000c, 0x0000017f, 0x0000017e, 0x0000017d, 0x0003003e, 0x000000bb, 0x0000017f, 0x000200f9, - 0x0000016b, 0x000200f8, 0x0000016b, 0x0004003d, 0x0000000c, 0x00000182, 0x000000bb, 0x0007000c, - 0x0000000c, 0x00000183, 0x00000001, 0x00000028, 0x00000182, 0x000000c5, 0x0004003d, 0x00000006, - 0x00000184, 0x00000076, 0x0005008e, 0x0000000c, 0x00000185, 0x00000183, 0x00000184, 0x00050051, - 0x00000006, 0x00000186, 0x00000185, 0x00000000, 0x00050051, 0x00000006, 0x00000187, 0x00000185, - 0x00000001, 0x00050051, 0x00000006, 0x00000188, 0x00000185, 0x00000002, 0x00070050, 0x00000051, - 0x00000189, 0x00000186, 0x00000187, 0x00000188, 0x00000080, 0x0003003e, 0x00000181, 0x00000189, - 0x000100fd, 0x00010038, 0x00050036, 0x00000006, 0x0000000a, 0x00000000, 0x00000008, 0x00030037, - 0x00000007, 0x00000009, 0x000200f8, 0x0000000b, 0x0004003b, 0x00000007, 0x00000016, 0x00000007, - 0x0004003b, 0x00000007, 0x0000001c, 0x00000007, 0x0003003e, 0x00000016, 0x00000017, 0x0004003d, - 0x00000006, 0x00000018, 0x00000009, 0x000500bc, 0x0000001a, 0x0000001b, 0x00000018, 0x00000019, - 0x000300f7, 0x0000001e, 0x00000000, 0x000400fa, 0x0000001b, 0x0000001d, 0x00000024, 0x000200f8, - 0x0000001d, 0x0004003d, 0x00000006, 0x00000020, 0x00000009, 0x0004007f, 0x00000006, 0x00000021, - 0x00000020, 0x0006000c, 0x00000006, 0x00000022, 0x00000001, 0x0000001b, 0x00000021, 0x00050083, - 0x00000006, 0x00000023, 0x0000001f, 0x00000022, 0x0003003e, 0x0000001c, 0x00000023, 0x000200f9, - 0x0000001e, 0x000200f8, 0x00000024, 0x0004003d, 0x00000006, 0x00000025, 0x00000016, 0x0004003d, - 0x00000006, 0x00000027, 0x00000009, 0x00050083, 0x00000006, 0x00000028, 0x00000027, 0x00000019, - 0x00050085, 0x00000006, 0x00000029, 0x00000026, 0x00000028, 0x00050081, 0x00000006, 0x0000002a, - 0x00000025, 0x00000029, 0x0003003e, 0x0000001c, 0x0000002a, 0x000200f9, 0x0000001e, 0x000200f8, - 0x0000001e, 0x0004003d, 0x00000006, 0x0000002b, 0x0000001c, 0x000200fe, 0x0000002b, 0x00010038, - 0x00050036, 0x0000000c, 0x00000010, 0x00000000, 0x0000000e, 0x00030037, 0x0000000d, 0x0000000f, - 0x000200f8, 0x00000011, 0x0004003b, 0x00000007, 0x0000002e, 0x00000007, 0x0004003b, 0x00000007, - 0x00000034, 0x00000007, 0x0004003b, 0x00000007, 0x00000039, 0x00000007, 0x00050041, 0x00000007, - 0x00000031, 0x0000000f, 0x00000030, 0x0004003d, 0x00000006, 0x00000032, 0x00000031, 0x0003003e, - 0x0000002e, 0x00000032, 0x00050039, 0x00000006, 0x00000033, 0x0000000a, 0x0000002e, 0x00050041, - 0x00000007, 0x00000036, 0x0000000f, 0x00000035, 0x0004003d, 0x00000006, 0x00000037, 0x00000036, - 0x0003003e, 0x00000034, 0x00000037, 0x00050039, 0x00000006, 0x00000038, 0x0000000a, 0x00000034, - 0x00050041, 0x00000007, 0x0000003b, 0x0000000f, 0x0000003a, 0x0004003d, 0x00000006, 0x0000003c, - 0x0000003b, 0x0003003e, 0x00000039, 0x0000003c, 0x00050039, 0x00000006, 0x0000003d, 0x0000000a, - 0x00000039, 0x00060050, 0x0000000c, 0x0000003e, 0x00000033, 0x00000038, 0x0000003d, 0x000200fe, - 0x0000003e, 0x00010038, 0x00050036, 0x00000006, 0x00000014, 0x00000000, 0x00000012, 0x00030037, - 0x0000000d, 0x00000013, 0x000200f8, 0x00000015, 0x00050041, 0x00000007, 0x00000041, 0x00000013, - 0x00000030, 0x0004003d, 0x00000006, 0x00000042, 0x00000041, 0x00050041, 0x00000007, 0x00000043, - 0x00000013, 0x00000035, 0x0004003d, 0x00000006, 0x00000044, 0x00000043, 0x00050041, 0x00000007, - 0x00000045, 0x00000013, 0x0000003a, 0x0004003d, 0x00000006, 0x00000046, 0x00000045, 0x0007000c, - 0x00000006, 0x00000047, 0x00000001, 0x00000028, 0x00000044, 0x00000046, 0x0007000c, 0x00000006, - 0x00000048, 0x00000001, 0x00000028, 0x00000042, 0x00000047, 0x000200fe, 0x00000048, 0x00010038, + 0x000b000f, 0x00000004, 0x00000004, 0x6e69616d, 0x00000000, 0x0000042c, 0x0000042e, 0x0000042f, + 0x00000430, 0x00000431, 0x00000432, 0x00030010, 0x00000004, 0x00000007, 0x00030003, 0x00000002, + 0x000001c2, 0x000a0004, 0x475f4c47, 0x4c474f4f, 0x70635f45, 0x74735f70, 0x5f656c79, 0x656e696c, + 0x7269645f, 0x69746365, 0x00006576, 0x00080004, 0x475f4c47, 0x4c474f4f, 0x6e695f45, 0x64756c63, + 0x69645f65, 0x74636572, 0x00657669, 0x00040005, 0x00000004, 0x6e69616d, 0x00000000, 0x00060005, + 0x0000000e, 0x6d6c756d, 0x33666d28, 0x66763b33, 0x00003b33, 0x00030005, 0x0000000c, 0x0000006d, + 0x00030005, 0x0000000d, 0x00000076, 0x00050005, 0x00000012, 0x39303779, 0x33667628, 0x0000003b, + 0x00030005, 0x00000011, 0x00000063, 0x00080005, 0x00000019, 0x69766964, 0x735f6564, 0x28656661, + 0x663b3166, 0x31663b31, 0x0000003b, 0x00030005, 0x00000016, 0x00000061, 0x00030005, 0x00000017, + 0x00000062, 0x00050005, 0x00000018, 0x6c6c6166, 0x6b636162, 0x00000000, 0x00070005, 0x0000001e, + 0x79706f63, 0x6769735f, 0x6676286e, 0x66763b33, 0x00003b33, 0x00030005, 0x0000001c, 0x0067616d, + 0x00030005, 0x0000001d, 0x00000073, 0x00050005, 0x00000022, 0x74726263, 0x33667628, 0x0000003b, + 0x00030005, 0x00000021, 0x00000078, 0x00080005, 0x00000025, 0x616c6b6f, 0x72665f62, 0x625f6d6f, + 0x39303774, 0x33667628, 0x0000003b, 0x00030005, 0x00000024, 0x00000063, 0x00080005, 0x00000028, + 0x30377462, 0x72665f39, 0x6f5f6d6f, 0x62616c6b, 0x33667628, 0x0000003b, 0x00030005, 0x00000027, + 0x0062616c, 0x00060005, 0x0000002b, 0x6d616c63, 0x70615f70, 0x66762831, 0x00003b33, 0x00030005, + 0x0000002a, 0x00000063, 0x00070005, 0x0000002f, 0x5f657568, 0x616c6b6f, 0x66762862, 0x66763b33, + 0x00003b33, 0x00050005, 0x0000002d, 0x6f636e69, 0x63657272, 0x00000074, 0x00040005, 0x0000002e, + 0x72726f63, 0x00746365, 0x00060005, 0x00000033, 0x62677273, 0x6365645f, 0x2865646f, 0x003b3166, + 0x00030005, 0x00000032, 0x00000063, 0x00080005, 0x00000038, 0x6d6d6167, 0x6f745f61, 0x6772735f, + 0x31662862, 0x3b31663b, 0x00000000, 0x00030005, 0x00000036, 0x00000063, 0x00030005, 0x00000037, + 0x00000067, 0x00060005, 0x0000003b, 0x6f6f6d73, 0x72656874, 0x3b316628, 0x00000000, 0x00030005, + 0x0000003a, 0x00000074, 0x00080005, 0x00000040, 0x68676968, 0x6867696c, 0x66287374, 0x31663b31, + 0x3b31663b, 0x00000000, 0x00030005, 0x0000003d, 0x00000078, 0x00030005, 0x0000003e, 0x00000068, + 0x00030005, 0x0000003f, 0x0064696d, 0x00070005, 0x00000045, 0x64616873, 0x2873776f, 0x663b3166, + 0x31663b31, 0x0000003b, 0x00030005, 0x00000042, 0x00000078, 0x00030005, 0x00000043, 0x00000073, + 0x00030005, 0x00000044, 0x0064696d, 0x00080005, 0x0000004d, 0x76727563, 0x31662865, 0x3b31663b, + 0x663b3166, 0x31663b31, 0x0000003b, 0x00030005, 0x00000048, 0x00000078, 0x00030005, 0x00000049, + 0x0000006e, 0x00030005, 0x0000004a, 0x00000067, 0x00030005, 0x0000004b, 0x00645f63, 0x00030005, + 0x0000004c, 0x00315f74, 0x00030005, 0x00000050, 0x00747244, 0x00060006, 0x00000050, 0x00000000, + 0x7374696e, 0x6165705f, 0x0000006b, 0x00060006, 0x00000050, 0x00000001, 0x6f707865, 0x65727573, + 0x00000000, 0x00060006, 0x00000050, 0x00000002, 0x68676968, 0x6867696c, 0x00007374, 0x00050006, + 0x00000050, 0x00000003, 0x64616873, 0x0073776f, 0x00060006, 0x00000050, 0x00000004, 0x746e6f63, + 0x74736172, 0x00000000, 0x00060006, 0x00000050, 0x00000005, 0x75746173, 0x69746172, 0x00006e6f, + 0x00060006, 0x00000050, 0x00000006, 0x68636564, 0x616d6f72, 0x00000000, 0x00050006, 0x00000050, + 0x00000007, 0x72616c66, 0x00000065, 0x00040006, 0x00000050, 0x00000008, 0x00657568, 0x00050006, + 0x00000050, 0x00000009, 0x776f6c62, 0x0074756f, 0x00070006, 0x00000050, 0x0000000a, 0x5f64696d, + 0x79617267, 0x74696e5f, 0x00000073, 0x00060006, 0x00000050, 0x0000000b, 0x6d616c63, 0x657a5f70, + 0x00006f72, 0x00110005, 0x00000055, 0x28747264, 0x3b336676, 0x75727473, 0x442d7463, 0x662d7472, + 0x31662d31, 0x2d31662d, 0x662d3166, 0x31662d31, 0x2d31662d, 0x662d3166, 0x31662d31, 0x2d31662d, + 0x3b313162, 0x00000000, 0x00040005, 0x00000053, 0x30377462, 0x00000039, 0x00030005, 0x00000054, + 0x00000064, 0x00070005, 0x00000058, 0x7475656e, 0x5f6c6172, 0x28726473, 0x3b336676, 0x00000000, + 0x00030005, 0x00000057, 0x00000063, 0x00080005, 0x0000005f, 0x72677075, 0x28656461, 0x3b336676, + 0x3b336676, 0x3b336676, 0x003b3166, 0x00060005, 0x0000005b, 0x6f746e75, 0x616d656e, 0x64657070, + 0x00000000, 0x00040005, 0x0000005c, 0x7475656e, 0x006c6172, 0x00040005, 0x0000005d, 0x64617267, + 0x00006465, 0x00050005, 0x0000005e, 0x65727473, 0x6874676e, 0x00000000, 0x00070005, 0x00000062, + 0x73656361, 0x7469665f, 0x28646574, 0x3b336676, 0x00000000, 0x00030005, 0x00000061, 0x00000078, + 0x000a0005, 0x0000006c, 0x745f786e, 0x6d656e6f, 0x76287061, 0x763b3366, 0x763b3466, 0x763b3466, + 0x763b3466, 0x003b3466, 0x00030005, 0x00000067, 0x00000078, 0x00030005, 0x00000068, 0x00003070, + 0x00030005, 0x00000069, 0x00003170, 0x00030005, 0x0000006a, 0x00003270, 0x00030005, 0x0000006b, + 0x00003370, 0x00030005, 0x00000089, 0x00000061, 0x00040005, 0x0000009b, 0x61726170, 0x0000006d, + 0x00040005, 0x0000009c, 0x61726170, 0x0000006d, 0x00040005, 0x000000bb, 0x61726170, 0x0000006d, + 0x00040005, 0x000000bc, 0x61726170, 0x0000006d, 0x00040005, 0x000000bf, 0x61726170, 0x0000006d, + 0x00040005, 0x000000c1, 0x61726170, 0x0000006d, 0x00040005, 0x000000c2, 0x61726170, 0x0000006d, + 0x00030005, 0x000000c6, 0x00736d6c, 0x00040005, 0x000000d2, 0x61726170, 0x0000006d, 0x00040005, + 0x000000d3, 0x61726170, 0x0000006d, 0x00040005, 0x000000e8, 0x61726170, 0x0000006d, 0x00040005, + 0x000000e9, 0x61726170, 0x0000006d, 0x00040005, 0x00000107, 0x61726170, 0x0000006d, 0x00040005, + 0x00000108, 0x61726170, 0x0000006d, 0x00040005, 0x0000010c, 0x61726170, 0x0000006d, 0x00040005, + 0x0000010d, 0x61726170, 0x0000006d, 0x00030005, 0x00000111, 0x00006c69, 0x00040005, 0x00000112, + 0x61726170, 0x0000006d, 0x00030005, 0x00000115, 0x00006c63, 0x00040005, 0x00000116, 0x61726170, + 0x0000006d, 0x00030005, 0x00000119, 0x00657270, 0x00030005, 0x0000011f, 0x00006261, 0x00040005, + 0x00000124, 0x61726170, 0x0000006d, 0x00040005, 0x00000126, 0x61726170, 0x0000006d, 0x00040005, + 0x00000127, 0x61726170, 0x0000006d, 0x00040005, 0x00000133, 0x61726170, 0x0000006d, 0x00040005, + 0x00000136, 0x61726170, 0x0000006d, 0x00040005, 0x00000152, 0x61726170, 0x0000006d, 0x00030005, + 0x0000016d, 0x00000074, 0x00040005, 0x0000017c, 0x61726170, 0x0000006d, 0x00030005, 0x0000018e, + 0x00000062, 0x00040005, 0x0000019f, 0x61726170, 0x0000006d, 0x00040005, 0x000001a0, 0x61726170, + 0x0000006d, 0x00040005, 0x000001a1, 0x61726170, 0x0000006d, 0x00040005, 0x000001ac, 0x69746172, + 0x0000006f, 0x00040005, 0x000001ad, 0x61726170, 0x0000006d, 0x00040005, 0x000001af, 0x61726170, + 0x0000006d, 0x00040005, 0x000001b1, 0x61726170, 0x0000006d, 0x00050005, 0x000001b4, 0x65736162, + 0x7265745f, 0x0000006d, 0x00050005, 0x000001b8, 0x65736162, 0x6163735f, 0x0000656c, 0x00040005, + 0x000001b9, 0x61726170, 0x0000006d, 0x00040005, 0x000001bb, 0x61726170, 0x0000006d, 0x00040005, + 0x000001bd, 0x61726170, 0x0000006d, 0x00060005, 0x000001bf, 0x64616873, 0x665f776f, 0x726f6f6c, + 0x00000000, 0x00030005, 0x000001c3, 0x00000074, 0x00040005, 0x000001d3, 0x61726170, 0x0000006d, + 0x00040005, 0x000001da, 0x73696172, 0x00006465, 0x00040005, 0x000001df, 0x61726170, 0x0000006d, + 0x00040005, 0x000001e1, 0x61726170, 0x0000006d, 0x00040005, 0x000001e2, 0x61726170, 0x0000006d, + 0x00040005, 0x000001f1, 0x65776f6c, 0x00646572, 0x00040005, 0x000001f7, 0x61726170, 0x0000006d, + 0x00040005, 0x000001f9, 0x61726170, 0x0000006d, 0x00040005, 0x000001fa, 0x61726170, 0x0000006d, + 0x00030005, 0x0000020a, 0x00305f6d, 0x00030005, 0x0000020e, 0x00315f6d, 0x00040005, 0x0000021b, + 0x69685f72, 0x00000074, 0x00030005, 0x00000223, 0x00000075, 0x00030005, 0x0000022e, 0x0000006d, + 0x00030005, 0x00000232, 0x00695f77, 0x00030005, 0x00000238, 0x00745f63, 0x00040005, 0x0000023f, + 0x70695f67, 0x00000000, 0x00040005, 0x0000024a, 0x70695f67, 0x00003270, 0x00030005, 0x0000025c, + 0x00325f77, 0x00030005, 0x00000260, 0x00325f73, 0x00030005, 0x00000264, 0x00325f75, 0x00030005, + 0x00000270, 0x00325f6d, 0x00030005, 0x00000274, 0x00007374, 0x00040005, 0x00000289, 0x6b616570, + 0x00000000, 0x00050005, 0x0000028f, 0x726f5f79, 0x6e696769, 0x00006c61, 0x00040005, 0x00000290, + 0x61726170, 0x0000006d, 0x00030005, 0x00000293, 0x00000079, 0x00040005, 0x0000029a, 0x61726170, + 0x0000006d, 0x00040005, 0x0000029c, 0x61726170, 0x0000006d, 0x00040005, 0x0000029f, 0x61726170, + 0x0000006d, 0x00040005, 0x000002a2, 0x61726170, 0x0000006d, 0x00040005, 0x000002a4, 0x61726170, + 0x0000006d, 0x00040005, 0x000002a7, 0x61726170, 0x0000006d, 0x00040005, 0x000002a9, 0x656e5f79, + 0x00000077, 0x00040005, 0x000002ad, 0x61726170, 0x0000006d, 0x00040005, 0x000002af, 0x61726170, + 0x0000006d, 0x00040005, 0x000002b2, 0x61726170, 0x0000006d, 0x00040005, 0x000002b5, 0x61726170, + 0x0000006d, 0x00040005, 0x000002b8, 0x61726170, 0x0000006d, 0x00040005, 0x000002be, 0x6f6c6f63, + 0x00000072, 0x00030005, 0x000002e9, 0x0062616c, 0x00040005, 0x000002ea, 0x61726170, 0x0000006d, + 0x00040005, 0x000002f2, 0x5f646c6f, 0x0062616c, 0x00040005, 0x000002f3, 0x61726170, 0x0000006d, + 0x00030005, 0x000002f6, 0x00657270, 0x00040005, 0x00000309, 0x61726170, 0x0000006d, 0x00040005, + 0x0000030b, 0x61726170, 0x0000006d, 0x00040005, 0x0000030c, 0x61726170, 0x0000006d, 0x00050005, + 0x0000032e, 0x63726570, 0x5f746e65, 0x0078616d, 0x00040005, 0x00000334, 0x6e616863, 0x00006567, + 0x00040005, 0x00000354, 0x61726170, 0x0000006d, 0x00030005, 0x00000365, 0x00000064, 0x00040005, + 0x00000369, 0x61726170, 0x0000006d, 0x00040005, 0x0000036b, 0x61726170, 0x0000006d, 0x00030005, + 0x00000370, 0x00007579, 0x00040005, 0x00000371, 0x61726170, 0x0000006d, 0x00030005, 0x00000374, + 0x00006e79, 0x00040005, 0x00000375, 0x61726170, 0x0000006d, 0x00030005, 0x00000378, 0x00006779, + 0x00040005, 0x00000379, 0x61726170, 0x0000006d, 0x00040005, 0x00000381, 0x69746172, 0x0000006f, + 0x00040005, 0x00000386, 0x656e5f79, 0x00000077, 0x00040005, 0x00000397, 0x6c616373, 0x00006465, + 0x00040005, 0x0000039b, 0x61726170, 0x0000006d, 0x00040005, 0x0000039c, 0x61726170, 0x0000006d, + 0x00040005, 0x000003bf, 0x696e6176, 0x00616c6c, 0x00040005, 0x000003c0, 0x61726170, 0x0000006d, + 0x00040005, 0x000003cb, 0x6f6c6f63, 0x00000072, 0x00040005, 0x000003d2, 0x64617267, 0x00006465, + 0x00040005, 0x000003db, 0x61726170, 0x0000006d, 0x00040005, 0x000003de, 0x61726170, 0x0000006d, + 0x00040005, 0x000003e0, 0x61726170, 0x0000006d, 0x00040005, 0x000003e1, 0x61726170, 0x0000006d, + 0x00040005, 0x000003e3, 0x61726170, 0x0000006d, 0x00040005, 0x000003e8, 0x6b616570, 0x00000000, + 0x00040005, 0x000003f9, 0x61726170, 0x0000006d, 0x00040005, 0x000003fb, 0x61726170, 0x0000006d, + 0x00030005, 0x000003fd, 0x00000064, 0x00040005, 0x00000419, 0x61726170, 0x0000006d, 0x00040005, + 0x0000041b, 0x61726170, 0x0000006d, 0x00030005, 0x0000042c, 0x0000006f, 0x00030005, 0x0000042e, + 0x00003061, 0x00030005, 0x0000042f, 0x00003161, 0x00030005, 0x00000430, 0x00003261, 0x00030005, + 0x00000431, 0x00003361, 0x00030005, 0x00000432, 0x00003461, 0x00040005, 0x00000433, 0x61726170, + 0x0000006d, 0x00040005, 0x00000436, 0x61726170, 0x0000006d, 0x00040005, 0x00000438, 0x61726170, + 0x0000006d, 0x00040005, 0x0000043a, 0x61726170, 0x0000006d, 0x00040005, 0x0000043c, 0x61726170, + 0x0000006d, 0x00040047, 0x0000042c, 0x0000001e, 0x00000000, 0x00040047, 0x0000042e, 0x0000001e, + 0x00000000, 0x00040047, 0x0000042f, 0x0000001e, 0x00000001, 0x00040047, 0x00000430, 0x0000001e, + 0x00000002, 0x00040047, 0x00000431, 0x0000001e, 0x00000003, 0x00040047, 0x00000432, 0x0000001e, + 0x00000004, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, + 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000003, 0x00040018, 0x00000008, 0x00000007, + 0x00000003, 0x00040020, 0x00000009, 0x00000007, 0x00000008, 0x00040020, 0x0000000a, 0x00000007, + 0x00000007, 0x00050021, 0x0000000b, 0x00000007, 0x00000009, 0x0000000a, 0x00040021, 0x00000010, + 0x00000006, 0x0000000a, 0x00040020, 0x00000014, 0x00000007, 0x00000006, 0x00060021, 0x00000015, + 0x00000006, 0x00000014, 0x00000014, 0x00000014, 0x00050021, 0x0000001b, 0x00000007, 0x0000000a, + 0x0000000a, 0x00040021, 0x00000020, 0x00000007, 0x0000000a, 0x00040021, 0x00000031, 0x00000006, + 0x00000014, 0x00050021, 0x00000035, 0x00000006, 0x00000014, 0x00000014, 0x00080021, 0x00000047, + 0x00000006, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00020014, 0x0000004f, + 0x000e001e, 0x00000050, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, + 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x0000004f, 0x00040020, 0x00000051, + 0x00000007, 0x00000050, 0x00050021, 0x00000052, 0x00000007, 0x0000000a, 0x00000051, 0x00070021, + 0x0000005a, 0x00000007, 0x0000000a, 0x0000000a, 0x0000000a, 0x00000014, 0x00040017, 0x00000064, + 0x00000006, 0x00000004, 0x00040020, 0x00000065, 0x00000007, 0x00000064, 0x00080021, 0x00000066, + 0x00000007, 0x0000000a, 0x00000065, 0x00000065, 0x00000065, 0x00000065, 0x0004002b, 0x00000006, + 0x00000074, 0x3e59be0a, 0x0004002b, 0x00000006, 0x00000075, 0x3f37154b, 0x0004002b, 0x00000006, + 0x00000076, 0x3d93d991, 0x0006002c, 0x00000007, 0x00000077, 0x00000074, 0x00000075, 0x00000076, + 0x0004002b, 0x00000006, 0x0000007c, 0x00000000, 0x0006002c, 0x00000007, 0x00000090, 0x0000007c, + 0x0000007c, 0x0000007c, 0x00040017, 0x00000091, 0x0000004f, 0x00000003, 0x0004002b, 0x00000006, + 0x00000098, 0x3eaaaaab, 0x0006002c, 0x00000007, 0x00000099, 0x00000098, 0x00000098, 0x00000098, + 0x0004002b, 0x00000006, 0x000000a1, 0x3e578152, 0x0004002b, 0x00000006, 0x000000a2, 0x3f4b2a89, + 0x0004002b, 0x00000006, 0x000000a3, 0xbb856ece, 0x0006002c, 0x00000007, 0x000000a4, 0x000000a1, + 0x000000a2, 0x000000a3, 0x0004002b, 0x00000006, 0x000000a5, 0x3ffd2f0e, 0x0004002b, 0x00000006, + 0x000000a6, 0xc01b6e0e, 0x0004002b, 0x00000006, 0x000000a7, 0x3ee6b438, 0x0006002c, 0x00000007, + 0x000000a8, 0x000000a5, 0x000000a6, 0x000000a7, 0x0004002b, 0x00000006, 0x000000a9, 0x3cd434b4, + 0x0004002b, 0x00000006, 0x000000aa, 0x3f4863bb, 0x0004002b, 0x00000006, 0x000000ab, 0xbf4f0560, + 0x0006002c, 0x00000007, 0x000000ac, 0x000000a9, 0x000000aa, 0x000000ab, 0x0006002c, 0x00000008, + 0x000000ad, 0x000000a4, 0x000000a8, 0x000000ac, 0x0004002b, 0x00000006, 0x000000ae, 0x3ed30eb1, + 0x0004002b, 0x00000006, 0x000000af, 0x3f094d17, 0x0004002b, 0x00000006, 0x000000b0, 0x3d52b909, + 0x0006002c, 0x00000007, 0x000000b1, 0x000000ae, 0x000000af, 0x000000b0, 0x0004002b, 0x00000006, + 0x000000b2, 0x3e58fd3b, 0x0004002b, 0x00000006, 0x000000b3, 0x3f2e4253, 0x0004002b, 0x00000006, + 0x000000b4, 0x3ddbf2f0, 0x0006002c, 0x00000007, 0x000000b5, 0x000000b2, 0x000000b3, 0x000000b4, + 0x0004002b, 0x00000006, 0x000000b6, 0x3db4d7ec, 0x0004002b, 0x00000006, 0x000000b7, 0x3e903d74, + 0x0004002b, 0x00000006, 0x000000b8, 0x3f214649, 0x0006002c, 0x00000007, 0x000000b9, 0x000000b6, + 0x000000b7, 0x000000b8, 0x0006002c, 0x00000008, 0x000000ba, 0x000000b1, 0x000000b5, 0x000000b9, + 0x0004002b, 0x00000006, 0x000000c7, 0x3f800000, 0x0004002b, 0x00000006, 0x000000c8, 0x3ecaecc9, + 0x0004002b, 0x00000006, 0x000000c9, 0x3e5cfba9, 0x0006002c, 0x00000007, 0x000000ca, 0x000000c7, + 0x000000c8, 0x000000c9, 0x0004002b, 0x00000006, 0x000000cb, 0xbdd8308c, 0x0004002b, 0x00000006, + 0x000000cc, 0xbd82c5fa, 0x0006002c, 0x00000007, 0x000000cd, 0x000000c7, 0x000000cb, 0x000000cc, + 0x0004002b, 0x00000006, 0x000000ce, 0xbdb7437b, 0x0004002b, 0x00000006, 0x000000cf, 0xbfa54f66, + 0x0006002c, 0x00000007, 0x000000d0, 0x000000c7, 0x000000ce, 0x000000cf, 0x0006002c, 0x00000008, + 0x000000d1, 0x000000ca, 0x000000cd, 0x000000d0, 0x0004002b, 0x00000006, 0x000000d6, 0x408274ab, + 0x0004002b, 0x00000006, 0x000000d7, 0xc053b18c, 0x0004002b, 0x00000006, 0x000000d8, 0x3e6c8362, + 0x0006002c, 0x00000007, 0x000000d9, 0x000000d6, 0x000000d7, 0x000000d8, 0x0004002b, 0x00000006, + 0x000000da, 0xbfa25c2d, 0x0004002b, 0x00000006, 0x000000db, 0x40270644, 0x0004002b, 0x00000006, + 0x000000dc, 0xbeaec16a, 0x0006002c, 0x00000007, 0x000000dd, 0x000000da, 0x000000db, 0x000000dc, + 0x0004002b, 0x00000006, 0x000000de, 0xbb897f53, 0x0004002b, 0x00000006, 0x000000df, 0xbf34133e, + 0x0004002b, 0x00000006, 0x000000e0, 0x3fda931e, 0x0006002c, 0x00000007, 0x000000e1, 0x000000de, + 0x000000df, 0x000000e0, 0x0006002c, 0x00000008, 0x000000e2, 0x000000d9, 0x000000dd, 0x000000e1, + 0x0004002b, 0x00000006, 0x000000ed, 0x3fda3f1c, 0x0004002b, 0x00000006, 0x000000ee, 0xbf1f2dc5, + 0x0004002b, 0x00000006, 0x000000ef, 0xbdaa83a1, 0x0006002c, 0x00000007, 0x000000f0, 0x000000ed, + 0x000000ee, 0x000000ef, 0x0004002b, 0x00000006, 0x000000f1, 0xbe0561f0, 0x0004002b, 0x00000006, + 0x000000f2, 0x3f9205e4, 0x0004002b, 0x00000006, 0x000000f3, 0xbc2cd2db, 0x0006002c, 0x00000007, + 0x000000f4, 0x000000f1, 0x000000f2, 0x000000f3, 0x0004002b, 0x00000006, 0x000000f5, 0xbcc4a2b0, + 0x0004002b, 0x00000006, 0x000000f6, 0xbe041071, 0x0004002b, 0x00000006, 0x000000f7, 0x3f939499, + 0x0006002c, 0x00000007, 0x000000f8, 0x000000f5, 0x000000f6, 0x000000f7, 0x0006002c, 0x00000008, + 0x000000f9, 0x000000f0, 0x000000f4, 0x000000f8, 0x0004002b, 0x00000006, 0x000000fa, 0x3f1cf3f4, + 0x0004002b, 0x00000006, 0x000000fb, 0x3eadd5fa, 0x0004002b, 0x00000006, 0x000000fc, 0x3d4210f5, + 0x0006002c, 0x00000007, 0x000000fd, 0x000000fa, 0x000000fb, 0x000000fc, 0x0004002b, 0x00000006, + 0x000000fe, 0x3d8fc1ba, 0x0004002b, 0x00000006, 0x000000ff, 0x3f6a962b, 0x0004002b, 0x00000006, + 0x00000100, 0x3c5c6773, 0x0006002c, 0x00000007, 0x00000101, 0x000000fe, 0x000000ff, 0x00000100, + 0x0004002b, 0x00000006, 0x00000102, 0x3ca8e208, 0x0004002b, 0x00000006, 0x00000103, 0x3de0661e, + 0x0004002b, 0x00000006, 0x00000104, 0x3f5eac2c, 0x0006002c, 0x00000007, 0x00000105, 0x00000102, + 0x00000103, 0x00000104, 0x0006002c, 0x00000008, 0x00000106, 0x000000fd, 0x00000101, 0x00000105, + 0x00040017, 0x0000011a, 0x00000006, 0x00000002, 0x00040020, 0x0000011e, 0x00000007, 0x0000011a, + 0x00040015, 0x0000012c, 0x00000020, 0x00000000, 0x0004002b, 0x0000012c, 0x0000012d, 0x00000001, + 0x0004002b, 0x0000012c, 0x00000130, 0x00000002, 0x0004002b, 0x00000006, 0x0000013b, 0x3d25aee6, + 0x0004002b, 0x00000006, 0x00000141, 0x414eb852, 0x0004002b, 0x00000006, 0x00000145, 0x3d6147ae, + 0x0004002b, 0x00000006, 0x00000147, 0x3f870a3d, 0x0004002b, 0x00000006, 0x00000149, 0x4019999a, + 0x0004002b, 0x00000006, 0x0000015d, 0x40c00000, 0x0004002b, 0x00000006, 0x0000015f, 0x41700000, + 0x0004002b, 0x00000006, 0x00000162, 0x41200000, 0x0004002b, 0x00000006, 0x00000193, 0x40000000, + 0x0004002b, 0x00000006, 0x000001c1, 0x41800000, 0x0004002b, 0x00000006, 0x0000020c, 0x42c80000, + 0x0004002b, 0x00000006, 0x0000020f, 0x3f000000, 0x0004002b, 0x00000006, 0x00000213, 0x40800000, + 0x0004002b, 0x00000006, 0x0000021c, 0x43000000, 0x0004002b, 0x00000006, 0x0000021f, 0x40935d8e, + 0x0004002b, 0x00000006, 0x00000236, 0x3f317218, 0x0004002b, 0x00000006, 0x0000025d, 0x3e3851ec, + 0x00040015, 0x0000028a, 0x00000020, 0x00000001, 0x0004002b, 0x0000028a, 0x0000028b, 0x00000000, + 0x0004002b, 0x0000028a, 0x00000295, 0x00000001, 0x0004002b, 0x0000028a, 0x00000299, 0x00000002, + 0x0004002b, 0x0000028a, 0x000002a1, 0x00000003, 0x0004002b, 0x0000028a, 0x000002aa, 0x00000004, + 0x0004002b, 0x0000028a, 0x000002ab, 0x0000000a, 0x0004002b, 0x0000028a, 0x000002ac, 0x00000007, + 0x0004002b, 0x0000028a, 0x000002cb, 0x00000006, 0x0004002b, 0x0000028a, 0x000002d2, 0x00000005, + 0x0004002b, 0x0000028a, 0x000002da, 0x00000008, 0x0004002b, 0x0000028a, 0x000002e2, 0x00000009, + 0x0004002b, 0x00000006, 0x00000331, 0x461c4000, 0x0004002b, 0x0000028a, 0x00000357, 0x0000000b, + 0x00040020, 0x00000358, 0x00000007, 0x0000004f, 0x0004002b, 0x00000006, 0x00000366, 0x41900000, + 0x00030029, 0x0000004f, 0x00000367, 0x000f002c, 0x00000050, 0x00000368, 0x0000020c, 0x000000c7, + 0x000000c7, 0x000000c7, 0x000000c7, 0x000000c7, 0x0000007c, 0x0000007c, 0x0000007c, 0x0000007c, + 0x00000366, 0x00000367, 0x0004002b, 0x00000006, 0x000003a7, 0x4020a3d7, 0x0004002b, 0x00000006, + 0x000003aa, 0x3cf5c28f, 0x0004002b, 0x00000006, 0x000003af, 0x401b851f, 0x0004002b, 0x00000006, + 0x000003b2, 0x3f170a3d, 0x0004002b, 0x00000006, 0x000003b6, 0x3e0f5c29, 0x0004002b, 0x0000012c, + 0x000003c3, 0x00000003, 0x0004002b, 0x0000012c, 0x000003e9, 0x00000000, 0x0004002b, 0x00000006, + 0x000003f7, 0x400ccccd, 0x0004002b, 0x00000006, 0x0000040c, 0x3dcccccd, 0x0003002a, 0x0000004f, + 0x00000417, 0x00040020, 0x0000042b, 0x00000003, 0x00000064, 0x0004003b, 0x0000042b, 0x0000042c, + 0x00000003, 0x00040020, 0x0000042d, 0x00000001, 0x00000064, 0x0004003b, 0x0000042d, 0x0000042e, + 0x00000001, 0x0004003b, 0x0000042d, 0x0000042f, 0x00000001, 0x0004003b, 0x0000042d, 0x00000430, + 0x00000001, 0x0004003b, 0x0000042d, 0x00000431, 0x00000001, 0x0004003b, 0x0000042d, 0x00000432, + 0x00000001, 0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, + 0x0004003b, 0x0000000a, 0x00000433, 0x00000007, 0x0004003b, 0x00000065, 0x00000436, 0x00000007, + 0x0004003b, 0x00000065, 0x00000438, 0x00000007, 0x0004003b, 0x00000065, 0x0000043a, 0x00000007, + 0x0004003b, 0x00000065, 0x0000043c, 0x00000007, 0x0004003d, 0x00000064, 0x00000434, 0x0000042e, + 0x0008004f, 0x00000007, 0x00000435, 0x00000434, 0x00000434, 0x00000000, 0x00000001, 0x00000002, + 0x0003003e, 0x00000433, 0x00000435, 0x0004003d, 0x00000064, 0x00000437, 0x0000042f, 0x0003003e, + 0x00000436, 0x00000437, 0x0004003d, 0x00000064, 0x00000439, 0x00000430, 0x0003003e, 0x00000438, + 0x00000439, 0x0004003d, 0x00000064, 0x0000043b, 0x00000431, 0x0003003e, 0x0000043a, 0x0000043b, + 0x0004003d, 0x00000064, 0x0000043d, 0x00000432, 0x0003003e, 0x0000043c, 0x0000043d, 0x00090039, + 0x00000007, 0x0000043e, 0x0000006c, 0x00000433, 0x00000436, 0x00000438, 0x0000043a, 0x0000043c, + 0x00050051, 0x00000006, 0x0000043f, 0x0000043e, 0x00000000, 0x00050051, 0x00000006, 0x00000440, + 0x0000043e, 0x00000001, 0x00050051, 0x00000006, 0x00000441, 0x0000043e, 0x00000002, 0x00070050, + 0x00000064, 0x00000442, 0x0000043f, 0x00000440, 0x00000441, 0x000000c7, 0x0003003e, 0x0000042c, + 0x00000442, 0x000100fd, 0x00010038, 0x00050036, 0x00000007, 0x0000000e, 0x00000000, 0x0000000b, + 0x00030037, 0x00000009, 0x0000000c, 0x00030037, 0x0000000a, 0x0000000d, 0x000200f8, 0x0000000f, + 0x0004003d, 0x00000007, 0x0000006e, 0x0000000d, 0x0004003d, 0x00000008, 0x0000006f, 0x0000000c, + 0x00050090, 0x00000007, 0x00000070, 0x0000006e, 0x0000006f, 0x000200fe, 0x00000070, 0x00010038, + 0x00050036, 0x00000006, 0x00000012, 0x00000000, 0x00000010, 0x00030037, 0x0000000a, 0x00000011, + 0x000200f8, 0x00000013, 0x0004003d, 0x00000007, 0x00000073, 0x00000011, 0x00050094, 0x00000006, + 0x00000078, 0x00000073, 0x00000077, 0x000200fe, 0x00000078, 0x00010038, 0x00050036, 0x00000006, + 0x00000019, 0x00000000, 0x00000015, 0x00030037, 0x00000014, 0x00000016, 0x00030037, 0x00000014, + 0x00000017, 0x00030037, 0x00000014, 0x00000018, 0x000200f8, 0x0000001a, 0x0004003b, 0x00000014, + 0x0000007e, 0x00000007, 0x0004003d, 0x00000006, 0x0000007b, 0x00000017, 0x000500b4, 0x0000004f, + 0x0000007d, 0x0000007b, 0x0000007c, 0x000300f7, 0x00000080, 0x00000000, 0x000400fa, 0x0000007d, + 0x0000007f, 0x00000082, 0x000200f8, 0x0000007f, 0x0004003d, 0x00000006, 0x00000081, 0x00000018, + 0x0003003e, 0x0000007e, 0x00000081, 0x000200f9, 0x00000080, 0x000200f8, 0x00000082, 0x0004003d, + 0x00000006, 0x00000083, 0x00000016, 0x0004003d, 0x00000006, 0x00000084, 0x00000017, 0x00050088, + 0x00000006, 0x00000085, 0x00000083, 0x00000084, 0x0003003e, 0x0000007e, 0x00000085, 0x000200f9, + 0x00000080, 0x000200f8, 0x00000080, 0x0004003d, 0x00000006, 0x00000086, 0x0000007e, 0x000200fe, + 0x00000086, 0x00010038, 0x00050036, 0x00000007, 0x0000001e, 0x00000000, 0x0000001b, 0x00030037, + 0x0000000a, 0x0000001c, 0x00030037, 0x0000000a, 0x0000001d, 0x000200f8, 0x0000001f, 0x0004003b, + 0x0000000a, 0x00000089, 0x00000007, 0x0004003d, 0x00000007, 0x0000008a, 0x0000001c, 0x0006000c, + 0x00000007, 0x0000008b, 0x00000001, 0x00000004, 0x0000008a, 0x0003003e, 0x00000089, 0x0000008b, + 0x0004003d, 0x00000007, 0x0000008c, 0x00000089, 0x0004003d, 0x00000007, 0x0000008d, 0x00000089, + 0x0004007f, 0x00000007, 0x0000008e, 0x0000008d, 0x0004003d, 0x00000007, 0x0000008f, 0x0000001d, + 0x000500b8, 0x00000091, 0x00000092, 0x0000008f, 0x00000090, 0x000600a9, 0x00000007, 0x00000093, + 0x00000092, 0x0000008e, 0x0000008c, 0x000200fe, 0x00000093, 0x00010038, 0x00050036, 0x00000007, + 0x00000022, 0x00000000, 0x00000020, 0x00030037, 0x0000000a, 0x00000021, 0x000200f8, 0x00000023, + 0x0004003b, 0x0000000a, 0x0000009b, 0x00000007, 0x0004003b, 0x0000000a, 0x0000009c, 0x00000007, + 0x0004003d, 0x00000007, 0x00000096, 0x00000021, 0x0006000c, 0x00000007, 0x00000097, 0x00000001, + 0x00000004, 0x00000096, 0x0007000c, 0x00000007, 0x0000009a, 0x00000001, 0x0000001a, 0x00000097, + 0x00000099, 0x0003003e, 0x0000009b, 0x0000009a, 0x0004003d, 0x00000007, 0x0000009d, 0x00000021, + 0x0003003e, 0x0000009c, 0x0000009d, 0x00060039, 0x00000007, 0x0000009e, 0x0000001e, 0x0000009b, + 0x0000009c, 0x000200fe, 0x0000009e, 0x00010038, 0x00050036, 0x00000007, 0x00000025, 0x00000000, + 0x00000020, 0x00030037, 0x0000000a, 0x00000024, 0x000200f8, 0x00000026, 0x0004003b, 0x00000009, + 0x000000bb, 0x00000007, 0x0004003b, 0x0000000a, 0x000000bc, 0x00000007, 0x0004003b, 0x0000000a, + 0x000000bf, 0x00000007, 0x0004003b, 0x00000009, 0x000000c1, 0x00000007, 0x0004003b, 0x0000000a, + 0x000000c2, 0x00000007, 0x0003003e, 0x000000bb, 0x000000ba, 0x0004003d, 0x00000007, 0x000000bd, + 0x00000024, 0x0003003e, 0x000000bc, 0x000000bd, 0x00060039, 0x00000007, 0x000000be, 0x0000000e, + 0x000000bb, 0x000000bc, 0x0003003e, 0x000000bf, 0x000000be, 0x00050039, 0x00000007, 0x000000c0, + 0x00000022, 0x000000bf, 0x0003003e, 0x000000c1, 0x000000ad, 0x0003003e, 0x000000c2, 0x000000c0, + 0x00060039, 0x00000007, 0x000000c3, 0x0000000e, 0x000000c1, 0x000000c2, 0x000200fe, 0x000000c3, + 0x00010038, 0x00050036, 0x00000007, 0x00000028, 0x00000000, 0x00000020, 0x00030037, 0x0000000a, + 0x00000027, 0x000200f8, 0x00000029, 0x0004003b, 0x0000000a, 0x000000c6, 0x00000007, 0x0004003b, + 0x00000009, 0x000000d2, 0x00000007, 0x0004003b, 0x0000000a, 0x000000d3, 0x00000007, 0x0004003b, + 0x00000009, 0x000000e8, 0x00000007, 0x0004003b, 0x0000000a, 0x000000e9, 0x00000007, 0x0003003e, + 0x000000d2, 0x000000d1, 0x0004003d, 0x00000007, 0x000000d4, 0x00000027, 0x0003003e, 0x000000d3, + 0x000000d4, 0x00060039, 0x00000007, 0x000000d5, 0x0000000e, 0x000000d2, 0x000000d3, 0x0003003e, + 0x000000c6, 0x000000d5, 0x0004003d, 0x00000007, 0x000000e3, 0x000000c6, 0x0004003d, 0x00000007, + 0x000000e4, 0x000000c6, 0x00050085, 0x00000007, 0x000000e5, 0x000000e3, 0x000000e4, 0x0004003d, + 0x00000007, 0x000000e6, 0x000000c6, 0x00050085, 0x00000007, 0x000000e7, 0x000000e5, 0x000000e6, + 0x0003003e, 0x000000e8, 0x000000e2, 0x0003003e, 0x000000e9, 0x000000e7, 0x00060039, 0x00000007, + 0x000000ea, 0x0000000e, 0x000000e8, 0x000000e9, 0x000200fe, 0x000000ea, 0x00010038, 0x00050036, + 0x00000007, 0x0000002b, 0x00000000, 0x00000020, 0x00030037, 0x0000000a, 0x0000002a, 0x000200f8, + 0x0000002c, 0x0004003b, 0x00000009, 0x00000107, 0x00000007, 0x0004003b, 0x0000000a, 0x00000108, + 0x00000007, 0x0004003b, 0x00000009, 0x0000010c, 0x00000007, 0x0004003b, 0x0000000a, 0x0000010d, + 0x00000007, 0x0003003e, 0x00000107, 0x00000106, 0x0004003d, 0x00000007, 0x00000109, 0x0000002a, + 0x0003003e, 0x00000108, 0x00000109, 0x00060039, 0x00000007, 0x0000010a, 0x0000000e, 0x00000107, + 0x00000108, 0x0007000c, 0x00000007, 0x0000010b, 0x00000001, 0x00000028, 0x0000010a, 0x00000090, + 0x0003003e, 0x0000010c, 0x000000f9, 0x0003003e, 0x0000010d, 0x0000010b, 0x00060039, 0x00000007, + 0x0000010e, 0x0000000e, 0x0000010c, 0x0000010d, 0x000200fe, 0x0000010e, 0x00010038, 0x00050036, + 0x00000007, 0x0000002f, 0x00000000, 0x0000001b, 0x00030037, 0x0000000a, 0x0000002d, 0x00030037, + 0x0000000a, 0x0000002e, 0x000200f8, 0x00000030, 0x0004003b, 0x0000000a, 0x00000111, 0x00000007, + 0x0004003b, 0x0000000a, 0x00000112, 0x00000007, 0x0004003b, 0x0000000a, 0x00000115, 0x00000007, + 0x0004003b, 0x0000000a, 0x00000116, 0x00000007, 0x0004003b, 0x00000014, 0x00000119, 0x00000007, + 0x0004003b, 0x0000011e, 0x0000011f, 0x00000007, 0x0004003b, 0x00000014, 0x00000124, 0x00000007, + 0x0004003b, 0x00000014, 0x00000126, 0x00000007, 0x0004003b, 0x00000014, 0x00000127, 0x00000007, + 0x0004003b, 0x0000000a, 0x00000133, 0x00000007, 0x0004003b, 0x0000000a, 0x00000136, 0x00000007, + 0x0004003d, 0x00000007, 0x00000113, 0x0000002d, 0x0003003e, 0x00000112, 0x00000113, 0x00050039, + 0x00000007, 0x00000114, 0x00000025, 0x00000112, 0x0003003e, 0x00000111, 0x00000114, 0x0004003d, + 0x00000007, 0x00000117, 0x0000002e, 0x0003003e, 0x00000116, 0x00000117, 0x00050039, 0x00000007, + 0x00000118, 0x00000025, 0x00000116, 0x0003003e, 0x00000115, 0x00000118, 0x0004003d, 0x00000007, + 0x0000011b, 0x00000111, 0x0007004f, 0x0000011a, 0x0000011c, 0x0000011b, 0x0000011b, 0x00000001, + 0x00000002, 0x0006000c, 0x00000006, 0x0000011d, 0x00000001, 0x00000042, 0x0000011c, 0x0003003e, + 0x00000119, 0x0000011d, 0x0004003d, 0x00000007, 0x00000120, 0x00000115, 0x0007004f, 0x0000011a, + 0x00000121, 0x00000120, 0x00000120, 0x00000001, 0x00000002, 0x0003003e, 0x0000011f, 0x00000121, + 0x0004003d, 0x0000011a, 0x00000122, 0x0000011f, 0x0006000c, 0x00000006, 0x00000123, 0x00000001, + 0x00000042, 0x00000122, 0x0004003d, 0x00000006, 0x00000125, 0x00000119, 0x0003003e, 0x00000124, + 0x00000125, 0x0003003e, 0x00000126, 0x00000123, 0x0003003e, 0x00000127, 0x000000c7, 0x00070039, + 0x00000006, 0x00000128, 0x00000019, 0x00000124, 0x00000126, 0x00000127, 0x0004003d, 0x0000011a, + 0x00000129, 0x0000011f, 0x0005008e, 0x0000011a, 0x0000012a, 0x00000129, 0x00000128, 0x0003003e, + 0x0000011f, 0x0000012a, 0x0004003d, 0x0000011a, 0x0000012b, 0x0000011f, 0x00050041, 0x00000014, + 0x0000012e, 0x00000111, 0x0000012d, 0x00050051, 0x00000006, 0x0000012f, 0x0000012b, 0x00000000, + 0x0003003e, 0x0000012e, 0x0000012f, 0x00050041, 0x00000014, 0x00000131, 0x00000111, 0x00000130, + 0x00050051, 0x00000006, 0x00000132, 0x0000012b, 0x00000001, 0x0003003e, 0x00000131, 0x00000132, + 0x0004003d, 0x00000007, 0x00000134, 0x00000111, 0x0003003e, 0x00000133, 0x00000134, 0x00050039, + 0x00000007, 0x00000135, 0x00000028, 0x00000133, 0x0003003e, 0x00000136, 0x00000135, 0x00050039, + 0x00000007, 0x00000137, 0x0000002b, 0x00000136, 0x000200fe, 0x00000137, 0x00010038, 0x00050036, + 0x00000006, 0x00000033, 0x00000000, 0x00000031, 0x00030037, 0x00000014, 0x00000032, 0x000200f8, + 0x00000034, 0x0004003b, 0x00000014, 0x0000013d, 0x00000007, 0x0004003d, 0x00000006, 0x0000013a, + 0x00000032, 0x000500bc, 0x0000004f, 0x0000013c, 0x0000013a, 0x0000013b, 0x000300f7, 0x0000013f, + 0x00000000, 0x000400fa, 0x0000013c, 0x0000013e, 0x00000143, 0x000200f8, 0x0000013e, 0x0004003d, + 0x00000006, 0x00000140, 0x00000032, 0x00050088, 0x00000006, 0x00000142, 0x00000140, 0x00000141, + 0x0003003e, 0x0000013d, 0x00000142, 0x000200f9, 0x0000013f, 0x000200f8, 0x00000143, 0x0004003d, + 0x00000006, 0x00000144, 0x00000032, 0x00050081, 0x00000006, 0x00000146, 0x00000144, 0x00000145, + 0x00050088, 0x00000006, 0x00000148, 0x00000146, 0x00000147, 0x0007000c, 0x00000006, 0x0000014a, + 0x00000001, 0x0000001a, 0x00000148, 0x00000149, 0x0003003e, 0x0000013d, 0x0000014a, 0x000200f9, + 0x0000013f, 0x000200f8, 0x0000013f, 0x0004003d, 0x00000006, 0x0000014b, 0x0000013d, 0x000200fe, + 0x0000014b, 0x00010038, 0x00050036, 0x00000006, 0x00000038, 0x00000000, 0x00000035, 0x00030037, + 0x00000014, 0x00000036, 0x00030037, 0x00000014, 0x00000037, 0x000200f8, 0x00000039, 0x0004003b, + 0x00000014, 0x00000152, 0x00000007, 0x0004003d, 0x00000006, 0x0000014e, 0x00000036, 0x0004003d, + 0x00000006, 0x0000014f, 0x00000037, 0x00050088, 0x00000006, 0x00000150, 0x000000c7, 0x0000014f, + 0x0007000c, 0x00000006, 0x00000151, 0x00000001, 0x0000001a, 0x0000014e, 0x00000150, 0x0003003e, + 0x00000152, 0x00000151, 0x00050039, 0x00000006, 0x00000153, 0x00000033, 0x00000152, 0x000200fe, + 0x00000153, 0x00010038, 0x00050036, 0x00000006, 0x0000003b, 0x00000000, 0x00000031, 0x00030037, + 0x00000014, 0x0000003a, 0x000200f8, 0x0000003c, 0x0004003d, 0x00000006, 0x00000156, 0x0000003a, + 0x0004003d, 0x00000006, 0x00000157, 0x0000003a, 0x00050085, 0x00000006, 0x00000158, 0x00000156, + 0x00000157, 0x0004003d, 0x00000006, 0x00000159, 0x0000003a, 0x00050085, 0x00000006, 0x0000015a, + 0x00000158, 0x00000159, 0x0004003d, 0x00000006, 0x0000015b, 0x0000003a, 0x0004003d, 0x00000006, + 0x0000015c, 0x0000003a, 0x00050085, 0x00000006, 0x0000015e, 0x0000015c, 0x0000015d, 0x00050083, + 0x00000006, 0x00000160, 0x0000015e, 0x0000015f, 0x00050085, 0x00000006, 0x00000161, 0x0000015b, + 0x00000160, 0x00050081, 0x00000006, 0x00000163, 0x00000161, 0x00000162, 0x00050085, 0x00000006, + 0x00000164, 0x0000015a, 0x00000163, 0x000200fe, 0x00000164, 0x00010038, 0x00050036, 0x00000006, + 0x00000040, 0x00000000, 0x00000015, 0x00030037, 0x00000014, 0x0000003d, 0x00030037, 0x00000014, + 0x0000003e, 0x00030037, 0x00000014, 0x0000003f, 0x000200f8, 0x00000041, 0x0004003b, 0x00000014, + 0x0000016d, 0x00000007, 0x0004003b, 0x00000014, 0x0000017c, 0x00000007, 0x0004003b, 0x00000014, + 0x0000018e, 0x00000007, 0x0004003b, 0x00000014, 0x0000019f, 0x00000007, 0x0004003b, 0x00000014, + 0x000001a0, 0x00000007, 0x0004003b, 0x00000014, 0x000001a1, 0x00000007, 0x0004003d, 0x00000006, + 0x00000167, 0x0000003e, 0x000500b4, 0x0000004f, 0x00000168, 0x00000167, 0x000000c7, 0x000300f7, + 0x0000016a, 0x00000000, 0x000400fa, 0x00000168, 0x00000169, 0x0000016a, 0x000200f8, 0x00000169, + 0x0004003d, 0x00000006, 0x0000016b, 0x0000003d, 0x000200fe, 0x0000016b, 0x000200f8, 0x0000016a, + 0x0003003e, 0x0000016d, 0x0000007c, 0x0004003d, 0x00000006, 0x0000016e, 0x0000003d, 0x0004003d, + 0x00000006, 0x0000016f, 0x0000003f, 0x000500ba, 0x0000004f, 0x00000170, 0x0000016e, 0x0000016f, + 0x000300f7, 0x00000172, 0x00000000, 0x000400fa, 0x00000170, 0x00000171, 0x00000172, 0x000200f8, + 0x00000171, 0x0004003d, 0x00000006, 0x00000173, 0x0000003d, 0x0004003d, 0x00000006, 0x00000174, + 0x0000003f, 0x00050088, 0x00000006, 0x00000175, 0x00000173, 0x00000174, 0x0006000c, 0x00000006, + 0x00000176, 0x00000001, 0x0000001e, 0x00000175, 0x0004003d, 0x00000006, 0x00000177, 0x0000003f, + 0x00050088, 0x00000006, 0x00000178, 0x000000c7, 0x00000177, 0x0006000c, 0x00000006, 0x00000179, + 0x00000001, 0x0000001e, 0x00000178, 0x00050088, 0x00000006, 0x0000017a, 0x00000176, 0x00000179, + 0x0008000c, 0x00000006, 0x0000017b, 0x00000001, 0x0000002b, 0x0000017a, 0x0000007c, 0x000000c7, + 0x0003003e, 0x0000016d, 0x0000017b, 0x000200f9, 0x00000172, 0x000200f8, 0x00000172, 0x0004003d, + 0x00000006, 0x0000017d, 0x0000016d, 0x0003003e, 0x0000017c, 0x0000017d, 0x00050039, 0x00000006, + 0x0000017e, 0x0000003b, 0x0000017c, 0x0003003e, 0x0000016d, 0x0000017e, 0x0004003d, 0x00000006, + 0x0000017f, 0x0000003e, 0x000500ba, 0x0000004f, 0x00000180, 0x0000017f, 0x000000c7, 0x000300f7, + 0x00000182, 0x00000000, 0x000400fa, 0x00000180, 0x00000181, 0x00000182, 0x000200f8, 0x00000181, + 0x0004003d, 0x00000006, 0x00000183, 0x0000003d, 0x0004003d, 0x00000006, 0x00000184, 0x0000003f, + 0x0004003d, 0x00000006, 0x00000185, 0x0000003d, 0x0004003d, 0x00000006, 0x00000186, 0x0000003f, + 0x00050088, 0x00000006, 0x00000187, 0x00000185, 0x00000186, 0x0004003d, 0x00000006, 0x00000188, + 0x0000003e, 0x0007000c, 0x00000006, 0x00000189, 0x00000001, 0x0000001a, 0x00000187, 0x00000188, + 0x00050085, 0x00000006, 0x0000018a, 0x00000184, 0x00000189, 0x0004003d, 0x00000006, 0x0000018b, + 0x0000016d, 0x0008000c, 0x00000006, 0x0000018c, 0x00000001, 0x0000002e, 0x00000183, 0x0000018a, + 0x0000018b, 0x000200fe, 0x0000018c, 0x000200f8, 0x00000182, 0x0004003d, 0x00000006, 0x0000018f, + 0x0000003f, 0x0004003d, 0x00000006, 0x00000190, 0x0000003d, 0x0004003d, 0x00000006, 0x00000191, + 0x0000003f, 0x00050088, 0x00000006, 0x00000192, 0x00000190, 0x00000191, 0x0004003d, 0x00000006, + 0x00000194, 0x0000003e, 0x00050083, 0x00000006, 0x00000195, 0x00000193, 0x00000194, 0x0007000c, + 0x00000006, 0x00000196, 0x00000001, 0x0000001a, 0x00000192, 0x00000195, 0x00050085, 0x00000006, + 0x00000197, 0x0000018f, 0x00000196, 0x0003003e, 0x0000018e, 0x00000197, 0x0004003d, 0x00000006, + 0x00000198, 0x0000003d, 0x0004003d, 0x00000006, 0x00000199, 0x0000003d, 0x00050085, 0x00000006, + 0x0000019a, 0x00000198, 0x00000199, 0x0004003d, 0x00000006, 0x0000019b, 0x0000003d, 0x0004003d, + 0x00000006, 0x0000019c, 0x0000018e, 0x0004003d, 0x00000006, 0x0000019d, 0x0000016d, 0x0008000c, + 0x00000006, 0x0000019e, 0x00000001, 0x0000002e, 0x0000019b, 0x0000019c, 0x0000019d, 0x0003003e, + 0x0000019f, 0x0000019a, 0x0003003e, 0x000001a0, 0x0000019e, 0x0004003d, 0x00000006, 0x000001a2, + 0x0000003d, 0x0003003e, 0x000001a1, 0x000001a2, 0x00070039, 0x00000006, 0x000001a3, 0x00000019, + 0x0000019f, 0x000001a0, 0x000001a1, 0x000200fe, 0x000001a3, 0x00010038, 0x00050036, 0x00000006, + 0x00000045, 0x00000000, 0x00000015, 0x00030037, 0x00000014, 0x00000042, 0x00030037, 0x00000014, + 0x00000043, 0x00030037, 0x00000014, 0x00000044, 0x000200f8, 0x00000046, 0x0004003b, 0x00000014, + 0x000001ac, 0x00000007, 0x0004003b, 0x00000014, 0x000001ad, 0x00000007, 0x0004003b, 0x00000014, + 0x000001af, 0x00000007, 0x0004003b, 0x00000014, 0x000001b1, 0x00000007, 0x0004003b, 0x00000014, + 0x000001b4, 0x00000007, 0x0004003b, 0x00000014, 0x000001b8, 0x00000007, 0x0004003b, 0x00000014, + 0x000001b9, 0x00000007, 0x0004003b, 0x00000014, 0x000001bb, 0x00000007, 0x0004003b, 0x00000014, + 0x000001bd, 0x00000007, 0x0004003b, 0x00000014, 0x000001bf, 0x00000007, 0x0004003b, 0x00000014, + 0x000001c3, 0x00000007, 0x0004003b, 0x00000014, 0x000001d3, 0x00000007, 0x0004003b, 0x00000014, + 0x000001da, 0x00000007, 0x0004003b, 0x00000014, 0x000001df, 0x00000007, 0x0004003b, 0x00000014, + 0x000001e1, 0x00000007, 0x0004003b, 0x00000014, 0x000001e2, 0x00000007, 0x0004003b, 0x00000014, + 0x000001f1, 0x00000007, 0x0004003b, 0x00000014, 0x000001f7, 0x00000007, 0x0004003b, 0x00000014, + 0x000001f9, 0x00000007, 0x0004003b, 0x00000014, 0x000001fa, 0x00000007, 0x0004003d, 0x00000006, + 0x000001a6, 0x00000043, 0x000500b4, 0x0000004f, 0x000001a7, 0x000001a6, 0x000000c7, 0x000300f7, + 0x000001a9, 0x00000000, 0x000400fa, 0x000001a7, 0x000001a8, 0x000001a9, 0x000200f8, 0x000001a8, + 0x0004003d, 0x00000006, 0x000001aa, 0x00000042, 0x000200fe, 0x000001aa, 0x000200f8, 0x000001a9, + 0x0004003d, 0x00000006, 0x000001ae, 0x00000042, 0x0003003e, 0x000001ad, 0x000001ae, 0x0004003d, + 0x00000006, 0x000001b0, 0x00000044, 0x0003003e, 0x000001af, 0x000001b0, 0x0003003e, 0x000001b1, + 0x0000007c, 0x00070039, 0x00000006, 0x000001b2, 0x00000019, 0x000001ad, 0x000001af, 0x000001b1, + 0x0007000c, 0x00000006, 0x000001b3, 0x00000001, 0x00000028, 0x000001b2, 0x0000007c, 0x0003003e, + 0x000001ac, 0x000001b3, 0x0004003d, 0x00000006, 0x000001b5, 0x00000042, 0x0004003d, 0x00000006, + 0x000001b6, 0x00000044, 0x00050085, 0x00000006, 0x000001b7, 0x000001b5, 0x000001b6, 0x0003003e, + 0x000001b4, 0x000001b7, 0x0004003d, 0x00000006, 0x000001ba, 0x000001b4, 0x0003003e, 0x000001b9, + 0x000001ba, 0x0004003d, 0x00000006, 0x000001bc, 0x000001ac, 0x0003003e, 0x000001bb, 0x000001bc, + 0x0003003e, 0x000001bd, 0x0000007c, 0x00070039, 0x00000006, 0x000001be, 0x00000019, 0x000001b9, + 0x000001bb, 0x000001bd, 0x0003003e, 0x000001b8, 0x000001be, 0x0004003d, 0x00000006, 0x000001c0, + 0x00000044, 0x00050088, 0x00000006, 0x000001c2, 0x000001c0, 0x000001c1, 0x0003003e, 0x000001bf, + 0x000001c2, 0x0003003e, 0x000001c3, 0x000000c7, 0x0004003d, 0x00000006, 0x000001c4, 0x00000042, + 0x0004003d, 0x00000006, 0x000001c5, 0x000001bf, 0x000500ba, 0x0000004f, 0x000001c6, 0x000001c4, + 0x000001c5, 0x000300f7, 0x000001c8, 0x00000000, 0x000400fa, 0x000001c6, 0x000001c7, 0x000001c8, + 0x000200f8, 0x000001c7, 0x0004003d, 0x00000006, 0x000001c9, 0x00000042, 0x0004003d, 0x00000006, + 0x000001ca, 0x00000044, 0x00050088, 0x00000006, 0x000001cb, 0x000001c9, 0x000001ca, 0x0006000c, + 0x00000006, 0x000001cc, 0x00000001, 0x0000001e, 0x000001cb, 0x0004003d, 0x00000006, 0x000001cd, + 0x000001bf, 0x0004003d, 0x00000006, 0x000001ce, 0x00000044, 0x00050088, 0x00000006, 0x000001cf, + 0x000001cd, 0x000001ce, 0x0006000c, 0x00000006, 0x000001d0, 0x00000001, 0x0000001e, 0x000001cf, + 0x00050088, 0x00000006, 0x000001d1, 0x000001cc, 0x000001d0, 0x0008000c, 0x00000006, 0x000001d2, + 0x00000001, 0x0000002b, 0x000001d1, 0x0000007c, 0x000000c7, 0x0003003e, 0x000001c3, 0x000001d2, + 0x000200f9, 0x000001c8, 0x000200f8, 0x000001c8, 0x0004003d, 0x00000006, 0x000001d4, 0x000001c3, + 0x0003003e, 0x000001d3, 0x000001d4, 0x00050039, 0x00000006, 0x000001d5, 0x0000003b, 0x000001d3, + 0x0003003e, 0x000001c3, 0x000001d5, 0x0004003d, 0x00000006, 0x000001d6, 0x00000043, 0x000500ba, + 0x0000004f, 0x000001d7, 0x000001d6, 0x000000c7, 0x000300f7, 0x000001d9, 0x00000000, 0x000400fa, + 0x000001d7, 0x000001d8, 0x000001d9, 0x000200f8, 0x000001d8, 0x0004003d, 0x00000006, 0x000001db, + 0x00000042, 0x0004003d, 0x00000006, 0x000001dc, 0x000001ac, 0x0004003d, 0x00000006, 0x000001dd, + 0x00000043, 0x0007000c, 0x00000006, 0x000001de, 0x00000001, 0x0000001a, 0x000001dc, 0x000001dd, + 0x0004003d, 0x00000006, 0x000001e0, 0x000001b4, 0x0003003e, 0x000001df, 0x000001e0, 0x0003003e, + 0x000001e1, 0x000001de, 0x0003003e, 0x000001e2, 0x0000007c, 0x00070039, 0x00000006, 0x000001e3, + 0x00000019, 0x000001df, 0x000001e1, 0x000001e2, 0x00050081, 0x00000006, 0x000001e4, 0x000000c7, + 0x000001e3, 0x00050085, 0x00000006, 0x000001e5, 0x000001db, 0x000001e4, 0x0003003e, 0x000001da, + 0x000001e5, 0x0004003d, 0x00000006, 0x000001e6, 0x00000042, 0x0004003d, 0x00000006, 0x000001e7, + 0x000001da, 0x0004003d, 0x00000006, 0x000001e8, 0x00000042, 0x0004003d, 0x00000006, 0x000001e9, + 0x000001b8, 0x00050081, 0x00000006, 0x000001ea, 0x000000c7, 0x000001e9, 0x00050085, 0x00000006, + 0x000001eb, 0x000001e8, 0x000001ea, 0x00050083, 0x00000006, 0x000001ec, 0x000001e7, 0x000001eb, + 0x0004003d, 0x00000006, 0x000001ed, 0x000001c3, 0x00050085, 0x00000006, 0x000001ee, 0x000001ec, + 0x000001ed, 0x00050081, 0x00000006, 0x000001ef, 0x000001e6, 0x000001ee, 0x000200fe, 0x000001ef, + 0x000200f8, 0x000001d9, 0x0004003d, 0x00000006, 0x000001f2, 0x00000042, 0x0004003d, 0x00000006, + 0x000001f3, 0x000001ac, 0x0004003d, 0x00000006, 0x000001f4, 0x00000043, 0x00050083, 0x00000006, + 0x000001f5, 0x00000193, 0x000001f4, 0x0007000c, 0x00000006, 0x000001f6, 0x00000001, 0x0000001a, + 0x000001f3, 0x000001f5, 0x0004003d, 0x00000006, 0x000001f8, 0x000001b4, 0x0003003e, 0x000001f7, + 0x000001f8, 0x0003003e, 0x000001f9, 0x000001f6, 0x0003003e, 0x000001fa, 0x0000007c, 0x00070039, + 0x00000006, 0x000001fb, 0x00000019, 0x000001f7, 0x000001f9, 0x000001fa, 0x00050083, 0x00000006, + 0x000001fc, 0x000000c7, 0x000001fb, 0x00050085, 0x00000006, 0x000001fd, 0x000001f2, 0x000001fc, + 0x0003003e, 0x000001f1, 0x000001fd, 0x0004003d, 0x00000006, 0x000001fe, 0x00000042, 0x0004003d, + 0x00000006, 0x000001ff, 0x000001f1, 0x0004003d, 0x00000006, 0x00000200, 0x00000042, 0x0004003d, + 0x00000006, 0x00000201, 0x000001b8, 0x00050083, 0x00000006, 0x00000202, 0x000000c7, 0x00000201, + 0x00050085, 0x00000006, 0x00000203, 0x00000200, 0x00000202, 0x00050083, 0x00000006, 0x00000204, + 0x000001ff, 0x00000203, 0x0004003d, 0x00000006, 0x00000205, 0x000001c3, 0x00050085, 0x00000006, + 0x00000206, 0x00000204, 0x00000205, 0x00050081, 0x00000006, 0x00000207, 0x000001fe, 0x00000206, + 0x000200fe, 0x00000207, 0x00010038, 0x00050036, 0x00000006, 0x0000004d, 0x00000000, 0x00000047, + 0x00030037, 0x00000014, 0x00000048, 0x00030037, 0x00000014, 0x00000049, 0x00030037, 0x00000014, + 0x0000004a, 0x00030037, 0x00000014, 0x0000004b, 0x00030037, 0x00000014, 0x0000004c, 0x000200f8, + 0x0000004e, 0x0004003b, 0x00000014, 0x0000020a, 0x00000007, 0x0004003b, 0x00000014, 0x0000020e, + 0x00000007, 0x0004003b, 0x00000014, 0x0000021b, 0x00000007, 0x0004003b, 0x00000014, 0x00000223, + 0x00000007, 0x0004003b, 0x00000014, 0x0000022e, 0x00000007, 0x0004003b, 0x00000014, 0x00000232, + 0x00000007, 0x0004003b, 0x00000014, 0x00000238, 0x00000007, 0x0004003b, 0x00000014, 0x0000023f, + 0x00000007, 0x0004003b, 0x00000014, 0x0000024a, 0x00000007, 0x0004003b, 0x00000014, 0x0000025c, + 0x00000007, 0x0004003b, 0x00000014, 0x00000260, 0x00000007, 0x0004003b, 0x00000014, 0x00000264, + 0x00000007, 0x0004003b, 0x00000014, 0x00000270, 0x00000007, 0x0004003b, 0x00000014, 0x00000274, + 0x00000007, 0x0004003d, 0x00000006, 0x0000020b, 0x00000049, 0x00050088, 0x00000006, 0x0000020d, + 0x0000020b, 0x0000020c, 0x0003003e, 0x0000020a, 0x0000020d, 0x0004003d, 0x00000006, 0x00000210, + 0x0000020a, 0x0004003d, 0x00000006, 0x00000211, 0x0000020a, 0x0004003d, 0x00000006, 0x00000212, + 0x0000020a, 0x0004003d, 0x00000006, 0x00000214, 0x0000004c, 0x00050085, 0x00000006, 0x00000215, + 0x00000213, 0x00000214, 0x00050081, 0x00000006, 0x00000216, 0x00000212, 0x00000215, 0x00050085, + 0x00000006, 0x00000217, 0x00000211, 0x00000216, 0x0006000c, 0x00000006, 0x00000218, 0x00000001, + 0x0000001f, 0x00000217, 0x00050081, 0x00000006, 0x00000219, 0x00000210, 0x00000218, 0x00050085, + 0x00000006, 0x0000021a, 0x0000020f, 0x00000219, 0x0003003e, 0x0000020e, 0x0000021a, 0x0004003d, + 0x00000006, 0x0000021d, 0x0000020a, 0x0006000c, 0x00000006, 0x0000021e, 0x00000001, 0x0000001c, + 0x0000021d, 0x00050088, 0x00000006, 0x00000220, 0x0000021e, 0x0000021f, 0x00050085, 0x00000006, + 0x00000221, 0x0000021c, 0x00000220, 0x00050081, 0x00000006, 0x00000222, 0x0000021c, 0x00000221, + 0x0003003e, 0x0000021b, 0x00000222, 0x0004003d, 0x00000006, 0x00000224, 0x0000021b, 0x0004003d, + 0x00000006, 0x00000225, 0x0000020e, 0x00050088, 0x00000006, 0x00000226, 0x00000224, 0x00000225, + 0x0004003d, 0x00000006, 0x00000227, 0x0000021b, 0x0004003d, 0x00000006, 0x00000228, 0x0000020e, + 0x00050088, 0x00000006, 0x00000229, 0x00000227, 0x00000228, 0x00050081, 0x00000006, 0x0000022a, + 0x00000229, 0x000000c7, 0x00050088, 0x00000006, 0x0000022b, 0x00000226, 0x0000022a, 0x0004003d, + 0x00000006, 0x0000022c, 0x0000004a, 0x0007000c, 0x00000006, 0x0000022d, 0x00000001, 0x0000001a, + 0x0000022b, 0x0000022c, 0x0003003e, 0x00000223, 0x0000022d, 0x0004003d, 0x00000006, 0x0000022f, + 0x0000020e, 0x0004003d, 0x00000006, 0x00000230, 0x00000223, 0x00050088, 0x00000006, 0x00000231, + 0x0000022f, 0x00000230, 0x0003003e, 0x0000022e, 0x00000231, 0x0004003d, 0x00000006, 0x00000233, + 0x00000049, 0x00050088, 0x00000006, 0x00000234, 0x00000233, 0x0000020c, 0x0006000c, 0x00000006, + 0x00000235, 0x00000001, 0x0000001c, 0x00000234, 0x00050088, 0x00000006, 0x00000237, 0x00000235, + 0x00000236, 0x0003003e, 0x00000232, 0x00000237, 0x0004003d, 0x00000006, 0x00000239, 0x0000004b, + 0x00050088, 0x00000006, 0x0000023a, 0x00000239, 0x0000020c, 0x0004003d, 0x00000006, 0x0000023b, + 0x00000232, 0x00050085, 0x00000006, 0x0000023c, 0x0000023b, 0x0000007c, 0x00050081, 0x00000006, + 0x0000023d, 0x000000c7, 0x0000023c, 0x00050085, 0x00000006, 0x0000023e, 0x0000023a, 0x0000023d, + 0x0003003e, 0x00000238, 0x0000023e, 0x0004003d, 0x00000006, 0x00000240, 0x00000238, 0x0004003d, + 0x00000006, 0x00000241, 0x00000238, 0x0004003d, 0x00000006, 0x00000242, 0x00000238, 0x0004003d, + 0x00000006, 0x00000243, 0x0000004c, 0x00050085, 0x00000006, 0x00000244, 0x00000213, 0x00000243, + 0x00050081, 0x00000006, 0x00000245, 0x00000242, 0x00000244, 0x00050085, 0x00000006, 0x00000246, + 0x00000241, 0x00000245, 0x0006000c, 0x00000006, 0x00000247, 0x00000001, 0x0000001f, 0x00000246, + 0x00050081, 0x00000006, 0x00000248, 0x00000240, 0x00000247, 0x00050085, 0x00000006, 0x00000249, + 0x0000020f, 0x00000248, 0x0003003e, 0x0000023f, 0x00000249, 0x0004003d, 0x00000006, 0x0000024b, + 0x0000020e, 0x0004007f, 0x00000006, 0x0000024c, 0x0000024b, 0x0004003d, 0x00000006, 0x0000024d, + 0x0000023f, 0x0004003d, 0x00000006, 0x0000024e, 0x0000022e, 0x00050088, 0x00000006, 0x0000024f, + 0x0000024d, 0x0000024e, 0x0004003d, 0x00000006, 0x00000250, 0x0000004a, 0x00050088, 0x00000006, + 0x00000251, 0x000000c7, 0x00000250, 0x0007000c, 0x00000006, 0x00000252, 0x00000001, 0x0000001a, + 0x0000024f, 0x00000251, 0x00050085, 0x00000006, 0x00000253, 0x0000024c, 0x00000252, 0x0004003d, + 0x00000006, 0x00000254, 0x0000023f, 0x0004003d, 0x00000006, 0x00000255, 0x0000022e, 0x00050088, + 0x00000006, 0x00000256, 0x00000254, 0x00000255, 0x0004003d, 0x00000006, 0x00000257, 0x0000004a, + 0x00050088, 0x00000006, 0x00000258, 0x000000c7, 0x00000257, 0x0007000c, 0x00000006, 0x00000259, + 0x00000001, 0x0000001a, 0x00000256, 0x00000258, 0x00050083, 0x00000006, 0x0000025a, 0x00000259, + 0x000000c7, 0x00050088, 0x00000006, 0x0000025b, 0x00000253, 0x0000025a, 0x0003003e, 0x0000024a, + 0x0000025b, 0x0004003d, 0x00000006, 0x0000025e, 0x0000024a, 0x00050088, 0x00000006, 0x0000025f, + 0x0000025d, 0x0000025e, 0x0003003e, 0x0000025c, 0x0000025f, 0x0004003d, 0x00000006, 0x00000261, + 0x0000025c, 0x0004003d, 0x00000006, 0x00000262, 0x0000020e, 0x00050085, 0x00000006, 0x00000263, + 0x00000261, 0x00000262, 0x0003003e, 0x00000260, 0x00000263, 0x0004003d, 0x00000006, 0x00000265, + 0x0000021b, 0x0004003d, 0x00000006, 0x00000266, 0x0000020e, 0x00050088, 0x00000006, 0x00000267, + 0x00000265, 0x00000266, 0x0004003d, 0x00000006, 0x00000268, 0x0000021b, 0x0004003d, 0x00000006, + 0x00000269, 0x0000020e, 0x00050088, 0x00000006, 0x0000026a, 0x00000268, 0x00000269, 0x0004003d, + 0x00000006, 0x0000026b, 0x0000025c, 0x00050081, 0x00000006, 0x0000026c, 0x0000026a, 0x0000026b, + 0x00050088, 0x00000006, 0x0000026d, 0x00000267, 0x0000026c, 0x0004003d, 0x00000006, 0x0000026e, + 0x0000004a, 0x0007000c, 0x00000006, 0x0000026f, 0x00000001, 0x0000001a, 0x0000026d, 0x0000026e, + 0x0003003e, 0x00000264, 0x0000026f, 0x0004003d, 0x00000006, 0x00000271, 0x0000020e, 0x0004003d, + 0x00000006, 0x00000272, 0x00000264, 0x00050088, 0x00000006, 0x00000273, 0x00000271, 0x00000272, + 0x0003003e, 0x00000270, 0x00000273, 0x0004003d, 0x00000006, 0x00000275, 0x00000048, 0x0007000c, + 0x00000006, 0x00000276, 0x00000001, 0x00000028, 0x0000007c, 0x00000275, 0x0004003d, 0x00000006, + 0x00000277, 0x00000048, 0x0004003d, 0x00000006, 0x00000278, 0x00000260, 0x00050081, 0x00000006, + 0x00000279, 0x00000277, 0x00000278, 0x00050088, 0x00000006, 0x0000027a, 0x00000276, 0x00000279, + 0x0004003d, 0x00000006, 0x0000027b, 0x0000004a, 0x0007000c, 0x00000006, 0x0000027c, 0x00000001, + 0x0000001a, 0x0000027a, 0x0000027b, 0x0004003d, 0x00000006, 0x0000027d, 0x00000270, 0x00050085, + 0x00000006, 0x0000027e, 0x0000027c, 0x0000027d, 0x0003003e, 0x00000274, 0x0000027e, 0x0004003d, + 0x00000006, 0x0000027f, 0x00000274, 0x0004003d, 0x00000006, 0x00000280, 0x00000274, 0x00050085, + 0x00000006, 0x00000281, 0x0000027f, 0x00000280, 0x0004003d, 0x00000006, 0x00000282, 0x00000274, + 0x0004003d, 0x00000006, 0x00000283, 0x0000004c, 0x00050081, 0x00000006, 0x00000284, 0x00000282, + 0x00000283, 0x00050088, 0x00000006, 0x00000285, 0x00000281, 0x00000284, 0x0007000c, 0x00000006, + 0x00000286, 0x00000001, 0x00000028, 0x0000007c, 0x00000285, 0x000200fe, 0x00000286, 0x00010038, + 0x00050036, 0x00000007, 0x00000055, 0x00000000, 0x00000052, 0x00030037, 0x0000000a, 0x00000053, + 0x00030037, 0x00000051, 0x00000054, 0x000200f8, 0x00000056, 0x0004003b, 0x00000014, 0x00000289, + 0x00000007, 0x0004003b, 0x00000014, 0x0000028f, 0x00000007, 0x0004003b, 0x0000000a, 0x00000290, + 0x00000007, 0x0004003b, 0x00000014, 0x00000293, 0x00000007, 0x0004003b, 0x00000014, 0x0000029a, + 0x00000007, 0x0004003b, 0x00000014, 0x0000029c, 0x00000007, 0x0004003b, 0x00000014, 0x0000029f, + 0x00000007, 0x0004003b, 0x00000014, 0x000002a2, 0x00000007, 0x0004003b, 0x00000014, 0x000002a4, + 0x00000007, 0x0004003b, 0x00000014, 0x000002a7, 0x00000007, 0x0004003b, 0x00000014, 0x000002a9, + 0x00000007, 0x0004003b, 0x00000014, 0x000002ad, 0x00000007, 0x0004003b, 0x00000014, 0x000002af, + 0x00000007, 0x0004003b, 0x00000014, 0x000002b2, 0x00000007, 0x0004003b, 0x00000014, 0x000002b5, + 0x00000007, 0x0004003b, 0x00000014, 0x000002b8, 0x00000007, 0x0004003b, 0x0000000a, 0x000002be, + 0x00000007, 0x0004003b, 0x00000014, 0x000002c2, 0x00000007, 0x0004003b, 0x0000000a, 0x000002e9, + 0x00000007, 0x0004003b, 0x0000000a, 0x000002ea, 0x00000007, 0x0004003b, 0x0000000a, 0x000002f2, + 0x00000007, 0x0004003b, 0x0000000a, 0x000002f3, 0x00000007, 0x0004003b, 0x00000014, 0x000002f6, + 0x00000007, 0x0004003b, 0x00000014, 0x00000309, 0x00000007, 0x0004003b, 0x00000014, 0x0000030b, + 0x00000007, 0x0004003b, 0x00000014, 0x0000030c, 0x00000007, 0x0004003b, 0x00000014, 0x0000032e, + 0x00000007, 0x0004003b, 0x00000014, 0x00000334, 0x00000007, 0x0004003b, 0x0000000a, 0x00000354, + 0x00000007, 0x00050041, 0x00000014, 0x0000028c, 0x00000054, 0x0000028b, 0x0004003d, 0x00000006, + 0x0000028d, 0x0000028c, 0x00050088, 0x00000006, 0x0000028e, 0x0000028d, 0x0000020c, 0x0003003e, + 0x00000289, 0x0000028e, 0x0004003d, 0x00000007, 0x00000291, 0x00000053, 0x0003003e, 0x00000290, + 0x00000291, 0x00050039, 0x00000006, 0x00000292, 0x00000012, 0x00000290, 0x0003003e, 0x0000028f, + 0x00000292, 0x0004003d, 0x00000006, 0x00000294, 0x0000028f, 0x00050041, 0x00000014, 0x00000296, + 0x00000054, 0x00000295, 0x0004003d, 0x00000006, 0x00000297, 0x00000296, 0x00050085, 0x00000006, + 0x00000298, 0x00000294, 0x00000297, 0x0003003e, 0x00000293, 0x00000298, 0x0004003d, 0x00000006, + 0x0000029b, 0x00000293, 0x0003003e, 0x0000029a, 0x0000029b, 0x00050041, 0x00000014, 0x0000029d, + 0x00000054, 0x00000299, 0x0004003d, 0x00000006, 0x0000029e, 0x0000029d, 0x0003003e, 0x0000029c, + 0x0000029e, 0x0003003e, 0x0000029f, 0x0000025d, 0x00070039, 0x00000006, 0x000002a0, 0x00000040, + 0x0000029a, 0x0000029c, 0x0000029f, 0x0003003e, 0x00000293, 0x000002a0, 0x0004003d, 0x00000006, + 0x000002a3, 0x00000293, 0x0003003e, 0x000002a2, 0x000002a3, 0x00050041, 0x00000014, 0x000002a5, + 0x00000054, 0x000002a1, 0x0004003d, 0x00000006, 0x000002a6, 0x000002a5, 0x0003003e, 0x000002a4, + 0x000002a6, 0x0003003e, 0x000002a7, 0x0000025d, 0x00070039, 0x00000006, 0x000002a8, 0x00000045, + 0x000002a2, 0x000002a4, 0x000002a7, 0x0003003e, 0x00000293, 0x000002a8, 0x0004003d, 0x00000006, + 0x000002ae, 0x00000293, 0x0003003e, 0x000002ad, 0x000002ae, 0x00050041, 0x00000014, 0x000002b0, + 0x00000054, 0x0000028b, 0x0004003d, 0x00000006, 0x000002b1, 0x000002b0, 0x0003003e, 0x000002af, + 0x000002b1, 0x00050041, 0x00000014, 0x000002b3, 0x00000054, 0x000002aa, 0x0004003d, 0x00000006, + 0x000002b4, 0x000002b3, 0x0003003e, 0x000002b2, 0x000002b4, 0x00050041, 0x00000014, 0x000002b6, + 0x00000054, 0x000002ab, 0x0004003d, 0x00000006, 0x000002b7, 0x000002b6, 0x0003003e, 0x000002b5, + 0x000002b7, 0x00050041, 0x00000014, 0x000002b9, 0x00000054, 0x000002ac, 0x0004003d, 0x00000006, + 0x000002ba, 0x000002b9, 0x0003003e, 0x000002b8, 0x000002ba, 0x00090039, 0x00000006, 0x000002bb, + 0x0000004d, 0x000002ad, 0x000002af, 0x000002b2, 0x000002b5, 0x000002b8, 0x0004003d, 0x00000006, + 0x000002bc, 0x00000289, 0x0008000c, 0x00000006, 0x000002bd, 0x00000001, 0x0000002b, 0x000002bb, + 0x0000007c, 0x000002bc, 0x0003003e, 0x000002a9, 0x000002bd, 0x0004003d, 0x00000007, 0x000002bf, + 0x00000053, 0x0004003d, 0x00000006, 0x000002c0, 0x0000028f, 0x000500ba, 0x0000004f, 0x000002c1, + 0x000002c0, 0x0000007c, 0x000300f7, 0x000002c4, 0x00000000, 0x000400fa, 0x000002c1, 0x000002c3, + 0x000002c8, 0x000200f8, 0x000002c3, 0x0004003d, 0x00000006, 0x000002c5, 0x000002a9, 0x0004003d, + 0x00000006, 0x000002c6, 0x0000028f, 0x00050088, 0x00000006, 0x000002c7, 0x000002c5, 0x000002c6, + 0x0003003e, 0x000002c2, 0x000002c7, 0x000200f9, 0x000002c4, 0x000200f8, 0x000002c8, 0x0003003e, + 0x000002c2, 0x0000007c, 0x000200f9, 0x000002c4, 0x000200f8, 0x000002c4, 0x0004003d, 0x00000006, + 0x000002c9, 0x000002c2, 0x0005008e, 0x00000007, 0x000002ca, 0x000002bf, 0x000002c9, 0x0003003e, + 0x000002be, 0x000002ca, 0x00050041, 0x00000014, 0x000002cc, 0x00000054, 0x000002cb, 0x0004003d, + 0x00000006, 0x000002cd, 0x000002cc, 0x000500b7, 0x0000004f, 0x000002ce, 0x000002cd, 0x0000007c, + 0x000400a8, 0x0000004f, 0x000002cf, 0x000002ce, 0x000300f7, 0x000002d1, 0x00000000, 0x000400fa, + 0x000002cf, 0x000002d0, 0x000002d1, 0x000200f8, 0x000002d0, 0x00050041, 0x00000014, 0x000002d3, + 0x00000054, 0x000002d2, 0x0004003d, 0x00000006, 0x000002d4, 0x000002d3, 0x000500b7, 0x0000004f, + 0x000002d5, 0x000002d4, 0x000000c7, 0x000200f9, 0x000002d1, 0x000200f8, 0x000002d1, 0x000700f5, + 0x0000004f, 0x000002d6, 0x000002ce, 0x000002c4, 0x000002d5, 0x000002d0, 0x000400a8, 0x0000004f, + 0x000002d7, 0x000002d6, 0x000300f7, 0x000002d9, 0x00000000, 0x000400fa, 0x000002d7, 0x000002d8, + 0x000002d9, 0x000200f8, 0x000002d8, 0x00050041, 0x00000014, 0x000002db, 0x00000054, 0x000002da, + 0x0004003d, 0x00000006, 0x000002dc, 0x000002db, 0x000500b7, 0x0000004f, 0x000002dd, 0x000002dc, + 0x0000007c, 0x000200f9, 0x000002d9, 0x000200f8, 0x000002d9, 0x000700f5, 0x0000004f, 0x000002de, + 0x000002d6, 0x000002d1, 0x000002dd, 0x000002d8, 0x000400a8, 0x0000004f, 0x000002df, 0x000002de, + 0x000300f7, 0x000002e1, 0x00000000, 0x000400fa, 0x000002df, 0x000002e0, 0x000002e1, 0x000200f8, + 0x000002e0, 0x00050041, 0x00000014, 0x000002e3, 0x00000054, 0x000002e2, 0x0004003d, 0x00000006, + 0x000002e4, 0x000002e3, 0x000500b7, 0x0000004f, 0x000002e5, 0x000002e4, 0x0000007c, 0x000200f9, + 0x000002e1, 0x000200f8, 0x000002e1, 0x000700f5, 0x0000004f, 0x000002e6, 0x000002de, 0x000002d9, + 0x000002e5, 0x000002e0, 0x000300f7, 0x000002e8, 0x00000000, 0x000400fa, 0x000002e6, 0x000002e7, + 0x000002e8, 0x000200f8, 0x000002e7, 0x0004003d, 0x00000007, 0x000002eb, 0x000002be, 0x0003003e, + 0x000002ea, 0x000002eb, 0x00050039, 0x00000007, 0x000002ec, 0x00000025, 0x000002ea, 0x0003003e, + 0x000002e9, 0x000002ec, 0x00050041, 0x00000014, 0x000002ed, 0x00000054, 0x000002da, 0x0004003d, + 0x00000006, 0x000002ee, 0x000002ed, 0x000500b7, 0x0000004f, 0x000002ef, 0x000002ee, 0x0000007c, + 0x000300f7, 0x000002f1, 0x00000000, 0x000400fa, 0x000002ef, 0x000002f0, 0x000002f1, 0x000200f8, + 0x000002f0, 0x0004003d, 0x00000007, 0x000002f4, 0x00000053, 0x0003003e, 0x000002f3, 0x000002f4, + 0x00050039, 0x00000007, 0x000002f5, 0x00000025, 0x000002f3, 0x0003003e, 0x000002f2, 0x000002f5, + 0x0004003d, 0x00000007, 0x000002f7, 0x000002e9, 0x0007004f, 0x0000011a, 0x000002f8, 0x000002f7, + 0x000002f7, 0x00000001, 0x00000002, 0x0006000c, 0x00000006, 0x000002f9, 0x00000001, 0x00000042, + 0x000002f8, 0x0003003e, 0x000002f6, 0x000002f9, 0x0004003d, 0x00000007, 0x000002fa, 0x000002e9, + 0x0007004f, 0x0000011a, 0x000002fb, 0x000002fa, 0x000002fa, 0x00000001, 0x00000002, 0x0004003d, + 0x00000007, 0x000002fc, 0x000002f2, 0x0007004f, 0x0000011a, 0x000002fd, 0x000002fc, 0x000002fc, + 0x00000001, 0x00000002, 0x00050041, 0x00000014, 0x000002fe, 0x00000054, 0x000002da, 0x0004003d, + 0x00000006, 0x000002ff, 0x000002fe, 0x00050050, 0x0000011a, 0x00000300, 0x000002ff, 0x000002ff, + 0x0008000c, 0x0000011a, 0x00000301, 0x00000001, 0x0000002e, 0x000002fb, 0x000002fd, 0x00000300, + 0x00050041, 0x00000014, 0x00000302, 0x000002e9, 0x0000012d, 0x00050051, 0x00000006, 0x00000303, + 0x00000301, 0x00000000, 0x0003003e, 0x00000302, 0x00000303, 0x00050041, 0x00000014, 0x00000304, + 0x000002e9, 0x00000130, 0x00050051, 0x00000006, 0x00000305, 0x00000301, 0x00000001, 0x0003003e, + 0x00000304, 0x00000305, 0x0004003d, 0x00000007, 0x00000306, 0x000002e9, 0x0007004f, 0x0000011a, + 0x00000307, 0x00000306, 0x00000306, 0x00000001, 0x00000002, 0x0006000c, 0x00000006, 0x00000308, + 0x00000001, 0x00000042, 0x00000307, 0x0004003d, 0x00000006, 0x0000030a, 0x000002f6, 0x0003003e, + 0x00000309, 0x0000030a, 0x0003003e, 0x0000030b, 0x00000308, 0x0003003e, 0x0000030c, 0x000000c7, + 0x00070039, 0x00000006, 0x0000030d, 0x00000019, 0x00000309, 0x0000030b, 0x0000030c, 0x0004003d, + 0x00000007, 0x0000030e, 0x000002e9, 0x0007004f, 0x0000011a, 0x0000030f, 0x0000030e, 0x0000030e, + 0x00000001, 0x00000002, 0x0005008e, 0x0000011a, 0x00000310, 0x0000030f, 0x0000030d, 0x00050041, + 0x00000014, 0x00000311, 0x000002e9, 0x0000012d, 0x00050051, 0x00000006, 0x00000312, 0x00000310, + 0x00000000, 0x0003003e, 0x00000311, 0x00000312, 0x00050041, 0x00000014, 0x00000313, 0x000002e9, + 0x00000130, 0x00050051, 0x00000006, 0x00000314, 0x00000310, 0x00000001, 0x0003003e, 0x00000313, + 0x00000314, 0x000200f9, 0x000002f1, 0x000200f8, 0x000002f1, 0x00050041, 0x00000014, 0x00000315, + 0x00000054, 0x000002cb, 0x0004003d, 0x00000006, 0x00000316, 0x00000315, 0x000500b7, 0x0000004f, + 0x00000317, 0x00000316, 0x0000007c, 0x000300f7, 0x00000319, 0x00000000, 0x000400fa, 0x00000317, + 0x00000318, 0x00000319, 0x000200f8, 0x00000318, 0x0004003d, 0x00000006, 0x0000031a, 0x0000028f, + 0x00050088, 0x00000006, 0x0000031b, 0x0000031a, 0x0000020c, 0x00050041, 0x00000014, 0x0000031c, + 0x00000054, 0x000002cb, 0x0004003d, 0x00000006, 0x0000031d, 0x0000031c, 0x00050083, 0x00000006, + 0x0000031e, 0x000000c7, 0x0000031d, 0x0007000c, 0x00000006, 0x0000031f, 0x00000001, 0x0000001a, + 0x0000031b, 0x0000031e, 0x0008000c, 0x00000006, 0x00000320, 0x00000001, 0x0000002b, 0x0000031f, + 0x0000007c, 0x000000c7, 0x0008000c, 0x00000006, 0x00000321, 0x00000001, 0x0000002e, 0x000000c7, + 0x0000007c, 0x00000320, 0x0004003d, 0x00000007, 0x00000322, 0x000002e9, 0x0007004f, 0x0000011a, + 0x00000323, 0x00000322, 0x00000322, 0x00000001, 0x00000002, 0x0005008e, 0x0000011a, 0x00000324, + 0x00000323, 0x00000321, 0x00050041, 0x00000014, 0x00000325, 0x000002e9, 0x0000012d, 0x00050051, + 0x00000006, 0x00000326, 0x00000324, 0x00000000, 0x0003003e, 0x00000325, 0x00000326, 0x00050041, + 0x00000014, 0x00000327, 0x000002e9, 0x00000130, 0x00050051, 0x00000006, 0x00000328, 0x00000324, + 0x00000001, 0x0003003e, 0x00000327, 0x00000328, 0x000200f9, 0x00000319, 0x000200f8, 0x00000319, + 0x00050041, 0x00000014, 0x00000329, 0x00000054, 0x000002e2, 0x0004003d, 0x00000006, 0x0000032a, + 0x00000329, 0x000500b7, 0x0000004f, 0x0000032b, 0x0000032a, 0x0000007c, 0x000300f7, 0x0000032d, + 0x00000000, 0x000400fa, 0x0000032b, 0x0000032c, 0x0000032d, 0x000200f8, 0x0000032c, 0x0004003d, + 0x00000006, 0x0000032f, 0x0000028f, 0x00050085, 0x00000006, 0x00000330, 0x0000032f, 0x0000020c, + 0x00050088, 0x00000006, 0x00000332, 0x00000330, 0x00000331, 0x0008000c, 0x00000006, 0x00000333, + 0x00000001, 0x0000002b, 0x00000332, 0x0000007c, 0x000000c7, 0x0003003e, 0x0000032e, 0x00000333, + 0x0004003d, 0x00000006, 0x00000335, 0x0000032e, 0x00050083, 0x00000006, 0x00000336, 0x000000c7, + 0x00000335, 0x00050041, 0x00000014, 0x00000337, 0x00000054, 0x000002e2, 0x0004003d, 0x00000006, + 0x00000338, 0x00000337, 0x0006000c, 0x00000006, 0x00000339, 0x00000001, 0x00000004, 0x00000338, + 0x00050085, 0x00000006, 0x0000033a, 0x0000020c, 0x00000339, 0x0007000c, 0x00000006, 0x0000033b, + 0x00000001, 0x0000001a, 0x00000336, 0x0000033a, 0x0003003e, 0x00000334, 0x0000033b, 0x00050041, + 0x00000014, 0x0000033c, 0x00000054, 0x000002e2, 0x0004003d, 0x00000006, 0x0000033d, 0x0000033c, + 0x000500b8, 0x0000004f, 0x0000033e, 0x0000033d, 0x0000007c, 0x000300f7, 0x00000340, 0x00000000, + 0x000400fa, 0x0000033e, 0x0000033f, 0x00000340, 0x000200f8, 0x0000033f, 0x0004003d, 0x00000006, + 0x00000341, 0x00000334, 0x00050083, 0x00000006, 0x00000342, 0x00000193, 0x00000341, 0x0003003e, + 0x00000334, 0x00000342, 0x000200f9, 0x00000340, 0x000200f8, 0x00000340, 0x0004003d, 0x00000006, + 0x00000343, 0x00000334, 0x0004003d, 0x00000007, 0x00000344, 0x000002e9, 0x0007004f, 0x0000011a, + 0x00000345, 0x00000344, 0x00000344, 0x00000001, 0x00000002, 0x0005008e, 0x0000011a, 0x00000346, + 0x00000345, 0x00000343, 0x00050041, 0x00000014, 0x00000347, 0x000002e9, 0x0000012d, 0x00050051, + 0x00000006, 0x00000348, 0x00000346, 0x00000000, 0x0003003e, 0x00000347, 0x00000348, 0x00050041, + 0x00000014, 0x00000349, 0x000002e9, 0x00000130, 0x00050051, 0x00000006, 0x0000034a, 0x00000346, + 0x00000001, 0x0003003e, 0x00000349, 0x0000034a, 0x000200f9, 0x0000032d, 0x000200f8, 0x0000032d, + 0x00050041, 0x00000014, 0x0000034b, 0x00000054, 0x000002d2, 0x0004003d, 0x00000006, 0x0000034c, + 0x0000034b, 0x0004003d, 0x00000007, 0x0000034d, 0x000002e9, 0x0007004f, 0x0000011a, 0x0000034e, + 0x0000034d, 0x0000034d, 0x00000001, 0x00000002, 0x0005008e, 0x0000011a, 0x0000034f, 0x0000034e, + 0x0000034c, 0x00050041, 0x00000014, 0x00000350, 0x000002e9, 0x0000012d, 0x00050051, 0x00000006, + 0x00000351, 0x0000034f, 0x00000000, 0x0003003e, 0x00000350, 0x00000351, 0x00050041, 0x00000014, + 0x00000352, 0x000002e9, 0x00000130, 0x00050051, 0x00000006, 0x00000353, 0x0000034f, 0x00000001, + 0x0003003e, 0x00000352, 0x00000353, 0x0004003d, 0x00000007, 0x00000355, 0x000002e9, 0x0003003e, + 0x00000354, 0x00000355, 0x00050039, 0x00000007, 0x00000356, 0x00000028, 0x00000354, 0x0003003e, + 0x000002be, 0x00000356, 0x000200f9, 0x000002e8, 0x000200f8, 0x000002e8, 0x00050041, 0x00000358, + 0x00000359, 0x00000054, 0x00000357, 0x0004003d, 0x0000004f, 0x0000035a, 0x00000359, 0x000300f7, + 0x0000035c, 0x00000000, 0x000400fa, 0x0000035a, 0x0000035b, 0x0000035c, 0x000200f8, 0x0000035b, + 0x0004003d, 0x00000007, 0x0000035d, 0x000002be, 0x0007000c, 0x00000007, 0x0000035e, 0x00000001, + 0x00000028, 0x0000035d, 0x00000090, 0x0003003e, 0x000002be, 0x0000035e, 0x000200f9, 0x0000035c, + 0x000200f8, 0x0000035c, 0x0004003d, 0x00000007, 0x0000035f, 0x000002be, 0x0004003d, 0x00000006, + 0x00000360, 0x00000289, 0x00060050, 0x00000007, 0x00000361, 0x00000360, 0x00000360, 0x00000360, + 0x0007000c, 0x00000007, 0x00000362, 0x00000001, 0x00000025, 0x0000035f, 0x00000361, 0x000200fe, + 0x00000362, 0x00010038, 0x00050036, 0x00000007, 0x00000058, 0x00000000, 0x00000020, 0x00030037, + 0x0000000a, 0x00000057, 0x000200f8, 0x00000059, 0x0004003b, 0x00000051, 0x00000365, 0x00000007, + 0x0004003b, 0x0000000a, 0x00000369, 0x00000007, 0x0004003b, 0x00000051, 0x0000036b, 0x00000007, + 0x0003003e, 0x00000365, 0x00000368, 0x0004003d, 0x00000007, 0x0000036a, 0x00000057, 0x0003003e, + 0x00000369, 0x0000036a, 0x0004003d, 0x00000050, 0x0000036c, 0x00000365, 0x0003003e, 0x0000036b, + 0x0000036c, 0x00060039, 0x00000007, 0x0000036d, 0x00000055, 0x00000369, 0x0000036b, 0x000200fe, + 0x0000036d, 0x00010038, 0x00050036, 0x00000007, 0x0000005f, 0x00000000, 0x0000005a, 0x00030037, + 0x0000000a, 0x0000005b, 0x00030037, 0x0000000a, 0x0000005c, 0x00030037, 0x0000000a, 0x0000005d, + 0x00030037, 0x00000014, 0x0000005e, 0x000200f8, 0x00000060, 0x0004003b, 0x00000014, 0x00000370, + 0x00000007, 0x0004003b, 0x0000000a, 0x00000371, 0x00000007, 0x0004003b, 0x00000014, 0x00000374, + 0x00000007, 0x0004003b, 0x0000000a, 0x00000375, 0x00000007, 0x0004003b, 0x00000014, 0x00000378, + 0x00000007, 0x0004003b, 0x0000000a, 0x00000379, 0x00000007, 0x0004003b, 0x00000014, 0x00000381, + 0x00000007, 0x0004003b, 0x00000014, 0x00000386, 0x00000007, 0x0004003b, 0x00000014, 0x0000038f, + 0x00000007, 0x0004003b, 0x0000000a, 0x00000397, 0x00000007, 0x0004003b, 0x0000000a, 0x0000039b, + 0x00000007, 0x0004003b, 0x0000000a, 0x0000039c, 0x00000007, 0x0004003d, 0x00000007, 0x00000372, + 0x0000005b, 0x0003003e, 0x00000371, 0x00000372, 0x00050039, 0x00000006, 0x00000373, 0x00000012, + 0x00000371, 0x0003003e, 0x00000370, 0x00000373, 0x0004003d, 0x00000007, 0x00000376, 0x0000005c, + 0x0003003e, 0x00000375, 0x00000376, 0x00050039, 0x00000006, 0x00000377, 0x00000012, 0x00000375, + 0x0003003e, 0x00000374, 0x00000377, 0x0004003d, 0x00000007, 0x0000037a, 0x0000005d, 0x0003003e, + 0x00000379, 0x0000037a, 0x00050039, 0x00000006, 0x0000037b, 0x00000012, 0x00000379, 0x0003003e, + 0x00000378, 0x0000037b, 0x0004003d, 0x00000006, 0x0000037c, 0x00000370, 0x0004003d, 0x00000006, + 0x0000037d, 0x00000374, 0x000500b8, 0x0000004f, 0x0000037e, 0x0000037c, 0x0000037d, 0x000300f7, + 0x00000380, 0x00000000, 0x000400fa, 0x0000037e, 0x0000037f, 0x00000385, 0x000200f8, 0x0000037f, + 0x0004003d, 0x00000006, 0x00000382, 0x00000370, 0x0004003d, 0x00000006, 0x00000383, 0x00000374, + 0x00050088, 0x00000006, 0x00000384, 0x00000382, 0x00000383, 0x0003003e, 0x00000381, 0x00000384, + 0x000200f9, 0x00000380, 0x000200f8, 0x00000385, 0x0004003d, 0x00000006, 0x00000387, 0x00000378, + 0x0004003d, 0x00000006, 0x00000388, 0x00000370, 0x0004003d, 0x00000006, 0x00000389, 0x00000374, + 0x00050083, 0x00000006, 0x0000038a, 0x00000388, 0x00000389, 0x0007000c, 0x00000006, 0x0000038b, + 0x00000001, 0x00000028, 0x0000007c, 0x0000038a, 0x00050081, 0x00000006, 0x0000038c, 0x00000387, + 0x0000038b, 0x0003003e, 0x00000386, 0x0000038c, 0x0004003d, 0x00000006, 0x0000038d, 0x00000378, + 0x000500ba, 0x0000004f, 0x0000038e, 0x0000038d, 0x0000007c, 0x000300f7, 0x00000391, 0x00000000, + 0x000400fa, 0x0000038e, 0x00000390, 0x00000395, 0x000200f8, 0x00000390, 0x0004003d, 0x00000006, + 0x00000392, 0x00000386, 0x0004003d, 0x00000006, 0x00000393, 0x00000378, 0x00050088, 0x00000006, + 0x00000394, 0x00000392, 0x00000393, 0x0003003e, 0x0000038f, 0x00000394, 0x000200f9, 0x00000391, + 0x000200f8, 0x00000395, 0x0003003e, 0x0000038f, 0x0000007c, 0x000200f9, 0x00000391, 0x000200f8, + 0x00000391, 0x0004003d, 0x00000006, 0x00000396, 0x0000038f, 0x0003003e, 0x00000381, 0x00000396, + 0x000200f9, 0x00000380, 0x000200f8, 0x00000380, 0x0004003d, 0x00000007, 0x00000398, 0x0000005d, + 0x0004003d, 0x00000006, 0x00000399, 0x00000381, 0x0005008e, 0x00000007, 0x0000039a, 0x00000398, + 0x00000399, 0x0003003e, 0x0000039b, 0x0000039a, 0x0004003d, 0x00000007, 0x0000039d, 0x0000005d, + 0x0003003e, 0x0000039c, 0x0000039d, 0x00060039, 0x00000007, 0x0000039e, 0x0000002f, 0x0000039b, + 0x0000039c, 0x0003003e, 0x00000397, 0x0000039e, 0x0004003d, 0x00000007, 0x0000039f, 0x0000005b, + 0x0004003d, 0x00000007, 0x000003a0, 0x00000397, 0x0004003d, 0x00000006, 0x000003a1, 0x0000005e, + 0x00060050, 0x00000007, 0x000003a2, 0x000003a1, 0x000003a1, 0x000003a1, 0x0008000c, 0x00000007, + 0x000003a3, 0x00000001, 0x0000002e, 0x0000039f, 0x000003a0, 0x000003a2, 0x000200fe, 0x000003a3, + 0x00010038, 0x00050036, 0x00000007, 0x00000062, 0x00000000, 0x00000020, 0x00030037, 0x0000000a, + 0x00000061, 0x000200f8, 0x00000063, 0x0004003d, 0x00000007, 0x000003a6, 0x00000061, 0x0004003d, + 0x00000007, 0x000003a8, 0x00000061, 0x0005008e, 0x00000007, 0x000003a9, 0x000003a8, 0x000003a7, + 0x00060050, 0x00000007, 0x000003ab, 0x000003aa, 0x000003aa, 0x000003aa, 0x00050081, 0x00000007, + 0x000003ac, 0x000003a9, 0x000003ab, 0x00050085, 0x00000007, 0x000003ad, 0x000003a6, 0x000003ac, + 0x0004003d, 0x00000007, 0x000003ae, 0x00000061, 0x0004003d, 0x00000007, 0x000003b0, 0x00000061, + 0x0005008e, 0x00000007, 0x000003b1, 0x000003b0, 0x000003af, 0x00060050, 0x00000007, 0x000003b3, + 0x000003b2, 0x000003b2, 0x000003b2, 0x00050081, 0x00000007, 0x000003b4, 0x000003b1, 0x000003b3, + 0x00050085, 0x00000007, 0x000003b5, 0x000003ae, 0x000003b4, 0x00060050, 0x00000007, 0x000003b7, + 0x000003b6, 0x000003b6, 0x000003b6, 0x00050081, 0x00000007, 0x000003b8, 0x000003b5, 0x000003b7, + 0x00050088, 0x00000007, 0x000003b9, 0x000003ad, 0x000003b8, 0x00060050, 0x00000007, 0x000003ba, + 0x0000007c, 0x0000007c, 0x0000007c, 0x00060050, 0x00000007, 0x000003bb, 0x000000c7, 0x000000c7, + 0x000000c7, 0x0008000c, 0x00000007, 0x000003bc, 0x00000001, 0x0000002b, 0x000003b9, 0x000003ba, + 0x000003bb, 0x000200fe, 0x000003bc, 0x00010038, 0x00050036, 0x00000007, 0x0000006c, 0x00000000, + 0x00000066, 0x00030037, 0x0000000a, 0x00000067, 0x00030037, 0x00000065, 0x00000068, 0x00030037, + 0x00000065, 0x00000069, 0x00030037, 0x00000065, 0x0000006a, 0x00030037, 0x00000065, 0x0000006b, + 0x000200f8, 0x0000006d, 0x0004003b, 0x0000000a, 0x000003bf, 0x00000007, 0x0004003b, 0x0000000a, + 0x000003c0, 0x00000007, 0x0004003b, 0x0000000a, 0x000003cb, 0x00000007, 0x0004003b, 0x0000000a, + 0x000003d2, 0x00000007, 0x0004003b, 0x0000000a, 0x000003d6, 0x00000007, 0x0004003b, 0x0000000a, + 0x000003db, 0x00000007, 0x0004003b, 0x0000000a, 0x000003de, 0x00000007, 0x0004003b, 0x0000000a, + 0x000003e0, 0x00000007, 0x0004003b, 0x0000000a, 0x000003e1, 0x00000007, 0x0004003b, 0x00000014, + 0x000003e3, 0x00000007, 0x0004003b, 0x00000014, 0x000003e8, 0x00000007, 0x0004003b, 0x00000014, + 0x000003f9, 0x00000007, 0x0004003b, 0x00000014, 0x000003fb, 0x00000007, 0x0004003b, 0x00000051, + 0x000003fd, 0x00000007, 0x0004003b, 0x0000000a, 0x00000419, 0x00000007, 0x0004003b, 0x00000051, + 0x0000041b, 0x00000007, 0x0004003d, 0x00000007, 0x000003c1, 0x00000067, 0x0003003e, 0x000003c0, + 0x000003c1, 0x00050039, 0x00000007, 0x000003c2, 0x00000062, 0x000003c0, 0x0003003e, 0x000003bf, + 0x000003c2, 0x00050041, 0x00000014, 0x000003c4, 0x00000068, 0x000003c3, 0x0004003d, 0x00000006, + 0x000003c5, 0x000003c4, 0x000500b8, 0x0000004f, 0x000003c6, 0x000003c5, 0x0000007c, 0x000300f7, + 0x000003c8, 0x00000000, 0x000400fa, 0x000003c6, 0x000003c7, 0x000003c8, 0x000200f8, 0x000003c7, + 0x0004003d, 0x00000007, 0x000003c9, 0x000003bf, 0x000200fe, 0x000003c9, 0x000200f8, 0x000003c8, + 0x0004003d, 0x00000007, 0x000003cc, 0x000003bf, 0x0003003e, 0x000003cb, 0x000003cc, 0x00050041, + 0x00000014, 0x000003cd, 0x00000068, 0x000003c3, 0x0004003d, 0x00000006, 0x000003ce, 0x000003cd, + 0x000500ba, 0x0000004f, 0x000003cf, 0x000003ce, 0x0000007c, 0x000300f7, 0x000003d1, 0x00000000, + 0x000400fa, 0x000003cf, 0x000003d0, 0x000003d1, 0x000200f8, 0x000003d0, 0x00050041, 0x00000014, + 0x000003d3, 0x0000006b, 0x0000012d, 0x0004003d, 0x00000006, 0x000003d4, 0x000003d3, 0x000500b4, + 0x0000004f, 0x000003d5, 0x000003d4, 0x0000007c, 0x000300f7, 0x000003d8, 0x00000000, 0x000400fa, + 0x000003d5, 0x000003d7, 0x000003da, 0x000200f8, 0x000003d7, 0x0004003d, 0x00000007, 0x000003d9, + 0x00000067, 0x0003003e, 0x000003d6, 0x000003d9, 0x000200f9, 0x000003d8, 0x000200f8, 0x000003da, + 0x0004003d, 0x00000007, 0x000003dc, 0x00000067, 0x0003003e, 0x000003db, 0x000003dc, 0x00050039, + 0x00000007, 0x000003dd, 0x00000058, 0x000003db, 0x0004003d, 0x00000007, 0x000003df, 0x00000067, + 0x0003003e, 0x000003de, 0x000003df, 0x0003003e, 0x000003e0, 0x000003dd, 0x0004003d, 0x00000007, + 0x000003e2, 0x000003bf, 0x0003003e, 0x000003e1, 0x000003e2, 0x00050041, 0x00000014, 0x000003e4, + 0x0000006b, 0x0000012d, 0x0004003d, 0x00000006, 0x000003e5, 0x000003e4, 0x0003003e, 0x000003e3, + 0x000003e5, 0x00080039, 0x00000007, 0x000003e6, 0x0000005f, 0x000003de, 0x000003e0, 0x000003e1, + 0x000003e3, 0x0003003e, 0x000003d6, 0x000003e6, 0x000200f9, 0x000003d8, 0x000200f8, 0x000003d8, + 0x0004003d, 0x00000007, 0x000003e7, 0x000003d6, 0x0003003e, 0x000003d2, 0x000003e7, 0x00050041, + 0x00000014, 0x000003ea, 0x00000068, 0x000003e9, 0x0004003d, 0x00000006, 0x000003eb, 0x000003ea, + 0x00050041, 0x00000014, 0x000003ec, 0x00000068, 0x0000012d, 0x0004003d, 0x00000006, 0x000003ed, + 0x000003ec, 0x00050088, 0x00000006, 0x000003ee, 0x000003eb, 0x000003ed, 0x0003003e, 0x000003e8, + 0x000003ee, 0x00050041, 0x00000014, 0x000003ef, 0x0000006b, 0x00000130, 0x0004003d, 0x00000006, + 0x000003f0, 0x000003ef, 0x000500b7, 0x0000004f, 0x000003f1, 0x000003f0, 0x0000007c, 0x000300f7, + 0x000003f3, 0x00000000, 0x000400fa, 0x000003f1, 0x000003f2, 0x000003f3, 0x000200f8, 0x000003f2, + 0x00050041, 0x00000014, 0x000003f4, 0x0000006b, 0x00000130, 0x0004003d, 0x00000006, 0x000003f5, + 0x000003f4, 0x000500b4, 0x0000004f, 0x000003f6, 0x000003f5, 0x000000c7, 0x000600a9, 0x00000006, + 0x000003f8, 0x000003f6, 0x000003f7, 0x00000149, 0x0004003d, 0x00000006, 0x000003fa, 0x000003e8, + 0x0003003e, 0x000003f9, 0x000003fa, 0x0003003e, 0x000003fb, 0x000003f8, 0x00060039, 0x00000006, + 0x000003fc, 0x00000038, 0x000003f9, 0x000003fb, 0x0003003e, 0x000003e8, 0x000003fc, 0x000200f9, + 0x000003f3, 0x000200f8, 0x000003f3, 0x0004003d, 0x00000006, 0x000003fe, 0x000003e8, 0x00050085, + 0x00000006, 0x000003ff, 0x000003fe, 0x0000020c, 0x00050041, 0x00000014, 0x00000400, 0x00000069, + 0x000003e9, 0x0004003d, 0x00000006, 0x00000401, 0x00000400, 0x00050041, 0x00000014, 0x00000402, + 0x00000069, 0x0000012d, 0x0004003d, 0x00000006, 0x00000403, 0x00000402, 0x00050041, 0x00000014, + 0x00000404, 0x00000069, 0x00000130, 0x0004003d, 0x00000006, 0x00000405, 0x00000404, 0x00050041, + 0x00000014, 0x00000406, 0x00000069, 0x000003c3, 0x0004003d, 0x00000006, 0x00000407, 0x00000406, + 0x00050041, 0x00000014, 0x00000408, 0x0000006a, 0x000003e9, 0x0004003d, 0x00000006, 0x00000409, + 0x00000408, 0x00050041, 0x00000014, 0x0000040a, 0x0000006a, 0x00000130, 0x0004003d, 0x00000006, + 0x0000040b, 0x0000040a, 0x00050041, 0x00000014, 0x0000040d, 0x0000006a, 0x000003c3, 0x0004003d, + 0x00000006, 0x0000040e, 0x0000040d, 0x0007000c, 0x00000006, 0x0000040f, 0x00000001, 0x0000001a, + 0x0000040e, 0x00000162, 0x00050085, 0x00000006, 0x00000410, 0x0000040c, 0x0000040f, 0x00050041, + 0x00000014, 0x00000411, 0x0000006b, 0x000003e9, 0x0004003d, 0x00000006, 0x00000412, 0x00000411, + 0x00050041, 0x00000014, 0x00000413, 0x0000006a, 0x0000012d, 0x0004003d, 0x00000006, 0x00000414, + 0x00000413, 0x00050083, 0x00000006, 0x00000415, 0x00000414, 0x000000c7, 0x0004007f, 0x00000006, + 0x00000416, 0x00000415, 0x000f0050, 0x00000050, 0x00000418, 0x000003ff, 0x00000401, 0x00000403, + 0x00000405, 0x00000407, 0x00000409, 0x0000040b, 0x00000410, 0x00000412, 0x00000416, 0x00000366, + 0x00000417, 0x0003003e, 0x000003fd, 0x00000418, 0x0004003d, 0x00000007, 0x0000041a, 0x000003d2, + 0x0003003e, 0x00000419, 0x0000041a, 0x0004003d, 0x00000050, 0x0000041c, 0x000003fd, 0x0003003e, + 0x0000041b, 0x0000041c, 0x00060039, 0x00000007, 0x0000041d, 0x00000055, 0x00000419, 0x0000041b, + 0x0003003e, 0x000003cb, 0x0000041d, 0x000200f9, 0x000003d1, 0x000200f8, 0x000003d1, 0x00050041, + 0x00000014, 0x0000041e, 0x00000068, 0x0000012d, 0x0004003d, 0x00000006, 0x0000041f, 0x0000041e, + 0x00050041, 0x00000014, 0x00000420, 0x00000068, 0x00000130, 0x0004003d, 0x00000006, 0x00000421, + 0x00000420, 0x00050088, 0x00000006, 0x00000422, 0x0000041f, 0x00000421, 0x0004003d, 0x00000007, + 0x00000423, 0x000003cb, 0x0005008e, 0x00000007, 0x00000424, 0x00000423, 0x00000422, 0x0003003e, + 0x000003cb, 0x00000424, 0x0004003d, 0x00000007, 0x00000425, 0x000003cb, 0x0004003d, 0x00000007, + 0x00000426, 0x000003cb, 0x0004009c, 0x00000091, 0x00000427, 0x00000426, 0x000600a9, 0x00000007, + 0x00000428, 0x00000427, 0x00000090, 0x00000425, 0x000200fe, 0x00000428, 0x00010038, }; diff --git a/runtime/hdr_ui_spv.h b/runtime/hdr_ui_spv.h index 1854ac8a..95557b01 100644 --- a/runtime/hdr_ui_spv.h +++ b/runtime/hdr_ui_spv.h @@ -1,15 +1,15 @@ // Generated by tools/build_shaders.py from runtime/shaders/hdr_ui.frag; do not edit. -// source sha256 59cfbb1ab5393fdb743016cbf75a085ee8a05929c7ea67a69b4ab77f26a14303 +// source sha256 c079e2083b25881a388f6278ef906080d9dcac51383bd30fc2b71dc2ecf82ac9 #pragma once #include static const uint32_t hdr_ui_spv[] = { - 0x07230203, 0x00010300, 0x000d000b, 0x000000be, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, + 0x07230203, 0x00010300, 0x000d000b, 0x000000da, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, - 0x0007000f, 0x00000004, 0x00000004, 0x6e69616d, 0x00000000, 0x0000004f, 0x00000068, 0x00030010, + 0x0007000f, 0x00000004, 0x00000004, 0x6e69616d, 0x00000000, 0x0000004f, 0x00000088, 0x00030010, 0x00000004, 0x00000007, 0x00040047, 0x0000004b, 0x00000021, 0x00000000, 0x00040047, 0x0000004b, - 0x00000022, 0x00000000, 0x00040047, 0x0000004f, 0x0000001e, 0x00000000, 0x00040047, 0x00000068, - 0x0000001e, 0x00000000, 0x00030047, 0x0000007b, 0x00000002, 0x00050048, 0x0000007b, 0x00000000, - 0x00000023, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, + 0x00000022, 0x00000000, 0x00040047, 0x0000004f, 0x0000001e, 0x00000000, 0x00030047, 0x00000066, + 0x00000002, 0x00050048, 0x00000066, 0x00000000, 0x00000023, 0x00000000, 0x00040047, 0x00000088, + 0x0000001e, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, 0x00000006, 0x00000020, 0x00040017, 0x00000007, 0x00000006, 0x00000003, 0x0004002b, 0x00000006, 0x00000015, 0x3d6147ae, 0x0004002b, 0x00000006, 0x0000001b, 0x4019999a, 0x0006002c, 0x00000007, 0x0000001c, 0x0000001b, 0x0000001b, 0x0000001b, 0x0004002b, 0x00000006, 0x0000001f, 0x3d25aee6, @@ -24,50 +24,63 @@ static const uint32_t hdr_ui_spv[] = { 0x00000000, 0x0003001b, 0x00000049, 0x00000048, 0x00040020, 0x0000004a, 0x00000000, 0x00000049, 0x0004003b, 0x0000004a, 0x0000004b, 0x00000000, 0x00040017, 0x0000004d, 0x00000006, 0x00000002, 0x00040020, 0x0000004e, 0x00000001, 0x0000004d, 0x0004003b, 0x0000004e, 0x0000004f, 0x00000001, - 0x00040015, 0x00000052, 0x00000020, 0x00000000, 0x00040020, 0x00000067, 0x00000003, 0x00000045, - 0x0004003b, 0x00000067, 0x00000068, 0x00000003, 0x00040018, 0x00000069, 0x00000007, 0x00000003, - 0x0004002b, 0x00000006, 0x0000006a, 0x3f209d49, 0x0004002b, 0x00000006, 0x0000006b, 0x3d8d844d, - 0x0004002b, 0x00000006, 0x0000006c, 0x3c86594b, 0x0006002c, 0x00000007, 0x0000006d, 0x0000006a, - 0x0000006b, 0x0000006c, 0x0004002b, 0x00000006, 0x0000006e, 0x3ea89a02, 0x0004002b, 0x00000006, - 0x0000006f, 0x3f6b645a, 0x0004002b, 0x00000006, 0x00000070, 0x3db43958, 0x0006002c, 0x00000007, - 0x00000071, 0x0000006e, 0x0000006f, 0x00000070, 0x0004002b, 0x00000006, 0x00000072, 0x3d315b57, - 0x0004002b, 0x00000006, 0x00000073, 0x3c3ac711, 0x0004002b, 0x00000006, 0x00000074, 0x3f65460b, - 0x0006002c, 0x00000007, 0x00000075, 0x00000072, 0x00000073, 0x00000074, 0x0006002c, 0x00000069, - 0x00000076, 0x0000006d, 0x00000071, 0x00000075, 0x0006002c, 0x00000007, 0x00000079, 0x0000002c, - 0x0000002c, 0x0000002c, 0x0003001e, 0x0000007b, 0x00000045, 0x00040020, 0x0000007c, 0x00000009, - 0x0000007b, 0x0004003b, 0x0000007c, 0x0000007d, 0x00000009, 0x00040015, 0x0000007e, 0x00000020, - 0x00000001, 0x0004002b, 0x0000007e, 0x0000007f, 0x00000000, 0x0004002b, 0x00000052, 0x00000080, - 0x00000000, 0x00040020, 0x00000081, 0x00000009, 0x00000006, 0x0006002c, 0x00000007, 0x000000b2, - 0x0000002d, 0x0000002d, 0x0000002d, 0x0006002c, 0x00000007, 0x000000b4, 0x00000015, 0x00000015, - 0x00000015, 0x0006002c, 0x00000007, 0x000000b7, 0x00000034, 0x00000034, 0x00000034, 0x0004002b, - 0x00000006, 0x000000b8, 0x3d9e8391, 0x0006002c, 0x00000007, 0x000000b9, 0x000000b8, 0x000000b8, - 0x000000b8, 0x0004002b, 0x00000006, 0x000000ba, 0x3f72a76f, 0x0006002c, 0x00000007, 0x000000bb, - 0x000000ba, 0x000000ba, 0x000000ba, 0x0004002b, 0x00000006, 0x000000bc, 0x38d1b717, 0x0006002c, - 0x00000007, 0x000000bd, 0x000000bc, 0x000000bc, 0x000000bc, 0x00050036, 0x00000002, 0x00000004, - 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003d, 0x00000049, 0x0000004c, 0x0000004b, - 0x0004003d, 0x0000004d, 0x00000050, 0x0000004f, 0x00050057, 0x00000045, 0x00000051, 0x0000004c, - 0x00000050, 0x00050051, 0x00000006, 0x00000056, 0x00000051, 0x00000003, 0x000500bc, 0x00000021, - 0x00000057, 0x00000056, 0x0000002c, 0x000300f7, 0x00000059, 0x00000000, 0x000400fa, 0x00000057, - 0x00000058, 0x00000059, 0x000200f8, 0x00000058, 0x000100fc, 0x000200f8, 0x00000059, 0x0008004f, - 0x00000007, 0x0000005d, 0x00000051, 0x00000051, 0x00000000, 0x00000001, 0x00000002, 0x00060050, - 0x00000007, 0x00000060, 0x00000056, 0x00000056, 0x00000056, 0x00050088, 0x00000007, 0x00000061, - 0x0000005d, 0x00000060, 0x0008000c, 0x00000007, 0x00000064, 0x00000001, 0x0000002b, 0x00000061, - 0x00000079, 0x000000b2, 0x00050085, 0x00000007, 0x00000091, 0x00000064, 0x000000b9, 0x00050081, - 0x00000007, 0x00000094, 0x00000064, 0x000000b4, 0x00050085, 0x00000007, 0x00000096, 0x00000094, - 0x000000bb, 0x0007000c, 0x00000007, 0x00000097, 0x00000001, 0x0000001a, 0x00000096, 0x0000001c, - 0x000500ba, 0x00000022, 0x00000099, 0x00000064, 0x00000020, 0x000600a9, 0x00000007, 0x0000009a, - 0x00000099, 0x00000097, 0x00000091, 0x00050091, 0x00000007, 0x00000078, 0x00000076, 0x0000009a, - 0x0007000c, 0x00000007, 0x0000007a, 0x00000001, 0x00000028, 0x00000078, 0x00000079, 0x00060041, - 0x00000081, 0x00000082, 0x0000007d, 0x0000007f, 0x00000080, 0x0004003d, 0x00000006, 0x00000083, - 0x00000082, 0x0005008e, 0x00000007, 0x00000084, 0x0000007a, 0x00000083, 0x00050085, 0x00000007, - 0x000000a0, 0x00000084, 0x000000bd, 0x0008000c, 0x00000007, 0x000000a3, 0x00000001, 0x0000002b, - 0x000000a0, 0x00000079, 0x000000b2, 0x0007000c, 0x00000007, 0x000000a4, 0x00000001, 0x0000001a, - 0x000000a3, 0x00000032, 0x0005008e, 0x00000007, 0x000000a6, 0x000000a4, 0x00000035, 0x00050081, - 0x00000007, 0x000000a8, 0x000000b7, 0x000000a6, 0x0005008e, 0x00000007, 0x000000aa, 0x000000a4, - 0x0000003a, 0x00050081, 0x00000007, 0x000000ac, 0x000000b2, 0x000000aa, 0x00050088, 0x00000007, - 0x000000ad, 0x000000a8, 0x000000ac, 0x0007000c, 0x00000007, 0x000000ae, 0x00000001, 0x0000001a, - 0x000000ad, 0x00000041, 0x00050051, 0x00000006, 0x00000089, 0x000000ae, 0x00000000, 0x00050051, - 0x00000006, 0x0000008a, 0x000000ae, 0x00000001, 0x00050051, 0x00000006, 0x0000008b, 0x000000ae, - 0x00000002, 0x00070050, 0x00000045, 0x0000008c, 0x00000089, 0x0000008a, 0x0000008b, 0x00000056, - 0x0003003e, 0x00000068, 0x0000008c, 0x000100fd, 0x00010038, + 0x00040015, 0x00000052, 0x00000020, 0x00000000, 0x0003001e, 0x00000066, 0x00000045, 0x00040020, + 0x00000067, 0x00000009, 0x00000066, 0x0004003b, 0x00000067, 0x00000068, 0x00000009, 0x00040015, + 0x00000069, 0x00000020, 0x00000001, 0x0004002b, 0x00000069, 0x0000006a, 0x00000000, 0x0004002b, + 0x00000052, 0x0000006b, 0x00000001, 0x00040020, 0x0000006c, 0x00000009, 0x00000006, 0x0004002b, + 0x00000006, 0x00000074, 0x400ccccd, 0x0006002c, 0x00000007, 0x00000075, 0x00000074, 0x00000074, + 0x00000074, 0x0004002b, 0x00000006, 0x0000007a, 0x40000000, 0x00040020, 0x00000087, 0x00000003, + 0x00000045, 0x0004003b, 0x00000087, 0x00000088, 0x00000003, 0x00040018, 0x00000089, 0x00000007, + 0x00000003, 0x0004002b, 0x00000006, 0x0000008a, 0x3f209d49, 0x0004002b, 0x00000006, 0x0000008b, + 0x3d8d844d, 0x0004002b, 0x00000006, 0x0000008c, 0x3c86594b, 0x0006002c, 0x00000007, 0x0000008d, + 0x0000008a, 0x0000008b, 0x0000008c, 0x0004002b, 0x00000006, 0x0000008e, 0x3ea89a02, 0x0004002b, + 0x00000006, 0x0000008f, 0x3f6b645a, 0x0004002b, 0x00000006, 0x00000090, 0x3db43958, 0x0006002c, + 0x00000007, 0x00000091, 0x0000008e, 0x0000008f, 0x00000090, 0x0004002b, 0x00000006, 0x00000092, + 0x3d315b57, 0x0004002b, 0x00000006, 0x00000093, 0x3c3ac711, 0x0004002b, 0x00000006, 0x00000094, + 0x3f65460b, 0x0006002c, 0x00000007, 0x00000095, 0x00000092, 0x00000093, 0x00000094, 0x0006002c, + 0x00000089, 0x00000096, 0x0000008d, 0x00000091, 0x00000095, 0x0006002c, 0x00000007, 0x00000099, + 0x0000002c, 0x0000002c, 0x0000002c, 0x0004002b, 0x00000052, 0x0000009b, 0x00000000, 0x0006002c, + 0x00000007, 0x000000ce, 0x0000002d, 0x0000002d, 0x0000002d, 0x0006002c, 0x00000007, 0x000000d0, + 0x00000034, 0x00000034, 0x00000034, 0x0006002c, 0x00000007, 0x000000d2, 0x00000015, 0x00000015, + 0x00000015, 0x0004002b, 0x00000006, 0x000000d4, 0x3d9e8391, 0x0006002c, 0x00000007, 0x000000d5, + 0x000000d4, 0x000000d4, 0x000000d4, 0x0004002b, 0x00000006, 0x000000d6, 0x3f72a76f, 0x0006002c, + 0x00000007, 0x000000d7, 0x000000d6, 0x000000d6, 0x000000d6, 0x0004002b, 0x00000006, 0x000000d8, + 0x38d1b717, 0x0006002c, 0x00000007, 0x000000d9, 0x000000d8, 0x000000d8, 0x000000d8, 0x00050036, + 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200f8, 0x00000005, 0x0004003d, 0x00000049, + 0x0000004c, 0x0000004b, 0x0004003d, 0x0000004d, 0x00000050, 0x0000004f, 0x00050057, 0x00000045, + 0x00000051, 0x0000004c, 0x00000050, 0x00050051, 0x00000006, 0x00000056, 0x00000051, 0x00000003, + 0x000500bc, 0x00000021, 0x00000057, 0x00000056, 0x0000002c, 0x000300f7, 0x00000059, 0x00000000, + 0x000400fa, 0x00000057, 0x00000058, 0x00000059, 0x000200f8, 0x00000058, 0x000100fc, 0x000200f8, + 0x00000059, 0x0008004f, 0x00000007, 0x0000005d, 0x00000051, 0x00000051, 0x00000000, 0x00000001, + 0x00000002, 0x00060050, 0x00000007, 0x00000060, 0x00000056, 0x00000056, 0x00000056, 0x00050088, + 0x00000007, 0x00000061, 0x0000005d, 0x00000060, 0x0008000c, 0x00000007, 0x00000064, 0x00000001, + 0x0000002b, 0x00000061, 0x00000099, 0x000000ce, 0x00060041, 0x0000006c, 0x0000006d, 0x00000068, + 0x0000006a, 0x0000006b, 0x0004003d, 0x00000006, 0x0000006e, 0x0000006d, 0x000500b4, 0x00000021, + 0x0000006f, 0x0000006e, 0x0000002d, 0x000300f7, 0x00000072, 0x00000000, 0x000400fa, 0x0000006f, + 0x00000071, 0x00000077, 0x000200f8, 0x00000071, 0x0007000c, 0x00000007, 0x00000076, 0x00000001, + 0x0000001a, 0x00000064, 0x00000075, 0x000200f9, 0x00000072, 0x000200f8, 0x00000077, 0x000500b4, + 0x00000021, 0x0000007b, 0x0000006e, 0x0000007a, 0x000300f7, 0x0000007e, 0x00000000, 0x000400fa, + 0x0000007b, 0x0000007d, 0x00000081, 0x000200f8, 0x0000007d, 0x0007000c, 0x00000007, 0x00000080, + 0x00000001, 0x0000001a, 0x00000064, 0x0000001c, 0x000200f9, 0x0000007e, 0x000200f8, 0x00000081, + 0x00050085, 0x00000007, 0x000000ab, 0x00000064, 0x000000d5, 0x00050081, 0x00000007, 0x000000ae, + 0x00000064, 0x000000d2, 0x00050085, 0x00000007, 0x000000b0, 0x000000ae, 0x000000d7, 0x0007000c, + 0x00000007, 0x000000b1, 0x00000001, 0x0000001a, 0x000000b0, 0x0000001c, 0x000500ba, 0x00000022, + 0x000000b3, 0x00000064, 0x00000020, 0x000600a9, 0x00000007, 0x000000b4, 0x000000b3, 0x000000b1, + 0x000000ab, 0x000200f9, 0x0000007e, 0x000200f8, 0x0000007e, 0x000700f5, 0x00000007, 0x000000cc, + 0x00000080, 0x0000007d, 0x000000b4, 0x00000081, 0x000200f9, 0x00000072, 0x000200f8, 0x00000072, + 0x000700f5, 0x00000007, 0x000000cd, 0x00000076, 0x00000071, 0x000000cc, 0x0000007e, 0x00050091, + 0x00000007, 0x00000098, 0x00000096, 0x000000cd, 0x0007000c, 0x00000007, 0x0000009a, 0x00000001, + 0x00000028, 0x00000098, 0x00000099, 0x00060041, 0x0000006c, 0x0000009c, 0x00000068, 0x0000006a, + 0x0000009b, 0x0004003d, 0x00000006, 0x0000009d, 0x0000009c, 0x0005008e, 0x00000007, 0x0000009e, + 0x0000009a, 0x0000009d, 0x00050085, 0x00000007, 0x000000ba, 0x0000009e, 0x000000d9, 0x0008000c, + 0x00000007, 0x000000bd, 0x00000001, 0x0000002b, 0x000000ba, 0x00000099, 0x000000ce, 0x0007000c, + 0x00000007, 0x000000be, 0x00000001, 0x0000001a, 0x000000bd, 0x00000032, 0x0005008e, 0x00000007, + 0x000000c0, 0x000000be, 0x00000035, 0x00050081, 0x00000007, 0x000000c2, 0x000000d0, 0x000000c0, + 0x0005008e, 0x00000007, 0x000000c4, 0x000000be, 0x0000003a, 0x00050081, 0x00000007, 0x000000c6, + 0x000000ce, 0x000000c4, 0x00050088, 0x00000007, 0x000000c7, 0x000000c2, 0x000000c6, 0x0007000c, + 0x00000007, 0x000000c8, 0x00000001, 0x0000001a, 0x000000c7, 0x00000041, 0x00050051, 0x00000006, + 0x000000a3, 0x000000c8, 0x00000000, 0x00050051, 0x00000006, 0x000000a4, 0x000000c8, 0x00000001, + 0x00050051, 0x00000006, 0x000000a5, 0x000000c8, 0x00000002, 0x00070050, 0x00000045, 0x000000a6, + 0x000000a3, 0x000000a4, 0x000000a5, 0x00000056, 0x0003003e, 0x00000088, 0x000000a6, 0x000100fd, + 0x00010038, }; diff --git a/runtime/shaders/hdr_encode.comp b/runtime/shaders/hdr_encode.comp index c6fb04da..ba1010db 100644 --- a/runtime/shaders/hdr_encode.comp +++ b/runtime/shaders/hdr_encode.comp @@ -1,9 +1,29 @@ #version 450 +// +// Copyright (c) 2025 Carlos Lopez Jr. +// +// 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. +// // HDR10 encode on the present (runtime/vk_hdr.c vk_hdr_encode): the game's picture, crop rectangle at offset, linear // Rec. 709 with the HUD's white at 1.0 (an sRGB view decodes the 8-bit window texture), into an RGBA16F image of PQ -// code values in Rec. 2020 that FSR 1 or the blit then scale into the HDR10 swapchain. p.x: nits of 1.0, p.y: the -// display's peak in nits, p.z: 1 when the source holds sRGB-encoded values in a UNORM format. -// PQ: SMPTE ST 2084; the Rec. 709 to Rec. 2020 matrix: ITU-R BT.2087. +// code values in Rec. 2020 that FSR 1 or the blit then scale into the HDR10 swapchain. In order: the gamma correction +// (the game's sRGB-encoded look shown as a 2.2 or 2.4 display would: decode of the sRGB code with that power), the +// conversion to Rec. 2020, a gamut compression that desaturates towards the grey of the same luminance until no +// channel is negative (in a gamma-encoded space whose 50% is the scene's mid grey), the HUD's white in nits, the +// largest channel scaled down to the peak, and PQ (SMPTE ST 2084). +// p.x: nits of 1.0, p.y: the display's peak in nits, p.z: 1 when the source holds sRGB-encoded values in a UNORM +// format, p.w: gamma correction (0 none, 1: 2.2, 2: 2.4). layout(local_size_x = 8, local_size_y = 8) in; layout(binding = 0) uniform sampler2D src; layout(binding = 1, rgba16f) uniform writeonly image2D dst; @@ -13,10 +33,24 @@ layout(push_constant) uniform P { vec4 p; } pc; -vec3 srgb_decode(vec3 c) { - return mix(c / 12.92, pow((c + 0.055) / 1.055, vec3(2.4)), greaterThan(c, vec3(0.04045))); +vec3 copy_sign(vec3 mag, vec3 s) { + vec3 a = abs(mag); + return mix(a, -a, lessThan(s, vec3(0.0))); } +vec3 sign_pow(vec3 x, float e) { return copy_sign(pow(abs(x), vec3(e)), x); } + +vec3 srgb_decode(vec3 c) { + return mix(pow((c + 0.055) / 1.055, vec3(2.4)), c / 12.92, lessThanEqual(c, vec3(0.04045))); +} + +vec3 srgb_encode(vec3 c) { + return mix(1.055 * pow(c, vec3(1.0 / 2.4)) - 0.055, c * 12.92, lessThanEqual(c, vec3(0.0031308))); +} + +// The colour an sRGB code shows on a display of power g, sign kept. +vec3 gamma_correct(vec3 c, float g) { return copy_sign(pow(srgb_encode(abs(c)), vec3(g)), c); } + vec3 pq(vec3 nits) { const float m1 = 0.1593017578125, m2 = 78.84375, c1 = 0.8359375, c2 = 18.8515625, c3 = 18.6875; vec3 y = pow(clamp(nits / 10000.0, 0.0, 1.0), vec3(m1)); @@ -26,9 +60,25 @@ vec3 pq(vec3 nits) { void main() { ivec2 at = ivec2(gl_GlobalInvocationID.xy); if (any(greaterThanEqual(at, pc.size))) return; - vec3 c = max(texelFetch(src, at + pc.offset, 0).rgb, vec3(0.0)); + vec3 c = texelFetch(src, at + pc.offset, 0).rgb; if (pc.p.z > 0.5) c = srgb_decode(clamp(c, 0.0, 1.0)); - const mat3 to2020 = mat3(0.6274, 0.0691, 0.0164, 0.3293, 0.9195, 0.0880, 0.0433, 0.0114, 0.8956); - vec3 nits = min(max(to2020 * c, vec3(0.0)) * pc.p.x, vec3(pc.p.y)); - imageStore(dst, at, vec4(pq(nits), 1.0)); + c = mix(c, vec3(0.0), isnan(c)); + if (pc.p.w == 1.0) c = gamma_correct(c, 2.2); + else if (pc.p.w == 2.0) c = gamma_correct(c, 2.4); + // Rec. 709 to Rec. 2020 (rows) + c = c * mat3(0.6274038960, 0.3292830384, 0.0433130657, + 0.0690972894, 0.9195403951, 0.0113623156, + 0.0163914388, 0.0880133078, 0.8955952532); + float gray = dot(c, vec3(0.2627002120, 0.6779980715, 0.0593017165)); + const float MID_GRAY_GAMMA = log(1.0 / pow(10.0, 0.75)) / log(0.5); // about 2.49: 18% grey encodes to 50% + vec3 encoded = sign_pow(c, 1.0 / MID_GRAY_GAMMA); + float encoded_gray = pow(max(gray, 0.0), 1.0 / MID_GRAY_GAMMA); + float lowest = min(0.0, min(encoded.r, min(encoded.g, encoded.b))); + float distance = encoded_gray - lowest; + float ratio = distance == 0.0 ? 0.0 : -lowest / distance; + c = sign_pow(mix(vec3(encoded_gray), encoded, 1.0 - ratio), MID_GRAY_GAMMA); + c *= pc.p.x; + float max_channel = max(max(max(c.r, c.g), c.b), pc.p.y); + c *= pc.p.y / max_channel; + imageStore(dst, at, vec4(pq(max(c, vec3(0.0))), 1.0)); } diff --git a/runtime/shaders/hdr_tonemap.frag b/runtime/shaders/hdr_tonemap.frag index 78b6ee06..a3dcd919 100644 --- a/runtime/shaders/hdr_tonemap.frag +++ b/runtime/shaders/hdr_tonemap.frag @@ -1,73 +1,228 @@ #version 450 -// The game's tonemap pass for HDR output (runtime/vk_hdr.c vk_hdr_shader_swap puts it in place of the translated -// shader when NX2NAVI_HDR=1). Same inputs as the game's: fp_t_tcb_8 (bloom, clamped to 10000 as the game does) plus -// fp_t_tcb_A (the scene), weights in c1[0] and the saturation grade in c3[0]. The game maps luminance and each channel -// with 1 - e^-x, blends the two by the luminance curve squared, clamps to 0..1 and grades saturation. Here the curve is -// the game's up to PIVOT and a straight line with its slope above, so mid-greys look as in SDR and highlights keep -// going; the grade works on the colour divided by its largest channel above 1; a roll-off on the largest channel stops -// at the display's peak. The output is relative to the HUD's white (1.0), which the present maps to NX2NAVI_HDR_UI_NITS. -// Hue correction (hdr.z, NX2NAVI_HDR_HUE): the game's SDR clamp turns bright saturated colours towards white (a torch flame -// clips red, then green, and reads yellow-white, the colour its emitted light was tuned to); the extended curve keeps -// their ratios, so they stay saturated. From the picture's white upwards the colour moves towards the game's own SDR -// result at the HDR luminance, by up to hdr.z. -// The approach: an "extended vanilla" curve. -// Bindings are those of the game's translated shader: vk_hdr.c rewrites them from the original's names. -layout(location = 0) in vec4 uv; -layout(location = 0) out vec4 color; +// build_shaders: keep functions +// +// Copyright (c) 2025 Carlos Lopez Jr. +// +// 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. +// +// The HDR tonemap, as a function that runtime/vk_hdr.c (vk_hdr_shader_swap) splices into the game's own tonemap +// shader: nx_tonemap takes the three values the game feeds its fitted ACES curve (its scene light after its colour +// matrix, bloom and exposure) and returns the colour the shader then stores, linear Rec. 709 relative to the HUD's +// white, which the present encodes to PQ (shaders/hdr_encode.comp). main only exists so the compiler keeps the +// functions; vk_hdr.c drops it. build_shaders.py compiles this file without optimisation ("keep functions" above), +// as inlining would leave no function to splice. +// +// The picture: the game's SDR result (its curve, clamped) is the colour grade; the tone mapper upgrades it to the +// HDR range by luminance against a neutral SDR curve of the same input, then maps that onto the display: a +// luminance curve towards the peak with exposure, highlights, shadows, contrast and flare, and in OkLab the hue of +// the input, saturation, highlight saturation and blowout. Settings (vk_hdr.c vk_hdr_support, support buffer bytes +// 1440..1503): +// p0: peak nits, game nits (white of the picture), HUD nits, tone mapper (-1: the game's own SDR picture, as when the +// swapchain is not HDR10; 0: the game's curve; 3: the HDR tone mapper) +// p1: exposure, highlights, shadows, contrast +// p2: saturation, highlight saturation, blowout, flare (parsed: 1 = unchanged for the first two) +// p3: hue correction, grade strength, gamma correction (0 off, 1: 2.2, 2: 2.4; applied on the present), unused +layout(location = 0) in vec4 a0; +layout(location = 1) in vec4 a1; +layout(location = 2) in vec4 a2; +layout(location = 3) in vec4 a3; +layout(location = 4) in vec4 a4; +layout(location = 0) out vec4 o; -layout(set = 0, binding = 0, std140) uniform SupportBuffer { - vec4 pad[90]; - vec4 hdr; // byte 1440 (vk_exec_draw.c support_fill): game white / HUD white, peak / game white, hue correction -} support_buffer; -layout(set = 0, binding = 1) uniform sampler2D fp_t_tcb_8; -layout(set = 0, binding = 2) uniform sampler2D fp_t_tcb_A; -layout(set = 0, binding = 3, std140) uniform C1 { vec4 v[4096]; } fp_c1; -layout(set = 0, binding = 4, std140) uniform C3 { vec4 v[4096]; } fp_c3; +// Matrices are written row by row; mulm(m, v) is the row-vector product of that layout. +vec3 mulm(mat3 m, vec3 v) { return v * m; } -const float PIVOT = 0.18; +const mat3 BT709_TO_AP1 = mat3(0.6130974024, 0.3395231462, 0.0473794514, + 0.0701937225, 0.9163538791, 0.0134523985, + 0.0206155929, 0.1095697729, 0.8698146342); +const mat3 AP1_TO_BT709 = mat3(1.7050509927, -0.6217921207, -0.0832588720, + -0.1302564175, 1.1408047366, -0.0105483191, + -0.0240033568, -0.1289689761, 1.1529723329); +const mat3 BT709_TO_OKLABLMS = mat3(0.4122214708, 0.5363325363, 0.0514459929, + 0.2119034982, 0.6806995451, 0.1073969566, + 0.0883024619, 0.2817188376, 0.6299787005); +const mat3 OKLABLMS_TO_OKLAB = mat3(0.2104542553, 0.7936177850, -0.0040720468, + 1.9779984951, -2.4285922050, 0.4505937099, + 0.0259040371, 0.7827717662, -0.8086757660); +const mat3 OKLAB_TO_OKLABLMS = mat3(1.0, 0.3963377774, 0.2158037573, + 1.0, -0.1055613458, -0.0638541728, + 1.0, -0.0894841775, -1.2914855480); +const mat3 OKLABLMS_TO_BT709 = mat3(4.0767416621, -3.3077115913, 0.2309699292, + -1.2684380046, 2.6097574011, -0.3413193965, + -0.0041960863, -0.7034186147, 1.7076147010); -float curve(float x) { // the game's 1 - e^-x below PIVOT, its tangent there above - float y0 = 1.0 - exp(-PIVOT); - return x <= PIVOT ? 1.0 - exp(-x) : y0 + exp(-PIVOT) * (x - PIVOT); +float y709(vec3 c) { return dot(c, vec3(0.2126390059, 0.7151686788, 0.0721923154)); } + +float divide_safe(float a, float b, float fallback) { return b == 0.0 ? fallback : a / b; } + +vec3 copy_sign(vec3 mag, vec3 s) { + vec3 a = abs(mag); + return mix(a, -a, lessThan(s, vec3(0.0))); } -vec3 curve3(vec3 x) { return vec3(curve(x.r), curve(x.g), curve(x.b)); } +vec3 cbrt(vec3 x) { return copy_sign(pow(abs(x), vec3(1.0 / 3.0)), x); } -float maxc(vec3 c) { return max(c.r, max(c.g, c.b)); } +vec3 oklab_from_bt709(vec3 c) { return mulm(OKLABLMS_TO_OKLAB, cbrt(mulm(BT709_TO_OKLABLMS, c))); } -void main() { - vec3 x = min(texture(fp_t_tcb_8, uv.xy).rgb, vec3(10000.0)) + texture(fp_t_tcb_A, uv.xy).rgb; - vec4 w = fp_c1.v[0], g = fp_c3.v[0]; - float game = support_buffer.hdr.x > 0.0 ? support_buffer.hdr.x : 1.0; - float peak = support_buffer.hdr.y > 1.0 ? support_buffer.hdr.y : 1.0; +vec3 bt709_from_oklab(vec3 lab) { + vec3 lms = mulm(OKLAB_TO_OKLABLMS, lab); + return mulm(OKLABLMS_TO_BT709, lms * lms * lms); +} - float lum = max(x.r * 0.2989 + x.g * w.x + x.b * w.y, 0.0); - float sdr = 1.0 - exp(-lum); - vec3 by_lum = lum > 0.0 ? x * (curve(lum) / lum) : x; - vec3 c = max(mix(by_lum, curve3(x), sdr * sdr), vec3(0.0)); +vec3 clamp_ap1(vec3 c) { return mulm(AP1_TO_BT709, max(mulm(BT709_TO_AP1, c), vec3(0.0))); } - // the game's saturation grade, on the colour scaled into 0..1 by its largest channel - float s = max(maxc(c), 1.0); - vec3 n = c / s; - float m = maxc(n); - float d = n.r * 0.6666667 + (n.g + n.b) * w.z - 1.0; - float grade = g.y * (1.0 - d * d) + g.x; - c = s * ((n - m) * grade + m); +// The hue (OkLab a, b direction) of correct with the chrominance of incorrect. +vec3 hue_oklab(vec3 incorrect, vec3 correct) { + vec3 il = oklab_from_bt709(incorrect), cl = oklab_from_bt709(correct); + float pre = length(il.yz); + vec2 ab = cl.yz; + ab *= divide_safe(pre, length(ab), 1.0); + il.yz = ab; + return clamp_ap1(bt709_from_oklab(il)); +} - // the game's own SDR result: the same blend clamped to 0..1, graded - vec3 sdr_c = clamp(mix(lum > 0.0 ? x * (sdr / lum) : x, vec3(1.0) - exp(-x), sdr * sdr), 0.0, 1.0); - float sm = maxc(sdr_c), sd = sdr_c.r * 0.6666667 + (sdr_c.g + sdr_c.b) * w.z - 1.0; - sdr_c = (sdr_c - sm) * (g.y * (1.0 - sd * sd) + g.x) + sm; - float hue = clamp(support_buffer.hdr.z, 0.0, 1.0); - const vec3 Y = vec3(0.2126, 0.7152, 0.0722); // Rec. 709 luminance - float yc = dot(c, Y), ys = dot(sdr_c, Y); - if (hue > 0.0 && ys > 1e-5) c = mix(c, max(sdr_c, vec3(0.0)) * (yc / ys), hue * smoothstep(0.5, 1.5, maxc(c))); +float srgb_decode(float c) { return c <= 0.04045 ? c / 12.92 : pow((c + 0.055) / 1.055, 2.4); } - // roll-off of the largest channel from half the peak to the peak - float top = maxc(c), knee = 0.5 * peak; - if (top > knee) { - float r = peak - knee; - c *= (knee + r * (1.0 - exp(-(top - knee) / r))) / top; +// pow_to_srgb: a value of a gamma-g picture as the sRGB value of the same code (the peak's correction). +float gamma_to_srgb(float c, float g) { return srgb_decode(pow(c, 1.0 / g)); } + +float smoother(float t) { return t * t * t * (t * (t * 6.0 - 15.0) + 10.0); } + +float highlights(float x, float h, float mid) { + if (h == 1.0) return x; + float t = 0.0; + if (x > mid) t = clamp(log2(x / mid) / log2(1.0 / mid), 0.0, 1.0); + t = smoother(t); + if (h > 1.0) return mix(x, mid * pow(x / mid, h), t); + float b = mid * pow(x / mid, 2.0 - h); + return divide_safe(x * x, mix(x, b, t), x); +} + +float shadows(float x, float s, float mid) { + if (s == 1.0) return x; + float ratio = max(divide_safe(x, mid, 0.0), 0.0); + float base_term = x * mid; + float base_scale = divide_safe(base_term, ratio, 0.0); + float shadow_floor = mid / 16.0; + float t = 1.0; + if (x > shadow_floor) t = clamp(log2(x / mid) / log2(shadow_floor / mid), 0.0, 1.0); + t = smoother(t); + if (s > 1.0) { + float raised = x * (1.0 + divide_safe(base_term, pow(ratio, s), 0.0)); + return x + (raised - x * (1.0 + base_scale)) * t; } - color = vec4(max(c, vec3(0.0)) * game, 0.0); + float lowered = x * (1.0 - divide_safe(base_term, pow(ratio, 2.0 - s), 0.0)); + return x + (lowered - x * (1.0 - base_scale)) * t; } + +// The luminance curve: n peak nits, g contrast, c_d mid grey in nits, t_1 flare; 100 nits reference, scene grey 0.18. +float curve(float x, float n, float g, float c_d, float t_1) { + const float n_r = 100.0, c = 0.18, w_g = 0.0, r_hit_min = 128.0, r_hit_max = 256.0; + float m_0 = n / n_r; + float m_1 = 0.5 * (m_0 + sqrt(m_0 * (m_0 + 4.0 * t_1))); + float r_hit = r_hit_min + (r_hit_max - r_hit_min) * (log(m_0) / log(10000.0 / 100.0)); + float u = pow((r_hit / m_1) / ((r_hit / m_1) + 1.0), g); + float m = m_1 / u; + float w_i = log(n / 100.0) / log(2.0); + float c_t = (c_d / n_r) * (1.0 + w_i * w_g); + float g_ip = 0.5 * (c_t + sqrt(c_t * (c_t + 4.0 * t_1))); + float g_ipp2 = -m_1 * pow(g_ip / m, 1.0 / g) / (pow(g_ip / m, 1.0 / g) - 1.0); + float w_2 = c / g_ipp2; + float s_2 = w_2 * m_1; + float u_2 = pow((r_hit / m_1) / ((r_hit / m_1) + w_2), g); + float m_2 = m_1 / u_2; + float ts = pow(max(0.0, x) / (x + s_2), g) * m_2; + return max(0.0, (ts * ts) / (ts + t_1)); +} + +struct Drt { + float nits_peak, exposure, highlights, shadows, contrast, saturation, dechroma, flare, hue, blowout; + float mid_gray_nits; + bool clamp_zero; // clamp to Rec. 709 (no negative channel) before the peak +}; + +// The tone mapper by luminance, then hue, saturation and blowout in OkLab; clamped to the peak in Rec. 709. +vec3 drt(vec3 bt709, Drt d) { + const float mid = 0.18; + float peak = d.nits_peak / 100.0; + float y_original = y709(bt709); + float y = y_original * d.exposure; + y = highlights(y, d.highlights, mid); + y = shadows(y, d.shadows, mid); + float y_new = clamp(curve(y, d.nits_peak, d.contrast, d.mid_gray_nits, d.flare), 0.0, peak); + vec3 color = bt709 * (y_original > 0.0 ? y_new / y_original : 0.0); + if (d.dechroma != 0.0 || d.saturation != 1.0 || d.hue != 0.0 || d.blowout != 0.0) { + vec3 lab = oklab_from_bt709(color); + if (d.hue != 0.0) { + vec3 old_lab = oklab_from_bt709(bt709); + float pre = length(lab.yz); + lab.yz = mix(lab.yz, old_lab.yz, d.hue); + lab.yz *= divide_safe(pre, length(lab.yz), 1.0); + } + if (d.dechroma != 0.0) lab.yz *= mix(1.0, 0.0, clamp(pow(y_original / 100.0, 1.0 - d.dechroma), 0.0, 1.0)); + if (d.blowout != 0.0) { + float percent_max = clamp(y_original * 100.0 / 10000.0, 0.0, 1.0); + float change = pow(1.0 - percent_max, 100.0 * abs(d.blowout)); + if (d.blowout < 0.0) change = 2.0 - change; + lab.yz *= change; + } + lab.yz *= d.saturation; + color = bt709_from_oklab(lab); + } + if (d.clamp_zero) color = max(color, vec3(0.0)); + return min(color, vec3(peak)); +} + +// The same curve at SDR range with nothing changed: what the SDR grade is measured against. +vec3 neutral_sdr(vec3 c) { + Drt d = Drt(100.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 18.0, true); + return drt(c, d); +} + +// The graded SDR colour carried to the HDR range: its luminance gains what the untonemapped colour has above the +// neutral SDR curve, in the graded colour's hue. +vec3 upgrade(vec3 untonemapped, vec3 neutral, vec3 graded, float strength) { + float yu = y709(untonemapped), yn = y709(neutral), yg = y709(graded); + float ratio; + if (yu < yn) { + ratio = yu / yn; + } else { + float y_new = yg + max(0.0, yu - yn); + ratio = yg > 0.0 ? y_new / yg : 0.0; + } + vec3 scaled = hue_oklab(graded * ratio, graded); + return mix(untonemapped, scaled, strength); +} + +vec3 aces_fitted(vec3 x) { // the game's curve and clamp + return clamp(x * (2.51 * x + 0.03) / (x * (2.43 * x + 0.59) + 0.14), 0.0, 1.0); +} + +vec3 nx_tonemap(vec3 x, vec4 p0, vec4 p1, vec4 p2, vec4 p3) { + vec3 vanilla = aces_fitted(x); + if (p0.w < 0.0) return vanilla; + vec3 color = vanilla; + if (p0.w > 0.0) { + vec3 graded = p3.y == 0.0 ? x : upgrade(x, neutral_sdr(x), vanilla, p3.y); + float peak = p0.x / p0.y; // the display's peak in picture whites; corrected for the present's gamma + if (p3.z != 0.0) peak = gamma_to_srgb(peak, p3.z == 1.0 ? 2.2 : 2.4); + Drt d = Drt(peak * 100.0, p1.x, p1.y, p1.z, p1.w, p2.x, p2.z, 0.10 * pow(p2.w, 10.0), p3.x, -(p2.y - 1.0), + 18.0, false); + color = drt(graded, d); + } + color *= p0.y / p0.z; // the picture's white against the HUD's + return mix(color, vec3(0.0), isnan(color)); +} + +void main() { o = vec4(nx_tonemap(a0.xyz, a1, a2, a3, a4), 1.0); } diff --git a/runtime/shaders/hdr_ui.frag b/runtime/shaders/hdr_ui.frag index 30299d03..d3a7e22f 100644 --- a/runtime/shaders/hdr_ui.frag +++ b/runtime/shaders/hdr_ui.frag @@ -1,6 +1,7 @@ #version 450 // The in-game menu on an HDR10 swapchain (runtime/vk_hdr.c vk_hdr_ui_compose): ImGui drew it into an RGBA8 image, -// premultiplied sRGB colour over a clear 0; this turns each pixel back into its colour, puts its white at p.x nits and +// premultiplied sRGB colour over a clear 0; this turns each pixel back into its colour (with the picture's gamma +// correction p.y: 0 none, 1: 2.2, 2: 2.4, as shaders/hdr_encode.comp applies it), puts its white at p.x nits and // writes the PQ code with its coverage, which the pipeline blends over the picture (in PQ code values, as the menu // blends in sRGB code values on an SDR swapchain). PQ: SMPTE ST 2084; Rec. 709 to Rec. 2020: ITU-R BT.2087. layout(location = 0) in vec2 uv; @@ -21,7 +22,8 @@ vec3 pq(vec3 nits) { void main() { vec4 u = texture(ui, uv); if (u.a <= 0.0) discard; - vec3 c = srgb_decode(clamp(u.rgb / u.a, 0.0, 1.0)); + vec3 code = clamp(u.rgb / u.a, 0.0, 1.0); + vec3 c = pc.p.y == 1.0 ? pow(code, vec3(2.2)) : pc.p.y == 2.0 ? pow(code, vec3(2.4)) : srgb_decode(code); const mat3 to2020 = mat3(0.6274, 0.0691, 0.0164, 0.3293, 0.9195, 0.0880, 0.0433, 0.0114, 0.8956); color = vec4(pq(max(to2020 * c, vec3(0.0)) * pc.p.x), u.a); } diff --git a/runtime/ui/menu.cpp b/runtime/ui/menu.cpp index 01cae30e..6f2ee373 100644 --- a/runtime/ui/menu.cpp +++ b/runtime/ui/menu.cpp @@ -851,18 +851,35 @@ static const char *hdr_note(void) { return note; } -// HDR (vk_hdr.c), after a restart: off, the runtime's own (the game's tonemap kept above SDR white) or the game's native -// HDR. The brightness rows follow while it is on. +// HDR (vk_hdr.c), after a restart: off, the HDR tone mapper over the game's picture or the game's native HDR. The +// brightness rows follow while it is on; the tone mapper's own rows only with the first (native HDR is the game's +// picture as it is), its grading rows only with its own curve chosen. static void row_hdr(void) { static const char *const values[] = {"0", "1", "native"}; - const char *names[] = {menu_text(UI_MENU_FRAMEGEN_OFF), menu_text(UI_MENU_HDR_ENHANCED), menu_text(UI_MENU_HDR_NATIVE)}; + const char *names[] = {menu_text(UI_MENU_FRAMEGEN_OFF), menu_text(UI_MENU_HDR_TONEMAPPED), menu_text(UI_MENU_HDR_NATIVE)}; opt_choice_list("NX2NAVI_HDR", UI_MENU_HDR, values, names, 3, UI_MENU_HDR_DESC, -1, hdr_note()); if (!cfg_bool("NX2NAVI_HDR")) return; opt_slider("NX2NAVI_HDR_PEAK_NITS", UI_MENU_HDR_PEAK, 400, 10000, UI_MENU_HDR_PEAK_DESC, 50, "%.0f nits"); - opt_slider("NX2NAVI_HDR_GAME_NITS", UI_MENU_HDR_GAME, 80, 500, UI_MENU_HDR_GAME_DESC, 5, "%.0f nits"); - opt_slider("NX2NAVI_HDR_UI_NITS", UI_MENU_HDR_UI, 80, 500, UI_MENU_HDR_UI_DESC, 5, "%.0f nits"); - // no hue slider: the hue correction belonged to the runtime's replacement tonemap, and Enhanced now extends the - // game's own tonemap in place (vk_hdr.c aces_extend), so NX2NAVI_HDR_HUE changes nothing in this game + opt_slider("NX2NAVI_HDR_GAME_NITS", UI_MENU_HDR_GAME, 48, 500, UI_MENU_HDR_GAME_DESC, 1, "%.0f nits"); + opt_slider("NX2NAVI_HDR_UI_NITS", UI_MENU_HDR_UI, 48, 500, UI_MENU_HDR_UI_DESC, 1, "%.0f nits"); + if (!strcmp(cfg_value("NX2NAVI_HDR"), "native")) return; + static const char *const gammas[] = {"off", "2.2", "2.4"}; + const char *gamma_names[] = {menu_text(UI_MENU_FRAMEGEN_OFF), "2.2", "BT.1886 (2.4)"}; + opt_choice_list("NX2NAVI_HDR_GAMMA", UI_MENU_HDR_GAMMA, gammas, gamma_names, 3, UI_MENU_HDR_GAMMA_DESC); + static const char *const curves[] = {"vanilla", "renodrt"}; + static const char *const curve_names[] = {"Vanilla", "RenoDRT"}; + opt_choice_list("NX2NAVI_HDR_TONEMAP", UI_MENU_HDR_TONEMAP, curves, curve_names, 2, UI_MENU_HDR_TONEMAP_DESC); + if (!strcmp(cfg_value("NX2NAVI_HDR_TONEMAP"), "vanilla")) return; + opt_slider("NX2NAVI_HDR_EXPOSURE", UI_MENU_HDR_EXPOSURE, 0, 200, UI_MENU_HDR_EXPOSURE_DESC, 5, "%.0f %%"); + opt_slider("NX2NAVI_HDR_HIGHLIGHTS", UI_MENU_HDR_HIGHLIGHTS, 0, 100, UI_MENU_HDR_HIGHLIGHTS_DESC, 1, "%.0f"); + opt_slider("NX2NAVI_HDR_SHADOWS", UI_MENU_HDR_SHADOWS, 0, 100, UI_MENU_HDR_SHADOWS_DESC, 1, "%.0f"); + opt_slider("NX2NAVI_HDR_CONTRAST", UI_MENU_HDR_CONTRAST, 0, 100, UI_MENU_HDR_CONTRAST_DESC, 1, "%.0f"); + opt_slider("NX2NAVI_HDR_SATURATION", UI_MENU_HDR_SATURATION, 0, 100, UI_MENU_HDR_SATURATION_DESC, 1, "%.0f"); + opt_slider("NX2NAVI_HDR_HIGHLIGHT_SAT", UI_MENU_HDR_HIGHLIGHT_SAT, 0, 100, UI_MENU_HDR_HIGHLIGHT_SAT_DESC, 1, "%.0f"); + opt_slider("NX2NAVI_HDR_BLOWOUT", UI_MENU_HDR_BLOWOUT, 0, 100, UI_MENU_HDR_BLOWOUT_DESC, 1, "%.0f"); + opt_slider("NX2NAVI_HDR_FLARE", UI_MENU_HDR_FLARE, 0, 100, UI_MENU_HDR_FLARE_DESC, 1, "%.0f"); + opt_slider("NX2NAVI_HDR_HUE", UI_MENU_HDR_HUE, 0, 100, UI_MENU_HDR_HUE_DESC, 5, "%.0f %%"); + opt_slider("NX2NAVI_HDR_GRADE", UI_MENU_HDR_GRADE, 0, 100, UI_MENU_HDR_GRADE_DESC, 5, "%.0f %%"); } // Frame generation (vk_fg.cpp, at once; NVIDIA's after a restart); it needs a temporal upscaler's motion vectors @@ -1359,7 +1376,7 @@ static void perf_picture(const MenuTarget *t, PerfPanel *p) { else snprintf(v[7], sizeof v[7], "%sp", r); } const char *hdr = cfg_value("NX2NAVI_HDR"); - snprintf(v[8], sizeof v[8], "%s", menu_text(!strcmp(hdr, "native") ? UI_MENU_HDR_NATIVE : cfg_bool("NX2NAVI_HDR") ? UI_MENU_HDR_ENHANCED : UI_MENU_FRAMEGEN_OFF)); + snprintf(v[8], sizeof v[8], "%s", menu_text(!strcmp(hdr, "native") ? UI_MENU_HDR_NATIVE : cfg_bool("NX2NAVI_HDR") ? UI_MENU_HDR_TONEMAPPED : UI_MENU_FRAMEGEN_OFF)); const char *fg = cfg_value("NX2NAVI_FRAMEGEN"); snprintf(v[9], sizeof v[9], "%s", !strcmp(fg, "fsr3") ? "AMD FSR 3.1" : !strcmp(fg, "dlss") ? "NVIDIA DLSS" : menu_text(UI_MENU_FRAMEGEN_OFF)); // The 3D scene's size is known only where resolution.c sets it (the builds with its patch sets); Ocarina sizes its diff --git a/runtime/ui_text.c b/runtime/ui_text.c index 931b8769..b4a866d2 100644 --- a/runtime/ui_text.c +++ b/runtime/ui_text.c @@ -111,9 +111,33 @@ static const char *const text_en[UI_TEXT_COUNT] = { [UI_MENU_HDR_GAME_DESC] = "Brightness of white in the game, in nits.", [UI_MENU_HDR_UI] = "HUD and menu brightness", [UI_MENU_HDR_UI_DESC] = "Brightness of the HUD and this menu, in nits.", - [UI_MENU_HDR_HUE] = "Highlight hue correction", - [UI_MENU_HDR_HUE_DESC] = "Bright colours such as fire and sparks turn towards white as in the game's own SDR picture, " - "matching the light they cast; 0 keeps them fully saturated.", + [UI_MENU_HDR_HUE] = "Hue correction", + [UI_MENU_HDR_HUE_DESC] = "How much bright colours keep the hue they have before the tone mapper; 0 lets them shift " + "as the curve takes them.", + [UI_MENU_HDR_GAMMA] = "Gamma correction", + [UI_MENU_HDR_GAMMA_DESC] = "Shows the picture as a 2.2 or BT.1886 (2.4) display would, as the game was made to be " + "seen; Off keeps the sRGB curve, with lighter shadows.", + [UI_MENU_HDR_TONEMAP] = "Tone mapper", + [UI_MENU_HDR_TONEMAP_DESC] = "Vanilla: the game's own curve at SDR brightness. RenoDRT: the game's look carried up " + "to your display's peak.", + [UI_MENU_HDR_EXPOSURE] = "Exposure", + [UI_MENU_HDR_EXPOSURE_DESC] = "Brightness of the whole picture before the tone mapper; 100 % leaves it unchanged.", + [UI_MENU_HDR_HIGHLIGHTS] = "Highlights", + [UI_MENU_HDR_HIGHLIGHTS_DESC] = "Brightness of the bright parts; 50 leaves them unchanged.", + [UI_MENU_HDR_SHADOWS] = "Shadows", + [UI_MENU_HDR_SHADOWS_DESC] = "Brightness of the dark parts; 50 leaves them unchanged.", + [UI_MENU_HDR_CONTRAST] = "Contrast", + [UI_MENU_HDR_CONTRAST_DESC] = "Contrast around mid grey; 50 leaves it unchanged.", + [UI_MENU_HDR_SATURATION] = "Saturation", + [UI_MENU_HDR_SATURATION_DESC] = "Strength of all colours; 50 leaves it unchanged.", + [UI_MENU_HDR_HIGHLIGHT_SAT] = "Highlight saturation", + [UI_MENU_HDR_HIGHLIGHT_SAT_DESC] = "Strength of the colours of the brightest parts; 50 leaves it unchanged.", + [UI_MENU_HDR_BLOWOUT] = "Blowout", + [UI_MENU_HDR_BLOWOUT_DESC] = "Turns the brightest parts towards white; 0 keeps their colour.", + [UI_MENU_HDR_FLARE] = "Flare", + [UI_MENU_HDR_FLARE_DESC] = "Lifts the darkest parts as a little stray light would; 0 keeps black black.", + [UI_MENU_HDR_GRADE] = "Colour grading", + [UI_MENU_HDR_GRADE_DESC] = "How much of the game's own colour grading the HDR picture keeps; 0 is the scene without it.", [UI_MENU_SHADOW_SCALE] = "Shadow resolution", [UI_MENU_SHADOW_SCALE_DESC] = "Sharper shadows. Higher costs more GPU power.", [UI_MENU_PCSS] = "Soft shadows", @@ -489,7 +513,7 @@ static const char *const text_en[UI_TEXT_COUNT] = { [UI_MENU_FRAMEGEN] = "Frame generation", [UI_MENU_FRAMEGEN_DESC] = "Adds generated frames for smoother motion. Needs DLSS or FSR 3.1.", [UI_MENU_FRAMEGEN_OFF] = "Off", - [UI_MENU_HDR_ENHANCED] = "Enhanced", [UI_MENU_HDR_NATIVE] = "Native (the game's)", + [UI_MENU_HDR_TONEMAPPED] = "RenoDX", [UI_MENU_HDR_NATIVE] = "Native (the game's)", [UI_MENU_FRAMEGEN_NOTE] = "needs DLSS or FSR 3.1", [UI_MENU_FRAMEGEN_NEEDS] = "choose a DLSS or FSR 3.1 mode under Upscaling first", [UI_MENU_FRAMEGEN_NEEDS_FSR] = "choose an FSR 3.1 mode under Upscaling first", @@ -588,9 +612,33 @@ static const char *const text_ru[UI_TEXT_COUNT] = { [UI_MENU_HDR_GAME_DESC] = "Яркость белого в игре, в нитах.", [UI_MENU_HDR_UI] = "Яркость интерфейса и меню", [UI_MENU_HDR_UI_DESC] = "Яркость интерфейса и этого меню, в нитах.", - [UI_MENU_HDR_HUE] = "Коррекция оттенка бликов", - [UI_MENU_HDR_HUE_DESC] = "Яркие цвета (огонь, искры) уходят к белому, как в SDR-картинке игры, и совпадают со светом, " - "который они дают; 0 оставляет их полностью насыщенными.", + [UI_MENU_HDR_HUE] = "Коррекция оттенка", + [UI_MENU_HDR_HUE_DESC] = "Насколько яркие цвета сохраняют оттенок, который был до тональной кривой; при 0 они " + "смещаются вместе с кривой.", + [UI_MENU_HDR_GAMMA] = "Коррекция гаммы", + [UI_MENU_HDR_GAMMA_DESC] = "Показывает картинку так, как её показал бы экран с гаммой 2.2 или BT.1886 (2.4), для " + "которого игра делалась; «Выкл.» оставляет кривую sRGB с более светлыми тенями.", + [UI_MENU_HDR_TONEMAP] = "Тональная кривая", + [UI_MENU_HDR_TONEMAP_DESC] = "Vanilla: собственная кривая игры с яркостью SDR. RenoDRT: вид игры, доведённый до " + "пиковой яркости экрана.", + [UI_MENU_HDR_EXPOSURE] = "Экспозиция", + [UI_MENU_HDR_EXPOSURE_DESC] = "Яркость всей картинки до тональной кривой; 100 % оставляет её без изменений.", + [UI_MENU_HDR_HIGHLIGHTS] = "Света", + [UI_MENU_HDR_HIGHLIGHTS_DESC] = "Яркость светлых участков; 50 оставляет их без изменений.", + [UI_MENU_HDR_SHADOWS] = "Тени", + [UI_MENU_HDR_SHADOWS_DESC] = "Яркость тёмных участков; 50 оставляет их без изменений.", + [UI_MENU_HDR_CONTRAST] = "Контраст", + [UI_MENU_HDR_CONTRAST_DESC] = "Контраст вокруг среднего серого; 50 оставляет его без изменений.", + [UI_MENU_HDR_SATURATION] = "Насыщенность", + [UI_MENU_HDR_SATURATION_DESC] = "Сила всех цветов; 50 оставляет её без изменений.", + [UI_MENU_HDR_HIGHLIGHT_SAT] = "Насыщенность светов", + [UI_MENU_HDR_HIGHLIGHT_SAT_DESC] = "Сила цвета самых ярких участков; 50 оставляет её без изменений.", + [UI_MENU_HDR_BLOWOUT] = "Выгорание", + [UI_MENU_HDR_BLOWOUT_DESC] = "Уводит самые яркие участки к белому; 0 сохраняет их цвет.", + [UI_MENU_HDR_FLARE] = "Засветка", + [UI_MENU_HDR_FLARE_DESC] = "Приподнимает самые тёмные участки, как немного рассеянного света; 0 оставляет чёрное чёрным.", + [UI_MENU_HDR_GRADE] = "Цветокоррекция игры", + [UI_MENU_HDR_GRADE_DESC] = "Сколько собственной цветокоррекции игры сохраняет HDR-картинка; 0 — сцена без неё.", [UI_MENU_SHADOW_SCALE] = "Разрешение теней", [UI_MENU_SHADOW_SCALE_DESC] = "Более чёткие тени. Выше — больше нагрузка на видеокарту.", [UI_MENU_PCSS] = "Мягкие тени", @@ -1375,9 +1423,33 @@ static const char *const text_pt_br[UI_TEXT_COUNT] = { [UI_MENU_WALK_SCALE_DESC] = "A inclinação dos analógicos do teclado enquanto a tecla de andar está segura. Metade " "é andar, a inclinação total é correr.", [UI_MENU_OV_SCALE_DOWN] = "bilinear (nitidez FSR 0)", - [UI_MENU_HDR_HUE] = "Correção de matiz dos realces", - [UI_MENU_HDR_HUE_DESC] = "Cores fortes como fogo e faíscas vão para o branco como na imagem SDR do próprio jogo e " - "combinam com a luz que emitem; 0 as mantém totalmente saturadas.", + [UI_MENU_HDR_HUE] = "Correção de matiz", + [UI_MENU_HDR_HUE_DESC] = "Quanto as cores brilhantes mantêm o matiz que tinham antes da curva de tons; 0 deixa que " + "mudem com a curva.", + [UI_MENU_HDR_GAMMA] = "Correção de gama", + [UI_MENU_HDR_GAMMA_DESC] = "Mostra a imagem como uma tela de gama 2.2 ou BT.1886 (2.4) mostraria, como o jogo foi " + "feito para ser visto; Desligado mantém a curva sRGB, com sombras mais claras.", + [UI_MENU_HDR_TONEMAP] = "Curva de tons", + [UI_MENU_HDR_TONEMAP_DESC] = "Vanilla: a curva do próprio jogo, com brilho SDR. RenoDRT: o visual do jogo levado até " + "o pico da sua tela.", + [UI_MENU_HDR_EXPOSURE] = "Exposição", + [UI_MENU_HDR_EXPOSURE_DESC] = "Brilho de toda a imagem antes da curva de tons; 100 % a deixa como está.", + [UI_MENU_HDR_HIGHLIGHTS] = "Realces", + [UI_MENU_HDR_HIGHLIGHTS_DESC] = "Brilho das partes claras; 50 as deixa como estão.", + [UI_MENU_HDR_SHADOWS] = "Sombras", + [UI_MENU_HDR_SHADOWS_DESC] = "Brilho das partes escuras; 50 as deixa como estão.", + [UI_MENU_HDR_CONTRAST] = "Contraste", + [UI_MENU_HDR_CONTRAST_DESC] = "Contraste em torno do cinza médio; 50 o deixa como está.", + [UI_MENU_HDR_SATURATION] = "Saturação", + [UI_MENU_HDR_SATURATION_DESC] = "Força de todas as cores; 50 a deixa como está.", + [UI_MENU_HDR_HIGHLIGHT_SAT] = "Saturação dos realces", + [UI_MENU_HDR_HIGHLIGHT_SAT_DESC] = "Força das cores das partes mais claras; 50 a deixa como está.", + [UI_MENU_HDR_BLOWOUT] = "Estouro", + [UI_MENU_HDR_BLOWOUT_DESC] = "Leva as partes mais claras para o branco; 0 mantém a cor delas.", + [UI_MENU_HDR_FLARE] = "Flare", + [UI_MENU_HDR_FLARE_DESC] = "Ergue as partes mais escuras como um pouco de luz difusa faria; 0 mantém o preto preto.", + [UI_MENU_HDR_GRADE] = "Gradação de cor", + [UI_MENU_HDR_GRADE_DESC] = "Quanto da gradação de cor do próprio jogo a imagem HDR mantém; 0 é a cena sem ela.", [UI_MENU_SHADOW_SCALE] = "Resolução das sombras", [UI_MENU_SHADOW_SCALE_DESC] = "Sombras mais nítidas. Mais alto exige mais da placa de vídeo.", [UI_MENU_SHADOW_RANGE] = "Alcance das cascatas de sombra", @@ -1968,8 +2040,30 @@ static const char *const text_zh_hans[UI_TEXT_COUNT] = { [UI_MENU_WALK_SCALE] = "步行幅度", [UI_MENU_WALK_SCALE_DESC] = "按住步行键时键盘摇杆的推动幅度。一半为走路,推满为奔跑。", [UI_MENU_OV_SCALE_DOWN] = "双线性(FSR 锐度 0)", - [UI_MENU_HDR_HUE] = "高光色调校正", - [UI_MENU_HDR_HUE_DESC] = "火焰、火花等明亮色彩像游戏自身的 SDR 画面一样趋向白色,与它们发出的光一致;0 保持完全饱和。", + [UI_MENU_HDR_HUE] = "色调校正", + [UI_MENU_HDR_HUE_DESC] = "明亮色彩保留色调映射前色调的程度;0 让它们随曲线偏移。", + [UI_MENU_HDR_GAMMA] = "伽马校正", + [UI_MENU_HDR_GAMMA_DESC] = "按游戏设计时的观看方式,以 2.2 或 BT.1886(2.4)显示器的效果呈现画面;关闭则保留 sRGB 曲线,暗部更亮。", + [UI_MENU_HDR_TONEMAP] = "色调映射", + [UI_MENU_HDR_TONEMAP_DESC] = "Vanilla:游戏自身的曲线,SDR 亮度。RenoDRT:把游戏的观感延伸到显示器的峰值亮度。", + [UI_MENU_HDR_EXPOSURE] = "曝光", + [UI_MENU_HDR_EXPOSURE_DESC] = "色调映射前整个画面的亮度;100 % 保持不变。", + [UI_MENU_HDR_HIGHLIGHTS] = "高光", + [UI_MENU_HDR_HIGHLIGHTS_DESC] = "明亮部分的亮度;50 保持不变。", + [UI_MENU_HDR_SHADOWS] = "阴影", + [UI_MENU_HDR_SHADOWS_DESC] = "暗部的亮度;50 保持不变。", + [UI_MENU_HDR_CONTRAST] = "对比度", + [UI_MENU_HDR_CONTRAST_DESC] = "中灰周围的对比度;50 保持不变。", + [UI_MENU_HDR_SATURATION] = "饱和度", + [UI_MENU_HDR_SATURATION_DESC] = "所有色彩的强度;50 保持不变。", + [UI_MENU_HDR_HIGHLIGHT_SAT] = "高光饱和度", + [UI_MENU_HDR_HIGHLIGHT_SAT_DESC] = "最亮部分的色彩强度;50 保持不变。", + [UI_MENU_HDR_BLOWOUT] = "过曝", + [UI_MENU_HDR_BLOWOUT_DESC] = "让最亮的部分趋向白色;0 保留其颜色。", + [UI_MENU_HDR_FLARE] = "眩光", + [UI_MENU_HDR_FLARE_DESC] = "像少量杂散光一样提亮最暗的部分;0 保持纯黑。", + [UI_MENU_HDR_GRADE] = "调色", + [UI_MENU_HDR_GRADE_DESC] = "HDR 画面保留游戏自身调色的程度;0 为不含调色的场景。", [UI_MENU_SHADOW_SCALE] = "阴影分辨率", [UI_MENU_SHADOW_SCALE_DESC] = "让阴影更清晰。越高越吃显卡。", [UI_MENU_SHADOW_RANGE] = "阴影级联范围", diff --git a/runtime/ui_text.h b/runtime/ui_text.h index e480011b..cb2ed3db 100644 --- a/runtime/ui_text.h +++ b/runtime/ui_text.h @@ -50,6 +50,12 @@ typedef enum { UI_MENU_HDR_GROUP, // group heading over the HDR rows UI_MENU_HDR, UI_MENU_HDR_DESC, UI_MENU_HDR_PEAK, UI_MENU_HDR_PEAK_DESC, UI_MENU_HDR_GAME, UI_MENU_HDR_GAME_DESC, UI_MENU_HDR_UI, UI_MENU_HDR_UI_DESC, UI_MENU_HDR_HUE, UI_MENU_HDR_HUE_DESC, + UI_MENU_HDR_GAMMA, UI_MENU_HDR_GAMMA_DESC, UI_MENU_HDR_TONEMAP, UI_MENU_HDR_TONEMAP_DESC, + UI_MENU_HDR_EXPOSURE, UI_MENU_HDR_EXPOSURE_DESC, UI_MENU_HDR_HIGHLIGHTS, UI_MENU_HDR_HIGHLIGHTS_DESC, + UI_MENU_HDR_SHADOWS, UI_MENU_HDR_SHADOWS_DESC, UI_MENU_HDR_CONTRAST, UI_MENU_HDR_CONTRAST_DESC, + UI_MENU_HDR_SATURATION, UI_MENU_HDR_SATURATION_DESC, UI_MENU_HDR_HIGHLIGHT_SAT, UI_MENU_HDR_HIGHLIGHT_SAT_DESC, + UI_MENU_HDR_BLOWOUT, UI_MENU_HDR_BLOWOUT_DESC, UI_MENU_HDR_FLARE, UI_MENU_HDR_FLARE_DESC, + UI_MENU_HDR_GRADE, UI_MENU_HDR_GRADE_DESC, UI_MENU_SHADOW_SCALE, UI_MENU_SHADOW_SCALE_DESC, UI_MENU_SHADOW_RANGE, UI_MENU_SHADOW_RANGE_DESC, UI_MENU_CONTACT_SHADOWS, UI_MENU_CONTACT_SHADOWS_DESC, @@ -244,7 +250,7 @@ typedef enum { // the settings menu's Picture rows for this game (ui/menu.cpp tab_screen): one upscaling choice (bilinear, FSR 1 // or a DLSS mode) and the picture's resolution UI_MENU_UPSCALING, UI_MENU_UPSCALING_DESC, UI_MENU_FRAMEGEN, UI_MENU_FRAMEGEN_DESC, - UI_MENU_FRAMEGEN_OFF, UI_MENU_FRAMEGEN_NOTE, UI_MENU_FRAMEGEN_NEEDS, UI_MENU_HDR_ENHANCED, UI_MENU_HDR_NATIVE, + UI_MENU_FRAMEGEN_OFF, UI_MENU_FRAMEGEN_NOTE, UI_MENU_FRAMEGEN_NEEDS, UI_MENU_HDR_TONEMAPPED, UI_MENU_HDR_NATIVE, UI_MENU_GAME_RES, UI_MENU_GAME_RES_DESC, UI_MENU_GAME_RES_NATIVE, // the same rows' texts on a GPU DLSS does not run on (not NVIDIA): the menu leaves DLSS out there UI_MENU_UPSCALING_DESC_FSR, UI_MENU_FRAMEGEN_DESC_FSR, UI_MENU_FRAMEGEN_NOTE_FSR, diff --git a/runtime/vk.h b/runtime/vk.h index a85d44ac..ee749e80 100644 --- a/runtime/vk.h +++ b/runtime/vk.h @@ -176,8 +176,9 @@ VkImageView vk_hdr_ui_target(VkCommandBuffer cb, uint32_t w, uint32_t h); void vk_hdr_ui_compose(VkCommandBuffer cb, VkImageView dst_view, VkFormat fmt, uint32_t w, uint32_t h); void vk_hdr_to_srgb8(const uint8_t *in, uint8_t *out, size_t px, int a2r); void vk_hdr_release(void); // before the device goes away -// The support buffer's HDR parameters (vk_exec_draw.c support_fill, read by shaders/hdr_tonemap.frag). -void vk_hdr_support(float out[4]); +// The support buffer's HDR settings, four vec4 at 1440 (vk_exec_draw.c support_fill; read by the game's tonemap with +// shaders/hdr_tonemap.frag spliced in, vk_hdr.c tonemap_splice). +void vk_hdr_support(float out[16]); // vk_contact.c: screen-space contact shadows on the game's composed scene colour (NX2NAVI_CONTACT_SHADOWS) int vk_contact_strength(void); // percent, 0 = off void vk_contact_release(void); // before the device goes away diff --git a/runtime/vk_exec_draw.c b/runtime/vk_exec_draw.c index 47e3dd5b..4cfd8183 100644 --- a/runtime/vk_exec_draw.c +++ b/runtime/vk_exec_draw.c @@ -36,8 +36,8 @@ #define MAX_DESC 1024 #define CHUNK_BYTES (4u << 20) #define ZERO_BYTES 65536u -#define SUPPORT_BYTES 1456u // the translator's SupportBuffer (std140): alpha_test, is_bgra[8], viewport_inverse, viewport_size, ...; - // 1408 pcss and 1424 shadow_spread (translator patches 0010, 0011), 1440 HDR (support_fill) +#define SUPPORT_BYTES 1504u // the translator's SupportBuffer (std140): alpha_test, is_bgra[8], viewport_inverse, viewport_size, ...; + // 1408 pcss and 1424 shadow_spread (translator patches 0010, 0011), 1440..1503 HDR (support_fill) #define NVN_STAGE_VS 0 #define NVN_STAGE_FS 1 #define NVN_STAGE_CS 5 @@ -2279,10 +2279,10 @@ static void support_fill(uint8_t *b, float w, float h, float point_size) { memcpy(b + 1408, pcss_params(), 16); // pcss (translator patch 0010): soft sun shadows in the cascade compares memcpy(b + 1424, shadow_spread_params(), 16); // shadow_spread (translator patch 0011): sun shadow filter width for (int i = 0; i < 73; i++) memcpy(b + 192 + 16 * i, &one, 4); // render scale 1: the host renders at guest size - if (vk_hdr_wanted()) { // read by the HDR tonemap only (shaders/hdr_tonemap.frag), which declares it past the translator's - float hdr[4]; + if (vk_hdr_wanted()) { // read by the game's tonemap only, once vk_hdr.c tonemap_splice has grown its block past the translator's + float hdr[16]; vk_hdr_support(hdr); - memcpy(b + 1440, hdr, 16); + memcpy(b + 1440, hdr, sizeof hdr); } } diff --git a/runtime/vk_hdr.c b/runtime/vk_hdr.c index 614c74c4..836584bd 100644 --- a/runtime/vk_hdr.c +++ b/runtime/vk_hdr.c @@ -1,26 +1,28 @@ -// HDR output (NX2NAVI_HDR=1): an HDR10 swapchain (Rec. 2020 primaries, PQ) and a game picture with highlights above the -// SDR white. Settings: NX2NAVI_HDR (read at start), NX2NAVI_HDR_PEAK_NITS (the display's peak), NX2NAVI_HDR_GAME_NITS (the -// picture's white, "paper white") and NX2NAVI_HDR_UI_NITS (the HUD's and this menu's white), the three read when the -// settings change. With NX2NAVI_HDR=0 nothing here runs and the present is what it was. +// HDR output (NX2NAVI_HDR=1): an HDR10 swapchain (Rec. 2020 primaries, PQ) and a game picture tone mapped to the +// display's range. Settings: NX2NAVI_HDR (read at start); the nits NX2NAVI_HDR_PEAK_NITS (the display's peak), +// NX2NAVI_HDR_GAME_NITS (the picture's white, "paper white") and NX2NAVI_HDR_UI_NITS (the HUD's and this menu's white); +// NX2NAVI_HDR_GAMMA, NX2NAVI_HDR_TONEMAP and the grading sliders NX2NAVI_HDR_EXPOSURE .. NX2NAVI_HDR_GRADE, all read +// when the settings change (vk_hdr_support). With NX2NAVI_HDR=0 nothing here runs and the present is what it was. // // The game's picture (docs/architecture.md, "HDR"). The game tonemaps its scene into an r11g11b10f target, upscales it // and draws the HUD into a second one (float, nothing in these passes clamps), and one last draw copies that into the // 8-bit sRGB window texture it presents. So: // 1. vk_hdr_shader_swap, on each fragment shader as it loads (in memory only; the cache keeps the translator's): 1.1.1's -// tonemap ends in the fitted ACES curve and a clamp to 0..1 per channel, and aces_extend changes those clamps so -// values above 1 (relative to the HUD's white) survive, rolled off at the peak. Recognised by the curve's -// constants, not by a hash, so another translator still finds it. A tonemap of the earlier shape (1 - e^-x and a -// saturation grade) becomes shaders/hdr_tonemap.frag instead. The game's FSR 1 upscale after it would clamp the -// picture to 1 again; fsr_unclamp drops that clamp in its SPIR-V. +// tonemap ends in the fitted ACES curve and a clamp to 0..1 per channel. tonemap_splice links the function +// nx_tonemap of shaders/hdr_tonemap.frag into that shader and stores its result in place of the three clamped +// channels: the game's SDR result upgraded to the HDR range and mapped onto the display (that file says how), with +// the settings in four vec4 the support buffer gains at 1440. Recognised by the curve's constants, not by a hash, so +// another translator still finds it. The game's FSR 1 upscale after it would clamp the picture to 1 again; +// fsr_unclamp drops that clamp in its SPIR-V. // 2. vk_hdr_draw / vk_hdr_present_source: a draw into a presented window texture that samples one float texture of // its size is that copy; the present then reads the float texture instead of the window texture. Any other last // draw into it leaves the window texture, decoded from sRGB: menus and movies stay SDR at the HUD's white. // The present is queued before the next frame's work (vk_backend.c), so the float target is read before the game // draws into it again. -// 3. vk_hdr_encode: on the present, the crop rectangle goes to PQ code values in an RGBA16F image (shaders/hdr_encode.comp) -// that FSR 1 or the blit scale into the swapchain. vk_hdr_ui_*: the in-game menu draws into an RGBA8 image and -// shaders/hdr_ui.frag blends it onto the swapchain at the HUD's white. -// The tonemap's approach: the game's curve up to near its white, then its tangent ("extended vanilla"). +// 3. vk_hdr_encode: on the present, the crop rectangle goes to PQ code values in an RGBA16F image (shaders/hdr_encode.comp: +// gamma correction, gamut compression, the HUD's white and the peak) that FSR 1 or the blit scale into the +// swapchain. vk_hdr_ui_*: the in-game menu draws into an RGBA8 image and shaders/hdr_ui.frag blends it onto the +// swapchain at the HUD's white. #include "vk.h" #include @@ -52,7 +54,7 @@ int vk_hdr_wanted(void) { // NX2NAVI_HDR = native: the game's own HDR. The display is reported as HDR10 (ov_gfx.c QueryDisplayHdrStatus, with // the peak and paper white of the settings), and the game then renders its HDR picture itself and presents it as -// PQ-encoded Rec. 2020 in A2B10G10R10 (format 64), which goes to the HDR10 swapchain as it is: no tonemap swap, no +// PQ-encoded Rec. 2020 in A2B10G10R10 (format 64), which goes to the HDR10 swapchain as it is: no tonemap splice, no // float picture, no encode (pictures still presented in 8 bits, before the switch, are encoded as for 1). static int g_native = -1; int vk_hdr_native(void) { @@ -62,21 +64,43 @@ int vk_hdr_native(void) { void vk_hdr_off(void) { g_wanted = 0; } -// The three nits, read again when the settings change. The replay (every draw's support buffer) and the present -// thread read them: an update fills the snapshot not in use and then publishes it. -typedef struct { float peak, game, ui, hue; } Nits; +// The settings, read again when they change. The replay (every draw's support buffer) and the present thread read +// them: an update fills the snapshot not in use and then publishes it. +typedef struct { + float peak, game, ui; // nits + float gamma; // 0 none, 1: 2.2, 2: 2.4 (the present's correction, hdr_encode.comp) + float tm[16]; // the support buffer's four vec4 (shaders/hdr_tonemap.frag p0..p3) +} Nits; static struct { unsigned seen; int cur; Nits snap[2]; PlatMutex lock; } N = {.seen = ~0u, .lock = PLAT_MUTEX_INIT}; +static float clampf(float v, float lo, float hi) { return fminf(fmaxf(v, lo), hi); } + static Nits nits(void) { unsigned v = cfg_version(); if (__atomic_load_n(&N.seen, __ATOMIC_ACQUIRE) != v) { plat_mutex_lock(&N.lock); if (N.seen != v) { Nits *n = &N.snap[!N.cur]; - n->peak = fmaxf((float)cfg_double("NX2NAVI_HDR_PEAK_NITS"), 80.0f); - n->game = fmaxf((float)cfg_double("NX2NAVI_HDR_GAME_NITS"), 80.0f); - n->ui = fmaxf((float)cfg_double("NX2NAVI_HDR_UI_NITS"), 80.0f); - n->hue = fminf(fmaxf((float)cfg_double("NX2NAVI_HDR_HUE"), 0.0f), 100.0f) / 100.0f; + n->peak = clampf((float)cfg_double("NX2NAVI_HDR_PEAK_NITS"), 80.0f, 10000.0f); + n->game = clampf((float)cfg_double("NX2NAVI_HDR_GAME_NITS"), 48.0f, 500.0f); + n->ui = clampf((float)cfg_double("NX2NAVI_HDR_UI_NITS"), 48.0f, 500.0f); + const char *g = cfg_value("NX2NAVI_HDR_GAMMA"); + n->gamma = !strcmp(g, "2.2") ? 1.0f : !strcmp(g, "2.4") ? 2.0f : 0.0f; + // the sliders' 0..100 with 50 unchanged become factors around 1; blowout and hue are fractions + float pct[8]; + static const char *const keys[8] = {"NX2NAVI_HDR_HIGHLIGHTS", "NX2NAVI_HDR_SHADOWS", "NX2NAVI_HDR_CONTRAST", + "NX2NAVI_HDR_SATURATION", "NX2NAVI_HDR_HIGHLIGHT_SAT", "NX2NAVI_HDR_BLOWOUT", + "NX2NAVI_HDR_FLARE", "NX2NAVI_HDR_HUE"}; + for (int i = 0; i < 8; i++) pct[i] = clampf((float)cfg_double(keys[i]), 0.0f, 100.0f); + float *t = n->tm; + t[0] = n->peak, t[1] = n->game, t[2] = n->ui; + t[3] = !strcmp(cfg_value("NX2NAVI_HDR_TONEMAP"), "vanilla") ? 0.0f : 3.0f; + t[4] = clampf((float)cfg_double("NX2NAVI_HDR_EXPOSURE"), 0.0f, 200.0f) / 100.0f; + t[5] = pct[0] * 0.02f, t[6] = pct[1] * 0.02f, t[7] = pct[2] * 0.02f; + t[8] = pct[3] * 0.02f, t[9] = pct[4] * 0.02f, t[10] = pct[5] * 0.01f, t[11] = pct[6] * 0.02f; + t[12] = pct[7] * 0.01f; + t[13] = clampf((float)cfg_double("NX2NAVI_HDR_GRADE"), 0.0f, 100.0f) / 100.0f; + t[14] = n->gamma, t[15] = 0; __atomic_store_n(&N.cur, !N.cur, __ATOMIC_RELEASE); __atomic_store_n(&N.seen, v, __ATOMIC_RELEASE); } @@ -85,27 +109,36 @@ static Nits nits(void) { return N.snap[__atomic_load_n(&N.cur, __ATOMIC_ACQUIRE)]; } -void vk_hdr_support(float out[4]) { +void vk_hdr_support(float out[16]) { Nits n = nits(); - out[0] = n.game / n.ui; // the picture's white against the HUD's - out[1] = n.peak > n.game ? n.peak / n.game : 1.0f; // the peak against the picture's white - out[2] = n.hue; // hue correction of highlights (hdr_tonemap.frag) - out[3] = 0; + memcpy(out, n.tm, sizeof n.tm); + if (!vk_hdr_active()) out[3] = -1.0f; // no HDR10 swapchain (yet): the game's own SDR picture } // ---- 1. the tonemap shader -enum { SPV_OP_NAME = 5, SPV_OP_TYPE_FLOAT = 22, SPV_OP_CONSTANT = 43, SPV_OP_DECORATE = 71, SPV_DEC_BINDING = 33, - SPV_DEC_SET = 34 }; - -// The variables of the game's shader, in the order of hdr_tonemap.frag's bindings 0..4. -static const char *const tm_names[5] = {"support_buffer", "fp_t_tcb_8", "fp_t_tcb_A", "fp_c1", "fp_c3"}; +enum { SPV_OP_NAME = 5, SPV_OP_EXT_INST_IMPORT = 11, SPV_OP_EXT_INST = 12, SPV_OP_MEMORY_MODEL = 14, + SPV_OP_ENTRY_POINT = 15, SPV_OP_CAPABILITY = 17, SPV_OP_TYPE_BOOL = 20, SPV_OP_TYPE_INT = 21, + SPV_OP_TYPE_FLOAT = 22, SPV_OP_TYPE_VECTOR = 23, SPV_OP_TYPE_MATRIX = 24, SPV_OP_TYPE_STRUCT = 30, + SPV_OP_TYPE_POINTER = 32, SPV_OP_TYPE_FUNCTION = 33, SPV_OP_CONSTANT_TRUE = 41, SPV_OP_CONSTANT_FALSE = 42, + SPV_OP_CONSTANT = 43, SPV_OP_CONSTANT_COMPOSITE = 44, SPV_OP_CONSTANT_NULL = 46, SPV_OP_FUNCTION = 54, + SPV_OP_FUNCTION_PARAMETER = 55, SPV_OP_FUNCTION_END = 56, SPV_OP_FUNCTION_CALL = 57, SPV_OP_VARIABLE = 59, + SPV_OP_LOAD = 61, SPV_OP_STORE = 62, SPV_OP_ACCESS_CHAIN = 65, SPV_OP_DECORATE = 71, SPV_OP_MEMBER_DECORATE = 72, + SPV_OP_VECTOR_SHUFFLE = 79, SPV_OP_COMPOSITE_CONSTRUCT = 80, SPV_OP_COMPOSITE_EXTRACT = 81, + SPV_OP_COMPOSITE_INSERT = 82, SPV_OP_FMUL = 133, SPV_OP_FDIV = 136, SPV_OP_LOOP_MERGE = 246, + SPV_OP_SELECTION_MERGE = 247, SPV_OP_LABEL = 248, SPV_OP_BRANCH_CONDITIONAL = 250, SPV_OP_SWITCH = 251, + SPV_OP_LINE = 8, SPV_OP_NO_LINE = 317, SPV_DEC_OFFSET = 35, SPV_SC_UNIFORM = 2, SPV_SC_OUTPUT = 3, + SPV_SC_FUNCTION = 7, SPV_CAP_SHADER = 1, GLSL_FMA = 50, GLSL_FMAX = 40, GLSL_FCLAMP = 43, GLSL_NMAX = 80, + GLSL_NCLAMP = 81 }; static int name_is(const uint32_t *a, uint32_t len, const char *s) { // OpName operands after the id size_t n = strlen(s); return (len - 2) * 4 >= n + 1 && !memcmp(a + 1, s, n + 1); } +// A 0..1 clamp: translators write FClamp, or NClamp (NaN gives the low bound, as the GPU's saturate does). +static int is_clamp(uint32_t inst) { return inst == GLSL_FCLAMP || inst == GLSL_NCLAMP; } + // The game's FSR 1 pass after the tonemap (some frames take it in place of the plain pass, at 1:1 as well as when it // scales up; what picks it is not known yet) ends with clamp(colour, 0.0, 1.0) per channel, which cuts the HDR // highlights back to the HUD's white for as long as the game takes it. Its own 0..1 clamps of the filter weights each @@ -113,13 +146,6 @@ static int name_is(const uint32_t *a, uint32_t len, const char *s) { // OpName // max(x, 0.0): one word shorter, so the words after it move down and the module shrinks. Recognised by FSR's two // reciprocal constants (0x7ef07ebb, 0x7ef19fff) and its one texture fp_t_tcb_8. Returns the clamps changed, -1 for // that shader with no output clamp found (a translator that stores the colour another way), 0 for any other shader. -enum { SPV_OP_EXT_INST_IMPORT = 11, SPV_OP_EXT_INST = 12, SPV_OP_VARIABLE = 59, SPV_OP_STORE = 62, - SPV_OP_ACCESS_CHAIN = 65, SPV_SC_OUTPUT = 3, GLSL_FMAX = 40, GLSL_FCLAMP = 43, GLSL_NMAX = 80, - GLSL_NCLAMP = 81 }; -// A 0..1 clamp: translators write FClamp, or NClamp (NaN gives the low bound, as the GPU's saturate does); its -// replacement keeps the kind (NMax for NClamp). -static int is_clamp(uint32_t inst) { return inst == GLSL_FCLAMP || inst == GLSL_NCLAMP; } - static int fsr_unclamp(uint32_t *w, uint64_t *words) { uint64_t n = *words; uint32_t bound = w[3], glsl = 0, float_type = 0, zero = 0, one = 0; @@ -170,263 +196,358 @@ static int fsr_unclamp(uint32_t *w, uint64_t *words) { return changed ? changed : -1; } -// Ocarina 1.1.1's tonemap (one draw from the scene light target, R11G11B10F, into a target of the same size, before -// anti-aliasing, DLSS and the HUD): the game's exposure, then per channel the fitted ACES filmic curve -// x (2.51 x + 0.03) / (x (2.43 x + 0.59) + 0.14) and clamp(.., 0, 1), the value it stores. aces_extend changes each such -// clamp in place, so the game's exposure and look stay its own: -// y = aces(x) + d^2 / (1 + d), d = max(x - ACES_XP, 0): the game's curve up to ACES_XP (0.67 of the SDR white -// there), then a boost that starts flat (no crease in a gradient across ACES_XP) and grows to one picture white per -// unit of x, where the game's curve has flattened out near 1: bright light stays bright instead of all ending near -// white (x = 1.4, the sunlit leaves of a forest by day: 1.22 against the game's 0.86; x = 3: 2.6), -// a roll-off of y from half the peak to the peak (support +1440 .y: peak / picture white, at least 1), -// times the picture's white against the HUD's (+1440 .x). -// The values are relative to the HUD's white, as the present's encode expects. The support buffer gets a member at -// 1440 (vk_exec_draw.c support_fill writes it), which the translator's SupportBuffer ends before. Recognised by the -// curve's 2.51 / 0.03 pair feeding a clamp to 0..1: any shader that ends with that curve keeps its highlights. -// Returns the clamps changed (0: not that shader). -enum { SPV_OP_TYPE_INT = 21, SPV_OP_TYPE_BOOL = 20, SPV_OP_TYPE_VECTOR = 23, SPV_OP_TYPE_STRUCT = 30, - SPV_OP_TYPE_POINTER = 32, SPV_OP_FUNCTION = 54, SPV_OP_LOAD = 61, SPV_OP_COMPOSITE_EXTRACT = 81, - SPV_OP_FNEGATE = 127, SPV_OP_FADD = 129, SPV_OP_FSUB = 131, SPV_OP_FMUL = 133, SPV_OP_FDIV = 136, - SPV_OP_SELECT = 169, SPV_OP_FORD_GREATER = 186, SPV_OP_MEMBER_DECORATE = 72, SPV_DEC_OFFSET = 35, - SPV_SC_UNIFORM = 2, GLSL_EXP = 27, GLSL_FMA = 50 }; -#define ACES_XP 0.6f +// Which words of an instruction are literals rather than ids, for the opcodes the tonemap library uses (word j, 1 is +// the first after the opcode word). An opcode it does not know makes the splice give up (-1). +static int spv_literal(uint32_t op, uint32_t j) { + switch (op) { + case SPV_OP_FUNCTION: case SPV_OP_VARIABLE: return j == 3; + case SPV_OP_LOAD: return j >= 4; + case SPV_OP_STORE: return j >= 3; + case SPV_OP_COMPOSITE_EXTRACT: return j >= 4; + case SPV_OP_COMPOSITE_INSERT: case SPV_OP_VECTOR_SHUFFLE: return j >= 5; + case SPV_OP_EXT_INST: return j == 4; + case SPV_OP_SELECTION_MERGE: return j == 2; + case SPV_OP_LOOP_MERGE: return j >= 3; + case SPV_OP_BRANCH_CONDITIONAL: return j >= 4; + case SPV_OP_CONSTANT: return j >= 3; + case SPV_OP_TYPE_INT: case SPV_OP_TYPE_FLOAT: return j >= 2; + case SPV_OP_TYPE_VECTOR: case SPV_OP_TYPE_MATRIX: return j == 3; + case SPV_OP_TYPE_POINTER: return j == 2; + case SPV_OP_SWITCH: case SPV_OP_LINE: case SPV_OP_NO_LINE: case 63 /* OpCopyMemory */: return -1; + default: return 0; + } +} -static int aces_extend(uint32_t **spirv, uint64_t *words) { +typedef struct { uint32_t *w; uint64_t n, cap; int bad; } SpvOut; + +static void put(SpvOut *o, const uint32_t *ins, uint32_t len) { + if (o->n + len > o->cap) { + uint64_t cap = (o->n + len) * 2; + uint32_t *w = realloc(o->w, cap * sizeof *w); + if (!w) { o->bad = 1; return; } + o->w = w, o->cap = cap; + } + memcpy(o->w + o->n, ins, len * sizeof *ins); + o->n += len; +} +#define PUT(o, ...) do { const uint32_t ins_[] = {__VA_ARGS__}; const uint32_t n_ = sizeof ins_ / sizeof *ins_; \ + uint32_t h_[1] = {n_ << 16 | ins_[0]}; put(o, h_, 1); put(o, ins_ + 1, n_ - 1); } while (0) + +// One library instruction with its ids mapped (map[id], new ones already assigned); 0 when an id has no mapping. +static int put_mapped(SpvOut *o, const uint32_t *ins, const uint32_t *map, uint32_t lbound) { + uint32_t op = ins[0] & 0xffff, len = ins[0] >> 16, tmp[64]; + if (len > 64) return 0; + tmp[0] = ins[0]; + for (uint32_t j = 1; j < len; j++) { + int lit = spv_literal(op, j); + if (lit < 0) return 0; + if (lit) { tmp[j] = ins[j]; continue; } + if (ins[j] >= lbound || !map[ins[j]]) return 0; + tmp[j] = map[ins[j]]; + } + put(o, tmp, len); + return 1; +} + +static int is_type_op(uint32_t op) { return op >= 19 && op <= 39; } +static int is_const_op(uint32_t op) { return op >= SPV_OP_CONSTANT_TRUE && op <= SPV_OP_CONSTANT_NULL && op != 45; } + +// The fitted ACES curve the game ends its tonemap with: FClamp/NClamp(FMul(FMul(x, Fma(x, 2.51, 0.03)), rcp), 0, 1) +// per channel, each result stored to a function variable that the output store of its channel loads. tonemap_splice +// keeps everything the game computes and only changes what the three colour channels store: nx_tonemap of the three x +// (shaders/hdr_tonemap.frag), called just before the first of those stores, with the settings from four vec4 the +// support buffer gains at 1440 (vk_exec_draw.c support_fill writes them; the translator's SupportBuffer ends there). +// The library's types are matched to the game's where the same (SPIR-V allows one declaration of each), its constants +// and functions appended with new ids. Gives up (0) on any shape it does not expect, and the shader stays as it was. +static int tonemap_splice(uint32_t **spirv, uint64_t *words) { uint32_t *w = *spirv; uint64_t n = *words; - uint32_t bound = w[3], glsl = 0, ft = 0, bt = 0, it = 0, v4 = 0, c0 = 0, c1 = 0, c251 = 0, c003 = 0, sb = 0, sb_ptr = 0, - st = 0, st_len = 0, ptr_v4 = 0; + uint32_t bound = w[3]; + if (bound < 8 || bound > (1u << 22)) return 0; const float f251 = 2.51f, f003 = 0.03f, fone = 1.0f; uint32_t b251, b003, bone; memcpy(&b251, &f251, 4), memcpy(&b003, &f003, 4), memcpy(&bone, &fone, 4); - uint32_t last_offset = 0; - uint32_t *def = calloc(bound ? bound : 1, sizeof *def); // result id -> word index of its instruction - if (!def) return 0; + uint32_t glsl = 0, ft = 0, c0 = 0, c1 = 0, c251 = 0, c003 = 0, sb = 0, sb_ptr = 0, st = 0, st_len = 0, st_v4 = 0, + it = 0, ptr_v4u = 0, last_offset = 0; + uint64_t first_fn = 0, first_label = 0, st_at = 0, dec_at = 0; + int nfn = 0; + uint32_t *def = calloc(bound, sizeof *def); // result id -> word index of its instruction + int32_t *cval = calloc(bound, sizeof *cval); // integer constant id -> value + 1 + uint8_t *outv = calloc(bound, 1); // 1: an Output variable + if (!def || !cval || !outv) goto fail; for (uint64_t i = 5; i < n;) { uint32_t op = w[i] & 0xffff, len = w[i] >> 16; - if (!len || i + len > n) { free(def); return 0; } + if (!len || i + len > n) goto fail; const uint32_t *a = w + i + 1; if (op == SPV_OP_EXT_INST_IMPORT && len >= 3 && name_is(a, len, "GLSL.std.450")) glsl = a[0]; else if (op == SPV_OP_TYPE_FLOAT && len == 3 && a[1] == 32) ft = a[0]; - else if (op == SPV_OP_TYPE_BOOL && len == 2) bt = a[0]; - else if (op == SPV_OP_TYPE_INT && len == 4 && a[1] == 32 && a[2] == 1) it = a[0]; - else if (op == SPV_OP_TYPE_VECTOR && len == 4 && a[1] == ft && ft && a[2] == 4) v4 = a[0]; + else if (op == SPV_OP_TYPE_INT && len == 4 && a[1] == 32 && (!it || a[2] == 1)) it = a[0]; else if (op == SPV_OP_CONSTANT && len == 4 && a[0] == ft && ft) { if (a[2] == 0) c0 = a[1]; else if (a[2] == bone) c1 = a[1]; else if (a[2] == b251) c251 = a[1]; else if (a[2] == b003) c003 = a[1]; - } else if (op == SPV_OP_NAME && len >= 3 && name_is(a, len, "support_buffer")) sb = a[0]; - else if (op == SPV_OP_TYPE_POINTER && len == 4 && a[1] == SPV_SC_UNIFORM && a[2] == v4 && v4) ptr_v4 = a[0]; + } else if (op == SPV_OP_CONSTANT && len == 4 && a[1] < bound && a[2] < 0x10000) cval[a[1]] = (int32_t)a[2] + 1; + else if (op == SPV_OP_NAME && len >= 3 && name_is(a, len, "support_buffer")) sb = a[0]; else if (op == SPV_OP_MEMBER_DECORATE && len == 5 && a[1] == 10 && a[2] == SPV_DEC_OFFSET && a[3] == 1424) - last_offset = a[0]; // the struct whose member 10 is at 1424 - if (op == SPV_OP_VARIABLE && len >= 4 && a[1] == sb && sb) sb_ptr = a[0]; - // results: [0] type, [1] id for the instructions that have both - if ((op == SPV_OP_FMUL || op == SPV_OP_FDIV || op == SPV_OP_EXT_INST || op == SPV_OP_LOAD) && len >= 3 && a[1] < bound) + last_offset = a[0], dec_at = i; // the struct whose member 10 is at 1424 + else if (op == SPV_OP_FUNCTION) { nfn++; if (!first_fn) first_fn = i; } + else if (op == SPV_OP_LABEL && !first_label) first_label = i; + if (op == SPV_OP_VARIABLE && len >= 4 && a[1] < bound) { + if (a[1] == sb && sb) sb_ptr = a[0]; + if (a[2] == SPV_SC_OUTPUT) outv[a[1]] = 1; + } + if (len >= 3 && a[1] < bound && (op == SPV_OP_FMUL || op == SPV_OP_FDIV || op == SPV_OP_EXT_INST || + op == SPV_OP_LOAD || op == SPV_OP_ACCESS_CHAIN || op == SPV_OP_VARIABLE)) def[a[1]] = (uint32_t)i; i += len; } - for (uint64_t i = 5; i < n && sb_ptr; i += w[i] >> 16) // the support buffer's block: pointer -> struct - if ((w[i] & 0xffff) == SPV_OP_TYPE_POINTER && (w[i] >> 16) == 4 && w[i + 1] == sb_ptr) st = w[i + 3]; - for (uint64_t i = 5; i < n && st; i += w[i] >> 16) - if ((w[i] & 0xffff) == SPV_OP_TYPE_STRUCT && w[i + 1] == st) st_len = w[i] >> 16; - // the clamps: FClamp(FMul(FMul(x, Fma(x, 2.51, 0.03)), rcp), 0, 1) + for (uint64_t i = 5; i < n; i += w[i] >> 16) { // the support buffer's block and a Uniform vec4 pointer + uint32_t op = w[i] & 0xffff, len = w[i] >> 16; + if (op == SPV_OP_TYPE_POINTER && len == 4 && w[i + 1] == sb_ptr && sb_ptr) st = w[i + 3]; + } + for (uint64_t i = 5; i < n && st; i += w[i] >> 16) { + uint32_t op = w[i] & 0xffff, len = w[i] >> 16; + if (op == SPV_OP_TYPE_STRUCT && w[i + 1] == st) st_len = len, st_at = i, st_v4 = w[i + len - 1]; + } + for (uint64_t i = 5; i < n && st_v4; i += w[i] >> 16) + if ((w[i] & 0xffff) == SPV_OP_TYPE_POINTER && (w[i] >> 16) == 4 && w[i + 2] == SPV_SC_UNIFORM && w[i + 3] == st_v4) + ptr_v4u = w[i + 1]; + if (!glsl || !ft || !it || !c0 || !c1 || !c251 || !c003 || !sb || st_len != 13 || last_offset != st || nfn != 1 || + !first_label || first_label < first_fn) + goto fail; + // the clamp sites and their x enum { MAX_SITES = 8 }; uint64_t site[MAX_SITES]; - uint32_t site_x[MAX_SITES]; + uint32_t site_x[MAX_SITES], site_var[MAX_SITES]; int nsite = 0; - if (glsl && ft && bt && it && v4 && c0 && c1 && c251 && c003 && st_len == 13 && last_offset == st) - for (uint64_t i = 5; i < n && nsite < MAX_SITES; i += w[i] >> 16) { - const uint32_t *a = w + i + 1; - if ((w[i] & 0xffff) != SPV_OP_EXT_INST || (w[i] >> 16) != 8 || a[2] != glsl || !is_clamp(a[3]) || - a[5] != c0 || a[6] != c1 || a[4] >= bound || !def[a[4]]) - continue; - const uint32_t *m = w + def[a[4]]; // FMul(num, rcp) - if ((m[0] & 0xffff) != SPV_OP_FMUL || m[3] >= bound || !def[m[3]]) continue; - const uint32_t *num = w + def[m[3]]; // FMul(x, Fma(x, 2.51, 0.03)) - if ((num[0] & 0xffff) != SPV_OP_FMUL || num[4] >= bound || !def[num[4]]) continue; - const uint32_t *f = w + def[num[4]]; - if ((f[0] & 0xffff) != SPV_OP_EXT_INST || (f[0] >> 16) != 8 || f[4] != GLSL_FMA || f[6] != c251 || f[7] != c003) - continue; - site[nsite] = i, site_x[nsite++] = num[3]; + for (uint64_t i = first_fn; i < n && nsite < MAX_SITES; i += w[i] >> 16) { + const uint32_t *a = w + i + 1; + if ((w[i] & 0xffff) != SPV_OP_EXT_INST || (w[i] >> 16) != 8 || a[2] != glsl || !is_clamp(a[3]) || + a[5] != c0 || a[6] != c1 || a[4] >= bound || !def[a[4]]) + continue; + const uint32_t *m = w + def[a[4]]; // FMul(num, rcp) + if ((m[0] & 0xffff) != SPV_OP_FMUL || m[3] >= bound || !def[m[3]]) continue; + const uint32_t *num = w + def[m[3]]; // FMul(x, Fma(x, 2.51, 0.03)) + if ((num[0] & 0xffff) != SPV_OP_FMUL || num[4] >= bound || !def[num[4]]) continue; + const uint32_t *f = w + def[num[4]]; + if ((f[0] & 0xffff) != SPV_OP_EXT_INST || (f[0] >> 16) != 8 || f[4] != GLSL_FMA || f[6] != c251 || f[7] != c003) + continue; + site[nsite] = i, site_x[nsite] = num[3], site_var[nsite] = 0; + for (uint64_t j = i; j < n; j += w[j] >> 16) // OpStore var, result + if ((w[j] & 0xffff) == SPV_OP_STORE && (w[j] >> 16) >= 3 && w[j + 2] == a[1]) { site_var[nsite] = w[j + 1]; break; } + if (site_var[nsite]) nsite++; + } + if (nsite < 3) goto fail; + // the output stores of channels 0..2: OpStore (AccessChain out, c), value, with a load of a site's variable between + uint64_t chain_at[3] = {0}, store_at[3] = {0}; + int chan_site[3] = {-1, -1, -1}; + for (uint64_t i = first_fn; i < n; i += w[i] >> 16) { + const uint32_t *a = w + i + 1; + if ((w[i] & 0xffff) != SPV_OP_STORE || (w[i] >> 16) < 3 || a[0] >= bound || !def[a[0]]) continue; + const uint32_t *ch = w + def[a[0]]; + if ((ch[0] & 0xffff) != SPV_OP_ACCESS_CHAIN || (ch[0] >> 16) != 5 || ch[3] >= bound || !outv[ch[3]] || + ch[4] >= bound || cval[ch[4]] < 1 || cval[ch[4]] > 3) + continue; + int c = cval[ch[4]] - 1; + if (store_at[c]) goto fail; // a channel stored twice + chain_at[c] = def[a[0]], store_at[c] = i; + for (uint64_t j = chain_at[c]; j < i; j += w[j] >> 16) + if ((w[j] & 0xffff) == SPV_OP_LOAD) + for (int s = 0; s < nsite; s++) + if (w[j + 3] == site_var[s]) chan_site[c] = s; + } + uint64_t at = ~0ull, lo = ~0ull, hi = 0; // the insertion point; the span that must be one block + for (int c = 0; c < 3; c++) { + if (chan_site[c] < 0 || !store_at[c]) goto fail; + for (int d = 0; d < c; d++) + if (chan_site[d] == chan_site[c]) goto fail; + int s = chan_site[c]; + at = chain_at[c] < at ? chain_at[c] : at; + uint64_t xd = def[site_x[s]] ? def[site_x[s]] : site[s]; + lo = xd < lo ? xd : lo, lo = site[s] < lo ? site[s] : lo; + hi = store_at[c] > hi ? store_at[c] : hi; + } + for (int c = 0; c < 3; c++) + if (site[chan_site[c]] >= at || def[site_x[chan_site[c]]] >= at) goto fail; + for (uint64_t i = lo; i < hi; i += w[i] >> 16) + if ((w[i] & 0xffff) == SPV_OP_LABEL) goto fail; + + // the library: its ids mapped into the game's id space + const uint32_t *L = hdr_tonemap_spv; + const uint64_t ln = sizeof hdr_tonemap_spv / 4; + const uint32_t lbound = L[3]; + uint32_t *map = calloc(lbound, sizeof *map), id = bound; + SpvOut g = {0}, f = {0}, o = {0}; // the library's globals, its functions, the result + uint32_t entry = 0, fn = 0, fn_type = 0; + if (!map) goto fail; + for (uint64_t i = 5; i < ln; i += L[i] >> 16) { + uint32_t op = L[i] & 0xffff, len = L[i] >> 16; + if (op == SPV_OP_ENTRY_POINT) entry = L[i + 2]; + else if (op == SPV_OP_NAME && len >= 3 && !memcmp(L + i + 2, "nx_tonemap(", 11)) fn = L[i + 1]; + } + for (uint64_t i = 5; i < ln;) { + uint32_t op = L[i] & 0xffff, len = L[i] >> 16; + const uint32_t *a = L + i + 1; + if (op == SPV_OP_FUNCTION) break; + if (op == SPV_OP_CAPABILITY && a[0] != SPV_CAP_SHADER) goto lib_fail; + if (op == SPV_OP_EXT_INST_IMPORT) { + if (!name_is(a, len, "GLSL.std.450")) goto lib_fail; + map[a[0]] = glsl; + } else if (is_type_op(op)) { + uint32_t tmp[64]; + if (len > 64) goto lib_fail; + tmp[0] = L[i], tmp[1] = 0; + for (uint32_t j = 2; j < len; j++) { + int lit = spv_literal(op, j); + if (!lit && (a[j - 1] >= lbound || !map[a[j - 1]])) goto lib_fail; + tmp[j] = lit ? a[j - 1] : map[a[j - 1]]; + } + uint32_t same = 0; // the game's own declaration of this type (any but a struct) + for (uint64_t k = 5; k < first_fn && op != SPV_OP_TYPE_STRUCT && !same; k += w[k] >> 16) + if (w[k] == L[i] && !memcmp(w + k + 2, tmp + 2, (len - 2) * 4)) same = w[k + 1]; + if (same) { + map[a[0]] = same; + } else { + map[a[0]] = tmp[1] = id++; + put(&g, tmp, len); + } + } else if (is_const_op(op)) { + map[a[1]] = id++; + if (!put_mapped(&g, L + i, map, lbound)) goto lib_fail; + } else if (op == SPV_OP_VARIABLE && a[2] != 1 /* Input */ && a[2] != SPV_SC_OUTPUT) { + goto lib_fail; // a global the functions could use; main's inputs and output are left behind with main } - free(def); - if (!nsite) return 0; - float fxp = ACES_XP, fhalf = 0.5f; - uint32_t id = bound; - uint32_t new_ptr = ptr_v4 ? 0 : id++, ptr = ptr_v4 ? ptr_v4 : new_ptr; - uint32_t i11 = id++, kxp = id++, khalf = id++; - // the struct's extra word, its member decoration, four global instructions, 25 instructions of at most 8 words a site - uint64_t cap = n + 1 + 5 + 4 * 5 + (uint64_t)nsite * 25 * 8; - uint32_t *o = malloc(cap * sizeof *o); - if (!o) return 0; - uint64_t k = 0; - memcpy(o, w, 5 * sizeof *w), k = 5; - // one instruction: its opcode, then its operands -#define EMIT(...) do { const uint32_t ins_[] = {__VA_ARGS__}; const uint32_t n_ = sizeof ins_ / sizeof *ins_; \ - o[k] = n_ << 16 | ins_[0]; memcpy(o + k + 1, ins_ + 1, (n_ - 1) * sizeof *ins_); k += n_; } while (0) - int globals_done = 0, s = 0; + // names, decorations (the inputs' locations), the entry point and the memory model stay the game's + i += len; + } + for (uint64_t i = 5; i < ln; i += L[i] >> 16) // nx_tonemap's function type + if ((L[i] & 0xffff) == SPV_OP_FUNCTION && L[i + 2] == fn) fn_type = L[i + 4]; + if (!entry || !fn || !fn_type || !map[fn_type]) goto lib_fail; + // nx_tonemap(vec3, vec4 x 4) with its parameters by pointer, as the compiler writes them + const uint32_t *ftype = NULL; + for (uint64_t i = 5; i < ln && !ftype; i += L[i] >> 16) + if ((L[i] & 0xffff) == SPV_OP_TYPE_FUNCTION && L[i + 1] == fn_type && (L[i] >> 16) == 8) ftype = L + i; + if (!ftype) goto lib_fail; + uint32_t param_ptr[5], v3 = map[ftype[2]], v4 = 0, ptr_types_ok = 1; + for (int p = 0; p < 5; p++) { + param_ptr[p] = map[ftype[3 + p]]; + uint32_t pointee = 0; + for (uint64_t i = 5; i < ln; i += L[i] >> 16) + if ((L[i] & 0xffff) == SPV_OP_TYPE_POINTER && L[i + 1] == ftype[3 + p] && L[i + 2] == SPV_SC_FUNCTION) + pointee = map[L[i + 3]]; + if (!pointee || (p == 0 && pointee != v3) || (p > 0 && v4 && pointee != v4)) ptr_types_ok = 0; + if (p > 0) v4 = pointee; + } + if (!ptr_types_ok || v4 != st_v4) goto lib_fail; // the library's vec4 is the support buffer's + // the library's functions, all but its main. First a new id for every result in them (calls may refer ahead): + // OpLabel's is its first word, any other instruction's with a result its second. + uint64_t lib_fn = 0; + for (uint64_t i = 5; i < ln && !lib_fn; i += L[i] >> 16) + if ((L[i] & 0xffff) == SPV_OP_FUNCTION) lib_fn = i; + for (uint64_t i = lib_fn; i < ln && lib_fn; i += L[i] >> 16) { + uint32_t op = L[i] & 0xffff, len = L[i] >> 16, r; + switch (op) { + case SPV_OP_STORE: case SPV_OP_SELECTION_MERGE: case SPV_OP_LOOP_MERGE: case SPV_OP_BRANCH_CONDITIONAL: + case 249 /* OpBranch */: case 253 /* OpReturn */: case 254 /* OpReturnValue */: case SPV_OP_FUNCTION_END: + case 252 /* OpKill */: case 255 /* OpUnreachable */: + continue; + case SPV_OP_LABEL: r = len >= 2 ? L[i + 1] : 0; break; + default: r = len >= 3 ? L[i + 2] : 0; break; + } + if (!r || r >= lbound) goto lib_fail; + if (!map[r]) map[r] = id++; + } + int in_main = 0; + for (uint64_t i = lib_fn; i < ln && lib_fn; i += L[i] >> 16) { + uint32_t op = L[i] & 0xffff; + if (op == SPV_OP_FUNCTION) in_main = L[i + 2] == entry; + if (!in_main && !put_mapped(&f, L + i, map, lbound)) goto lib_fail; + if (op == SPV_OP_FUNCTION_END) in_main = 0; + } + if (!lib_fn || !map[fn] || g.bad || f.bad) goto lib_fail; + + // the result: the game's module with the support block grown, the library's globals before the first function, + // the call in main, the three stores changed, and the library's functions at the end + uint32_t idx[4], ptr_v4 = ptr_v4u ? ptr_v4u : id++, var[5], pv[4], pl[4], xv = id++, res = id++, e[3]; + for (int m = 0; m < 4; m++) idx[m] = id++, pv[m] = id++, pl[m] = id++; + for (int p = 0; p < 5; p++) var[p] = id++; + for (int c = 0; c < 3; c++) e[c] = id++; + put(&o, w, 5); for (uint64_t i = 5; i < n;) { uint32_t op = w[i] & 0xffff, len = w[i] >> 16; - const uint32_t *a = w + i + 1; - if (op == SPV_OP_FUNCTION && !globals_done) { // new types and constants close the global section - if (new_ptr) EMIT(SPV_OP_TYPE_POINTER, new_ptr, SPV_SC_UNIFORM, v4); - uint32_t b[2]; - memcpy(&b[0], &fxp, 4), memcpy(&b[1], &fhalf, 4); - EMIT(SPV_OP_CONSTANT, it, i11, 11); - EMIT(SPV_OP_CONSTANT, ft, kxp, b[0]); - EMIT(SPV_OP_CONSTANT, ft, khalf, b[1]); - globals_done = 1; + if (i == first_fn) { + put(&o, g.w, (uint32_t)g.n); + if (!ptr_v4u) PUT(&o, SPV_OP_TYPE_POINTER, ptr_v4, SPV_SC_UNIFORM, st_v4); + for (int m = 0; m < 4; m++) PUT(&o, SPV_OP_CONSTANT, it, idx[m], 11 + m); } - if (op == SPV_OP_TYPE_STRUCT && a[0] == st) { // the support block gains a vec4 at 1440 - memcpy(o + k, w + i, len * sizeof *w); - o[k] = (len + 1) << 16 | op; - o[k + len] = v4; - k += len + 1; - } else if (op == SPV_OP_MEMBER_DECORATE && len == 5 && a[0] == st && a[1] == 10 && a[2] == SPV_DEC_OFFSET && - a[3] == 1424) { - memcpy(o + k, w + i, len * sizeof *w), k += len; - EMIT(SPV_OP_MEMBER_DECORATE, st, 11, SPV_DEC_OFFSET, 1440); - } else if (s < nsite && i == site[s]) { - uint32_t x = site_x[s], r = a[4], res = a[1]; - uint32_t pv = id++, hv = id++, g = id++, p = id++, r0 = id++, dx = id++, d0 = id++, sq = id++, den = id++, - bo = id++, y = id++, pm = id++, kn = id++, rng = id++, d = id++, q = id++, nq = id++, e = id++, - om = id++, rl = id++, gk = id++, y2 = id++, gpos = id++, gs = id++; - EMIT(SPV_OP_ACCESS_CHAIN, ptr, pv, sb, i11); - EMIT(SPV_OP_LOAD, v4, hv, pv); - EMIT(SPV_OP_COMPOSITE_EXTRACT, ft, g, hv, 0); - EMIT(SPV_OP_COMPOSITE_EXTRACT, ft, p, hv, 1); - EMIT(SPV_OP_EXT_INST, ft, r0, glsl, GLSL_NMAX, r, c0); // NaN: 0, as the clamp gave - EMIT(SPV_OP_FSUB, ft, dx, x, kxp); // the boost above ACES_XP - EMIT(SPV_OP_EXT_INST, ft, d0, glsl, GLSL_NMAX, dx, c0); - EMIT(SPV_OP_FMUL, ft, sq, d0, d0); - EMIT(SPV_OP_FADD, ft, den, d0, c1); - EMIT(SPV_OP_FDIV, ft, bo, sq, den); - EMIT(SPV_OP_FADD, ft, y, r0, bo); - EMIT(SPV_OP_EXT_INST, ft, pm, glsl, GLSL_FMAX, p, c1); // the peak, in picture whites - EMIT(SPV_OP_FMUL, ft, kn, pm, khalf); // the knee: half of it - EMIT(SPV_OP_FSUB, ft, rng, pm, kn); - EMIT(SPV_OP_FSUB, ft, d, y, kn); - EMIT(SPV_OP_FDIV, ft, q, d, rng); - EMIT(SPV_OP_FNEGATE, ft, nq, q); - EMIT(SPV_OP_EXT_INST, ft, e, glsl, GLSL_EXP, nq); - EMIT(SPV_OP_FSUB, ft, om, c1, e); - EMIT(SPV_OP_EXT_INST, ft, rl, glsl, GLSL_FMA, rng, om, kn); - EMIT(SPV_OP_FORD_GREATER, bt, gk, y, kn); - EMIT(SPV_OP_SELECT, ft, y2, gk, rl, y); - EMIT(SPV_OP_FORD_GREATER, bt, gpos, g, c0); // the picture's white, 1 when unset - EMIT(SPV_OP_SELECT, ft, gs, gpos, g, c1); - EMIT(SPV_OP_FMUL, ft, res, y2, gs); - s++; + if (i == st_at) { // the support block gains four vec4 at 1440 + put(&o, w + i, len); + o.w[o.n - len] = (len + 4) << 16 | op; + for (int m = 0; m < 4; m++) put(&o, &st_v4, 1); + } else if (i == dec_at) { + put(&o, w + i, len); + for (int m = 0; m < 4; m++) PUT(&o, SPV_OP_MEMBER_DECORATE, st, 11 + m, SPV_DEC_OFFSET, 1440 + 16 * m); + } else if (i == first_label) { + put(&o, w + i, len); + for (int p = 0; p < 5; p++) PUT(&o, SPV_OP_VARIABLE, param_ptr[p], var[p], SPV_SC_FUNCTION); + } else if (i == store_at[0] || i == store_at[1] || i == store_at[2]) { + int c = i == store_at[0] ? 0 : i == store_at[1] ? 1 : 2; + put(&o, w + i, len); + o.w[o.n - len + 2] = e[c]; } else { - memcpy(o + k, w + i, len * sizeof *w), k += len; + if (i == at) { + for (int m = 0; m < 4; m++) { + PUT(&o, SPV_OP_ACCESS_CHAIN, ptr_v4, pv[m], sb, idx[m]); + PUT(&o, SPV_OP_LOAD, st_v4, pl[m], pv[m]); + } + PUT(&o, SPV_OP_COMPOSITE_CONSTRUCT, v3, xv, site_x[chan_site[0]], site_x[chan_site[1]], + site_x[chan_site[2]]); + PUT(&o, SPV_OP_STORE, var[0], xv); + for (int m = 0; m < 4; m++) PUT(&o, SPV_OP_STORE, var[m + 1], pl[m]); + PUT(&o, SPV_OP_FUNCTION_CALL, v3, res, map[fn], var[0], var[1], var[2], var[3], var[4]); + for (int c = 0; c < 3; c++) PUT(&o, SPV_OP_COMPOSITE_EXTRACT, ft, e[c], res, c); + } + put(&o, w + i, len); } i += len; } -#undef EMIT - if (!globals_done || s != nsite || k > cap) { - free(o); - return 0; - } - o[3] = id; + put(&o, f.w, (uint32_t)f.n); + if (o.bad) goto lib_fail; + o.w[3] = id; + free(map), free(g.w), free(f.w), free(def), free(cval), free(outv); free(*spirv); - *spirv = o; - *words = k; - return nsite; + *spirv = o.w; + *words = o.n; + return 1; +lib_fail: + free(map), free(g.w), free(f.w), free(o.w); +fail: + free(def), free(cval), free(outv); + return 0; } +#undef PUT void vk_hdr_shader_swap(uint32_t **spirv, uint64_t *words) { if (!vk_hdr_wanted() || vk_hdr_native() || !*spirv || *words < 5) return; - int extended = aces_extend(spirv, words); - if (extended > 0) { - static volatile int32_t exts; - rt_log("hdr: the game's tonemap keeps highlights above the picture's white (%d channels; %d shaders so far)", - extended, plat_inc32(&exts)); + if (tonemap_splice(spirv, words)) { + static volatile int32_t spliced; + rt_log("hdr: the game's tonemap maps its picture onto the display's range (%d shaders so far)", + plat_inc32(&spliced)); } int unclamped = fsr_unclamp(*spirv, words); if (unclamped > 0) { static volatile int32_t fsrs; rt_log("hdr: the game's FSR pass keeps values above 1 (%d output clamps; %d so far)", unclamped, plat_inc32(&fsrs)); - return; - } - if (unclamped < 0) { + } else if (unclamped < 0) { static volatile int32_t missed; if (plat_inc32(&missed) == 1) rt_log("hdr: the game's FSR pass was found but no clamp of its output; it still clips HDR highlights"); - return; } - const uint32_t *w = *spirv; - uint64_t n = *words; - // the game's constants: the BT.601 red weight, -1/ln 2 (e^-x as exp2), 2/3 (the grade's red weight), the bloom clamp - static const float want[4] = {0.298900008f, -1.44269502f, 0.666666687f, 10000.0f}; - uint32_t float_type = 0, found = 0, ids[5] = {0}, bind[5], set[5]; - int has_bind[5] = {0}; - for (uint64_t i = 5; i < n;) { - uint32_t op = w[i] & 0xffff, len = w[i] >> 16; - if (!len || i + len > n) return; - const uint32_t *a = w + i + 1; - if (op == SPV_OP_TYPE_FLOAT && len == 3 && a[1] == 32) float_type = a[0]; - else if (op == SPV_OP_CONSTANT && len == 4 && a[0] == float_type && float_type) - for (int k = 0; k < 4; k++) { - float f; - memcpy(&f, &a[2], 4); - if (f == want[k]) found |= 1u << k; - } - else if (op == SPV_OP_NAME && len >= 3) - for (int k = 0; k < 5; k++) - if (name_is(a, len, tm_names[k])) ids[k] = a[0]; - i += len; - } - if (found != 15) return; - for (int k = 0; k < 5; k++) - if (!ids[k]) return; - for (uint64_t i = 5; i < n;) { // the bindings and sets of those variables - uint32_t op = w[i] & 0xffff, len = w[i] >> 16; - const uint32_t *a = w + i + 1; - if (op == SPV_OP_DECORATE && len == 4) - for (int k = 0; k < 5; k++) - if (a[0] == ids[k]) { - if (a[1] == SPV_DEC_BINDING) bind[k] = a[2], has_bind[k] |= 1; - else if (a[1] == SPV_DEC_SET) set[k] = a[2], has_bind[k] |= 2; - } - i += len; - } - for (int k = 0; k < 5; k++) - if (has_bind[k] != 3) return; - uint64_t m = sizeof hdr_tonemap_spv / 4; - uint32_t *out = malloc(sizeof hdr_tonemap_spv); - if (!out) return; - memcpy(out, hdr_tonemap_spv, sizeof hdr_tonemap_spv); - // ours declares binding k for tm_names[k] in set 0: each gets the game's binding and set - uint32_t bound = out[3], *ours = calloc(bound ? bound : 1, sizeof *ours); // id -> our binding + 1 - if (!ours) { - free(out); - return; - } - for (uint64_t i = 5; i < m;) { - uint32_t op = out[i] & 0xffff, len = out[i] >> 16; - uint32_t *a = out + i + 1; - if (op == SPV_OP_DECORATE && len == 4 && a[1] == SPV_DEC_BINDING && a[2] < 5) { - if (a[0] < bound) ours[a[0]] = a[2] + 1; - a[2] = bind[a[2]]; - } - i += len; - } - for (uint64_t i = 5; i < m;) { - uint32_t op = out[i] & 0xffff, len = out[i] >> 16; - uint32_t *a = out + i + 1; - if (op == SPV_OP_DECORATE && len == 4 && a[1] == SPV_DEC_SET && a[0] < bound && ours[a[0]]) a[2] = set[ours[a[0]] - 1]; - i += len; - } - free(ours); - free(*spirv); - *spirv = out; - *words = m; - static volatile int32_t swaps; - rt_log("hdr: the game's tonemap shader runs as shaders/hdr_tonemap.frag (%d so far)", plat_inc32(&swaps)); } + // ---- 2. the picture the window texture is copied from int vk_hdr_track; // vk_exec_draw.c calls vk_hdr_draw: set at the first present with NX2NAVI_HDR=1 @@ -710,7 +831,7 @@ VkImage vk_hdr_encode(VkCommandBuffer cb, unsigned slot, VkImage src, VkFormat f vkCmdBindPipeline(cb, VK_PIPELINE_BIND_POINT_COMPUTE, H.enc); rec_push(H.push, cb, VK_PIPELINE_BIND_POINT_COMPUTE, H.enc_layout, 0, 2, w); struct { int32_t offset[2], size[2]; float p[4]; } pc = {{crop[0], crop[1]}, {crop[2], crop[3]}, - {n.ui, n.peak, decode ? 1.0f : 0.0f, 0}}; + {n.ui, n.peak, decode ? 1.0f : 0.0f, n.gamma}}; vkCmdPushConstants(cb, H.enc_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof pc, &pc); vkCmdDispatch(cb, ((uint32_t)crop[2] + 7) / 8, ((uint32_t)crop[3] + 7) / 8, 1); barrier(cb, src, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, CS, 0, ALL, 0); @@ -810,7 +931,8 @@ void vk_hdr_ui_compose(VkCommandBuffer cb, VkImageView dst_view, VkFormat fmt, u VkWriteDescriptorSet wr = {.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .dstBinding = 0, .descriptorCount = 1, .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, .pImageInfo = &ii}; rec_push(H.push, cb, VK_PIPELINE_BIND_POINT_GRAPHICS, H.ui_layout, 0, 1, &wr); - float pc[4] = {nits().ui, 0, 0, 0}; + Nits n = nits(); + float pc[4] = {n.ui, n.gamma, 0, 0}; vkCmdPushConstants(cb, H.ui_layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof pc, pc); vkCmdDraw(cb, 3, 1, 0, 0); vkCmdEndRendering(cb); diff --git a/tools/build_shaders.py b/tools/build_shaders.py index e4f627e3..40cc1a77 100644 --- a/tools/build_shaders.py +++ b/tools/build_shaders.py @@ -59,9 +59,12 @@ def stale(runtime): def compile_one(src): + # "// build_shaders: keep functions" in a source: no optimisation, so its functions stay functions (the HDR tonemap, + # which runtime/vk_hdr.c splices into the game's shader by function) + opt = [] if '// build_shaders: keep functions' in src.read_text(encoding='utf-8') else ['-O'] with tempfile.TemporaryDirectory() as tmp: spv = Path(tmp) / 'out.spv' - subprocess.run([str(BIN / 'glslc.exe') if WIN else 'glslc', '-O', f'--target-env={TARGET}', f'-fshader-stage={STAGES[src.suffix]}', + subprocess.run([str(BIN / 'glslc.exe') if WIN else 'glslc', *opt, f'--target-env={TARGET}', f'-fshader-stage={STAGES[src.suffix]}', '-o', str(spv), str(src)], check=True) subprocess.run([str(BIN / 'spirv-val.exe') if WIN else 'spirv-val', f'--target-env', TARGET, str(spv)], check=True) data = spv.read_bytes() diff --git a/tools/menu_preview.cpp b/tools/menu_preview.cpp index c477afdd..daa5d451 100644 --- a/tools/menu_preview.cpp +++ b/tools/menu_preview.cpp @@ -262,7 +262,7 @@ static void scene_overlay(float w, float h, float scale) { snprintf(p.picture[5], 64, "%s", menu_text(UI_MENU_ON)); snprintf(p.picture[6], 64, "21:9"); snprintf(p.picture[7], 64, "1440p"); - snprintf(p.picture[8], 64, "%s", menu_text(UI_MENU_HDR_ENHANCED)); + snprintf(p.picture[8], 64, "%s", menu_text(UI_MENU_HDR_TONEMAPPED)); snprintf(p.picture[9], 64, "%s", menu_text(UI_MENU_FRAMEGEN_OFF)); p.scene_known = false, p.fg_fps = 60, p.under_menu = false; perf_panel_draw(&p, w, scale);