15 Commits
Author SHA1 Message Date
AZiZ d46be6a68f Update v0.4 2026-10-10 23:45:02 +01:00
AZiZ 86bb7d474a opus audio/video bug patch 2026-10-10 23:44:10 +01:00
AZiZ a4d877b24d Update version badge to 0.4 in README.md 2026-10-10 23:42:08 +01:00
AZiZ d8050026b6 Enhance features in README with Opus and remote access
Updated features section to include Opus support and clarify phone/PC page functionality.
2026-10-10 23:41:13 +01:00
AZiZ 6b11ce8147 Update hardware decoding and add upscaling feature 2026-10-10 23:37:53 +01:00
AZiZ ebe77db666 Update hardware decoding and HDR features status 2026-10-10 23:34:05 +01:00
AZiZ 7b4e2d2ffe Readme 2026-10-10 18:21:44 +01:00
AZiZ 9aaeb373e9 Update v0.3.1 2026-10-10 16:41:16 +01:00
AZiZ c72b75db4f fixes Dolby TrueHD 7.1 2026-10-10 16:39:40 +01:00
AZiZ 82f942e8d6 Update version badge in README.md to 0.3 2026-10-09 23:06:03 +01:00
AZiZ 6613c82e5d Update README with Blu-ray Java menu status
Added note about Blu-ray Java (BD-J) menus not supported on PS5.
2026-10-09 23:05:02 +01:00
AZiZ 2e211f289e Delete README (1).md 2026-10-09 23:03:08 +01:00
AZiZ 016a7421d9 Add files via upload 2026-10-09 23:02:53 +01:00
AZiZ 3ed7996194 update readme #1 2026-10-09 23:01:29 +01:00
AZiZ 19a422b8b8 v0.3
Updates & fixes
2026-10-09 21:34:11 +01:00
46 changed files with 4952 additions and 470 deletions

No files matched your search

+12 -7
View File
@@ -10,7 +10,7 @@
</p>
<p align="center">
<img alt="Version" src="https://img.shields.io/badge/version-0.1-f37a2b">
<img alt="Version" src="https://img.shields.io/badge/version-0.4-f37a2b">
<img alt="Platform" src="https://img.shields.io/badge/platform-PS5-1f1f1f">
<img alt="VLC" src="https://img.shields.io/badge/libvlc-3.0.24-ff8800">
<img alt="Renderer" src="https://img.shields.io/badge/renderer-Vulkan%20(RADV)-c0561b">
@@ -21,13 +21,15 @@
## Features
- Plays nearly anything VLC plays: H.264, HEVC (8 and 10-bit), AV1, VP9, VC-1, MPEG-2 and more, up to 4K, with every common audio format, including TrueHD and DTS-HD.
- **Library** with Home, Videos, Music and Browse: thumbnails, Continue watching, Favourites and search.
- Plays nearly anything VLC plays: H.264, HEVC (8 and 10-bit), AV1, VP9, VC-1, MPEG-2 and more, up to 4K, with every common audio format, including TrueHD, DTS-HD and Opus.
- **Hardware decoding** on the PS5's video chip for H.264 and HEVC up to 4K, 10-bit HDR included.
- **HDR**: HDR10 and HLG go to an HDR TV as HDR, and are tone mapped with natural colours on an SDR one. Dolby Vision files play as their HDR10 base.
- **Library** with Home, Videos, Music, Playlists and Browse: thumbnails, Continue watching, Favourites and search.
- **Playlists**: make your own, add any video or song from anywhere with Options, reorder them; covers made from their videos; `.m3u` files on your drives play too.
- **Subtitles** in every script, styled ASS/SSA, size and colour, delay, plus **OpenSubtitles** downloads.
- **5.1 / 7.1 surround**, equalizer, night mode and audio delay.
- **Network**: SMB shares, DLNA servers, network links (HTTP, HLS, DASH…), free TV channels and internet radio.
- **PC/Phone page**: open `http://<ps5-ip>:8080` to send files to the PS5, use your pc or phone as a remote.
- **Phone & PC page**: open `http://<ps5-ip>:8080` in any browser to send files to the PS5, download them back to your phone or PC, or add your OpenSubtitles key.
- Music mode with covers and a visualizer, a photo viewer, DVD / Blu-ray folders, and ZIP / RAR / 7z archives.
- Two looks (**Classic** and **Modern**) and **16 languages**.
@@ -102,9 +104,11 @@ Optional full access. With etaHEN, OnionHEN or the Helper, VLC can lift its sand
| 360° videos (look around with the right stick) | ✅ |
| Frame-by-frame step | ✅ |
| Screenshots to PNG | ✅ |
| Hardware decoding (H.264 / HEVC / VP9 up to 4K) | Not yet |
| HDR → SDR tone mapping | Not yet |
| HDR10 output to the TV | Not yet |
| Hardware decoding (H.264 / HEVC) | ✅ |
| HDR → SDR tone mapping | ✅ |
| HDR10 output to the TV | ✅ |
| Hardware decoding (VP9 up to 4K) | Not yet |
| Upscaling up to 4K (FSR 1, Lanczos, Anime4K etc) | Not yet |
### 🔊 Audio
@@ -188,6 +192,7 @@ Optional full access. With etaHEN, OnionHEN or the Helper, VLC can lift its sand
|---|---|
| DVD folders and ISOs with menus | ✅ |
| Blu-ray folders and ISOs (unprotected) | ✅ |
| Blu-ray Java (BD-J) menus | ❌ needs Java, which the PS5 hasn't got: those discs play without menus |
| ZIP, RAR and 7z archives open like folders | ✅ |
## Building
+3 -3
View File
@@ -30,7 +30,7 @@ defs=(-DVK_NO_PROTOTYPES -DIMGUI_IMPL_VULKAN_USE_VOLK -DVLCPS5_HOST)
cflags=(-O2 -g -Wall -Wno-unused-function "${san[@]}" "${defs[@]}" "${inc[@]}")
# the newest of our headers: a file is built again when one changed (a struct
# that grew, a default argument) not only when the file itself did
newest_h=$(ls -t "$repo"/src/*.h | head -1)
newest_h=$(ls -t "$repo"/src/*.h "$repo"/src/gen/*.h | head -1)
objs=()
compile() { # source compiler [flags...]
@@ -48,7 +48,7 @@ done
compile "$repo/third_party/imgui/backends/imgui_impl_vulkan.cpp" g++ -std=c++17
compile "$repo/third_party/volk/volk.c" gcc -std=c11
compile "$repo/src/platform_host.c" gcc -std=gnu11
for f in gfx image prefs player library network osub lang web ui main; do
for f in gfx image prefs player subconv library network osub lang web ui main; do
compile "$repo/src/$f.cc" g++ -std=c++17 -Wno-missing-field-initializers
done
gcc -O2 -c "$static/static_modules.c" -o "$obj/static_modules.o"
@@ -67,5 +67,5 @@ if [[ ${VLCPS5_OWN_IO:-0} == 1 ]]; then
objs+=("$obj/libc_missing.o")
io_flags=(-Wl,--defsym=readv=xemu_ps5_readv -Wl,--defsym=writev=xemu_ps5_writev)
fi
g++ "${san[@]}" -o "$out/$name" "${objs[@]}" @"$static/link.rsp" -lpthread -ldl "${io_flags[@]}"
g++ "${san[@]}" -o "$out/$name" "${objs[@]}" @"$static/link.rsp" "$prefix/lib/libiconv.a" -lpthread -ldl "${io_flags[@]}"
echo "built $out/$name"
@@ -0,0 +1,17 @@
diff -ru a/modules/access/dvdnav.c b/modules/access/dvdnav.c
--- a/modules/access/dvdnav.c
+++ b/modules/access/dvdnav.c
@@ -89,6 +89,13 @@
static int AccessDemuxOpen ( vlc_object_t * );
static void Close( vlc_object_t * );
+/* VLC-PS5: configure looks for dvdnav_stream_cb with the plain preprocessor,
+ * without the cross prefix's include path, so it never finds it. libdvdnav
+ * 6.1 has it: DVD ISOs on a share or a link need this demux. */
+#ifndef HAVE_STREAM_CB_IN_DVDNAV_H
+# define HAVE_STREAM_CB_IN_DVDNAV_H 1
+#endif
+
#if DVDREAD_VERSION >= 50300 && defined( HAVE_STREAM_CB_IN_DVDNAV_H )
#define HAVE_DVDNAV_DEMUX
static int DemuxOpen ( vlc_object_t * );
+35
View File
@@ -0,0 +1,35 @@
--- a/modules/access/bluray.c 2026-10-09 16:18:09.281680898 +0000
+++ b/modules/access/bluray.c 2026-10-09 16:18:09.281979298 +0000
@@ -807,6 +807,11 @@
var_SetBool( p_demux, "ts-pcr-offsetfix", false );
var_AddCallback( p_demux->p_input, "intf-event", onIntfEvent, p_demux );
+ /* VLC-PS5: whether a menu (HDMV IG or pop-up) is on screen, and whether
+ * the film has a pop-up menu, for the app: the d-pad presses its buttons
+ * only then (a menu can show in any title, not only "Top Menu"). */
+ var_Create( p_demux->p_input, "bluray-menu-open", VLC_VAR_BOOL );
+ var_Create( p_demux->p_input, "bluray-popup", VLC_VAR_BOOL );
/* Open BluRay */
#ifdef BLURAY_DEMUX
@@ -1012,6 +1017,8 @@
demux_sys_t *p_sys = p_demux->p_sys;
var_DelCallback( p_demux->p_input, "intf-event", onIntfEvent, p_demux );
+ var_Destroy( p_demux->p_input, "bluray-menu-open" );
+ var_Destroy( p_demux->p_input, "bluray-popup" );
setTitleInfo(p_sys, NULL);
@@ -2809,9 +2816,11 @@
#endif
case BD_EVENT_MENU:
p_sys->b_menu_open = e->param;
+ var_SetBool( p_demux->p_input, "bluray-menu-open", e->param != 0 );
break;
case BD_EVENT_POPUP:
p_sys->b_popup_available = e->param;
+ var_SetBool( p_demux->p_input, "bluray-popup", e->param != 0 );
/* TODO: show / hide pop-up menu button in gui ? */
break;
@@ -0,0 +1,36 @@
--- a/modules/text_renderer/freetype/freetype.c 2026-10-09 16:41:20.491780240 +0000
+++ b/modules/text_renderer/freetype/freetype.c 2026-10-09 16:41:20.492100340 +0000
@@ -1081,6 +1081,33 @@
return psz_ucs4;
}
+#elif !defined( HAVE_ICONV )
+/* VLC-PS5: no iconv on the console (ToCharset gave nothing back, so plain-text
+ * subtitles drew nothing): the UTF-8 is read here, to native-endian UCS-4 as
+ * FREETYPE_TO_UCS asks; a bad byte becomes U+FFFD. */
+static void *ToUCS4( const char *in, size_t *outsize )
+{
+ size_t i_len = strlen( in );
+ uint32_t *p_out = vlc_alloc( i_len + 1, sizeof( *p_out ) );
+ if( unlikely( !p_out ) )
+ return NULL;
+ size_t i = 0;
+ while( *in )
+ {
+ uint32_t cp;
+ size_t i_bytes = vlc_towc( in, &cp );
+ if( i_bytes == 0 || i_bytes == (size_t)-1 )
+ {
+ cp = 0xFFFD;
+ i_bytes = 1;
+ }
+ p_out[i++] = cp;
+ in += i_bytes;
+ }
+ p_out[i] = 0;
+ *outsize = i * sizeof( *p_out );
+ return p_out;
+}
#else
# define ToUCS4( in, outsize ) ToCharset( FREETYPE_TO_UCS, ( in ), ( outsize ))
#endif
@@ -0,0 +1,23 @@
--- a/modules/demux/adaptive/http/HTTPConnection.cpp 2026-10-10 04:56:06.924021837 +0000
+++ b/modules/demux/adaptive/http/HTTPConnection.cpp 2026-10-10 04:56:06.924582937 +0000
@@ -195,14 +195,18 @@
int create(const char *uri,const std::string &ua,
const std::string &ref, const BytesRange &range)
{
- struct restuple *tpl = new struct restuple;
+ /* VLC-PS5: malloc, as vlc_http_res_destroy() frees it with
+ * free(); `new` here was a new/free mismatch (ASan) */
+ struct restuple *tpl = (struct restuple *) malloc(sizeof(*tpl));
+ if (tpl == nullptr)
+ return -1;
tpl->source = this;
this->range = range;
if (vlc_http_res_init(&tpl->resource, &this->callbacks, http_mgr, uri,
ua.empty() ? nullptr : ua.c_str(),
ref.empty() ? nullptr : ref.c_str()))
{
- delete tpl;
+ free(tpl);
return -1;
}
http_res = &tpl->resource;
@@ -0,0 +1,35 @@
--- a/modules/codec/avcodec/audio.c
+++ b/modules/codec/avcodec/audio.c
@@ -37,6 +37,7 @@
#include <vlc_avcodec.h>
#include "avcodec.h"
+#include "../../demux/xiph.h"
#include <libavcodec/avcodec.h>
#include <libavutil/mem.h>
@@ -103,6 +104,24 @@
i_size = 0;
}
+ /* VLC-PS5: VLC's demuxers hand Opus over as packed Xiph headers
+ * (OpusHead, OpusTags) for its own opus module; FFmpeg's decoder
+ * wants the OpusHead alone, else it reads no channels and fails */
+ if( p_dec->fmt_in.i_codec == VLC_CODEC_OPUS &&
+ ( i_size < 8 || memcmp( p_src, "OpusHead", 8 ) ) )
+ {
+ unsigned sizes[XIPH_MAX_HEADER_COUNT];
+ const void *headers[XIPH_MAX_HEADER_COUNT];
+ unsigned count;
+ if( !xiph_SplitHeaders( sizes, headers, &count, i_size, p_src ) &&
+ count > 0 && sizes[0] >= 19 &&
+ !memcmp( headers[0], "OpusHead", 8 ) )
+ {
+ i_offset = (const uint8_t *)headers[0] - p_src;
+ i_size = sizes[0];
+ }
+ }
+
if( i_size > 0 )
{
p_context->extradata =
+16
View File
@@ -0,0 +1,16 @@
--- a/modules/video_output/vmem.c
+++ b/modules/video_output/vmem.c
@@ -139,6 +139,13 @@
video_format_t fmt;
video_format_ApplyRotation(&fmt, &vd->fmt);
+ /* VLC-PS5: the picture's colours (HDR transfer, primaries, matrix,
+ * light levels), which the setup callback doesn't carry */
+ void (*colour)(void *, const video_format_t *) =
+ var_InheritAddress(vd, "vmem-colour");
+ if (colour != NULL)
+ colour(sys->opaque, &fmt);
+
if (setup != NULL) {
char chroma[5];
@@ -0,0 +1,34 @@
--- a/src/misc/picture.c
+++ b/src/misc/picture.c
@@ -62,9 +62,17 @@
/**
* Destroys a picture allocated with picture_NewFromFormat().
*/
+/* VLC-PS5: a 4K picture is 25 MiB and a video keeps 20 to 30 of them,
+ * more than the console's heap holds; the title puts big ones in its
+ * direct memory. Weak: without them, the heap as before. */
+extern void *vlc_ps5_big_alloc( size_t ) __attribute__((weak));
+extern int vlc_ps5_big_free( void * ) __attribute__((weak));
+#define VLC_PS5_BIG_PICTURE (4 << 20)
+
static void picture_Destroy( picture_t *p_picture )
{
- aligned_free( p_picture->p[0].p_pixels );
+ if( vlc_ps5_big_free == NULL || !vlc_ps5_big_free( p_picture->p[0].p_pixels ) )
+ aligned_free( p_picture->p[0].p_pixels );
free( p_picture );
}
@@ -274,7 +282,11 @@
goto error;
pic_size = (pic_size + 63) & ~63; /* must be a multiple of 64 */
- uint8_t *buf = aligned_alloc(64, pic_size);
+ uint8_t *buf = NULL;
+ if (vlc_ps5_big_alloc != NULL && pic_size >= VLC_PS5_BIG_PICTURE)
+ buf = vlc_ps5_big_alloc(pic_size);
+ if (buf == NULL)
+ buf = aligned_alloc(64, pic_size);
if (buf == NULL)
goto error;
+34
View File
@@ -0,0 +1,34 @@
--- a/modules/video_output/vmem.c
+++ b/modules/video_output/vmem.c
@@ -249,6 +249,10 @@
return sys->pool;
}
+/* VLC-PS5: the app's picture copy, when it has one */
+extern void vlc_ps5_copy_plane(uint8_t *, size_t, const uint8_t *, size_t, size_t,
+ unsigned) __attribute__((weak));
+
static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic)
{
vout_display_sys_t *sys = vd->sys;
@@ -265,7 +269,19 @@
picture_t *locked = picture_NewFromResource(&vd->fmt, &rsc);
if (likely(locked != NULL)) {
- picture_CopyPixels(locked, pic);
+ if (vlc_ps5_copy_plane != NULL) {
+ /* VLC-PS5: split over a few threads (a 4K picture is 25 MiB) */
+ for (int i = 0; i < locked->i_planes && i < pic->i_planes; i++) {
+ const plane_t *d = &locked->p[i], *s = &pic->p[i];
+ int lines = __MIN(d->i_visible_lines, s->i_visible_lines);
+ int bytes = __MIN(d->i_visible_pitch, s->i_visible_pitch);
+ if (lines > 0 && bytes > 0)
+ vlc_ps5_copy_plane(d->p_pixels, d->i_pitch, s->p_pixels, s->i_pitch,
+ bytes, lines);
+ }
+ } else {
+ picture_CopyPixels(locked, pic);
+ }
picture_Release(locked);
}
+49
View File
@@ -0,0 +1,49 @@
--- a/modules/access/smb2.c
+++ b/modules/access/smb2.c
@@ -123,6 +123,7 @@
struct srvsvc_netshareenumall_rep *share_enum;
#endif
uint64_t smb2_size;
+ uint64_t pos; /* VLC-PS5: where the next read starts */
vlc_url_t encoded_url;
bool eof;
bool smb2_connected;
@@ -320,8 +321,20 @@
/* Limit the read size since smb2_read_async() will complete only after
* reading the whole requested data and not when whatever data is available
* (high read size means a faster I/O but a higher latency). */
- if (len > 262144)
- len = 262144;
+ /* VLC-PS5: 2 MiB, fewer requests each waiting a network round trip
+ * (a 4K film needs 9 MB/s; 256 KiB at a time over Wi-Fi didn't make it),
+ * and never past the end of the file: a read crossing it failed, and with
+ * it the last metadata of a 13 GB Blu-ray image (console run 14) */
+ if (len > 2097152)
+ len = 2097152;
+ if (sys->smb2_size > 0) {
+ if (sys->pos >= sys->smb2_size) {
+ sys->eof = true;
+ return 0;
+ }
+ if (len > sys->smb2_size - sys->pos)
+ len = sys->smb2_size - sys->pos;
+ }
struct vlc_smb2_op op = VLC_SMB2_OP(access, &sys->smb2);
op.res.read.len = 0;
@@ -339,6 +352,7 @@
if (op.res.read.len == 0)
sys->eof = true;
+ sys->pos += op.res.read.len;
return op.res.read.len;
}
@@ -366,6 +380,7 @@
VLC_SMB2_SET_ERROR(&op, "smb2_lseek", err);
return err;
}
+ sys->pos = i_pos;
sys->eof = false;
return VLC_SUCCESS;
@@ -0,0 +1,94 @@
--- a/src/dvd_input.c
+++ b/src/dvd_input.c
@@ -103,6 +103,10 @@
/* dummy file input */
int fd;
+
+ /* VLC-PS5: a stream (DVDOpenStream) without libdvdcss */
+ dvd_reader_stream_cb *stream_cb;
+ uint64_t pos;
};
static dvd_input_t dvd_input_New(void *priv, dvd_logger_cb *logcb)
@@ -199,12 +203,26 @@
*/
static dvd_input_t file_open(void *priv, dvd_logger_cb *logcb,
const char *target,
- dvd_reader_stream_cb *stream_cb UNUSED)
+ dvd_reader_stream_cb *stream_cb)
{
dvd_input_t dev;
- if(target == NULL)
- return NULL;
+ if(target == NULL) {
+ /* VLC-PS5: no libdvdcss, so the plain input reads the stream itself
+ * (a DVD image on a network share). Unencrypted discs only. */
+ if(priv == NULL || stream_cb == NULL || !stream_cb->pf_seek || !stream_cb->pf_read)
+ return NULL;
+ dev = dvd_input_New(priv, logcb);
+ if(dev == NULL)
+ return NULL;
+ dev->fd = -1;
+ dev->stream_cb = stream_cb;
+ if(stream_cb->pf_seek(priv, 0) != 0) {
+ free(dev);
+ return NULL;
+ }
+ return dev;
+ }
/* Allocate the library structure */
dev = dvd_input_New(priv, logcb);
if(dev == NULL) {
@@ -256,6 +274,14 @@
{
off_t pos;
+ if(dev->stream_cb) {
+ uint64_t to = (uint64_t)blocks * DVD_VIDEO_LB_LEN;
+ if(dev->stream_cb->pf_seek(dev->priv, to) != 0)
+ return -1;
+ dev->pos = to;
+ return blocks;
+ }
+
pos = lseek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET);
if(pos < 0) {
return pos;
@@ -283,6 +309,26 @@
len = (size_t)blocks * DVD_VIDEO_LB_LEN;
bytes = 0;
+ if(dev->stream_cb) {
+ while(len > 0) {
+ int chunk = len > (1 << 30) ? (1 << 30) : (int)len;
+ int ret = dev->stream_cb->pf_read(dev->priv, ((char*)buffer) + bytes, chunk);
+ if(ret < 0)
+ return ret;
+ if(ret == 0)
+ break;
+ len -= ret;
+ bytes += ret;
+ dev->pos += ret;
+ }
+ if(bytes % DVD_VIDEO_LB_LEN) {
+ /* back to the last whole block, as the file input does */
+ dev->pos -= bytes % DVD_VIDEO_LB_LEN;
+ dev->stream_cb->pf_seek(dev->priv, dev->pos);
+ }
+ return (int) (bytes / DVD_VIDEO_LB_LEN);
+ }
+
while(len > 0) {
ssize_t ret = read(dev->fd, ((char*)buffer) + bytes, len);
@@ -318,7 +364,7 @@
{
int ret;
- ret = close(dev->fd);
+ ret = dev->stream_cb ? 0 : close(dev->fd);
free(dev);
+104
View File
@@ -0,0 +1,104 @@
--- a/src/vulkan/wsi/wsi_common_videoout.c
+++ b/src/vulkan/wsi/wsi_common_videoout.c
@@ -146,8 +146,46 @@
{
return -1;
}
+
+static int
+sceVideoOutSubmitChangeBufferAttribute2(int32_t handle, int32_t set, const void *attribute, const void *option)
+{
+ return 0;
+}
+
+struct ps5_video_out_output_status {
+ uint32_t resolution;
+ uint32_t dynamic_range;
+ uint64_t refresh_rate;
+ uint64_t flags;
+ uint64_t reserved[3];
+};
+
+static int
+sceVideoOutGetOutputStatus(int32_t handle, struct ps5_video_out_output_status *status)
+{
+ memset(status, 0, sizeof(*status));
+ status->dynamic_range = 1;
+ return 0;
+}
+#else
+/* VLC-PS5: VideoOut calls ps5platform/videoout.h doesn't declare. */
+struct ps5_video_out_output_status {
+ uint32_t resolution;
+ uint32_t dynamic_range; /* 0 unknown, 1 SDR, 2 HDR */
+ uint64_t refresh_rate;
+ uint64_t flags; /* bit 0: HDR output active */
+ uint64_t reserved[3];
+};
+int sceVideoOutSubmitChangeBufferAttribute2(int32_t handle, int32_t set, const void *attribute,
+ const void *option);
+int sceVideoOutGetOutputStatus(int32_t handle, struct ps5_video_out_output_status *status);
#endif
+/* VLC-PS5: HDR10 scanout, 10:10:10:2 in the framebuffers' B,G,R order with
+ * BT.2020 primaries and the PQ curve. */
+#define VLCPS5_VIDEO_OUT_PIXEL_FORMAT_HDR10 UINT64_C(0x8100070400000000)
+
/* The display and its modes: one each per process, as VideoOut is. */
struct wsi_videoout_mode {
uint32_t refresh_millihertz;
@@ -399,6 +437,54 @@
return VK_SUCCESS;
}
+/*
+ * VLC-PS5: HDR10 output. The framebuffers stay registered and are retyped in
+ * place (registering them again isn't possible while one is on screen); the
+ * new type applies from the next flip. The app waits for its GPU work to end
+ * first and from then on writes 10:10:10:2 PQ pixels into the same 32-bit
+ * buffers. 0 when VideoOut took it.
+ */
+int vlcps5_wsi_videoout_set_hdr(int enable);
+int vlcps5_wsi_videoout_dynamic_range(void);
+
+int
+vlcps5_wsi_videoout_set_hdr(int enable)
+{
+ struct wsi_videoout_output *out = &videoout_output;
+ mtx_lock(&out->lock);
+ int result = -1;
+ if (out->buffers) {
+ uint8_t attribute[PS5_VIDEO_OUT_ATTRIBUTE_BYTES] = {0};
+ sceVideoOutSetBufferAttribute2(attribute,
+ enable ? VLCPS5_VIDEO_OUT_PIXEL_FORMAT_HDR10
+ : PS5_VIDEO_OUT_PIXEL_FORMAT_B8G8R8A8_SDR,
+ PS5_VIDEO_OUT_TILING_64KB_R_X, VIDEOOUT_WIDTH, VIDEOOUT_HEIGHT, 0, 0, 0);
+ result = sceVideoOutSubmitChangeBufferAttribute2(out->handle, 0, attribute, NULL);
+ }
+ mtx_unlock(&out->lock);
+ fprintf(stderr, "wsi/videoout: framebuffers %s: 0x%08x\n", enable ? "HDR10" : "SDR", (unsigned)result);
+ return result;
+}
+
+/* VLC-PS5: what the output carries: 1 SDR, 2 HDR, 0 unknown, negative: no answer. */
+int
+vlcps5_wsi_videoout_dynamic_range(void)
+{
+ struct wsi_videoout_output *out = &videoout_output;
+ mtx_lock(&out->lock);
+ int result = -1;
+ if (videoout_open_locked()) {
+ struct ps5_video_out_output_status status;
+ memset(&status, 0, sizeof(status));
+ int rc = sceVideoOutGetOutputStatus(out->handle, &status);
+ result = rc == 0 ? (int)status.dynamic_range : -1;
+ fprintf(stderr, "wsi/videoout: output status 0x%08x: range %u, flags 0x%" PRIx64 "\n", (unsigned)rc,
+ status.dynamic_range, status.flags);
+ }
+ mtx_unlock(&out->lock);
+ return result;
+}
+
static int64_t
videoout_shown_argument_locked(void)
{
@@ -0,0 +1,18 @@
--- a/lib/socket.c 2026-10-10 18:59:32.030473620 +0000
+++ b/lib/socket.c 2026-10-10 18:59:32.038975423 +0000
@@ -1072,6 +1072,15 @@
set_nonblocking(fd);
set_tcp_sockopt(fd, TCP_NODELAY, 1);
+ /* VLC-PS5: big buffers, set before connect so the TCP window is
+ * agreed on with them. The console's default (64 KiB) let one window
+ * through per round trip: ~33 Mbit/s over Wi-Fi, under a 4K film's
+ * 70 and a 16 MiB prefetch taking seconds to start a video. */
+ {
+ int rcv = 4 * 1024 * 1024, snd = 1024 * 1024;
+ setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void *)&rcv, sizeof rcv);
+ setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *)&snd, sizeof snd);
+ }
#if 0 == CONFIGURE_OPTION_TCP_LINGER
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*)&yes, sizeof yes);
setsockopt(fd, SOL_SOCKET, SO_LINGER, (const void*)&lin, sizeof lin);
@@ -0,0 +1,55 @@
--- a/upnp/src/ssdp/ssdp_server.c 2026-10-09 20:35:17.057957885 +0000
+++ b/upnp/src/ssdp/ssdp_server.c 2026-10-09 20:35:17.058290985 +0000
@@ -981,6 +981,7 @@
INADDR_ANY,
SSDP_PORT,
errorBuffer);
+ fprintf(stderr, "upnp: bind UDP %d: %s\n", SSDP_PORT, errorBuffer);
ret = UPNP_E_SOCKET_BIND;
goto error_handler;
}
@@ -1509,10 +1510,23 @@
retVal = create_ssdp_sock_v4(&out->ssdpSock4);
if (retVal != UPNP_E_SUCCESS) {
#ifdef INCLUDE_CLIENT_APIS
- UpnpCloseSocket(out->ssdpReqSock4);
- UpnpCloseSocket(out->ssdpReqSock6);
- #endif /* INCLUDE_CLIENT_APIS */
+ /* VLC-PS5: port 1900 taken (the console's own SSDP,
+ * another user: no SO_REUSEPORT sharing when sandboxed).
+ * A control point searches without it. */
+ if (out->ssdpReqSock4 != INVALID_SOCKET) {
+ fprintf(stderr,
+ "upnp: no SSDP listener on port 1900 (%d): "
+ "searching only\n",
+ retVal);
+ out->ssdpSock4 = INVALID_SOCKET;
+ } else {
+ UpnpCloseSocket(out->ssdpReqSock4);
+ UpnpCloseSocket(out->ssdpReqSock6);
+ return retVal;
+ }
+ #else
return retVal;
+ #endif /* INCLUDE_CLIENT_APIS */
}
} else
out->ssdpSock4 = INVALID_SOCKET;
--- a/upnp/src/genlib/miniserver/miniserver.c 2026-10-09 20:35:17.061594185 +0000
+++ b/upnp/src/genlib/miniserver/miniserver.c 2026-10-09 20:35:17.061755185 +0000
@@ -1046,6 +1046,7 @@
"Error in IPv%d bind(): %s\n",
s->ip_version,
errorBuffer);
+ fprintf(stderr, "upnp: miniserver IPv%d bind: %s\n", s->ip_version, errorBuffer);
/* Bind failed. */
ret_val = UPNP_E_SOCKET_BIND;
goto error;
@@ -1298,6 +1299,7 @@
__FILE__,
__LINE__,
"Error in binding localhost!!!\n");
+ fprintf(stderr, "upnp: stop socket bind 127.0.0.1: errno %d\n", errno);
sock_close(miniServerStopSock);
return UPNP_E_SOCKET_BIND;
}
+18 -6
View File
@@ -38,7 +38,8 @@ mkdir -p "$work/obj" "$work/stubs"
# 1. The plugin table and the library list, read with the PS5 toolchain's nm.
# Plus our own plugins (ps5/modules): ps5http, http(s) through the console.
TARGET=ps5 NM="$sdk/bin/prospero-nm" APP_MODULES="vlc_entry__ps5http" bash "$here/gen-static-modules.sh" "$static"
TARGET=ps5 NM="$sdk/bin/prospero-nm" APP_MODULES="vlc_entry__ps5http vlc_entry__ps5vdec" \
bash "$here/gen-static-modules.sh" "$static"
# 2. Our objects, in an archive so --exclude-libs=ALL keeps them out of the
# title's exports (the converter refuses application exports).
@@ -52,12 +53,13 @@ cc "${cflags[@]}" -c "$static/static_modules.c" -o "$work/obj/static_modules.o"
cc "${cflags[@]}" -std=c11 -c "$repo/third_party/volk/volk.c" -o "$work/obj/volk.o"
cc "${cflags[@]}" -std=gnu11 -c "$repo/src/platform_ps5.c" -o "$work/obj/platform_ps5.o"
cc "${cflags[@]}" -std=gnu11 -c "$here/modules/ps5http.c" -o "$work/obj/ps5http.o"
cc "${cflags[@]}" -std=gnu11 -c "$here/modules/ps5vdec.c" -o "$work/obj/ps5vdec.o"
for f in imgui imgui_draw imgui_tables imgui_widgets; do
cc "${cflags[@]}" "${cxxflags[@]}" -c "$repo/third_party/imgui/$f.cpp" -o "$work/obj/$f.o"
done
cc "${cflags[@]}" "${cxxflags[@]}" -c "$repo/third_party/imgui/backends/imgui_impl_vulkan.cpp" \
-o "$work/obj/imgui_impl_vulkan.o"
for f in gfx image prefs player library network osub lang web ui main; do
for f in gfx image prefs player subconv library network osub lang web ui main; do
cc "${cflags[@]}" "${cxxflags[@]}" -c "$repo/src/$f.cc" -o "$work/obj/$f.o"
done
"$sdk/bin/prospero-ar" rcs "$work/libprobe.a" "$work"/obj/*.o
@@ -73,6 +75,10 @@ stub() {
}
stub libSceAgc vendor/ps5/sdk/stubs/agc_canary_link_stub.c
stub libSceAgcDriver vendor/ps5/sdk/stubs/agc_driver_canary_link_stub.c
# The console's video decoder (ps5/modules/ps5vdec.c): our own stub.
cc -std=c11 -O2 -fPIC -c "$here/stubs/videodec2_link_stub.c" -o "$work/libSceVideodec2_stub.o"
"$sdk/bin/prospero-lld" --shared -soname libSceVideodec2.prx \
-o "$work/stubs/libSceVideodec2.so" "$work/libSceVideodec2_stub.o"
# 3. VLC's archives for lld: -lfoo becomes our prefix's libfoo.a; the system
# libraries (pthread, dl, atomic, ...) are the SDK's .so stubs, linked below.
@@ -90,6 +96,8 @@ while read -r item; do
esac
done < "$static/link.rsp"
vlc_inputs+=("$prefix/lib/libps5compat.a")
# GNU libiconv: subtitle files that aren't UTF-8 (src/subconv.cc)
vlc_inputs+=("$prefix/lib/libiconv.a")
# 4. Link.
# shellcheck source=/dev/null
@@ -140,7 +148,7 @@ fi
-u vlc_static_modules \
"$work/app_crt.o" "$work/app_cpp_runtime.o" \
--start-group "$work/libprobe.a" "${vlc_inputs[@]}" --end-group \
"$work/stubs/libSceAgc.so" "$work/stubs/libSceAgcDriver.so" \
"$work/stubs/libSceAgc.so" "$work/stubs/libSceAgcDriver.so" "$work/stubs/libSceVideodec2.so" \
"${radv_link_inputs[@]}" \
--as-needed "$sdk"/target/lib/*.so 2>&1 | tee "$work/link.log" | grep -E "error|warning" | head -60
[[ ${PIPESTATUS[0]} -eq 0 && -f $work/llvm-pie.elf ]] || { echo "link failed: $work/link.log" >&2; exit 1; }
@@ -150,7 +158,8 @@ grep -aq "Video memory output" "$work/llvm-pie.elf" ||
"$tool" link --in "$work/llvm-pie.elf" --out "$work/eboot.elf" \
--stub-dir "$sdk/target/lib" --stub "$work/stubs/libSceAgc.so" \
--stub "$work/stubs/libSceAgcDriver.so" --module-sdk 0x02000009 \
--stub "$work/stubs/libSceAgcDriver.so" --stub "$work/stubs/libSceVideodec2.so" \
--module-sdk 0x02000009 \
--companion-sdk 0x08050001 --file-name eboot.elf
# 5. The title folder.
@@ -189,8 +198,11 @@ cp "$repo/assets/fonts/Inter-SemiBold.ttf" "$app/fonts/subtitle.ttf"
cp "$repo/assets/fonts/Inter-Regular.ttf" "$app/fonts/mono.ttf"
# Noto fonts for the scripts Inter lacks (Arabic, Hebrew, CJK, Thai, ...):
# subtitles (patches/0005) and file names in the interface.
mkdir -p "$app/fonts/fallback"
cp "$repo/assets/fonts/fallback/"* "$app/fonts/fallback/"
mkdir -p "$app/fonts/fallback" "$app/fonts/licenses"
# only fonts in fallback/: libass loads every file there (the OFL texts were
# "Error opening memory font" in every log); their licences beside them
cp "$repo/assets/fonts/fallback/"*.tt[fc] "$app/fonts/fallback/"
cp "$repo/assets/fonts/fallback/"*.txt "$app/fonts/licenses/"
# HTTPS: Mozilla's CA list (curl.se/ca), where GnuTLS looks for it (/app0/certs).
mkdir -p "$app/certs"
cp "$repo/assets/certs/cacert.pem" "$app/certs/"
+91
View File
@@ -150,6 +150,97 @@ static bool unmap_direct(void *addr, size_t len)
return found;
}
/*
* VLC's big pictures (patches/0015). A 4K 10-bit picture is 25 MiB and VLC
* keeps 20 to 30 of them, more than the heap (flexible memory) holds: the
* video then failed to start, a black screen (issue #9). Direct memory has
* room for them.
*/
#define BIG_MAX 128
static struct {
void *addr;
size_t len;
int64_t start;
} big_maps[BIG_MAX];
void *vlc_ps5_big_alloc(size_t len)
{
len = (len + DIRECT_ALIGNMENT - 1) & ~(DIRECT_ALIGNMENT - 1);
void *result = NULL;
pthread_mutex_lock(&direct_lock);
int slot = -1;
for (int i = 0; i < BIG_MAX && slot < 0; i++) {
if (!big_maps[i].addr) {
slot = i;
}
}
int64_t start = -1;
int rc = slot < 0 ? -1 :
sceKernelAllocateDirectMemory(0, sceKernelGetDirectMemorySize(), len,
DIRECT_ALIGNMENT, DIRECT_TYPE_CPU, &start);
if (rc == 0) {
result = ADDRESS_HINT;
rc = sceKernelMapDirectMemory(&result, len, KERNEL_PROT_READ | KERNEL_PROT_WRITE,
0, start, DIRECT_ALIGNMENT);
if (rc != 0) {
result = NULL;
rc = sceKernelMapDirectMemory(&result, len, KERNEL_PROT_READ | KERNEL_PROT_WRITE,
0, start, DIRECT_ALIGNMENT);
}
if (rc != 0) {
sceKernelReleaseDirectMemory(start, len);
result = NULL;
}
}
if (!result && slot >= 0) {
/* Direct memory full (the console's video decoder takes much of it
* for 4K, console run 7): flexible memory, of which there was 1.6 GiB
* left; start -1 marks it. */
start = -1;
result = ADDRESS_HINT;
rc = sceKernelMapFlexibleMemory(&result, len, KERNEL_PROT_READ | KERNEL_PROT_WRITE, 0);
if (rc != 0) {
result = NULL;
rc = sceKernelMapFlexibleMemory(&result, len, KERNEL_PROT_READ | KERNEL_PROT_WRITE, 0);
}
if (rc != 0)
result = NULL;
}
if (result) {
big_maps[slot].addr = result;
big_maps[slot].len = len;
big_maps[slot].start = start;
}
pthread_mutex_unlock(&direct_lock);
if (!result) {
report(slot < 0 ? "big picture (table full)" : "big picture", NULL, len, rc);
}
return result;
}
/* 1 if addr was vlc_ps5_big_alloc's (now freed), 0 if not. */
int vlc_ps5_big_free(void *addr)
{
int found = 0;
pthread_mutex_lock(&direct_lock);
for (int i = 0; i < BIG_MAX && !found; i++) {
if (big_maps[i].addr && big_maps[i].addr == addr) {
if (big_maps[i].start < 0) {
sceKernelReleaseFlexibleMemory(addr, big_maps[i].len);
big_maps[i].addr = NULL;
found = 1;
break;
}
sceKernelMunmap(addr, big_maps[i].len);
sceKernelReleaseDirectMemory(big_maps[i].start, big_maps[i].len);
big_maps[i].addr = NULL;
found = 1;
}
}
pthread_mutex_unlock(&direct_lock);
return found;
}
void *__wrap_mmap(void *addr, size_t len, int prot, int flags, int fd,
off_t offset)
{
+29 -1
View File
@@ -264,6 +264,10 @@ build_smb2() {
fetch "https://github.com/sahlberg/libsmb2/archive/refs/tags/libsmb2-$v.tar.gz" "libsmb2-$v.tar.gz"
unpack "libsmb2-$v.tar.gz" "$d"
patch -d "$src/$d" -p1 -s < "$src/vlc-3.0.24/contrib/src/smb2/0001-cmake-add-ENABLE_LIBKRB5-and-ENABLE_GSSAPI-options.patch"
# VLC-PS5's own (patches/smb2/): big socket buffers (the TCP window)
for p in "$(dirname "$(dirname "$here")")"/patches/smb2/*.patch; do
patch -d "$src/$d" -p1 -s < "$p"
done
cmake -S "$src/$d" -B "$src/build-smb2-$target" -G Ninja ${cmake_cross:-} \
-DCMAKE_INSTALL_PREFIX="$prefix" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release \
-DBUILD_SHARED_LIBS=OFF -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
@@ -281,6 +285,11 @@ build_upnp() {
for p in libtool-nostdlib-workaround miniserver; do
patch -d "$src/$d" -p1 -s < "$src/vlc-3.0.24/contrib/src/upnp/$p.patch"
done
# Ours: discovery without the SSDP listener when port 1900 can't be had
# (sandboxed on the console: UPNP_E_SOCKET_BIND).
for p in "$(dirname "$(dirname "$here")")"/patches/upnp/*.patch; do
patch -d "$src/$d" -p1 -s < "$p"
done
cmake -S "$src/$d" -B "$src/build-upnp-$target" -G Ninja ${cmake_cross:-} \
-DCMAKE_INSTALL_PREFIX="$prefix" -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_POSITION_INDEPENDENT_CODE=ON -DUPNP_BUILD_SHARED=OFF -DUPNP_BUILD_STATIC=ON \
@@ -320,6 +329,11 @@ build_dvdread() {
local v=6.1.3
fetch "https://download.videolan.org/pub/videolan/libdvdread/$v/libdvdread-$v.tar.bz2"
unpack "libdvdread-$v.tar.bz2" "libdvdread-$v"
# VLC-PS5's own (patches/dvdread/): DVD images read from a stream (a network
# share) without libdvdcss, which the PS5 build doesn't have.
for p in "$(dirname "$(dirname "$here")")"/patches/dvdread/*.patch; do
patch -d "$src/libdvdread-$v" -p1 -s < "$p"
done
(cd "$src/libdvdread-$v" && ./configure --prefix="$prefix" --libdir="$prefix/lib" \
${host_triple:+--host=$host_triple --build=x86_64-pc-linux-gnu} \
--enable-static --disable-shared --with-pic --disable-apidoc &&
@@ -365,7 +379,21 @@ build_libarchive() {
cmake --build "$src/build-libarchive-$target" && cmake --install "$src/build-libarchive-$target"
}
all=(nasm compat zlib ffmpeg dav1d ebml matroska dvbpsi freetype fribidi harfbuzz gmp nettle gnutls smb2 upnp libxml2 ass dvdread dvdnav bluray libarchive)
# Character sets for subtitle files that aren't UTF-8 (Windows-1252, GBK,
# Big5, Shift JIS, Windows-1256...): the console's libc has no iconv. The app
# converts such a file to UTF-8 before VLC reads it (src/subconv.cc).
build_iconv() {
local v=1.18
fetch "https://ftp.gnu.org/gnu/libiconv/libiconv-$v.tar.gz"
unpack "libiconv-$v.tar.gz" "libiconv-$v"
(cd "$src/libiconv-$v" && ./configure --prefix="$prefix" --libdir="$prefix/lib" \
${host_triple:+--host=$host_triple --build=x86_64-pc-linux-gnu} \
--enable-static --disable-shared --disable-nls --with-pic &&
make lib/localcharset.h && make -j"$jobs" -C lib && make -C lib install &&
install -m 644 include/iconv.h.inst "$prefix/include/iconv.h")
}
all=(nasm compat zlib ffmpeg dav1d ebml matroska dvbpsi freetype fribidi harfbuzz gmp nettle gnutls smb2 upnp libxml2 ass dvdread dvdnav bluray libarchive iconv)
recipes=("$@")
[[ ${#recipes[@]} -gt 0 ]] || recipes=("${all[@]}")
for r in "${recipes[@]}"; do
+18 -5
View File
@@ -186,8 +186,14 @@ static int send_request(stream_t *access, uint64_t offset)
int r = sceHttpSendRequest(sys->req, NULL, 0);
vlc_interrupt_unregister();
if (r < 0) {
PLOG("sending failed (%#x): VLC's own http is used from now on", (unsigned)r);
service_refused = true;
/* 0x8095xxxx: the console's SSL turned this one server down (its
* certificate, its ciphers). VLC's own http takes this link; the
* service stays for the others. Anything else: the service itself. */
bool ssl = ((unsigned)r & 0xFFFF0000u) == 0x80950000u;
PLOG("sending failed (%#x): %s", (unsigned)r,
ssl ? "SSL refused this server, VLC's own http takes this link" : "VLC's own http is used from now on");
if (!ssl)
service_refused = true;
drop_request(sys);
return VLC_EGENERIC;
}
@@ -319,10 +325,16 @@ static int Open(vlc_object_t *obj)
if (sys->redirect) {
/* VLC opens the new address (and probes the modules again). */
char *to = vlc_uri_resolve(access->psz_url, sys->redirect);
PLOG("redirected (%d) to %s", sys->status, to ? to : sys->redirect);
free(access->psz_url);
access->psz_url = to ? to : strdup(sys->redirect);
if (!to)
to = strdup(sys->redirect);
if (!to)
goto error;
PLOG("redirected (%d) to %s", sys->status, to);
/* Not freed here: access_New() keeps the old address (to spot a
* loop) and frees it itself. Freeing it too was a double free. */
access->psz_url = to;
Close(obj);
access->p_sys = NULL;
return VLC_ACCESS_REDIRECT;
}
if (sys->status == 401 || sys->status == 407) {
@@ -342,6 +354,7 @@ static int Open(vlc_object_t *obj)
error:
Close(obj);
access->p_sys = NULL; /* the next module (VLC's own http) starts clean */
return VLC_EGENERIC;
}
File diff suppressed because it is too large. Load diff
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# VLC-PS5's changes to the console's Vulkan driver (patches/mesa/): applied to
# the RADV source tree PS5_Vulkan's tools/build-radv.sh made, built, and
# installed where ps5/build-title.sh links it from. Run after build-radv.sh
# (which puts back the fork's own files when its revision changes).
#
# bash ps5/radv-patches.sh
#
# patches/mesa/0001: HDR10 output (the framebuffers switched in place, the
# output's dynamic range read back) for src/player.cc.
set -euo pipefail
here=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
repo=$(dirname "$here")
vk=${PS5_VULKAN:-$HOME/ps5/PS5_Vulkan}
src=$vk/.deps/work/radv-src
build=$vk/.deps/work/radv-build-ps5-release
install=$vk/.deps/native/radv-release
ninja=${NINJA:-$(command -v ninja || echo "$HOME/.local/bin/ninja")}
[[ -d $src && -f $build/build.ninja ]] || { echo "build RADV first: $vk/tools/build-radv.sh release" >&2; exit 2; }
for p in "$repo"/patches/mesa/*.patch; do
# each file keeps its fork original beside it, so a patch goes on once
target=$(sed -n 's/^+++ b\///p' "$p" | head -1)
[[ -f $src/$target.orig-vlcps5 ]] || cp "$src/$target" "$src/$target.orig-vlcps5"
cp "$src/$target.orig-vlcps5" "$src/$target"
patch -d "$src" -p1 -s < "$p"
echo "applied $(basename "$p")"
done
export PATH="$vk/.deps/work/radv-clc-bin:$PATH"
"$ninja" -C "$build" src/amd/vulkan/libvulkan_radeon.a > "$build.vlcps5.log" 2>&1 ||
{ grep -E "error|FAILED" "$build.vlcps5.log" | head -20 >&2; exit 1; }
cp "$build/src/amd/vulkan/libvulkan_radeon.a" "$install/lib/libvulkan_radeon.ps5.a"
printf 'VLC-PS5 patches: %s\n' "$(cd "$repo/patches/mesa" && ls *.patch | tr '\n' ' ')" >> "$install/PROVENANCE.txt"
echo "==> RADV with VLC-PS5's patches in $install"
+38
View File
@@ -0,0 +1,38 @@
{
"ageLevel": {
"default": 0
},
"applicationCategoryType": 0,
"applicationDrmType": "free",
"attribute": 0,
"attribute2": 0,
"attribute3": 524352,
"conceptId": "85300",
"contentBadgeType": 1,
"contentId": "UP9000-PPSA85300_00-VLCFORPS50000001",
"contentVersion": "01.000.005",
"downloadDataSize": 256,
"gameIntent": {
"permittedIntents": [
{
"intentType": "launchActivity"
}
]
},
"localizedParameters": {
"defaultLanguage": "en-US",
"en-US": {
"titleName": "VLC"
}
},
"masterVersion": "01.00",
"pubtools": {
"creationDate": "2026-10-06 00:00:00",
"loudnessSnd0": "-28.00",
"toolVersion": "2.00"
},
"requiredSystemSoftwareVersion": "0x0000000000000000",
"sdkVersion": "0x0000000000000000",
"titleId": "PPSA85300",
"versionFileUri": ""
}
+4 -11
View File
@@ -2,23 +2,16 @@
"ageLevel": {
"default": 0
},
"applicationCategoryType": 0,
"applicationCategoryType": 65536,
"applicationDrmType": "free",
"attribute": 0,
"attribute": 1644167168,
"attribute2": 0,
"attribute3": 524352,
"conceptId": "85300",
"contentBadgeType": 1,
"contentBadgeType": 2,
"contentId": "UP9000-PPSA85300_00-VLCFORPS50000001",
"contentVersion": "01.000.000",
"contentVersion": "01.000.005",
"downloadDataSize": 256,
"gameIntent": {
"permittedIntents": [
{
"intentType": "launchActivity"
}
]
},
"localizedParameters": {
"defaultLanguage": "en-US",
"en-US": {
+17
View File
@@ -0,0 +1,17 @@
/*
* Link stub for the console's libSceVideodec2: the names the title imports
* (ps5/modules/ps5vdec.c). Only linked against, never run: the console's own
* library answers these calls.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
int sceVideodec2QueryComputeMemoryInfo(void *info) { (void)info; return -1; }
int sceVideodec2AllocateComputeQueue(const void *config, const void *memory, void **queue) { (void)config; (void)memory; (void)queue; return -1; }
int sceVideodec2ReleaseComputeQueue(void *queue) { (void)queue; return -1; }
int sceVideodec2QueryDecoderMemoryInfo(const void *config, void *memory) { (void)config; (void)memory; return -1; }
int sceVideodec2CreateDecoder(const void *config, const void *memory, void **decoder) { (void)config; (void)memory; (void)decoder; return -1; }
int sceVideodec2DeleteDecoder(void *decoder) { (void)decoder; return -1; }
int sceVideodec2Decode(void *decoder, const void *input, void *frame, void *output) { (void)decoder; (void)input; (void)frame; (void)output; return -1; }
int sceVideodec2Flush(void *decoder, void *frame, void *output) { (void)decoder; (void)frame; (void)output; return -1; }
int sceVideodec2Reset(void *decoder) { (void)decoder; return -1; }
int sceVideodec2GetPictureInfo(const void *output, void *first, void *second) { (void)output; (void)first; (void)second; return -1; }
+10
View File
@@ -0,0 +1,10 @@
#version 450
// One triangle over the whole target (the UI layer composited in HDR mode).
layout(location = 0) out vec2 uv;
void main()
{
vec2 p = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
uv = p;
gl_Position = vec4(p * 2.0 - 1.0, 0.0, 1.0);
}
+45
View File
@@ -0,0 +1,45 @@
#version 450
// HDR output: the UI layer (8-bit, premultiplied, the TV's gamma) over the
// PQ picture. Its colours become light at a graphics white of pc.nits
// (BT.2408's 203), BT.709 -> BT.2020, then PQ; premultiplied again so it
// blends with ONE, ONE_MINUS_SRC_ALPHA as on an SDR screen.
layout(location = 0) in vec2 uv;
layout(location = 0) out vec4 color;
layout(set = 0, binding = 0) uniform sampler2D ui;
layout(push_constant) uniform Push {
float nits;
} pc;
const float PQ_M1 = 0.1593017578125, PQ_M2 = 78.84375;
const float PQ_C1 = 0.8359375, PQ_C2 = 18.8515625, PQ_C3 = 18.6875;
vec3 nits_to_pq(vec3 nits)
{
vec3 y = pow(clamp(nits / 10000.0, 0.0, 1.0), vec3(PQ_M1));
return pow((PQ_C1 + PQ_C2 * y) / (1.0 + PQ_C3 * y), vec3(PQ_M2));
}
void main()
{
vec4 c = texture(ui, uv);
if (c.a <= 0.0) {
color = vec4(0.0);
return;
}
vec3 straight = clamp(c.rgb / c.a, 0.0, 1.0);
vec3 lin = pow(straight, vec3(2.2)) * pc.nits;
/* BT.709 -> BT.2020 primaries (GLSL matrices are by column) */
lin = mat3(0.6274, 0.0691, 0.0164,
0.3293, 0.9195, 0.0880,
0.0433, 0.0114, 0.8956) * lin;
/* The blend happens on PQ codes: half-transparent black over the picture
* halved the code, which darkened it far more than on an SDR screen.
* There the blend is on gamma codes, leaving (1 - a)^2.2 of the light;
* the coverage that leaves that much of a 100-nit picture is used. */
const float ref = 100.0;
float left = pow(1.0 - c.a, 2.2);
float a = c.a < 1.0 ? 1.0 - nits_to_pq(vec3(ref * left)).x / nits_to_pq(vec3(ref)).x : 1.0;
color = vec4(nits_to_pq(lin) * a, a);
}
+103 -4
View File
@@ -1,8 +1,10 @@
#version 450
// Planar YCbCr (VLC's I420 / J420 / I0AL) to RGB. Same constants as
// Planar YCbCr (VLC's I420 / J420 / I0AL, or NV12 / P010) to RGB. Same constants as
// host/vlc_probe.c, which checked them against real frames in World 1.
// Then the picture controls: brightness and contrast on luma, hue and
// saturation on chroma, gamma on the result.
// saturation on chroma, gamma on the result. HDR (PQ, HLG) is tone mapped
// to SDR between the two; with HDR10 output on (outp.x), the picture goes
// out as PQ, BT.2020 instead.
layout(location = 0) in vec2 uv;
layout(location = 0) out vec4 color;
@@ -19,8 +21,96 @@ layout(push_constant) uniform Push {
vec4 adjust; // brightness, contrast, saturation, gamma exponent
vec4 view; // 360: yaw, pitch, tan(fov / 2), screen aspect
vec4 xform; // quarter turns clockwise, mirror, upside down, sharpen amount
vec4 hdr; // transfer (0 SDR, 1 PQ, 2 HLG), peak (nits), BT.2020 primaries (1), NV12/P010 (1)
vec4 outp; // HDR10 output (1): PQ, BT.2020; -, -, -
} pc;
/* HDR to SDR, the same sums as hdr_to_sdr() in player.cc (screenshots). */
const float SDR_WHITE = 203.0; // HDR's reference white (BT.2408) = the TV's white
const float PQ_M1 = 0.1593017578125, PQ_M2 = 78.84375;
const float PQ_C1 = 0.8359375, PQ_C2 = 18.8515625, PQ_C3 = 18.6875;
vec3 pq_to_nits(vec3 e)
{
vec3 p = pow(clamp(e, 0.0, 1.0), vec3(1.0 / PQ_M2));
return 10000.0 * pow(max(p - PQ_C1, 0.0) / (PQ_C2 - PQ_C3 * p), vec3(1.0 / PQ_M1));
}
float nits_to_pq(float nits)
{
float y = pow(clamp(nits / 10000.0, 0.0, 1.0), PQ_M1);
return pow((PQ_C1 + PQ_C2 * y) / (1.0 + PQ_C3 * y), PQ_M2);
}
/* HLG: scene light, then the system gamma of a 1000-nit TV (BT.2100) */
vec3 hlg_to_nits(vec3 e)
{
const float a = 0.17883277, b = 0.28466892, c = 0.55991073;
e = clamp(e, 0.0, 1.0);
vec3 s = mix(e * e / 3.0, (exp((e - c) / a) + b) / 12.0, step(vec3(0.5), e));
float ys = max(dot(s, vec3(0.2627, 0.6780, 0.0593)), 1e-6);
return 1000.0 * pow(ys, 0.2) * s;
}
vec3 nits_to_pq3(vec3 nits)
{
vec3 y = pow(clamp(nits / 10000.0, 0.0, 1.0), vec3(PQ_M1));
return pow((PQ_C1 + PQ_C2 * y) / (1.0 + PQ_C3 * y), vec3(PQ_M2));
}
/* HDR10 output: the picture as PQ with BT.2020 primaries. HDR10 is that
* already and goes through untouched; HLG and SDR become light (SDR white
* at 203 nits), then BT.2020, then PQ. */
vec3 to_pq_output(vec3 e)
{
if (pc.hdr.x > 0.5 && pc.hdr.x < 1.5 && pc.hdr.z > 0.5)
return e;
vec3 nits;
if (pc.hdr.x > 0.5)
nits = pc.hdr.x < 1.5 ? pq_to_nits(e) : hlg_to_nits(e);
else
nits = pow(clamp(e, 0.0, 1.0), vec3(2.4)) * SDR_WHITE;
if (pc.hdr.z < 0.5) {
/* BT.709 -> BT.2020 primaries */
nits = mat3(0.6274, 0.0691, 0.0164,
0.3293, 0.9195, 0.0880,
0.0433, 0.0114, 0.8956) * nits;
}
return nits_to_pq3(nits);
}
vec3 hdr_to_sdr(vec3 e)
{
vec3 nits = pc.hdr.x < 1.5 ? pq_to_nits(e) : hlg_to_nits(e);
/* BT.2390's roll-off on the brightest channel (keeps the hue): up to
* about half of SDR white nothing changes, above it the highlights bend
* down to fit under white. */
float peak = pc.hdr.y;
float sig = max(nits.r, max(nits.g, nits.b));
if (sig > 0.0 && peak > SDR_WHITE) {
float src = nits_to_pq(peak);
float e1 = min(nits_to_pq(sig) / src, 1.0);
float maxl = nits_to_pq(SDR_WHITE) / src;
float ks = 1.5 * maxl - 0.5;
float e2 = e1;
if (e1 > ks) {
float t = (e1 - ks) / (1.0 - ks), t2 = t * t, t3 = t2 * t;
e2 = (2.0 * t3 - 3.0 * t2 + 1.0) * ks + (t3 - 2.0 * t2 + t) * (1.0 - ks) +
(-2.0 * t3 + 3.0 * t2) * maxl;
}
nits *= pq_to_nits(vec3(e2 * src)).r / sig;
}
vec3 lin = nits / SDR_WHITE;
if (pc.hdr.z > 0.5) {
/* BT.2020 -> BT.709 primaries (linear light; GLSL matrices are by column) */
lin = mat3(1.6605, -0.1246, -0.0182,
-0.5876, 1.1329, -0.1006,
-0.0728, -0.0083, 1.1187) * lin;
}
/* back to a TV's signal (BT.1886, gamma 2.4) */
return pow(clamp(lin, 0.0, 1.0), vec3(1.0 / 2.4));
}
/* Rotate and flip: the point of the picture this pixel shows. */
vec2 turned_uv()
{
@@ -69,8 +159,11 @@ void main()
around += texture(tex_y, at + vec2(float(dx), float(dy)) * t).r;
y = clamp(y + (y - around * 0.125 * s) * pc.xform.w, 0.0, 1.0);
}
float u = texture(tex_u, at).r * s - 0.5;
float v = texture(tex_v, at).r * s - 0.5;
/* NV12 / P010: U and V side by side in the second plane */
vec2 chroma = pc.hdr.w > 0.5 ? texture(tex_u, at).rg
: vec2(texture(tex_u, at).r, texture(tex_v, at).r);
float u = chroma.x * s - 0.5;
float v = chroma.y * s - 0.5;
if (pc.params.y > 0.5) {
y = (y - 16.0 / 255.0) * (255.0 / 219.0);
u *= 255.0 / 224.0;
@@ -82,5 +175,11 @@ void main()
vec3 yuv = vec3(y, uv2);
vec3 rgb = clamp(vec3(dot(pc.row0.xyz, yuv), dot(pc.row1.xyz, yuv), dot(pc.row2.xyz, yuv)),
0.0, 1.0);
if (pc.outp.x > 0.5) {
color = vec4(to_pq_output(rgb), 1.0);
return;
}
if (pc.hdr.x > 0.5)
rgb = hdr_to_sdr(rgb);
color = vec4(pow(rgb, vec3(pc.adjust.w)), 1.0);
}
+43
View File
@@ -0,0 +1,43 @@
// 1116.2.0
#pragma once
const uint32_t spv_fullscreen_vert[] = {
0x07230203,0x00010300,0x0008000b,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0008000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000c,0x00000018,0x00000020,
0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,0x00000000,0x00030005,
0x00000009,0x00000070,0x00060005,0x0000000c,0x565f6c67,0x65747265,0x646e4978,0x00007865,
0x00030005,0x00000018,0x00007675,0x00060005,0x0000001e,0x505f6c67,0x65567265,0x78657472,
0x00000000,0x00060006,0x0000001e,0x00000000,0x505f6c67,0x7469736f,0x006e6f69,0x00070006,
0x0000001e,0x00000001,0x505f6c67,0x746e696f,0x657a6953,0x00000000,0x00070006,0x0000001e,
0x00000002,0x435f6c67,0x4470696c,0x61747369,0x0065636e,0x00070006,0x0000001e,0x00000003,
0x435f6c67,0x446c6c75,0x61747369,0x0065636e,0x00030005,0x00000020,0x00000000,0x00040047,
0x0000000c,0x0000000b,0x0000002a,0x00040047,0x00000018,0x0000001e,0x00000000,0x00030047,
0x0000001e,0x00000002,0x00050048,0x0000001e,0x00000000,0x0000000b,0x00000000,0x00050048,
0x0000001e,0x00000001,0x0000000b,0x00000001,0x00050048,0x0000001e,0x00000002,0x0000000b,
0x00000003,0x00050048,0x0000001e,0x00000003,0x0000000b,0x00000004,0x00020013,0x00000002,
0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,
0x00000006,0x00000002,0x00040020,0x00000008,0x00000007,0x00000007,0x00040015,0x0000000a,
0x00000020,0x00000001,0x00040020,0x0000000b,0x00000001,0x0000000a,0x0004003b,0x0000000b,
0x0000000c,0x00000001,0x0004002b,0x0000000a,0x0000000e,0x00000001,0x0004002b,0x0000000a,
0x00000010,0x00000002,0x00040020,0x00000017,0x00000003,0x00000007,0x0004003b,0x00000017,
0x00000018,0x00000003,0x00040017,0x0000001a,0x00000006,0x00000004,0x00040015,0x0000001b,
0x00000020,0x00000000,0x0004002b,0x0000001b,0x0000001c,0x00000001,0x0004001c,0x0000001d,
0x00000006,0x0000001c,0x0006001e,0x0000001e,0x0000001a,0x00000006,0x0000001d,0x0000001d,
0x00040020,0x0000001f,0x00000003,0x0000001e,0x0004003b,0x0000001f,0x00000020,0x00000003,
0x0004002b,0x0000000a,0x00000021,0x00000000,0x0004002b,0x00000006,0x00000023,0x40000000,
0x0004002b,0x00000006,0x00000025,0x3f800000,0x0004002b,0x00000006,0x00000028,0x00000000,
0x00040020,0x0000002c,0x00000003,0x0000001a,0x00050036,0x00000002,0x00000004,0x00000000,
0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000008,0x00000009,0x00000007,0x0004003d,
0x0000000a,0x0000000d,0x0000000c,0x000500c4,0x0000000a,0x0000000f,0x0000000d,0x0000000e,
0x000500c7,0x0000000a,0x00000011,0x0000000f,0x00000010,0x0004006f,0x00000006,0x00000012,
0x00000011,0x0004003d,0x0000000a,0x00000013,0x0000000c,0x000500c7,0x0000000a,0x00000014,
0x00000013,0x00000010,0x0004006f,0x00000006,0x00000015,0x00000014,0x00050050,0x00000007,
0x00000016,0x00000012,0x00000015,0x0003003e,0x00000009,0x00000016,0x0004003d,0x00000007,
0x00000019,0x00000009,0x0003003e,0x00000018,0x00000019,0x0004003d,0x00000007,0x00000022,
0x00000009,0x0005008e,0x00000007,0x00000024,0x00000022,0x00000023,0x00050050,0x00000007,
0x00000026,0x00000025,0x00000025,0x00050083,0x00000007,0x00000027,0x00000024,0x00000026,
0x00050051,0x00000006,0x00000029,0x00000027,0x00000000,0x00050051,0x00000006,0x0000002a,
0x00000027,0x00000001,0x00070050,0x0000001a,0x0000002b,0x00000029,0x0000002a,0x00000028,
0x00000025,0x00050041,0x0000002c,0x0000002d,0x00000020,0x00000021,0x0003003e,0x0000002d,
0x0000002b,0x000100fd,0x00010038
};
+109
View File
@@ -0,0 +1,109 @@
// 1116.2.0
#pragma once
const uint32_t spv_ui_pq_frag[] = {
0x07230203,0x00010300,0x0008000b,0x00000093,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000035,0x00000042,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,
0x00000000,0x00060005,0x0000000b,0x7374696e,0x5f6f745f,0x76287170,0x003b3366,0x00040005,
0x0000000a,0x7374696e,0x00000000,0x00030005,0x0000000d,0x00000079,0x00030005,0x0000002d,
0x00000063,0x00030005,0x00000031,0x00006975,0x00030005,0x00000035,0x00007675,0x00040005,
0x00000042,0x6f6c6f63,0x00000072,0x00050005,0x00000045,0x61727473,0x74686769,0x00000000,
0x00030005,0x0000004f,0x006e696c,0x00040005,0x00000054,0x68737550,0x00000000,0x00050006,
0x00000054,0x00000000,0x7374696e,0x00000000,0x00030005,0x00000056,0x00006370,0x00040005,
0x0000006d,0x7466656c,0x00000000,0x00030005,0x00000072,0x00000061,0x00040005,0x0000007d,
0x61726170,0x0000006d,0x00040005,0x00000082,0x61726170,0x0000006d,0x00040005,0x00000089,
0x61726170,0x0000006d,0x00040047,0x00000031,0x00000021,0x00000000,0x00040047,0x00000031,
0x00000022,0x00000000,0x00040047,0x00000035,0x0000001e,0x00000000,0x00040047,0x00000042,
0x0000001e,0x00000000,0x00030047,0x00000054,0x00000002,0x00050048,0x00000054,0x00000000,
0x00000023,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,
0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000003,0x00040020,0x00000008,
0x00000007,0x00000007,0x00040021,0x00000009,0x00000007,0x00000008,0x0004002b,0x00000006,
0x0000000f,0x461c4000,0x0004002b,0x00000006,0x00000012,0x00000000,0x0004002b,0x00000006,
0x00000013,0x3f800000,0x0004002b,0x00000006,0x00000017,0x3e232000,0x0006002c,0x00000007,
0x00000018,0x00000017,0x00000017,0x00000017,0x0004002b,0x00000006,0x0000001a,0x3f560000,
0x0004002b,0x00000006,0x0000001b,0x4196d000,0x0004002b,0x00000006,0x00000020,0x41958000,
0x0004002b,0x00000006,0x00000026,0x429db000,0x0006002c,0x00000007,0x00000027,0x00000026,
0x00000026,0x00000026,0x00040017,0x0000002b,0x00000006,0x00000004,0x00040020,0x0000002c,
0x00000007,0x0000002b,0x00090019,0x0000002e,0x00000006,0x00000001,0x00000000,0x00000000,
0x00000000,0x00000001,0x00000000,0x0003001b,0x0000002f,0x0000002e,0x00040020,0x00000030,
0x00000000,0x0000002f,0x0004003b,0x00000030,0x00000031,0x00000000,0x00040017,0x00000033,
0x00000006,0x00000002,0x00040020,0x00000034,0x00000001,0x00000033,0x0004003b,0x00000034,
0x00000035,0x00000001,0x00040015,0x00000038,0x00000020,0x00000000,0x0004002b,0x00000038,
0x00000039,0x00000003,0x00040020,0x0000003a,0x00000007,0x00000006,0x00020014,0x0000003d,
0x00040020,0x00000041,0x00000003,0x0000002b,0x0004003b,0x00000041,0x00000042,0x00000003,
0x0007002c,0x0000002b,0x00000043,0x00000012,0x00000012,0x00000012,0x00000012,0x0004002b,
0x00000006,0x00000051,0x400ccccd,0x0006002c,0x00000007,0x00000052,0x00000051,0x00000051,
0x00000051,0x0003001e,0x00000054,0x00000006,0x00040020,0x00000055,0x00000009,0x00000054,
0x0004003b,0x00000055,0x00000056,0x00000009,0x00040015,0x00000057,0x00000020,0x00000001,
0x0004002b,0x00000057,0x00000058,0x00000000,0x00040020,0x00000059,0x00000009,0x00000006,
0x00040018,0x0000005d,0x00000007,0x00000003,0x0004002b,0x00000006,0x0000005e,0x3f209d49,
0x0004002b,0x00000006,0x0000005f,0x3d8d844d,0x0004002b,0x00000006,0x00000060,0x3c86594b,
0x0006002c,0x00000007,0x00000061,0x0000005e,0x0000005f,0x00000060,0x0004002b,0x00000006,
0x00000062,0x3ea89a02,0x0004002b,0x00000006,0x00000063,0x3f6b645a,0x0004002b,0x00000006,
0x00000064,0x3db43958,0x0006002c,0x00000007,0x00000065,0x00000062,0x00000063,0x00000064,
0x0004002b,0x00000006,0x00000066,0x3d315b57,0x0004002b,0x00000006,0x00000067,0x3c3ac711,
0x0004002b,0x00000006,0x00000068,0x3f65460b,0x0006002c,0x00000007,0x00000069,0x00000066,
0x00000067,0x00000068,0x0006002c,0x0000005d,0x0000006a,0x00000061,0x00000065,0x00000069,
0x0004002b,0x00000006,0x00000079,0x42c80000,0x0004002b,0x00000038,0x0000007f,0x00000000,
0x0006002c,0x00000007,0x00000081,0x00000079,0x00000079,0x00000079,0x00050036,0x00000002,
0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x0004003b,0x0000002c,0x0000002d,
0x00000007,0x0004003b,0x00000008,0x00000045,0x00000007,0x0004003b,0x00000008,0x0000004f,
0x00000007,0x0004003b,0x0000003a,0x0000006d,0x00000007,0x0004003b,0x0000003a,0x00000072,
0x00000007,0x0004003b,0x0000003a,0x00000076,0x00000007,0x0004003b,0x00000008,0x0000007d,
0x00000007,0x0004003b,0x00000008,0x00000082,0x00000007,0x0004003b,0x00000008,0x00000089,
0x00000007,0x0004003d,0x0000002f,0x00000032,0x00000031,0x0004003d,0x00000033,0x00000036,
0x00000035,0x00050057,0x0000002b,0x00000037,0x00000032,0x00000036,0x0003003e,0x0000002d,
0x00000037,0x00050041,0x0000003a,0x0000003b,0x0000002d,0x00000039,0x0004003d,0x00000006,
0x0000003c,0x0000003b,0x000500bc,0x0000003d,0x0000003e,0x0000003c,0x00000012,0x000300f7,
0x00000040,0x00000000,0x000400fa,0x0000003e,0x0000003f,0x00000040,0x000200f8,0x0000003f,
0x0003003e,0x00000042,0x00000043,0x000100fd,0x000200f8,0x00000040,0x0004003d,0x0000002b,
0x00000046,0x0000002d,0x0008004f,0x00000007,0x00000047,0x00000046,0x00000046,0x00000000,
0x00000001,0x00000002,0x00050041,0x0000003a,0x00000048,0x0000002d,0x00000039,0x0004003d,
0x00000006,0x00000049,0x00000048,0x00060050,0x00000007,0x0000004a,0x00000049,0x00000049,
0x00000049,0x00050088,0x00000007,0x0000004b,0x00000047,0x0000004a,0x00060050,0x00000007,
0x0000004c,0x00000012,0x00000012,0x00000012,0x00060050,0x00000007,0x0000004d,0x00000013,
0x00000013,0x00000013,0x0008000c,0x00000007,0x0000004e,0x00000001,0x0000002b,0x0000004b,
0x0000004c,0x0000004d,0x0003003e,0x00000045,0x0000004e,0x0004003d,0x00000007,0x00000050,
0x00000045,0x0007000c,0x00000007,0x00000053,0x00000001,0x0000001a,0x00000050,0x00000052,
0x00050041,0x00000059,0x0000005a,0x00000056,0x00000058,0x0004003d,0x00000006,0x0000005b,
0x0000005a,0x0005008e,0x00000007,0x0000005c,0x00000053,0x0000005b,0x0003003e,0x0000004f,
0x0000005c,0x0004003d,0x00000007,0x0000006b,0x0000004f,0x00050091,0x00000007,0x0000006c,
0x0000006a,0x0000006b,0x0003003e,0x0000004f,0x0000006c,0x00050041,0x0000003a,0x0000006e,
0x0000002d,0x00000039,0x0004003d,0x00000006,0x0000006f,0x0000006e,0x00050083,0x00000006,
0x00000070,0x00000013,0x0000006f,0x0007000c,0x00000006,0x00000071,0x00000001,0x0000001a,
0x00000070,0x00000051,0x0003003e,0x0000006d,0x00000071,0x00050041,0x0000003a,0x00000073,
0x0000002d,0x00000039,0x0004003d,0x00000006,0x00000074,0x00000073,0x000500b8,0x0000003d,
0x00000075,0x00000074,0x00000013,0x000300f7,0x00000078,0x00000000,0x000400fa,0x00000075,
0x00000077,0x00000087,0x000200f8,0x00000077,0x0004003d,0x00000006,0x0000007a,0x0000006d,
0x00050085,0x00000006,0x0000007b,0x00000079,0x0000007a,0x00060050,0x00000007,0x0000007c,
0x0000007b,0x0000007b,0x0000007b,0x0003003e,0x0000007d,0x0000007c,0x00050039,0x00000007,
0x0000007e,0x0000000b,0x0000007d,0x00050051,0x00000006,0x00000080,0x0000007e,0x00000000,
0x0003003e,0x00000082,0x00000081,0x00050039,0x00000007,0x00000083,0x0000000b,0x00000082,
0x00050051,0x00000006,0x00000084,0x00000083,0x00000000,0x00050088,0x00000006,0x00000085,
0x00000080,0x00000084,0x00050083,0x00000006,0x00000086,0x00000013,0x00000085,0x0003003e,
0x00000076,0x00000086,0x000200f9,0x00000078,0x000200f8,0x00000087,0x0003003e,0x00000076,
0x00000013,0x000200f9,0x00000078,0x000200f8,0x00000078,0x0004003d,0x00000006,0x00000088,
0x00000076,0x0003003e,0x00000072,0x00000088,0x0004003d,0x00000007,0x0000008a,0x0000004f,
0x0003003e,0x00000089,0x0000008a,0x00050039,0x00000007,0x0000008b,0x0000000b,0x00000089,
0x0004003d,0x00000006,0x0000008c,0x00000072,0x0005008e,0x00000007,0x0000008d,0x0000008b,
0x0000008c,0x0004003d,0x00000006,0x0000008e,0x00000072,0x00050051,0x00000006,0x0000008f,
0x0000008d,0x00000000,0x00050051,0x00000006,0x00000090,0x0000008d,0x00000001,0x00050051,
0x00000006,0x00000091,0x0000008d,0x00000002,0x00070050,0x0000002b,0x00000092,0x0000008f,
0x00000090,0x00000091,0x0000008e,0x0003003e,0x00000042,0x00000092,0x000100fd,0x00010038,
0x00050036,0x00000007,0x0000000b,0x00000000,0x00000009,0x00030037,0x00000008,0x0000000a,
0x000200f8,0x0000000c,0x0004003b,0x00000008,0x0000000d,0x00000007,0x0004003d,0x00000007,
0x0000000e,0x0000000a,0x00060050,0x00000007,0x00000010,0x0000000f,0x0000000f,0x0000000f,
0x00050088,0x00000007,0x00000011,0x0000000e,0x00000010,0x00060050,0x00000007,0x00000014,
0x00000012,0x00000012,0x00000012,0x00060050,0x00000007,0x00000015,0x00000013,0x00000013,
0x00000013,0x0008000c,0x00000007,0x00000016,0x00000001,0x0000002b,0x00000011,0x00000014,
0x00000015,0x0007000c,0x00000007,0x00000019,0x00000001,0x0000001a,0x00000016,0x00000018,
0x0003003e,0x0000000d,0x00000019,0x0004003d,0x00000007,0x0000001c,0x0000000d,0x0005008e,
0x00000007,0x0000001d,0x0000001c,0x0000001b,0x00060050,0x00000007,0x0000001e,0x0000001a,
0x0000001a,0x0000001a,0x00050081,0x00000007,0x0000001f,0x0000001e,0x0000001d,0x0004003d,
0x00000007,0x00000021,0x0000000d,0x0005008e,0x00000007,0x00000022,0x00000021,0x00000020,
0x00060050,0x00000007,0x00000023,0x00000013,0x00000013,0x00000013,0x00050081,0x00000007,
0x00000024,0x00000023,0x00000022,0x00050088,0x00000007,0x00000025,0x0000001f,0x00000024,
0x0007000c,0x00000007,0x00000028,0x00000001,0x0000001a,0x00000025,0x00000027,0x000200fe,
0x00000028,0x00010038
};
+570 -294
View File
@@ -1,300 +1,576 @@
// 1116.2.0
#pragma once
const uint32_t spv_video_frag[] = {
0x07230203,0x00010300,0x0008000b,0x000001a8,0x00000000,0x00020011,0x00000001,0x00020011,
0x07230203,0x00010300,0x0008000b,0x00000336,0x00000000,0x00020011,0x00000001,0x00020011,
0x00000032,0x0006000b,0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,
0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000010,
0x0000019e,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,
0x00000004,0x6e69616d,0x00000000,0x00050005,0x00000009,0x6e727574,0x755f6465,0x00002876,
0x00060005,0x0000000b,0x65687073,0x61636972,0x76755f6c,0x00000028,0x00030005,0x0000000e,
0x0000006e,0x00030005,0x00000010,0x00007675,0x00040005,0x00000013,0x68737550,0x00000000,
0x00050006,0x00000013,0x00000000,0x30776f72,0x00000000,0x00050006,0x00000013,0x00000001,
0x31776f72,0x00000000,0x00050006,0x00000013,0x00000002,0x32776f72,0x00000000,0x00050006,
0x00000013,0x00000003,0x61726170,0x0000736d,0x00060006,0x00000013,0x00000004,0x735f7675,
0x656c6163,0x00000000,0x00050006,0x00000013,0x00000005,0x756a6461,0x00007473,0x00050006,
0x00000013,0x00000006,0x77656976,0x00000000,0x00050006,0x00000013,0x00000007,0x726f6678,
0x0000006d,0x00030005,0x00000015,0x00006370,0x00030005,0x00000039,0x00000071,0x00030005,
0x00000068,0x0063646e,0x00030005,0x00000073,0x00000064,0x00030005,0x00000086,0x00007063,
0x00030005,0x0000008a,0x00007073,0x00030005,0x000000a4,0x00007963,0x00030005,0x000000a8,
0x00007973,0x00030005,0x000000c2,0x006e6f6c,0x00030005,0x000000c8,0x0074616c,0x00030005,
0x000000dc,0x00000073,0x00030005,0x000000df,0x00007461,0x00030005,0x000000ea,0x00000079,
0x00040005,0x000000ee,0x5f786574,0x00000079,0x00030005,0x000000fb,0x00000074,0x00040005,
0x00000104,0x756f7261,0x0000646e,0x00030005,0x00000105,0x00007964,0x00030005,0x0000010e,
0x00007864,0x00030005,0x0000013c,0x00000075,0x00040005,0x0000013d,0x5f786574,0x00000075,
0x00030005,0x00000145,0x00000076,0x00040005,0x00000146,0x5f786574,0x00000076,0x00030005,
0x00000167,0x00000063,0x00030005,0x0000016b,0x00006e73,0x00030005,0x0000016f,0x00327675,
0x00030005,0x00000182,0x00767579,0x00030005,0x00000188,0x00626772,0x00040005,0x0000019e,
0x6f6c6f63,0x00000072,0x00040047,0x00000010,0x0000001e,0x00000000,0x00030047,0x00000013,
0x00000002,0x00050048,0x00000013,0x00000000,0x00000023,0x00000000,0x00050048,0x00000013,
0x00000001,0x00000023,0x00000010,0x00050048,0x00000013,0x00000002,0x00000023,0x00000020,
0x00050048,0x00000013,0x00000003,0x00000023,0x00000030,0x00050048,0x00000013,0x00000004,
0x00000023,0x00000040,0x00050048,0x00000013,0x00000005,0x00000023,0x00000050,0x00050048,
0x00000013,0x00000006,0x00000023,0x00000060,0x00050048,0x00000013,0x00000007,0x00000023,
0x00000070,0x00040047,0x000000ee,0x00000021,0x00000000,0x00040047,0x000000ee,0x00000022,
0x00000000,0x00040047,0x0000013d,0x00000021,0x00000001,0x00040047,0x0000013d,0x00000022,
0x00000000,0x00040047,0x00000146,0x00000021,0x00000002,0x00040047,0x00000146,0x00000022,
0x00000000,0x00040047,0x0000019e,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021,
0x00000000,0x00000001,0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000188,
0x0000031c,0x00030010,0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,
0x00000004,0x6e69616d,0x00000000,0x00060005,0x0000000b,0x745f7170,0x696e5f6f,0x76287374,
0x003b3366,0x00030005,0x0000000a,0x00000065,0x00060005,0x00000010,0x7374696e,0x5f6f745f,
0x66287170,0x00003b31,0x00040005,0x0000000f,0x7374696e,0x00000000,0x00070005,0x00000013,
0x5f676c68,0x6e5f6f74,0x28737469,0x3b336676,0x00000000,0x00030005,0x00000012,0x00000065,
0x00070005,0x00000016,0x7374696e,0x5f6f745f,0x28337170,0x3b336676,0x00000000,0x00040005,
0x00000015,0x7374696e,0x00000000,0x00070005,0x00000019,0x705f6f74,0x756f5f71,0x74757074,
0x33667628,0x0000003b,0x00030005,0x00000018,0x00000065,0x00060005,0x0000001c,0x5f726468,
0x735f6f74,0x76287264,0x003b3366,0x00030005,0x0000001b,0x00000065,0x00050005,0x00000020,
0x6e727574,0x755f6465,0x00002876,0x00060005,0x00000022,0x65687073,0x61636972,0x76755f6c,
0x00000028,0x00030005,0x00000024,0x00000070,0x00030005,0x00000042,0x00000079,0x00030005,
0x00000057,0x00000073,0x00030005,0x00000071,0x00007379,0x00030005,0x00000083,0x00000079,
0x00040005,0x0000009b,0x68737550,0x00000000,0x00050006,0x0000009b,0x00000000,0x30776f72,
0x00000000,0x00050006,0x0000009b,0x00000001,0x31776f72,0x00000000,0x00050006,0x0000009b,
0x00000002,0x32776f72,0x00000000,0x00050006,0x0000009b,0x00000003,0x61726170,0x0000736d,
0x00060006,0x0000009b,0x00000004,0x735f7675,0x656c6163,0x00000000,0x00050006,0x0000009b,
0x00000005,0x756a6461,0x00007473,0x00050006,0x0000009b,0x00000006,0x77656976,0x00000000,
0x00050006,0x0000009b,0x00000007,0x726f6678,0x0000006d,0x00040006,0x0000009b,0x00000008,
0x00726468,0x00050006,0x0000009b,0x00000009,0x7074756f,0x00000000,0x00030005,0x0000009d,
0x00006370,0x00040005,0x000000bd,0x7374696e,0x00000000,0x00040005,0x000000c4,0x61726170,
0x0000006d,0x00040005,0x000000c8,0x61726170,0x0000006d,0x00040005,0x000000eb,0x61726170,
0x0000006d,0x00040005,0x000000f0,0x7374696e,0x00000000,0x00040005,0x000000f7,0x61726170,
0x0000006d,0x00040005,0x000000fb,0x61726170,0x0000006d,0x00040005,0x000000ff,0x6b616570,
0x00000000,0x00030005,0x00000103,0x00676973,0x00030005,0x00000113,0x00637273,0x00040005,
0x00000114,0x61726170,0x0000006d,0x00030005,0x00000117,0x00003165,0x00040005,0x00000118,
0x61726170,0x0000006d,0x00040005,0x0000011e,0x6c78616d,0x00000000,0x00040005,0x0000011f,
0x61726170,0x0000006d,0x00030005,0x00000123,0x0000736b,0x00030005,0x00000127,0x00003265,
0x00030005,0x0000012e,0x00000074,0x00030005,0x00000135,0x00003274,0x00030005,0x00000139,
0x00003374,0x00040005,0x0000015d,0x61726170,0x0000006d,0x00030005,0x00000164,0x006e696c,
0x00030005,0x00000186,0x0000006e,0x00030005,0x00000188,0x00007675,0x00030005,0x000001a3,
0x00000071,0x00030005,0x000001d2,0x0063646e,0x00030005,0x000001da,0x00000064,0x00030005,
0x000001ed,0x00007063,0x00030005,0x000001f1,0x00007073,0x00030005,0x0000020b,0x00007963,
0x00030005,0x0000020f,0x00007973,0x00030005,0x00000229,0x006e6f6c,0x00030005,0x0000022f,
0x0074616c,0x00030005,0x00000243,0x00000073,0x00030005,0x00000246,0x00007461,0x00030005,
0x00000251,0x00000079,0x00040005,0x00000255,0x5f786574,0x00000079,0x00030005,0x00000261,
0x00000074,0x00040005,0x0000026a,0x756f7261,0x0000646e,0x00030005,0x0000026b,0x00007964,
0x00030005,0x00000274,0x00007864,0x00040005,0x000002a2,0x6f726863,0x0000616d,0x00040005,
0x000002a9,0x5f786574,0x00000075,0x00040005,0x000002b3,0x5f786574,0x00000076,0x00030005,
0x000002ba,0x00000075,0x00030005,0x000002c0,0x00000076,0x00030005,0x000002df,0x00000063,
0x00030005,0x000002e3,0x00006e73,0x00030005,0x000002e7,0x00327675,0x00030005,0x000002fa,
0x00767579,0x00030005,0x00000300,0x00626772,0x00040005,0x0000031c,0x6f6c6f63,0x00000072,
0x00040005,0x0000031d,0x61726170,0x0000006d,0x00040005,0x0000032a,0x61726170,0x0000006d,
0x00030047,0x0000009b,0x00000002,0x00050048,0x0000009b,0x00000000,0x00000023,0x00000000,
0x00050048,0x0000009b,0x00000001,0x00000023,0x00000010,0x00050048,0x0000009b,0x00000002,
0x00000023,0x00000020,0x00050048,0x0000009b,0x00000003,0x00000023,0x00000030,0x00050048,
0x0000009b,0x00000004,0x00000023,0x00000040,0x00050048,0x0000009b,0x00000005,0x00000023,
0x00000050,0x00050048,0x0000009b,0x00000006,0x00000023,0x00000060,0x00050048,0x0000009b,
0x00000007,0x00000023,0x00000070,0x00050048,0x0000009b,0x00000008,0x00000023,0x00000080,
0x00050048,0x0000009b,0x00000009,0x00000023,0x00000090,0x00040047,0x00000188,0x0000001e,
0x00000000,0x00040047,0x00000255,0x00000021,0x00000000,0x00040047,0x00000255,0x00000022,
0x00000000,0x00040047,0x000002a9,0x00000021,0x00000001,0x00040047,0x000002a9,0x00000022,
0x00000000,0x00040047,0x000002b3,0x00000021,0x00000002,0x00040047,0x000002b3,0x00000022,
0x00000000,0x00040047,0x0000031c,0x0000001e,0x00000000,0x00020013,0x00000002,0x00030021,
0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,
0x00000002,0x00030021,0x00000008,0x00000007,0x00040020,0x0000000d,0x00000007,0x00000007,
0x00040020,0x0000000f,0x00000001,0x00000007,0x0004003b,0x0000000f,0x00000010,0x00000001,
0x00040017,0x00000012,0x00000006,0x00000004,0x000a001e,0x00000013,0x00000012,0x00000012,
0x00000012,0x00000012,0x00000007,0x00000012,0x00000012,0x00000012,0x00040020,0x00000014,
0x00000009,0x00000013,0x0004003b,0x00000014,0x00000015,0x00000009,0x00040015,0x00000016,
0x00000020,0x00000001,0x0004002b,0x00000016,0x00000017,0x00000004,0x00040020,0x00000018,
0x00000009,0x00000007,0x0004002b,0x00000016,0x0000001c,0x00000007,0x00040015,0x0000001d,
0x00000020,0x00000000,0x0004002b,0x0000001d,0x0000001e,0x00000001,0x00040020,0x0000001f,
0x00000009,0x00000006,0x0004002b,0x00000006,0x00000022,0x3f000000,0x00020014,0x00000023,
0x0004002b,0x00000006,0x00000027,0x3f800000,0x0004002b,0x0000001d,0x00000028,0x00000000,
0x00040020,0x00000029,0x00000007,0x00000006,0x0004002b,0x0000001d,0x0000002e,0x00000002,
0x00040020,0x00000038,0x00000007,0x00000016,0x0004002b,0x00000016,0x0000003f,0x00000001,
0x0004002b,0x00000016,0x0000004b,0x00000002,0x0004002b,0x00000016,0x00000058,0x00000003,
0x0004002b,0x00000006,0x0000006d,0x40000000,0x00040017,0x00000071,0x00000006,0x00000003,
0x00040020,0x00000072,0x00000007,0x00000071,0x0004002b,0x00000016,0x00000076,0x00000006,
0x0004002b,0x0000001d,0x0000007a,0x00000003,0x0004002b,0x00000006,0x000000cb,0xbf800000,
0x0004002b,0x00000006,0x000000cf,0x40c90fdb,0x0004002b,0x00000006,0x000000d3,0x40490fdb,
0x00090019,0x000000eb,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,
0x00000000,0x0003001b,0x000000ec,0x000000eb,0x00040020,0x000000ed,0x00000000,0x000000ec,
0x0004003b,0x000000ed,0x000000ee,0x00000000,0x0004002b,0x00000006,0x000000f7,0x00000000,
0x0004002b,0x00000016,0x000000fd,0x00000000,0x00040017,0x000000ff,0x00000016,0x00000002,
0x0004002b,0x00000016,0x00000106,0xffffffff,0x0004002b,0x00000006,0x00000132,0x3e000000,
0x0004003b,0x000000ed,0x0000013d,0x00000000,0x0004003b,0x000000ed,0x00000146,0x00000000,
0x0004002b,0x00000006,0x00000154,0x3d808081,0x0004002b,0x00000006,0x00000156,0x3f950a85,
0x0004002b,0x00000006,0x00000158,0x3f91b6db,0x0004002b,0x00000016,0x0000015f,0x00000005,
0x00040020,0x00000189,0x00000009,0x00000012,0x00040020,0x0000019d,0x00000003,0x00000012,
0x0004003b,0x0000019d,0x0000019e,0x00000003,0x00050036,0x00000002,0x00000004,0x00000000,
0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000029,0x000000dc,0x00000007,0x0004003b,
0x0000000d,0x000000df,0x00000007,0x0004003b,0x0000000d,0x000000e3,0x00000007,0x0004003b,
0x00000029,0x000000ea,0x00000007,0x0004003b,0x0000000d,0x000000fb,0x00000007,0x0004003b,
0x00000029,0x00000104,0x00000007,0x0004003b,0x00000038,0x00000105,0x00000007,0x0004003b,
0x00000038,0x0000010e,0x00000007,0x0004003b,0x00000029,0x0000013c,0x00000007,0x0004003b,
0x00000029,0x00000145,0x00000007,0x0004003b,0x00000029,0x00000167,0x00000007,0x0004003b,
0x00000029,0x0000016b,0x00000007,0x0004003b,0x0000000d,0x0000016f,0x00000007,0x0004003b,
0x00000072,0x00000182,0x00000007,0x0004003b,0x00000072,0x00000188,0x00000007,0x00060041,
0x0000001f,0x000000dd,0x00000015,0x00000058,0x00000028,0x0004003d,0x00000006,0x000000de,
0x000000dd,0x0003003e,0x000000dc,0x000000de,0x00060041,0x0000001f,0x000000e0,0x00000015,
0x00000058,0x0000007a,0x0004003d,0x00000006,0x000000e1,0x000000e0,0x000500ba,0x00000023,
0x000000e2,0x000000e1,0x00000022,0x000300f7,0x000000e5,0x00000000,0x000400fa,0x000000e2,
0x000000e4,0x000000e7,0x000200f8,0x000000e4,0x00040039,0x00000007,0x000000e6,0x0000000b,
0x0003003e,0x000000e3,0x000000e6,0x000200f9,0x000000e5,0x000200f8,0x000000e7,0x00040039,
0x00000007,0x000000e8,0x00000009,0x0003003e,0x000000e3,0x000000e8,0x000200f9,0x000000e5,
0x000200f8,0x000000e5,0x0004003d,0x00000007,0x000000e9,0x000000e3,0x0003003e,0x000000df,
0x000000e9,0x0004003d,0x000000ec,0x000000ef,0x000000ee,0x0004003d,0x00000007,0x000000f0,
0x000000df,0x00050057,0x00000012,0x000000f1,0x000000ef,0x000000f0,0x00050051,0x00000006,
0x000000f2,0x000000f1,0x00000000,0x0004003d,0x00000006,0x000000f3,0x000000dc,0x00050085,
0x00000006,0x000000f4,0x000000f2,0x000000f3,0x0003003e,0x000000ea,0x000000f4,0x00060041,
0x0000001f,0x000000f5,0x00000015,0x0000001c,0x0000007a,0x0004003d,0x00000006,0x000000f6,
0x000000f5,0x000500ba,0x00000023,0x000000f8,0x000000f6,0x000000f7,0x000300f7,0x000000fa,
0x00000000,0x000400fa,0x000000f8,0x000000f9,0x000000fa,0x000200f8,0x000000f9,0x0004003d,
0x000000ec,0x000000fc,0x000000ee,0x00040064,0x000000eb,0x000000fe,0x000000fc,0x00050067,
0x000000ff,0x00000100,0x000000fe,0x000000fd,0x0004006f,0x00000007,0x00000101,0x00000100,
0x00050050,0x00000007,0x00000102,0x00000027,0x00000027,0x00050088,0x00000007,0x00000103,
0x00000102,0x00000101,0x0003003e,0x000000fb,0x00000103,0x0003003e,0x00000104,0x000000f7,
0x0003003e,0x00000105,0x00000106,0x000200f9,0x00000107,0x000200f8,0x00000107,0x000400f6,
0x00000109,0x0000010a,0x00000000,0x000200f9,0x0000010b,0x000200f8,0x0000010b,0x0004003d,
0x00000016,0x0000010c,0x00000105,0x000500b3,0x00000023,0x0000010d,0x0000010c,0x0000003f,
0x000400fa,0x0000010d,0x00000108,0x00000109,0x000200f8,0x00000108,0x0003003e,0x0000010e,
0x00000106,0x000200f9,0x0000010f,0x000200f8,0x0000010f,0x000400f6,0x00000111,0x00000112,
0x00000000,0x000200f9,0x00000113,0x000200f8,0x00000113,0x0004003d,0x00000016,0x00000114,
0x0000010e,0x000500b3,0x00000023,0x00000115,0x00000114,0x0000003f,0x000400fa,0x00000115,
0x00000110,0x00000111,0x000200f8,0x00000110,0x0004003d,0x00000016,0x00000116,0x0000010e,
0x000500ab,0x00000023,0x00000117,0x00000116,0x000000fd,0x0004003d,0x00000016,0x00000118,
0x00000105,0x000500ab,0x00000023,0x00000119,0x00000118,0x000000fd,0x000500a6,0x00000023,
0x0000011a,0x00000117,0x00000119,0x000300f7,0x0000011c,0x00000000,0x000400fa,0x0000011a,
0x0000011b,0x0000011c,0x000200f8,0x0000011b,0x0004003d,0x000000ec,0x0000011d,0x000000ee,
0x0004003d,0x00000007,0x0000011e,0x000000df,0x0004003d,0x00000016,0x0000011f,0x0000010e,
0x0004006f,0x00000006,0x00000120,0x0000011f,0x0004003d,0x00000016,0x00000121,0x00000105,
0x0004006f,0x00000006,0x00000122,0x00000121,0x00050050,0x00000007,0x00000123,0x00000120,
0x00000122,0x0004003d,0x00000007,0x00000124,0x000000fb,0x00050085,0x00000007,0x00000125,
0x00000123,0x00000124,0x00050081,0x00000007,0x00000126,0x0000011e,0x00000125,0x00050057,
0x00000012,0x00000127,0x0000011d,0x00000126,0x00050051,0x00000006,0x00000128,0x00000127,
0x00000000,0x0004003d,0x00000006,0x00000129,0x00000104,0x00050081,0x00000006,0x0000012a,
0x00000129,0x00000128,0x0003003e,0x00000104,0x0000012a,0x000200f9,0x0000011c,0x000200f8,
0x0000011c,0x000200f9,0x00000112,0x000200f8,0x00000112,0x0004003d,0x00000016,0x0000012b,
0x0000010e,0x00050080,0x00000016,0x0000012c,0x0000012b,0x0000003f,0x0003003e,0x0000010e,
0x0000012c,0x000200f9,0x0000010f,0x000200f8,0x00000111,0x000200f9,0x0000010a,0x000200f8,
0x0000010a,0x0004003d,0x00000016,0x0000012d,0x00000105,0x00050080,0x00000016,0x0000012e,
0x0000012d,0x0000003f,0x0003003e,0x00000105,0x0000012e,0x000200f9,0x00000107,0x000200f8,
0x00000109,0x0004003d,0x00000006,0x0000012f,0x000000ea,0x0004003d,0x00000006,0x00000130,
0x000000ea,0x0004003d,0x00000006,0x00000131,0x00000104,0x00050085,0x00000006,0x00000133,
0x00000131,0x00000132,0x0004003d,0x00000006,0x00000134,0x000000dc,0x00050085,0x00000006,
0x00000135,0x00000133,0x00000134,0x00050083,0x00000006,0x00000136,0x00000130,0x00000135,
0x00060041,0x0000001f,0x00000137,0x00000015,0x0000001c,0x0000007a,0x0004003d,0x00000006,
0x00000138,0x00000137,0x00050085,0x00000006,0x00000139,0x00000136,0x00000138,0x00050081,
0x00000006,0x0000013a,0x0000012f,0x00000139,0x0008000c,0x00000006,0x0000013b,0x00000001,
0x0000002b,0x0000013a,0x000000f7,0x00000027,0x0003003e,0x000000ea,0x0000013b,0x000200f9,
0x000000fa,0x000200f8,0x000000fa,0x0004003d,0x000000ec,0x0000013e,0x0000013d,0x0004003d,
0x00000007,0x0000013f,0x000000df,0x00050057,0x00000012,0x00000140,0x0000013e,0x0000013f,
0x00050051,0x00000006,0x00000141,0x00000140,0x00000000,0x0004003d,0x00000006,0x00000142,
0x000000dc,0x00050085,0x00000006,0x00000143,0x00000141,0x00000142,0x00050083,0x00000006,
0x00000144,0x00000143,0x00000022,0x0003003e,0x0000013c,0x00000144,0x0004003d,0x000000ec,
0x00000147,0x00000146,0x0004003d,0x00000007,0x00000148,0x000000df,0x00050057,0x00000012,
0x00000149,0x00000147,0x00000148,0x00050051,0x00000006,0x0000014a,0x00000149,0x00000000,
0x0004003d,0x00000006,0x0000014b,0x000000dc,0x00050085,0x00000006,0x0000014c,0x0000014a,
0x0000014b,0x00050083,0x00000006,0x0000014d,0x0000014c,0x00000022,0x0003003e,0x00000145,
0x0000014d,0x00060041,0x0000001f,0x0000014e,0x00000015,0x00000058,0x0000001e,0x0004003d,
0x00000006,0x0000014f,0x0000014e,0x000500ba,0x00000023,0x00000150,0x0000014f,0x00000022,
0x000300f7,0x00000152,0x00000000,0x000400fa,0x00000150,0x00000151,0x00000152,0x000200f8,
0x00000151,0x0004003d,0x00000006,0x00000153,0x000000ea,0x00050083,0x00000006,0x00000155,
0x00000153,0x00000154,0x00050085,0x00000006,0x00000157,0x00000155,0x00000156,0x0003003e,
0x000000ea,0x00000157,0x0004003d,0x00000006,0x00000159,0x0000013c,0x00050085,0x00000006,
0x0000015a,0x00000159,0x00000158,0x0003003e,0x0000013c,0x0000015a,0x0004003d,0x00000006,
0x0000015b,0x00000145,0x00050085,0x00000006,0x0000015c,0x0000015b,0x00000158,0x0003003e,
0x00000145,0x0000015c,0x000200f9,0x00000152,0x000200f8,0x00000152,0x0004003d,0x00000006,
0x0000015d,0x000000ea,0x00050083,0x00000006,0x0000015e,0x0000015d,0x00000022,0x00060041,
0x0000001f,0x00000160,0x00000015,0x0000015f,0x0000001e,0x0004003d,0x00000006,0x00000161,
0x00000160,0x00050085,0x00000006,0x00000162,0x0000015e,0x00000161,0x00050081,0x00000006,
0x00000163,0x00000162,0x00000022,0x00060041,0x0000001f,0x00000164,0x00000015,0x0000015f,
0x00000028,0x0004003d,0x00000006,0x00000165,0x00000164,0x00050081,0x00000006,0x00000166,
0x00000163,0x00000165,0x0003003e,0x000000ea,0x00000166,0x00060041,0x0000001f,0x00000168,
0x00000015,0x00000058,0x0000002e,0x0004003d,0x00000006,0x00000169,0x00000168,0x0006000c,
0x00000006,0x0000016a,0x00000001,0x0000000e,0x00000169,0x0003003e,0x00000167,0x0000016a,
0x00060041,0x0000001f,0x0000016c,0x00000015,0x00000058,0x0000002e,0x0004003d,0x00000006,
0x0000016d,0x0000016c,0x0006000c,0x00000006,0x0000016e,0x00000001,0x0000000d,0x0000016d,
0x0003003e,0x0000016b,0x0000016e,0x0004003d,0x00000006,0x00000170,0x0000013c,0x0004003d,
0x00000006,0x00000171,0x00000167,0x00050085,0x00000006,0x00000172,0x00000170,0x00000171,
0x0004003d,0x00000006,0x00000173,0x00000145,0x0004003d,0x00000006,0x00000174,0x0000016b,
0x00050085,0x00000006,0x00000175,0x00000173,0x00000174,0x00050083,0x00000006,0x00000176,
0x00000172,0x00000175,0x0004003d,0x00000006,0x00000177,0x0000013c,0x0004003d,0x00000006,
0x00000178,0x0000016b,0x00050085,0x00000006,0x00000179,0x00000177,0x00000178,0x0004003d,
0x00000006,0x0000017a,0x00000145,0x0004003d,0x00000006,0x0000017b,0x00000167,0x00050085,
0x00000006,0x0000017c,0x0000017a,0x0000017b,0x00050081,0x00000006,0x0000017d,0x00000179,
0x0000017c,0x00050050,0x00000007,0x0000017e,0x00000176,0x0000017d,0x00060041,0x0000001f,
0x0000017f,0x00000015,0x0000015f,0x0000002e,0x0004003d,0x00000006,0x00000180,0x0000017f,
0x0005008e,0x00000007,0x00000181,0x0000017e,0x00000180,0x0003003e,0x0000016f,0x00000181,
0x0004003d,0x00000006,0x00000183,0x000000ea,0x0004003d,0x00000007,0x00000184,0x0000016f,
0x00050051,0x00000006,0x00000185,0x00000184,0x00000000,0x00050051,0x00000006,0x00000186,
0x00000184,0x00000001,0x00060050,0x00000071,0x00000187,0x00000183,0x00000185,0x00000186,
0x0003003e,0x00000182,0x00000187,0x00050041,0x00000189,0x0000018a,0x00000015,0x000000fd,
0x0004003d,0x00000012,0x0000018b,0x0000018a,0x0008004f,0x00000071,0x0000018c,0x0000018b,
0x0000018b,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000071,0x0000018d,0x00000182,
0x00050094,0x00000006,0x0000018e,0x0000018c,0x0000018d,0x00050041,0x00000189,0x0000018f,
0x00000015,0x0000003f,0x0004003d,0x00000012,0x00000190,0x0000018f,0x0008004f,0x00000071,
0x00000191,0x00000190,0x00000190,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000071,
0x00000192,0x00000182,0x00050094,0x00000006,0x00000193,0x00000191,0x00000192,0x00050041,
0x00000189,0x00000194,0x00000015,0x0000004b,0x0004003d,0x00000012,0x00000195,0x00000194,
0x0008004f,0x00000071,0x00000196,0x00000195,0x00000195,0x00000000,0x00000001,0x00000002,
0x0004003d,0x00000071,0x00000197,0x00000182,0x00050094,0x00000006,0x00000198,0x00000196,
0x00000197,0x00060050,0x00000071,0x00000199,0x0000018e,0x00000193,0x00000198,0x00060050,
0x00000071,0x0000019a,0x000000f7,0x000000f7,0x000000f7,0x00060050,0x00000071,0x0000019b,
0x00000027,0x00000027,0x00000027,0x0008000c,0x00000071,0x0000019c,0x00000001,0x0000002b,
0x00000199,0x0000019a,0x0000019b,0x0003003e,0x00000188,0x0000019c,0x0004003d,0x00000071,
0x0000019f,0x00000188,0x00060041,0x0000001f,0x000001a0,0x00000015,0x0000015f,0x0000007a,
0x0004003d,0x00000006,0x000001a1,0x000001a0,0x00060050,0x00000071,0x000001a2,0x000001a1,
0x000001a1,0x000001a1,0x0007000c,0x00000071,0x000001a3,0x00000001,0x0000001a,0x0000019f,
0x000001a2,0x00050051,0x00000006,0x000001a4,0x000001a3,0x00000000,0x00050051,0x00000006,
0x000001a5,0x000001a3,0x00000001,0x00050051,0x00000006,0x000001a6,0x000001a3,0x00000002,
0x00070050,0x00000012,0x000001a7,0x000001a4,0x000001a5,0x000001a6,0x00000027,0x0003003e,
0x0000019e,0x000001a7,0x000100fd,0x00010038,0x00050036,0x00000007,0x00000009,0x00000000,
0x00000008,0x000200f8,0x0000000a,0x0004003b,0x0000000d,0x0000000e,0x00000007,0x0004003b,
0x00000038,0x00000039,0x00000007,0x0004003d,0x00000007,0x00000011,0x00000010,0x00050041,
0x00000018,0x00000019,0x00000015,0x00000017,0x0004003d,0x00000007,0x0000001a,0x00000019,
0x00050088,0x00000007,0x0000001b,0x00000011,0x0000001a,0x0003003e,0x0000000e,0x0000001b,
0x00060041,0x0000001f,0x00000020,0x00000015,0x0000001c,0x0000001e,0x0004003d,0x00000006,
0x00000021,0x00000020,0x000500ba,0x00000023,0x00000024,0x00000021,0x00000022,0x000300f7,
0x00000026,0x00000000,0x000400fa,0x00000024,0x00000025,0x00000026,0x000200f8,0x00000025,
0x00050041,0x00000029,0x0000002a,0x0000000e,0x00000028,0x0004003d,0x00000006,0x0000002b,
0x0000002a,0x00050083,0x00000006,0x0000002c,0x00000027,0x0000002b,0x00050041,0x00000029,
0x0000002d,0x0000000e,0x00000028,0x0003003e,0x0000002d,0x0000002c,0x000200f9,0x00000026,
0x000200f8,0x00000026,0x00060041,0x0000001f,0x0000002f,0x00000015,0x0000001c,0x0000002e,
0x0004003d,0x00000006,0x00000030,0x0000002f,0x000500ba,0x00000023,0x00000031,0x00000030,
0x00000022,0x000300f7,0x00000033,0x00000000,0x000400fa,0x00000031,0x00000032,0x00000033,
0x000200f8,0x00000032,0x00050041,0x00000029,0x00000034,0x0000000e,0x0000001e,0x0004003d,
0x00000006,0x00000035,0x00000034,0x00050083,0x00000006,0x00000036,0x00000027,0x00000035,
0x00050041,0x00000029,0x00000037,0x0000000e,0x0000001e,0x0003003e,0x00000037,0x00000036,
0x000200f9,0x00000033,0x000200f8,0x00000033,0x00060041,0x0000001f,0x0000003a,0x00000015,
0x0000001c,0x00000028,0x0004003d,0x00000006,0x0000003b,0x0000003a,0x00050081,0x00000006,
0x0000003c,0x0000003b,0x00000022,0x0004006e,0x00000016,0x0000003d,0x0000003c,0x0003003e,
0x00000039,0x0000003d,0x0004003d,0x00000016,0x0000003e,0x00000039,0x000500aa,0x00000023,
0x00000040,0x0000003e,0x0000003f,0x000300f7,0x00000042,0x00000000,0x000400fa,0x00000040,
0x00000041,0x00000049,0x000200f8,0x00000041,0x00050041,0x00000029,0x00000043,0x0000000e,
0x0000001e,0x0004003d,0x00000006,0x00000044,0x00000043,0x00050041,0x00000029,0x00000045,
0x0000000e,0x00000028,0x0004003d,0x00000006,0x00000046,0x00000045,0x00050083,0x00000006,
0x00000047,0x00000027,0x00000046,0x00050050,0x00000007,0x00000048,0x00000044,0x00000047,
0x0003003e,0x0000000e,0x00000048,0x000200f9,0x00000042,0x000200f8,0x00000049,0x0004003d,
0x00000016,0x0000004a,0x00000039,0x000500aa,0x00000023,0x0000004c,0x0000004a,0x0000004b,
0x000300f7,0x0000004e,0x00000000,0x000400fa,0x0000004c,0x0000004d,0x00000056,0x000200f8,
0x0000004d,0x00050041,0x00000029,0x0000004f,0x0000000e,0x00000028,0x0004003d,0x00000006,
0x00000050,0x0000004f,0x00050083,0x00000006,0x00000051,0x00000027,0x00000050,0x00050041,
0x00000029,0x00000052,0x0000000e,0x0000001e,0x0004003d,0x00000006,0x00000053,0x00000052,
0x00050083,0x00000006,0x00000054,0x00000027,0x00000053,0x00050050,0x00000007,0x00000055,
0x00000051,0x00000054,0x0003003e,0x0000000e,0x00000055,0x000200f9,0x0000004e,0x000200f8,
0x00000056,0x0004003d,0x00000016,0x00000057,0x00000039,0x000500aa,0x00000023,0x00000059,
0x00000057,0x00000058,0x000300f7,0x0000005b,0x00000000,0x000400fa,0x00000059,0x0000005a,
0x0000005b,0x000200f8,0x0000005a,0x00050041,0x00000029,0x0000005c,0x0000000e,0x0000001e,
0x0004003d,0x00000006,0x0000005d,0x0000005c,0x00050083,0x00000006,0x0000005e,0x00000027,
0x0000005d,0x00050041,0x00000029,0x0000005f,0x0000000e,0x00000028,0x0004003d,0x00000006,
0x00000060,0x0000005f,0x00050050,0x00000007,0x00000061,0x0000005e,0x00000060,0x0003003e,
0x0000000e,0x00000061,0x000200f9,0x0000005b,0x000200f8,0x0000005b,0x000200f9,0x0000004e,
0x000200f8,0x0000004e,0x000200f9,0x00000042,0x000200f8,0x00000042,0x0004003d,0x00000007,
0x00000062,0x0000000e,0x00050041,0x00000018,0x00000063,0x00000015,0x00000017,0x0004003d,
0x00000007,0x00000064,0x00000063,0x00050085,0x00000007,0x00000065,0x00000062,0x00000064,
0x000200fe,0x00000065,0x00010038,0x00050036,0x00000007,0x0000000b,0x00000000,0x00000008,
0x000200f8,0x0000000c,0x0004003b,0x0000000d,0x00000068,0x00000007,0x0004003b,0x00000072,
0x00000073,0x00000007,0x0004003b,0x00000029,0x00000086,0x00000007,0x0004003b,0x00000029,
0x0000008a,0x00000007,0x0004003b,0x00000029,0x000000a4,0x00000007,0x0004003b,0x00000029,
0x000000a8,0x00000007,0x0004003b,0x00000029,0x000000c2,0x00000007,0x0004003b,0x00000029,
0x000000c8,0x00000007,0x0004003d,0x00000007,0x00000069,0x00000010,0x00050041,0x00000018,
0x0000006a,0x00000015,0x00000017,0x0004003d,0x00000007,0x0000006b,0x0000006a,0x00050088,
0x00000007,0x0000006c,0x00000069,0x0000006b,0x0005008e,0x00000007,0x0000006e,0x0000006c,
0x0000006d,0x00050050,0x00000007,0x0000006f,0x00000027,0x00000027,0x00050083,0x00000007,
0x00000070,0x0000006e,0x0000006f,0x0003003e,0x00000068,0x00000070,0x00050041,0x00000029,
0x00000074,0x00000068,0x00000028,0x0004003d,0x00000006,0x00000075,0x00000074,0x00060041,
0x0000001f,0x00000077,0x00000015,0x00000076,0x0000002e,0x0004003d,0x00000006,0x00000078,
0x00000077,0x00050085,0x00000006,0x00000079,0x00000075,0x00000078,0x00060041,0x0000001f,
0x0000007b,0x00000015,0x00000076,0x0000007a,0x0004003d,0x00000006,0x0000007c,0x0000007b,
0x00050085,0x00000006,0x0000007d,0x00000079,0x0000007c,0x00050041,0x00000029,0x0000007e,
0x00000068,0x0000001e,0x0004003d,0x00000006,0x0000007f,0x0000007e,0x0004007f,0x00000006,
0x00000080,0x0000007f,0x00060041,0x0000001f,0x00000081,0x00000015,0x00000076,0x0000002e,
0x0004003d,0x00000006,0x00000082,0x00000081,0x00050085,0x00000006,0x00000083,0x00000080,
0x00000082,0x00060050,0x00000071,0x00000084,0x0000007d,0x00000083,0x00000027,0x0006000c,
0x00000071,0x00000085,0x00000001,0x00000045,0x00000084,0x0003003e,0x00000073,0x00000085,
0x00060041,0x0000001f,0x00000087,0x00000015,0x00000076,0x0000001e,0x0004003d,0x00000006,
0x00000088,0x00000087,0x0006000c,0x00000006,0x00000089,0x00000001,0x0000000e,0x00000088,
0x0003003e,0x00000086,0x00000089,0x00060041,0x0000001f,0x0000008b,0x00000015,0x00000076,
0x0000001e,0x0004003d,0x00000006,0x0000008c,0x0000008b,0x0006000c,0x00000006,0x0000008d,
0x00000001,0x0000000d,0x0000008c,0x0003003e,0x0000008a,0x0000008d,0x00050041,0x00000029,
0x0000008e,0x00000073,0x00000028,0x0004003d,0x00000006,0x0000008f,0x0000008e,0x00050041,
0x00000029,0x00000090,0x00000073,0x0000001e,0x0004003d,0x00000006,0x00000091,0x00000090,
0x0004003d,0x00000006,0x00000092,0x00000086,0x00050085,0x00000006,0x00000093,0x00000091,
0x00000092,0x00050041,0x00000029,0x00000094,0x00000073,0x0000002e,0x0004003d,0x00000006,
0x00000095,0x00000094,0x0004003d,0x00000006,0x00000096,0x0000008a,0x00050085,0x00000006,
0x00000097,0x00000095,0x00000096,0x00050081,0x00000006,0x00000098,0x00000093,0x00000097,
0x00050041,0x00000029,0x00000099,0x00000073,0x0000001e,0x0004003d,0x00000006,0x0000009a,
0x00000099,0x0004007f,0x00000006,0x0000009b,0x0000009a,0x0004003d,0x00000006,0x0000009c,
0x0000008a,0x00050085,0x00000006,0x0000009d,0x0000009b,0x0000009c,0x00050041,0x00000029,
0x0000009e,0x00000073,0x0000002e,0x0004003d,0x00000006,0x0000009f,0x0000009e,0x0004003d,
0x00000006,0x000000a0,0x00000086,0x00050085,0x00000006,0x000000a1,0x0000009f,0x000000a0,
0x00050081,0x00000006,0x000000a2,0x0000009d,0x000000a1,0x00060050,0x00000071,0x000000a3,
0x0000008f,0x00000098,0x000000a2,0x0003003e,0x00000073,0x000000a3,0x00060041,0x0000001f,
0x000000a5,0x00000015,0x00000076,0x00000028,0x0004003d,0x00000006,0x000000a6,0x000000a5,
0x0006000c,0x00000006,0x000000a7,0x00000001,0x0000000e,0x000000a6,0x0003003e,0x000000a4,
0x000000a7,0x00060041,0x0000001f,0x000000a9,0x00000015,0x00000076,0x00000028,0x0004003d,
0x00000006,0x000000aa,0x000000a9,0x0006000c,0x00000006,0x000000ab,0x00000001,0x0000000d,
0x000000aa,0x0003003e,0x000000a8,0x000000ab,0x00050041,0x00000029,0x000000ac,0x00000073,
0x00000028,0x0004003d,0x00000006,0x000000ad,0x000000ac,0x0004003d,0x00000006,0x000000ae,
0x000000a4,0x00050085,0x00000006,0x000000af,0x000000ad,0x000000ae,0x00050041,0x00000029,
0x000000b0,0x00000073,0x0000002e,0x0004003d,0x00000006,0x000000b1,0x000000b0,0x0004003d,
0x00000006,0x000000b2,0x000000a8,0x00050085,0x00000006,0x000000b3,0x000000b1,0x000000b2,
0x00050081,0x00000006,0x000000b4,0x000000af,0x000000b3,0x00050041,0x00000029,0x000000b5,
0x00000073,0x0000001e,0x0004003d,0x00000006,0x000000b6,0x000000b5,0x00050041,0x00000029,
0x000000b7,0x00000073,0x00000028,0x0004003d,0x00000006,0x000000b8,0x000000b7,0x0004007f,
0x00000006,0x000000b9,0x000000b8,0x0004003d,0x00000006,0x000000ba,0x000000a8,0x00050085,
0x00000006,0x000000bb,0x000000b9,0x000000ba,0x00050041,0x00000029,0x000000bc,0x00000073,
0x0000002e,0x0004003d,0x00000006,0x000000bd,0x000000bc,0x0004003d,0x00000006,0x000000be,
0x000000a4,0x00050085,0x00000006,0x000000bf,0x000000bd,0x000000be,0x00050081,0x00000006,
0x000000c0,0x000000bb,0x000000bf,0x00060050,0x00000071,0x000000c1,0x000000b4,0x000000b6,
0x000000c0,0x0003003e,0x00000073,0x000000c1,0x00050041,0x00000029,0x000000c3,0x00000073,
0x00000028,0x0004003d,0x00000006,0x000000c4,0x000000c3,0x00050041,0x00000029,0x000000c5,
0x00000073,0x0000002e,0x0004003d,0x00000006,0x000000c6,0x000000c5,0x0007000c,0x00000006,
0x000000c7,0x00000001,0x00000019,0x000000c4,0x000000c6,0x0003003e,0x000000c2,0x000000c7,
0x00050041,0x00000029,0x000000c9,0x00000073,0x0000001e,0x0004003d,0x00000006,0x000000ca,
0x000000c9,0x0008000c,0x00000006,0x000000cc,0x00000001,0x0000002b,0x000000ca,0x000000cb,
0x00000027,0x0006000c,0x00000006,0x000000cd,0x00000001,0x00000010,0x000000cc,0x0003003e,
0x000000c8,0x000000cd,0x0004003d,0x00000006,0x000000ce,0x000000c2,0x00050088,0x00000006,
0x000000d0,0x000000ce,0x000000cf,0x00050081,0x00000006,0x000000d1,0x000000d0,0x00000022,
0x0004003d,0x00000006,0x000000d2,0x000000c8,0x00050088,0x00000006,0x000000d4,0x000000d2,
0x000000d3,0x00050083,0x00000006,0x000000d5,0x00000022,0x000000d4,0x00050050,0x00000007,
0x000000d6,0x000000d1,0x000000d5,0x00050041,0x00000018,0x000000d7,0x00000015,0x00000017,
0x0004003d,0x00000007,0x000000d8,0x000000d7,0x00050085,0x00000007,0x000000d9,0x000000d6,
0x000000d8,0x000200fe,0x000000d9,0x00010038
0x00000003,0x00040020,0x00000008,0x00000007,0x00000007,0x00040021,0x00000009,0x00000007,
0x00000008,0x00040020,0x0000000d,0x00000007,0x00000006,0x00040021,0x0000000e,0x00000006,
0x0000000d,0x00040017,0x0000001e,0x00000006,0x00000002,0x00030021,0x0000001f,0x0000001e,
0x0004002b,0x00000006,0x00000026,0x00000000,0x0004002b,0x00000006,0x00000027,0x3f800000,
0x0004002b,0x00000006,0x0000002b,0x3c4fcdac,0x0006002c,0x00000007,0x0000002c,0x0000002b,
0x0000002b,0x0000002b,0x0004002b,0x00000006,0x0000002e,0x461c4000,0x0004002b,0x00000006,
0x00000030,0x3f560000,0x0004002b,0x00000006,0x00000035,0x4196d000,0x0004002b,0x00000006,
0x00000036,0x41958000,0x0004002b,0x00000006,0x0000003c,0x40c8e06b,0x0006002c,0x00000007,
0x0000003d,0x0000003c,0x0000003c,0x0000003c,0x0004002b,0x00000006,0x00000046,0x3e232000,
0x0004002b,0x00000006,0x0000004f,0x429db000,0x0004002b,0x00000006,0x0000005b,0x40400000,
0x0004002b,0x00000006,0x0000005f,0x3f0f564f,0x0004002b,0x00000006,0x00000062,0x3e371ff0,
0x0004002b,0x00000006,0x00000066,0x3e91c020,0x0004002b,0x00000006,0x00000069,0x41400000,
0x0004002b,0x00000006,0x0000006c,0x3f000000,0x0006002c,0x00000007,0x0000006d,0x0000006c,
0x0000006c,0x0000006c,0x0004002b,0x00000006,0x00000073,0x3e86809d,0x0004002b,0x00000006,
0x00000074,0x3f2d9168,0x0004002b,0x00000006,0x00000075,0x3d72e48f,0x0006002c,0x00000007,
0x00000076,0x00000073,0x00000074,0x00000075,0x0004002b,0x00000006,0x00000078,0x358637bd,
0x0004002b,0x00000006,0x0000007a,0x447a0000,0x0004002b,0x00000006,0x0000007c,0x3e4ccccd,
0x0006002c,0x00000007,0x0000008a,0x00000046,0x00000046,0x00000046,0x0006002c,0x00000007,
0x00000095,0x0000004f,0x0000004f,0x0000004f,0x00020014,0x00000099,0x00040017,0x0000009a,
0x00000006,0x00000004,0x000c001e,0x0000009b,0x0000009a,0x0000009a,0x0000009a,0x0000009a,
0x0000001e,0x0000009a,0x0000009a,0x0000009a,0x0000009a,0x0000009a,0x00040020,0x0000009c,
0x00000009,0x0000009b,0x0004003b,0x0000009c,0x0000009d,0x00000009,0x00040015,0x0000009e,
0x00000020,0x00000001,0x0004002b,0x0000009e,0x0000009f,0x00000008,0x00040015,0x000000a0,
0x00000020,0x00000000,0x0004002b,0x000000a0,0x000000a1,0x00000000,0x00040020,0x000000a2,
0x00000009,0x00000006,0x0004002b,0x00000006,0x000000aa,0x3fc00000,0x0004002b,0x000000a0,
0x000000af,0x00000002,0x0004002b,0x00000006,0x000000d1,0x4019999a,0x0006002c,0x00000007,
0x000000d2,0x000000d1,0x000000d1,0x000000d1,0x0004002b,0x00000006,0x000000d4,0x434b0000,
0x00040018,0x000000db,0x00000007,0x00000003,0x0004002b,0x00000006,0x000000dc,0x3f209d49,
0x0004002b,0x00000006,0x000000dd,0x3d8d844d,0x0004002b,0x00000006,0x000000de,0x3c86594b,
0x0006002c,0x00000007,0x000000df,0x000000dc,0x000000dd,0x000000de,0x0004002b,0x00000006,
0x000000e0,0x3ea89a02,0x0004002b,0x00000006,0x000000e1,0x3f6b645a,0x0004002b,0x00000006,
0x000000e2,0x3db43958,0x0006002c,0x00000007,0x000000e3,0x000000e0,0x000000e1,0x000000e2,
0x0004002b,0x00000006,0x000000e4,0x3d315b57,0x0004002b,0x00000006,0x000000e5,0x3c3ac711,
0x0004002b,0x00000006,0x000000e6,0x3f65460b,0x0006002c,0x00000007,0x000000e7,0x000000e4,
0x000000e5,0x000000e6,0x0006002c,0x000000db,0x000000e8,0x000000df,0x000000e3,0x000000e7,
0x0004002b,0x000000a0,0x00000100,0x00000001,0x0004002b,0x00000006,0x0000013d,0x40000000,
0x0004002b,0x00000006,0x00000150,0xc0000000,0x0004002b,0x00000006,0x0000016d,0x3fd48b44,
0x0004002b,0x00000006,0x0000016e,0xbdff2e49,0x0004002b,0x00000006,0x0000016f,0xbc95182b,
0x0006002c,0x00000007,0x00000170,0x0000016d,0x0000016e,0x0000016f,0x0004002b,0x00000006,
0x00000171,0xbf166cf4,0x0004002b,0x00000006,0x00000172,0x3f9102de,0x0004002b,0x00000006,
0x00000173,0xbdce075f,0x0006002c,0x00000007,0x00000174,0x00000171,0x00000172,0x00000173,
0x0004002b,0x00000006,0x00000175,0xbd95182b,0x0004002b,0x00000006,0x00000176,0xbc07fcb9,
0x0004002b,0x00000006,0x00000177,0x3f8f3190,0x0006002c,0x00000007,0x00000178,0x00000175,
0x00000176,0x00000177,0x0006002c,0x000000db,0x00000179,0x00000170,0x00000174,0x00000178,
0x0004002b,0x00000006,0x00000180,0x3ed55555,0x0006002c,0x00000007,0x00000181,0x00000180,
0x00000180,0x00000180,0x00040020,0x00000185,0x00000007,0x0000001e,0x00040020,0x00000187,
0x00000001,0x0000001e,0x0004003b,0x00000187,0x00000188,0x00000001,0x0004002b,0x0000009e,
0x0000018a,0x00000004,0x00040020,0x0000018b,0x00000009,0x0000001e,0x0004002b,0x0000009e,
0x0000018f,0x00000007,0x00040020,0x000001a2,0x00000007,0x0000009e,0x0004002b,0x0000009e,
0x000001a9,0x00000001,0x0004002b,0x0000009e,0x000001b5,0x00000002,0x0004002b,0x0000009e,
0x000001c2,0x00000003,0x0004002b,0x0000009e,0x000001dd,0x00000006,0x0004002b,0x000000a0,
0x000001e1,0x00000003,0x0004002b,0x00000006,0x00000232,0xbf800000,0x0004002b,0x00000006,
0x00000236,0x40c90fdb,0x0004002b,0x00000006,0x0000023a,0x40490fdb,0x00090019,0x00000252,
0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x0003001b,
0x00000253,0x00000252,0x00040020,0x00000254,0x00000000,0x00000253,0x0004003b,0x00000254,
0x00000255,0x00000000,0x0004002b,0x0000009e,0x00000263,0x00000000,0x00040017,0x00000265,
0x0000009e,0x00000002,0x0004002b,0x0000009e,0x0000026c,0xffffffff,0x0004002b,0x00000006,
0x00000298,0x3e000000,0x0004003b,0x00000254,0x000002a9,0x00000000,0x0004003b,0x00000254,
0x000002b3,0x00000000,0x0004002b,0x00000006,0x000002cc,0x3d808081,0x0004002b,0x00000006,
0x000002ce,0x3f950a85,0x0004002b,0x00000006,0x000002d0,0x3f91b6db,0x0004002b,0x0000009e,
0x000002d7,0x00000005,0x00040020,0x00000301,0x00000009,0x0000009a,0x0004002b,0x0000009e,
0x00000315,0x00000009,0x00040020,0x0000031b,0x00000003,0x0000009a,0x0004003b,0x0000031b,
0x0000031c,0x00000003,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,
0x00000005,0x0004003b,0x0000000d,0x00000243,0x00000007,0x0004003b,0x00000185,0x00000246,
0x00000007,0x0004003b,0x00000185,0x0000024a,0x00000007,0x0004003b,0x0000000d,0x00000251,
0x00000007,0x0004003b,0x00000185,0x00000261,0x00000007,0x0004003b,0x0000000d,0x0000026a,
0x00000007,0x0004003b,0x000001a2,0x0000026b,0x00000007,0x0004003b,0x000001a2,0x00000274,
0x00000007,0x0004003b,0x00000185,0x000002a2,0x00000007,0x0004003b,0x00000185,0x000002a6,
0x00000007,0x0004003b,0x0000000d,0x000002ba,0x00000007,0x0004003b,0x0000000d,0x000002c0,
0x00000007,0x0004003b,0x0000000d,0x000002df,0x00000007,0x0004003b,0x0000000d,0x000002e3,
0x00000007,0x0004003b,0x00000185,0x000002e7,0x00000007,0x0004003b,0x00000008,0x000002fa,
0x00000007,0x0004003b,0x00000008,0x00000300,0x00000007,0x0004003b,0x00000008,0x0000031d,
0x00000007,0x0004003b,0x00000008,0x0000032a,0x00000007,0x00060041,0x000000a2,0x00000244,
0x0000009d,0x000001c2,0x000000a1,0x0004003d,0x00000006,0x00000245,0x00000244,0x0003003e,
0x00000243,0x00000245,0x00060041,0x000000a2,0x00000247,0x0000009d,0x000001c2,0x000001e1,
0x0004003d,0x00000006,0x00000248,0x00000247,0x000500ba,0x00000099,0x00000249,0x00000248,
0x0000006c,0x000300f7,0x0000024c,0x00000000,0x000400fa,0x00000249,0x0000024b,0x0000024e,
0x000200f8,0x0000024b,0x00040039,0x0000001e,0x0000024d,0x00000022,0x0003003e,0x0000024a,
0x0000024d,0x000200f9,0x0000024c,0x000200f8,0x0000024e,0x00040039,0x0000001e,0x0000024f,
0x00000020,0x0003003e,0x0000024a,0x0000024f,0x000200f9,0x0000024c,0x000200f8,0x0000024c,
0x0004003d,0x0000001e,0x00000250,0x0000024a,0x0003003e,0x00000246,0x00000250,0x0004003d,
0x00000253,0x00000256,0x00000255,0x0004003d,0x0000001e,0x00000257,0x00000246,0x00050057,
0x0000009a,0x00000258,0x00000256,0x00000257,0x00050051,0x00000006,0x00000259,0x00000258,
0x00000000,0x0004003d,0x00000006,0x0000025a,0x00000243,0x00050085,0x00000006,0x0000025b,
0x00000259,0x0000025a,0x0003003e,0x00000251,0x0000025b,0x00060041,0x000000a2,0x0000025c,
0x0000009d,0x0000018f,0x000001e1,0x0004003d,0x00000006,0x0000025d,0x0000025c,0x000500ba,
0x00000099,0x0000025e,0x0000025d,0x00000026,0x000300f7,0x00000260,0x00000000,0x000400fa,
0x0000025e,0x0000025f,0x00000260,0x000200f8,0x0000025f,0x0004003d,0x00000253,0x00000262,
0x00000255,0x00040064,0x00000252,0x00000264,0x00000262,0x00050067,0x00000265,0x00000266,
0x00000264,0x00000263,0x0004006f,0x0000001e,0x00000267,0x00000266,0x00050050,0x0000001e,
0x00000268,0x00000027,0x00000027,0x00050088,0x0000001e,0x00000269,0x00000268,0x00000267,
0x0003003e,0x00000261,0x00000269,0x0003003e,0x0000026a,0x00000026,0x0003003e,0x0000026b,
0x0000026c,0x000200f9,0x0000026d,0x000200f8,0x0000026d,0x000400f6,0x0000026f,0x00000270,
0x00000000,0x000200f9,0x00000271,0x000200f8,0x00000271,0x0004003d,0x0000009e,0x00000272,
0x0000026b,0x000500b3,0x00000099,0x00000273,0x00000272,0x000001a9,0x000400fa,0x00000273,
0x0000026e,0x0000026f,0x000200f8,0x0000026e,0x0003003e,0x00000274,0x0000026c,0x000200f9,
0x00000275,0x000200f8,0x00000275,0x000400f6,0x00000277,0x00000278,0x00000000,0x000200f9,
0x00000279,0x000200f8,0x00000279,0x0004003d,0x0000009e,0x0000027a,0x00000274,0x000500b3,
0x00000099,0x0000027b,0x0000027a,0x000001a9,0x000400fa,0x0000027b,0x00000276,0x00000277,
0x000200f8,0x00000276,0x0004003d,0x0000009e,0x0000027c,0x00000274,0x000500ab,0x00000099,
0x0000027d,0x0000027c,0x00000263,0x0004003d,0x0000009e,0x0000027e,0x0000026b,0x000500ab,
0x00000099,0x0000027f,0x0000027e,0x00000263,0x000500a6,0x00000099,0x00000280,0x0000027d,
0x0000027f,0x000300f7,0x00000282,0x00000000,0x000400fa,0x00000280,0x00000281,0x00000282,
0x000200f8,0x00000281,0x0004003d,0x00000253,0x00000283,0x00000255,0x0004003d,0x0000001e,
0x00000284,0x00000246,0x0004003d,0x0000009e,0x00000285,0x00000274,0x0004006f,0x00000006,
0x00000286,0x00000285,0x0004003d,0x0000009e,0x00000287,0x0000026b,0x0004006f,0x00000006,
0x00000288,0x00000287,0x00050050,0x0000001e,0x00000289,0x00000286,0x00000288,0x0004003d,
0x0000001e,0x0000028a,0x00000261,0x00050085,0x0000001e,0x0000028b,0x00000289,0x0000028a,
0x00050081,0x0000001e,0x0000028c,0x00000284,0x0000028b,0x00050057,0x0000009a,0x0000028d,
0x00000283,0x0000028c,0x00050051,0x00000006,0x0000028e,0x0000028d,0x00000000,0x0004003d,
0x00000006,0x0000028f,0x0000026a,0x00050081,0x00000006,0x00000290,0x0000028f,0x0000028e,
0x0003003e,0x0000026a,0x00000290,0x000200f9,0x00000282,0x000200f8,0x00000282,0x000200f9,
0x00000278,0x000200f8,0x00000278,0x0004003d,0x0000009e,0x00000291,0x00000274,0x00050080,
0x0000009e,0x00000292,0x00000291,0x000001a9,0x0003003e,0x00000274,0x00000292,0x000200f9,
0x00000275,0x000200f8,0x00000277,0x000200f9,0x00000270,0x000200f8,0x00000270,0x0004003d,
0x0000009e,0x00000293,0x0000026b,0x00050080,0x0000009e,0x00000294,0x00000293,0x000001a9,
0x0003003e,0x0000026b,0x00000294,0x000200f9,0x0000026d,0x000200f8,0x0000026f,0x0004003d,
0x00000006,0x00000295,0x00000251,0x0004003d,0x00000006,0x00000296,0x00000251,0x0004003d,
0x00000006,0x00000297,0x0000026a,0x00050085,0x00000006,0x00000299,0x00000297,0x00000298,
0x0004003d,0x00000006,0x0000029a,0x00000243,0x00050085,0x00000006,0x0000029b,0x00000299,
0x0000029a,0x00050083,0x00000006,0x0000029c,0x00000296,0x0000029b,0x00060041,0x000000a2,
0x0000029d,0x0000009d,0x0000018f,0x000001e1,0x0004003d,0x00000006,0x0000029e,0x0000029d,
0x00050085,0x00000006,0x0000029f,0x0000029c,0x0000029e,0x00050081,0x00000006,0x000002a0,
0x00000295,0x0000029f,0x0008000c,0x00000006,0x000002a1,0x00000001,0x0000002b,0x000002a0,
0x00000026,0x00000027,0x0003003e,0x00000251,0x000002a1,0x000200f9,0x00000260,0x000200f8,
0x00000260,0x00060041,0x000000a2,0x000002a3,0x0000009d,0x0000009f,0x000001e1,0x0004003d,
0x00000006,0x000002a4,0x000002a3,0x000500ba,0x00000099,0x000002a5,0x000002a4,0x0000006c,
0x000300f7,0x000002a8,0x00000000,0x000400fa,0x000002a5,0x000002a7,0x000002ae,0x000200f8,
0x000002a7,0x0004003d,0x00000253,0x000002aa,0x000002a9,0x0004003d,0x0000001e,0x000002ab,
0x00000246,0x00050057,0x0000009a,0x000002ac,0x000002aa,0x000002ab,0x0007004f,0x0000001e,
0x000002ad,0x000002ac,0x000002ac,0x00000000,0x00000001,0x0003003e,0x000002a6,0x000002ad,
0x000200f9,0x000002a8,0x000200f8,0x000002ae,0x0004003d,0x00000253,0x000002af,0x000002a9,
0x0004003d,0x0000001e,0x000002b0,0x00000246,0x00050057,0x0000009a,0x000002b1,0x000002af,
0x000002b0,0x00050051,0x00000006,0x000002b2,0x000002b1,0x00000000,0x0004003d,0x00000253,
0x000002b4,0x000002b3,0x0004003d,0x0000001e,0x000002b5,0x00000246,0x00050057,0x0000009a,
0x000002b6,0x000002b4,0x000002b5,0x00050051,0x00000006,0x000002b7,0x000002b6,0x00000000,
0x00050050,0x0000001e,0x000002b8,0x000002b2,0x000002b7,0x0003003e,0x000002a6,0x000002b8,
0x000200f9,0x000002a8,0x000200f8,0x000002a8,0x0004003d,0x0000001e,0x000002b9,0x000002a6,
0x0003003e,0x000002a2,0x000002b9,0x00050041,0x0000000d,0x000002bb,0x000002a2,0x000000a1,
0x0004003d,0x00000006,0x000002bc,0x000002bb,0x0004003d,0x00000006,0x000002bd,0x00000243,
0x00050085,0x00000006,0x000002be,0x000002bc,0x000002bd,0x00050083,0x00000006,0x000002bf,
0x000002be,0x0000006c,0x0003003e,0x000002ba,0x000002bf,0x00050041,0x0000000d,0x000002c1,
0x000002a2,0x00000100,0x0004003d,0x00000006,0x000002c2,0x000002c1,0x0004003d,0x00000006,
0x000002c3,0x00000243,0x00050085,0x00000006,0x000002c4,0x000002c2,0x000002c3,0x00050083,
0x00000006,0x000002c5,0x000002c4,0x0000006c,0x0003003e,0x000002c0,0x000002c5,0x00060041,
0x000000a2,0x000002c6,0x0000009d,0x000001c2,0x00000100,0x0004003d,0x00000006,0x000002c7,
0x000002c6,0x000500ba,0x00000099,0x000002c8,0x000002c7,0x0000006c,0x000300f7,0x000002ca,
0x00000000,0x000400fa,0x000002c8,0x000002c9,0x000002ca,0x000200f8,0x000002c9,0x0004003d,
0x00000006,0x000002cb,0x00000251,0x00050083,0x00000006,0x000002cd,0x000002cb,0x000002cc,
0x00050085,0x00000006,0x000002cf,0x000002cd,0x000002ce,0x0003003e,0x00000251,0x000002cf,
0x0004003d,0x00000006,0x000002d1,0x000002ba,0x00050085,0x00000006,0x000002d2,0x000002d1,
0x000002d0,0x0003003e,0x000002ba,0x000002d2,0x0004003d,0x00000006,0x000002d3,0x000002c0,
0x00050085,0x00000006,0x000002d4,0x000002d3,0x000002d0,0x0003003e,0x000002c0,0x000002d4,
0x000200f9,0x000002ca,0x000200f8,0x000002ca,0x0004003d,0x00000006,0x000002d5,0x00000251,
0x00050083,0x00000006,0x000002d6,0x000002d5,0x0000006c,0x00060041,0x000000a2,0x000002d8,
0x0000009d,0x000002d7,0x00000100,0x0004003d,0x00000006,0x000002d9,0x000002d8,0x00050085,
0x00000006,0x000002da,0x000002d6,0x000002d9,0x00050081,0x00000006,0x000002db,0x000002da,
0x0000006c,0x00060041,0x000000a2,0x000002dc,0x0000009d,0x000002d7,0x000000a1,0x0004003d,
0x00000006,0x000002dd,0x000002dc,0x00050081,0x00000006,0x000002de,0x000002db,0x000002dd,
0x0003003e,0x00000251,0x000002de,0x00060041,0x000000a2,0x000002e0,0x0000009d,0x000001c2,
0x000000af,0x0004003d,0x00000006,0x000002e1,0x000002e0,0x0006000c,0x00000006,0x000002e2,
0x00000001,0x0000000e,0x000002e1,0x0003003e,0x000002df,0x000002e2,0x00060041,0x000000a2,
0x000002e4,0x0000009d,0x000001c2,0x000000af,0x0004003d,0x00000006,0x000002e5,0x000002e4,
0x0006000c,0x00000006,0x000002e6,0x00000001,0x0000000d,0x000002e5,0x0003003e,0x000002e3,
0x000002e6,0x0004003d,0x00000006,0x000002e8,0x000002ba,0x0004003d,0x00000006,0x000002e9,
0x000002df,0x00050085,0x00000006,0x000002ea,0x000002e8,0x000002e9,0x0004003d,0x00000006,
0x000002eb,0x000002c0,0x0004003d,0x00000006,0x000002ec,0x000002e3,0x00050085,0x00000006,
0x000002ed,0x000002eb,0x000002ec,0x00050083,0x00000006,0x000002ee,0x000002ea,0x000002ed,
0x0004003d,0x00000006,0x000002ef,0x000002ba,0x0004003d,0x00000006,0x000002f0,0x000002e3,
0x00050085,0x00000006,0x000002f1,0x000002ef,0x000002f0,0x0004003d,0x00000006,0x000002f2,
0x000002c0,0x0004003d,0x00000006,0x000002f3,0x000002df,0x00050085,0x00000006,0x000002f4,
0x000002f2,0x000002f3,0x00050081,0x00000006,0x000002f5,0x000002f1,0x000002f4,0x00050050,
0x0000001e,0x000002f6,0x000002ee,0x000002f5,0x00060041,0x000000a2,0x000002f7,0x0000009d,
0x000002d7,0x000000af,0x0004003d,0x00000006,0x000002f8,0x000002f7,0x0005008e,0x0000001e,
0x000002f9,0x000002f6,0x000002f8,0x0003003e,0x000002e7,0x000002f9,0x0004003d,0x00000006,
0x000002fb,0x00000251,0x0004003d,0x0000001e,0x000002fc,0x000002e7,0x00050051,0x00000006,
0x000002fd,0x000002fc,0x00000000,0x00050051,0x00000006,0x000002fe,0x000002fc,0x00000001,
0x00060050,0x00000007,0x000002ff,0x000002fb,0x000002fd,0x000002fe,0x0003003e,0x000002fa,
0x000002ff,0x00050041,0x00000301,0x00000302,0x0000009d,0x00000263,0x0004003d,0x0000009a,
0x00000303,0x00000302,0x0008004f,0x00000007,0x00000304,0x00000303,0x00000303,0x00000000,
0x00000001,0x00000002,0x0004003d,0x00000007,0x00000305,0x000002fa,0x00050094,0x00000006,
0x00000306,0x00000304,0x00000305,0x00050041,0x00000301,0x00000307,0x0000009d,0x000001a9,
0x0004003d,0x0000009a,0x00000308,0x00000307,0x0008004f,0x00000007,0x00000309,0x00000308,
0x00000308,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000007,0x0000030a,0x000002fa,
0x00050094,0x00000006,0x0000030b,0x00000309,0x0000030a,0x00050041,0x00000301,0x0000030c,
0x0000009d,0x000001b5,0x0004003d,0x0000009a,0x0000030d,0x0000030c,0x0008004f,0x00000007,
0x0000030e,0x0000030d,0x0000030d,0x00000000,0x00000001,0x00000002,0x0004003d,0x00000007,
0x0000030f,0x000002fa,0x00050094,0x00000006,0x00000310,0x0000030e,0x0000030f,0x00060050,
0x00000007,0x00000311,0x00000306,0x0000030b,0x00000310,0x00060050,0x00000007,0x00000312,
0x00000026,0x00000026,0x00000026,0x00060050,0x00000007,0x00000313,0x00000027,0x00000027,
0x00000027,0x0008000c,0x00000007,0x00000314,0x00000001,0x0000002b,0x00000311,0x00000312,
0x00000313,0x0003003e,0x00000300,0x00000314,0x00060041,0x000000a2,0x00000316,0x0000009d,
0x00000315,0x000000a1,0x0004003d,0x00000006,0x00000317,0x00000316,0x000500ba,0x00000099,
0x00000318,0x00000317,0x0000006c,0x000300f7,0x0000031a,0x00000000,0x000400fa,0x00000318,
0x00000319,0x0000031a,0x000200f8,0x00000319,0x0004003d,0x00000007,0x0000031e,0x00000300,
0x0003003e,0x0000031d,0x0000031e,0x00050039,0x00000007,0x0000031f,0x00000019,0x0000031d,
0x00050051,0x00000006,0x00000320,0x0000031f,0x00000000,0x00050051,0x00000006,0x00000321,
0x0000031f,0x00000001,0x00050051,0x00000006,0x00000322,0x0000031f,0x00000002,0x00070050,
0x0000009a,0x00000323,0x00000320,0x00000321,0x00000322,0x00000027,0x0003003e,0x0000031c,
0x00000323,0x000100fd,0x000200f8,0x0000031a,0x00060041,0x000000a2,0x00000325,0x0000009d,
0x0000009f,0x000000a1,0x0004003d,0x00000006,0x00000326,0x00000325,0x000500ba,0x00000099,
0x00000327,0x00000326,0x0000006c,0x000300f7,0x00000329,0x00000000,0x000400fa,0x00000327,
0x00000328,0x00000329,0x000200f8,0x00000328,0x0004003d,0x00000007,0x0000032b,0x00000300,
0x0003003e,0x0000032a,0x0000032b,0x00050039,0x00000007,0x0000032c,0x0000001c,0x0000032a,
0x0003003e,0x00000300,0x0000032c,0x000200f9,0x00000329,0x000200f8,0x00000329,0x0004003d,
0x00000007,0x0000032d,0x00000300,0x00060041,0x000000a2,0x0000032e,0x0000009d,0x000002d7,
0x000001e1,0x0004003d,0x00000006,0x0000032f,0x0000032e,0x00060050,0x00000007,0x00000330,
0x0000032f,0x0000032f,0x0000032f,0x0007000c,0x00000007,0x00000331,0x00000001,0x0000001a,
0x0000032d,0x00000330,0x00050051,0x00000006,0x00000332,0x00000331,0x00000000,0x00050051,
0x00000006,0x00000333,0x00000331,0x00000001,0x00050051,0x00000006,0x00000334,0x00000331,
0x00000002,0x00070050,0x0000009a,0x00000335,0x00000332,0x00000333,0x00000334,0x00000027,
0x0003003e,0x0000031c,0x00000335,0x000100fd,0x00010038,0x00050036,0x00000007,0x0000000b,
0x00000000,0x00000009,0x00030037,0x00000008,0x0000000a,0x000200f8,0x0000000c,0x0004003b,
0x00000008,0x00000024,0x00000007,0x0004003d,0x00000007,0x00000025,0x0000000a,0x00060050,
0x00000007,0x00000028,0x00000026,0x00000026,0x00000026,0x00060050,0x00000007,0x00000029,
0x00000027,0x00000027,0x00000027,0x0008000c,0x00000007,0x0000002a,0x00000001,0x0000002b,
0x00000025,0x00000028,0x00000029,0x0007000c,0x00000007,0x0000002d,0x00000001,0x0000001a,
0x0000002a,0x0000002c,0x0003003e,0x00000024,0x0000002d,0x0004003d,0x00000007,0x0000002f,
0x00000024,0x00060050,0x00000007,0x00000031,0x00000030,0x00000030,0x00000030,0x00050083,
0x00000007,0x00000032,0x0000002f,0x00000031,0x00060050,0x00000007,0x00000033,0x00000026,
0x00000026,0x00000026,0x0007000c,0x00000007,0x00000034,0x00000001,0x00000028,0x00000032,
0x00000033,0x0004003d,0x00000007,0x00000037,0x00000024,0x0005008e,0x00000007,0x00000038,
0x00000037,0x00000036,0x00060050,0x00000007,0x00000039,0x00000035,0x00000035,0x00000035,
0x00050083,0x00000007,0x0000003a,0x00000039,0x00000038,0x00050088,0x00000007,0x0000003b,
0x00000034,0x0000003a,0x0007000c,0x00000007,0x0000003e,0x00000001,0x0000001a,0x0000003b,
0x0000003d,0x0005008e,0x00000007,0x0000003f,0x0000003e,0x0000002e,0x000200fe,0x0000003f,
0x00010038,0x00050036,0x00000006,0x00000010,0x00000000,0x0000000e,0x00030037,0x0000000d,
0x0000000f,0x000200f8,0x00000011,0x0004003b,0x0000000d,0x00000042,0x00000007,0x0004003d,
0x00000006,0x00000043,0x0000000f,0x00050088,0x00000006,0x00000044,0x00000043,0x0000002e,
0x0008000c,0x00000006,0x00000045,0x00000001,0x0000002b,0x00000044,0x00000026,0x00000027,
0x0007000c,0x00000006,0x00000047,0x00000001,0x0000001a,0x00000045,0x00000046,0x0003003e,
0x00000042,0x00000047,0x0004003d,0x00000006,0x00000048,0x00000042,0x00050085,0x00000006,
0x00000049,0x00000035,0x00000048,0x00050081,0x00000006,0x0000004a,0x00000030,0x00000049,
0x0004003d,0x00000006,0x0000004b,0x00000042,0x00050085,0x00000006,0x0000004c,0x00000036,
0x0000004b,0x00050081,0x00000006,0x0000004d,0x00000027,0x0000004c,0x00050088,0x00000006,
0x0000004e,0x0000004a,0x0000004d,0x0007000c,0x00000006,0x00000050,0x00000001,0x0000001a,
0x0000004e,0x0000004f,0x000200fe,0x00000050,0x00010038,0x00050036,0x00000007,0x00000013,
0x00000000,0x00000009,0x00030037,0x00000008,0x00000012,0x000200f8,0x00000014,0x0004003b,
0x00000008,0x00000057,0x00000007,0x0004003b,0x0000000d,0x00000071,0x00000007,0x0004003d,
0x00000007,0x00000053,0x00000012,0x00060050,0x00000007,0x00000054,0x00000026,0x00000026,
0x00000026,0x00060050,0x00000007,0x00000055,0x00000027,0x00000027,0x00000027,0x0008000c,
0x00000007,0x00000056,0x00000001,0x0000002b,0x00000053,0x00000054,0x00000055,0x0003003e,
0x00000012,0x00000056,0x0004003d,0x00000007,0x00000058,0x00000012,0x0004003d,0x00000007,
0x00000059,0x00000012,0x00050085,0x00000007,0x0000005a,0x00000058,0x00000059,0x00060050,
0x00000007,0x0000005c,0x0000005b,0x0000005b,0x0000005b,0x00050088,0x00000007,0x0000005d,
0x0000005a,0x0000005c,0x0004003d,0x00000007,0x0000005e,0x00000012,0x00060050,0x00000007,
0x00000060,0x0000005f,0x0000005f,0x0000005f,0x00050083,0x00000007,0x00000061,0x0000005e,
0x00000060,0x00060050,0x00000007,0x00000063,0x00000062,0x00000062,0x00000062,0x00050088,
0x00000007,0x00000064,0x00000061,0x00000063,0x0006000c,0x00000007,0x00000065,0x00000001,
0x0000001b,0x00000064,0x00060050,0x00000007,0x00000067,0x00000066,0x00000066,0x00000066,
0x00050081,0x00000007,0x00000068,0x00000065,0x00000067,0x00060050,0x00000007,0x0000006a,
0x00000069,0x00000069,0x00000069,0x00050088,0x00000007,0x0000006b,0x00000068,0x0000006a,
0x0004003d,0x00000007,0x0000006e,0x00000012,0x0007000c,0x00000007,0x0000006f,0x00000001,
0x00000030,0x0000006d,0x0000006e,0x0008000c,0x00000007,0x00000070,0x00000001,0x0000002e,
0x0000005d,0x0000006b,0x0000006f,0x0003003e,0x00000057,0x00000070,0x0004003d,0x00000007,
0x00000072,0x00000057,0x00050094,0x00000006,0x00000077,0x00000072,0x00000076,0x0007000c,
0x00000006,0x00000079,0x00000001,0x00000028,0x00000077,0x00000078,0x0003003e,0x00000071,
0x00000079,0x0004003d,0x00000006,0x0000007b,0x00000071,0x0007000c,0x00000006,0x0000007d,
0x00000001,0x0000001a,0x0000007b,0x0000007c,0x00050085,0x00000006,0x0000007e,0x0000007a,
0x0000007d,0x0004003d,0x00000007,0x0000007f,0x00000057,0x0005008e,0x00000007,0x00000080,
0x0000007f,0x0000007e,0x000200fe,0x00000080,0x00010038,0x00050036,0x00000007,0x00000016,
0x00000000,0x00000009,0x00030037,0x00000008,0x00000015,0x000200f8,0x00000017,0x0004003b,
0x00000008,0x00000083,0x00000007,0x0004003d,0x00000007,0x00000084,0x00000015,0x00060050,
0x00000007,0x00000085,0x0000002e,0x0000002e,0x0000002e,0x00050088,0x00000007,0x00000086,
0x00000084,0x00000085,0x00060050,0x00000007,0x00000087,0x00000026,0x00000026,0x00000026,
0x00060050,0x00000007,0x00000088,0x00000027,0x00000027,0x00000027,0x0008000c,0x00000007,
0x00000089,0x00000001,0x0000002b,0x00000086,0x00000087,0x00000088,0x0007000c,0x00000007,
0x0000008b,0x00000001,0x0000001a,0x00000089,0x0000008a,0x0003003e,0x00000083,0x0000008b,
0x0004003d,0x00000007,0x0000008c,0x00000083,0x0005008e,0x00000007,0x0000008d,0x0000008c,
0x00000035,0x00060050,0x00000007,0x0000008e,0x00000030,0x00000030,0x00000030,0x00050081,
0x00000007,0x0000008f,0x0000008e,0x0000008d,0x0004003d,0x00000007,0x00000090,0x00000083,
0x0005008e,0x00000007,0x00000091,0x00000090,0x00000036,0x00060050,0x00000007,0x00000092,
0x00000027,0x00000027,0x00000027,0x00050081,0x00000007,0x00000093,0x00000092,0x00000091,
0x00050088,0x00000007,0x00000094,0x0000008f,0x00000093,0x0007000c,0x00000007,0x00000096,
0x00000001,0x0000001a,0x00000094,0x00000095,0x000200fe,0x00000096,0x00010038,0x00050036,
0x00000007,0x00000019,0x00000000,0x00000009,0x00030037,0x00000008,0x00000018,0x000200f8,
0x0000001a,0x0004003b,0x00000008,0x000000bd,0x00000007,0x0004003b,0x00000008,0x000000c1,
0x00000007,0x0004003b,0x00000008,0x000000c4,0x00000007,0x0004003b,0x00000008,0x000000c8,
0x00000007,0x0004003b,0x00000008,0x000000eb,0x00000007,0x00060041,0x000000a2,0x000000a3,
0x0000009d,0x0000009f,0x000000a1,0x0004003d,0x00000006,0x000000a4,0x000000a3,0x000500ba,
0x00000099,0x000000a5,0x000000a4,0x0000006c,0x000300f7,0x000000a7,0x00000000,0x000400fa,
0x000000a5,0x000000a6,0x000000a7,0x000200f8,0x000000a6,0x00060041,0x000000a2,0x000000a8,
0x0000009d,0x0000009f,0x000000a1,0x0004003d,0x00000006,0x000000a9,0x000000a8,0x000500b8,
0x00000099,0x000000ab,0x000000a9,0x000000aa,0x000200f9,0x000000a7,0x000200f8,0x000000a7,
0x000700f5,0x00000099,0x000000ac,0x000000a5,0x0000001a,0x000000ab,0x000000a6,0x000300f7,
0x000000ae,0x00000000,0x000400fa,0x000000ac,0x000000ad,0x000000ae,0x000200f8,0x000000ad,
0x00060041,0x000000a2,0x000000b0,0x0000009d,0x0000009f,0x000000af,0x0004003d,0x00000006,
0x000000b1,0x000000b0,0x000500ba,0x00000099,0x000000b2,0x000000b1,0x0000006c,0x000200f9,
0x000000ae,0x000200f8,0x000000ae,0x000700f5,0x00000099,0x000000b3,0x000000ac,0x000000a7,
0x000000b2,0x000000ad,0x000300f7,0x000000b5,0x00000000,0x000400fa,0x000000b3,0x000000b4,
0x000000b5,0x000200f8,0x000000b4,0x0004003d,0x00000007,0x000000b6,0x00000018,0x000200fe,
0x000000b6,0x000200f8,0x000000b5,0x00060041,0x000000a2,0x000000b8,0x0000009d,0x0000009f,
0x000000a1,0x0004003d,0x00000006,0x000000b9,0x000000b8,0x000500ba,0x00000099,0x000000ba,
0x000000b9,0x0000006c,0x000300f7,0x000000bc,0x00000000,0x000400fa,0x000000ba,0x000000bb,
0x000000cc,0x000200f8,0x000000bb,0x00060041,0x000000a2,0x000000be,0x0000009d,0x0000009f,
0x000000a1,0x0004003d,0x00000006,0x000000bf,0x000000be,0x000500b8,0x00000099,0x000000c0,
0x000000bf,0x000000aa,0x000300f7,0x000000c3,0x00000000,0x000400fa,0x000000c0,0x000000c2,
0x000000c7,0x000200f8,0x000000c2,0x0004003d,0x00000007,0x000000c5,0x00000018,0x0003003e,
0x000000c4,0x000000c5,0x00050039,0x00000007,0x000000c6,0x0000000b,0x000000c4,0x0003003e,
0x000000c1,0x000000c6,0x000200f9,0x000000c3,0x000200f8,0x000000c7,0x0004003d,0x00000007,
0x000000c9,0x00000018,0x0003003e,0x000000c8,0x000000c9,0x00050039,0x00000007,0x000000ca,
0x00000013,0x000000c8,0x0003003e,0x000000c1,0x000000ca,0x000200f9,0x000000c3,0x000200f8,
0x000000c3,0x0004003d,0x00000007,0x000000cb,0x000000c1,0x0003003e,0x000000bd,0x000000cb,
0x000200f9,0x000000bc,0x000200f8,0x000000cc,0x0004003d,0x00000007,0x000000cd,0x00000018,
0x00060050,0x00000007,0x000000ce,0x00000026,0x00000026,0x00000026,0x00060050,0x00000007,
0x000000cf,0x00000027,0x00000027,0x00000027,0x0008000c,0x00000007,0x000000d0,0x00000001,
0x0000002b,0x000000cd,0x000000ce,0x000000cf,0x0007000c,0x00000007,0x000000d3,0x00000001,
0x0000001a,0x000000d0,0x000000d2,0x0005008e,0x00000007,0x000000d5,0x000000d3,0x000000d4,
0x0003003e,0x000000bd,0x000000d5,0x000200f9,0x000000bc,0x000200f8,0x000000bc,0x00060041,
0x000000a2,0x000000d6,0x0000009d,0x0000009f,0x000000af,0x0004003d,0x00000006,0x000000d7,
0x000000d6,0x000500b8,0x00000099,0x000000d8,0x000000d7,0x0000006c,0x000300f7,0x000000da,
0x00000000,0x000400fa,0x000000d8,0x000000d9,0x000000da,0x000200f8,0x000000d9,0x0004003d,
0x00000007,0x000000e9,0x000000bd,0x00050091,0x00000007,0x000000ea,0x000000e8,0x000000e9,
0x0003003e,0x000000bd,0x000000ea,0x000200f9,0x000000da,0x000200f8,0x000000da,0x0004003d,
0x00000007,0x000000ec,0x000000bd,0x0003003e,0x000000eb,0x000000ec,0x00050039,0x00000007,
0x000000ed,0x00000016,0x000000eb,0x000200fe,0x000000ed,0x00010038,0x00050036,0x00000007,
0x0000001c,0x00000000,0x00000009,0x00030037,0x00000008,0x0000001b,0x000200f8,0x0000001d,
0x0004003b,0x00000008,0x000000f0,0x00000007,0x0004003b,0x00000008,0x000000f4,0x00000007,
0x0004003b,0x00000008,0x000000f7,0x00000007,0x0004003b,0x00000008,0x000000fb,0x00000007,
0x0004003b,0x0000000d,0x000000ff,0x00000007,0x0004003b,0x0000000d,0x00000103,0x00000007,
0x0004003b,0x0000000d,0x00000113,0x00000007,0x0004003b,0x0000000d,0x00000114,0x00000007,
0x0004003b,0x0000000d,0x00000117,0x00000007,0x0004003b,0x0000000d,0x00000118,0x00000007,
0x0004003b,0x0000000d,0x0000011e,0x00000007,0x0004003b,0x0000000d,0x0000011f,0x00000007,
0x0004003b,0x0000000d,0x00000123,0x00000007,0x0004003b,0x0000000d,0x00000127,0x00000007,
0x0004003b,0x0000000d,0x0000012e,0x00000007,0x0004003b,0x0000000d,0x00000135,0x00000007,
0x0004003b,0x0000000d,0x00000139,0x00000007,0x0004003b,0x00000008,0x0000015d,0x00000007,
0x0004003b,0x00000008,0x00000164,0x00000007,0x00060041,0x000000a2,0x000000f1,0x0000009d,
0x0000009f,0x000000a1,0x0004003d,0x00000006,0x000000f2,0x000000f1,0x000500b8,0x00000099,
0x000000f3,0x000000f2,0x000000aa,0x000300f7,0x000000f6,0x00000000,0x000400fa,0x000000f3,
0x000000f5,0x000000fa,0x000200f8,0x000000f5,0x0004003d,0x00000007,0x000000f8,0x0000001b,
0x0003003e,0x000000f7,0x000000f8,0x00050039,0x00000007,0x000000f9,0x0000000b,0x000000f7,
0x0003003e,0x000000f4,0x000000f9,0x000200f9,0x000000f6,0x000200f8,0x000000fa,0x0004003d,
0x00000007,0x000000fc,0x0000001b,0x0003003e,0x000000fb,0x000000fc,0x00050039,0x00000007,
0x000000fd,0x00000013,0x000000fb,0x0003003e,0x000000f4,0x000000fd,0x000200f9,0x000000f6,
0x000200f8,0x000000f6,0x0004003d,0x00000007,0x000000fe,0x000000f4,0x0003003e,0x000000f0,
0x000000fe,0x00060041,0x000000a2,0x00000101,0x0000009d,0x0000009f,0x00000100,0x0004003d,
0x00000006,0x00000102,0x00000101,0x0003003e,0x000000ff,0x00000102,0x00050041,0x0000000d,
0x00000104,0x000000f0,0x000000a1,0x0004003d,0x00000006,0x00000105,0x00000104,0x00050041,
0x0000000d,0x00000106,0x000000f0,0x00000100,0x0004003d,0x00000006,0x00000107,0x00000106,
0x00050041,0x0000000d,0x00000108,0x000000f0,0x000000af,0x0004003d,0x00000006,0x00000109,
0x00000108,0x0007000c,0x00000006,0x0000010a,0x00000001,0x00000028,0x00000107,0x00000109,
0x0007000c,0x00000006,0x0000010b,0x00000001,0x00000028,0x00000105,0x0000010a,0x0003003e,
0x00000103,0x0000010b,0x0004003d,0x00000006,0x0000010c,0x00000103,0x000500ba,0x00000099,
0x0000010d,0x0000010c,0x00000026,0x0004003d,0x00000006,0x0000010e,0x000000ff,0x000500ba,
0x00000099,0x0000010f,0x0000010e,0x000000d4,0x000500a7,0x00000099,0x00000110,0x0000010d,
0x0000010f,0x000300f7,0x00000112,0x00000000,0x000400fa,0x00000110,0x00000111,0x00000112,
0x000200f8,0x00000111,0x0004003d,0x00000006,0x00000115,0x000000ff,0x0003003e,0x00000114,
0x00000115,0x00050039,0x00000006,0x00000116,0x00000010,0x00000114,0x0003003e,0x00000113,
0x00000116,0x0004003d,0x00000006,0x00000119,0x00000103,0x0003003e,0x00000118,0x00000119,
0x00050039,0x00000006,0x0000011a,0x00000010,0x00000118,0x0004003d,0x00000006,0x0000011b,
0x00000113,0x00050088,0x00000006,0x0000011c,0x0000011a,0x0000011b,0x0007000c,0x00000006,
0x0000011d,0x00000001,0x00000025,0x0000011c,0x00000027,0x0003003e,0x00000117,0x0000011d,
0x0003003e,0x0000011f,0x000000d4,0x00050039,0x00000006,0x00000120,0x00000010,0x0000011f,
0x0004003d,0x00000006,0x00000121,0x00000113,0x00050088,0x00000006,0x00000122,0x00000120,
0x00000121,0x0003003e,0x0000011e,0x00000122,0x0004003d,0x00000006,0x00000124,0x0000011e,
0x00050085,0x00000006,0x00000125,0x000000aa,0x00000124,0x00050083,0x00000006,0x00000126,
0x00000125,0x0000006c,0x0003003e,0x00000123,0x00000126,0x0004003d,0x00000006,0x00000128,
0x00000117,0x0003003e,0x00000127,0x00000128,0x0004003d,0x00000006,0x00000129,0x00000117,
0x0004003d,0x00000006,0x0000012a,0x00000123,0x000500ba,0x00000099,0x0000012b,0x00000129,
0x0000012a,0x000300f7,0x0000012d,0x00000000,0x000400fa,0x0000012b,0x0000012c,0x0000012d,
0x000200f8,0x0000012c,0x0004003d,0x00000006,0x0000012f,0x00000117,0x0004003d,0x00000006,
0x00000130,0x00000123,0x00050083,0x00000006,0x00000131,0x0000012f,0x00000130,0x0004003d,
0x00000006,0x00000132,0x00000123,0x00050083,0x00000006,0x00000133,0x00000027,0x00000132,
0x00050088,0x00000006,0x00000134,0x00000131,0x00000133,0x0003003e,0x0000012e,0x00000134,
0x0004003d,0x00000006,0x00000136,0x0000012e,0x0004003d,0x00000006,0x00000137,0x0000012e,
0x00050085,0x00000006,0x00000138,0x00000136,0x00000137,0x0003003e,0x00000135,0x00000138,
0x0004003d,0x00000006,0x0000013a,0x00000135,0x0004003d,0x00000006,0x0000013b,0x0000012e,
0x00050085,0x00000006,0x0000013c,0x0000013a,0x0000013b,0x0003003e,0x00000139,0x0000013c,
0x0004003d,0x00000006,0x0000013e,0x00000139,0x00050085,0x00000006,0x0000013f,0x0000013d,
0x0000013e,0x0004003d,0x00000006,0x00000140,0x00000135,0x00050085,0x00000006,0x00000141,
0x0000005b,0x00000140,0x00050083,0x00000006,0x00000142,0x0000013f,0x00000141,0x00050081,
0x00000006,0x00000143,0x00000142,0x00000027,0x0004003d,0x00000006,0x00000144,0x00000123,
0x00050085,0x00000006,0x00000145,0x00000143,0x00000144,0x0004003d,0x00000006,0x00000146,
0x00000139,0x0004003d,0x00000006,0x00000147,0x00000135,0x00050085,0x00000006,0x00000148,
0x0000013d,0x00000147,0x00050083,0x00000006,0x00000149,0x00000146,0x00000148,0x0004003d,
0x00000006,0x0000014a,0x0000012e,0x00050081,0x00000006,0x0000014b,0x00000149,0x0000014a,
0x0004003d,0x00000006,0x0000014c,0x00000123,0x00050083,0x00000006,0x0000014d,0x00000027,
0x0000014c,0x00050085,0x00000006,0x0000014e,0x0000014b,0x0000014d,0x00050081,0x00000006,
0x0000014f,0x00000145,0x0000014e,0x0004003d,0x00000006,0x00000151,0x00000139,0x00050085,
0x00000006,0x00000152,0x00000150,0x00000151,0x0004003d,0x00000006,0x00000153,0x00000135,
0x00050085,0x00000006,0x00000154,0x0000005b,0x00000153,0x00050081,0x00000006,0x00000155,
0x00000152,0x00000154,0x0004003d,0x00000006,0x00000156,0x0000011e,0x00050085,0x00000006,
0x00000157,0x00000155,0x00000156,0x00050081,0x00000006,0x00000158,0x0000014f,0x00000157,
0x0003003e,0x00000127,0x00000158,0x000200f9,0x0000012d,0x000200f8,0x0000012d,0x0004003d,
0x00000006,0x00000159,0x00000127,0x0004003d,0x00000006,0x0000015a,0x00000113,0x00050085,
0x00000006,0x0000015b,0x00000159,0x0000015a,0x00060050,0x00000007,0x0000015c,0x0000015b,
0x0000015b,0x0000015b,0x0003003e,0x0000015d,0x0000015c,0x00050039,0x00000007,0x0000015e,
0x0000000b,0x0000015d,0x00050051,0x00000006,0x0000015f,0x0000015e,0x00000000,0x0004003d,
0x00000006,0x00000160,0x00000103,0x00050088,0x00000006,0x00000161,0x0000015f,0x00000160,
0x0004003d,0x00000007,0x00000162,0x000000f0,0x0005008e,0x00000007,0x00000163,0x00000162,
0x00000161,0x0003003e,0x000000f0,0x00000163,0x000200f9,0x00000112,0x000200f8,0x00000112,
0x0004003d,0x00000007,0x00000165,0x000000f0,0x00060050,0x00000007,0x00000166,0x000000d4,
0x000000d4,0x000000d4,0x00050088,0x00000007,0x00000167,0x00000165,0x00000166,0x0003003e,
0x00000164,0x00000167,0x00060041,0x000000a2,0x00000168,0x0000009d,0x0000009f,0x000000af,
0x0004003d,0x00000006,0x00000169,0x00000168,0x000500ba,0x00000099,0x0000016a,0x00000169,
0x0000006c,0x000300f7,0x0000016c,0x00000000,0x000400fa,0x0000016a,0x0000016b,0x0000016c,
0x000200f8,0x0000016b,0x0004003d,0x00000007,0x0000017a,0x00000164,0x00050091,0x00000007,
0x0000017b,0x00000179,0x0000017a,0x0003003e,0x00000164,0x0000017b,0x000200f9,0x0000016c,
0x000200f8,0x0000016c,0x0004003d,0x00000007,0x0000017c,0x00000164,0x00060050,0x00000007,
0x0000017d,0x00000026,0x00000026,0x00000026,0x00060050,0x00000007,0x0000017e,0x00000027,
0x00000027,0x00000027,0x0008000c,0x00000007,0x0000017f,0x00000001,0x0000002b,0x0000017c,
0x0000017d,0x0000017e,0x0007000c,0x00000007,0x00000182,0x00000001,0x0000001a,0x0000017f,
0x00000181,0x000200fe,0x00000182,0x00010038,0x00050036,0x0000001e,0x00000020,0x00000000,
0x0000001f,0x000200f8,0x00000021,0x0004003b,0x00000185,0x00000186,0x00000007,0x0004003b,
0x000001a2,0x000001a3,0x00000007,0x0004003d,0x0000001e,0x00000189,0x00000188,0x00050041,
0x0000018b,0x0000018c,0x0000009d,0x0000018a,0x0004003d,0x0000001e,0x0000018d,0x0000018c,
0x00050088,0x0000001e,0x0000018e,0x00000189,0x0000018d,0x0003003e,0x00000186,0x0000018e,
0x00060041,0x000000a2,0x00000190,0x0000009d,0x0000018f,0x00000100,0x0004003d,0x00000006,
0x00000191,0x00000190,0x000500ba,0x00000099,0x00000192,0x00000191,0x0000006c,0x000300f7,
0x00000194,0x00000000,0x000400fa,0x00000192,0x00000193,0x00000194,0x000200f8,0x00000193,
0x00050041,0x0000000d,0x00000195,0x00000186,0x000000a1,0x0004003d,0x00000006,0x00000196,
0x00000195,0x00050083,0x00000006,0x00000197,0x00000027,0x00000196,0x00050041,0x0000000d,
0x00000198,0x00000186,0x000000a1,0x0003003e,0x00000198,0x00000197,0x000200f9,0x00000194,
0x000200f8,0x00000194,0x00060041,0x000000a2,0x00000199,0x0000009d,0x0000018f,0x000000af,
0x0004003d,0x00000006,0x0000019a,0x00000199,0x000500ba,0x00000099,0x0000019b,0x0000019a,
0x0000006c,0x000300f7,0x0000019d,0x00000000,0x000400fa,0x0000019b,0x0000019c,0x0000019d,
0x000200f8,0x0000019c,0x00050041,0x0000000d,0x0000019e,0x00000186,0x00000100,0x0004003d,
0x00000006,0x0000019f,0x0000019e,0x00050083,0x00000006,0x000001a0,0x00000027,0x0000019f,
0x00050041,0x0000000d,0x000001a1,0x00000186,0x00000100,0x0003003e,0x000001a1,0x000001a0,
0x000200f9,0x0000019d,0x000200f8,0x0000019d,0x00060041,0x000000a2,0x000001a4,0x0000009d,
0x0000018f,0x000000a1,0x0004003d,0x00000006,0x000001a5,0x000001a4,0x00050081,0x00000006,
0x000001a6,0x000001a5,0x0000006c,0x0004006e,0x0000009e,0x000001a7,0x000001a6,0x0003003e,
0x000001a3,0x000001a7,0x0004003d,0x0000009e,0x000001a8,0x000001a3,0x000500aa,0x00000099,
0x000001aa,0x000001a8,0x000001a9,0x000300f7,0x000001ac,0x00000000,0x000400fa,0x000001aa,
0x000001ab,0x000001b3,0x000200f8,0x000001ab,0x00050041,0x0000000d,0x000001ad,0x00000186,
0x00000100,0x0004003d,0x00000006,0x000001ae,0x000001ad,0x00050041,0x0000000d,0x000001af,
0x00000186,0x000000a1,0x0004003d,0x00000006,0x000001b0,0x000001af,0x00050083,0x00000006,
0x000001b1,0x00000027,0x000001b0,0x00050050,0x0000001e,0x000001b2,0x000001ae,0x000001b1,
0x0003003e,0x00000186,0x000001b2,0x000200f9,0x000001ac,0x000200f8,0x000001b3,0x0004003d,
0x0000009e,0x000001b4,0x000001a3,0x000500aa,0x00000099,0x000001b6,0x000001b4,0x000001b5,
0x000300f7,0x000001b8,0x00000000,0x000400fa,0x000001b6,0x000001b7,0x000001c0,0x000200f8,
0x000001b7,0x00050041,0x0000000d,0x000001b9,0x00000186,0x000000a1,0x0004003d,0x00000006,
0x000001ba,0x000001b9,0x00050083,0x00000006,0x000001bb,0x00000027,0x000001ba,0x00050041,
0x0000000d,0x000001bc,0x00000186,0x00000100,0x0004003d,0x00000006,0x000001bd,0x000001bc,
0x00050083,0x00000006,0x000001be,0x00000027,0x000001bd,0x00050050,0x0000001e,0x000001bf,
0x000001bb,0x000001be,0x0003003e,0x00000186,0x000001bf,0x000200f9,0x000001b8,0x000200f8,
0x000001c0,0x0004003d,0x0000009e,0x000001c1,0x000001a3,0x000500aa,0x00000099,0x000001c3,
0x000001c1,0x000001c2,0x000300f7,0x000001c5,0x00000000,0x000400fa,0x000001c3,0x000001c4,
0x000001c5,0x000200f8,0x000001c4,0x00050041,0x0000000d,0x000001c6,0x00000186,0x00000100,
0x0004003d,0x00000006,0x000001c7,0x000001c6,0x00050083,0x00000006,0x000001c8,0x00000027,
0x000001c7,0x00050041,0x0000000d,0x000001c9,0x00000186,0x000000a1,0x0004003d,0x00000006,
0x000001ca,0x000001c9,0x00050050,0x0000001e,0x000001cb,0x000001c8,0x000001ca,0x0003003e,
0x00000186,0x000001cb,0x000200f9,0x000001c5,0x000200f8,0x000001c5,0x000200f9,0x000001b8,
0x000200f8,0x000001b8,0x000200f9,0x000001ac,0x000200f8,0x000001ac,0x0004003d,0x0000001e,
0x000001cc,0x00000186,0x00050041,0x0000018b,0x000001cd,0x0000009d,0x0000018a,0x0004003d,
0x0000001e,0x000001ce,0x000001cd,0x00050085,0x0000001e,0x000001cf,0x000001cc,0x000001ce,
0x000200fe,0x000001cf,0x00010038,0x00050036,0x0000001e,0x00000022,0x00000000,0x0000001f,
0x000200f8,0x00000023,0x0004003b,0x00000185,0x000001d2,0x00000007,0x0004003b,0x00000008,
0x000001da,0x00000007,0x0004003b,0x0000000d,0x000001ed,0x00000007,0x0004003b,0x0000000d,
0x000001f1,0x00000007,0x0004003b,0x0000000d,0x0000020b,0x00000007,0x0004003b,0x0000000d,
0x0000020f,0x00000007,0x0004003b,0x0000000d,0x00000229,0x00000007,0x0004003b,0x0000000d,
0x0000022f,0x00000007,0x0004003d,0x0000001e,0x000001d3,0x00000188,0x00050041,0x0000018b,
0x000001d4,0x0000009d,0x0000018a,0x0004003d,0x0000001e,0x000001d5,0x000001d4,0x00050088,
0x0000001e,0x000001d6,0x000001d3,0x000001d5,0x0005008e,0x0000001e,0x000001d7,0x000001d6,
0x0000013d,0x00050050,0x0000001e,0x000001d8,0x00000027,0x00000027,0x00050083,0x0000001e,
0x000001d9,0x000001d7,0x000001d8,0x0003003e,0x000001d2,0x000001d9,0x00050041,0x0000000d,
0x000001db,0x000001d2,0x000000a1,0x0004003d,0x00000006,0x000001dc,0x000001db,0x00060041,
0x000000a2,0x000001de,0x0000009d,0x000001dd,0x000000af,0x0004003d,0x00000006,0x000001df,
0x000001de,0x00050085,0x00000006,0x000001e0,0x000001dc,0x000001df,0x00060041,0x000000a2,
0x000001e2,0x0000009d,0x000001dd,0x000001e1,0x0004003d,0x00000006,0x000001e3,0x000001e2,
0x00050085,0x00000006,0x000001e4,0x000001e0,0x000001e3,0x00050041,0x0000000d,0x000001e5,
0x000001d2,0x00000100,0x0004003d,0x00000006,0x000001e6,0x000001e5,0x0004007f,0x00000006,
0x000001e7,0x000001e6,0x00060041,0x000000a2,0x000001e8,0x0000009d,0x000001dd,0x000000af,
0x0004003d,0x00000006,0x000001e9,0x000001e8,0x00050085,0x00000006,0x000001ea,0x000001e7,
0x000001e9,0x00060050,0x00000007,0x000001eb,0x000001e4,0x000001ea,0x00000027,0x0006000c,
0x00000007,0x000001ec,0x00000001,0x00000045,0x000001eb,0x0003003e,0x000001da,0x000001ec,
0x00060041,0x000000a2,0x000001ee,0x0000009d,0x000001dd,0x00000100,0x0004003d,0x00000006,
0x000001ef,0x000001ee,0x0006000c,0x00000006,0x000001f0,0x00000001,0x0000000e,0x000001ef,
0x0003003e,0x000001ed,0x000001f0,0x00060041,0x000000a2,0x000001f2,0x0000009d,0x000001dd,
0x00000100,0x0004003d,0x00000006,0x000001f3,0x000001f2,0x0006000c,0x00000006,0x000001f4,
0x00000001,0x0000000d,0x000001f3,0x0003003e,0x000001f1,0x000001f4,0x00050041,0x0000000d,
0x000001f5,0x000001da,0x000000a1,0x0004003d,0x00000006,0x000001f6,0x000001f5,0x00050041,
0x0000000d,0x000001f7,0x000001da,0x00000100,0x0004003d,0x00000006,0x000001f8,0x000001f7,
0x0004003d,0x00000006,0x000001f9,0x000001ed,0x00050085,0x00000006,0x000001fa,0x000001f8,
0x000001f9,0x00050041,0x0000000d,0x000001fb,0x000001da,0x000000af,0x0004003d,0x00000006,
0x000001fc,0x000001fb,0x0004003d,0x00000006,0x000001fd,0x000001f1,0x00050085,0x00000006,
0x000001fe,0x000001fc,0x000001fd,0x00050081,0x00000006,0x000001ff,0x000001fa,0x000001fe,
0x00050041,0x0000000d,0x00000200,0x000001da,0x00000100,0x0004003d,0x00000006,0x00000201,
0x00000200,0x0004007f,0x00000006,0x00000202,0x00000201,0x0004003d,0x00000006,0x00000203,
0x000001f1,0x00050085,0x00000006,0x00000204,0x00000202,0x00000203,0x00050041,0x0000000d,
0x00000205,0x000001da,0x000000af,0x0004003d,0x00000006,0x00000206,0x00000205,0x0004003d,
0x00000006,0x00000207,0x000001ed,0x00050085,0x00000006,0x00000208,0x00000206,0x00000207,
0x00050081,0x00000006,0x00000209,0x00000204,0x00000208,0x00060050,0x00000007,0x0000020a,
0x000001f6,0x000001ff,0x00000209,0x0003003e,0x000001da,0x0000020a,0x00060041,0x000000a2,
0x0000020c,0x0000009d,0x000001dd,0x000000a1,0x0004003d,0x00000006,0x0000020d,0x0000020c,
0x0006000c,0x00000006,0x0000020e,0x00000001,0x0000000e,0x0000020d,0x0003003e,0x0000020b,
0x0000020e,0x00060041,0x000000a2,0x00000210,0x0000009d,0x000001dd,0x000000a1,0x0004003d,
0x00000006,0x00000211,0x00000210,0x0006000c,0x00000006,0x00000212,0x00000001,0x0000000d,
0x00000211,0x0003003e,0x0000020f,0x00000212,0x00050041,0x0000000d,0x00000213,0x000001da,
0x000000a1,0x0004003d,0x00000006,0x00000214,0x00000213,0x0004003d,0x00000006,0x00000215,
0x0000020b,0x00050085,0x00000006,0x00000216,0x00000214,0x00000215,0x00050041,0x0000000d,
0x00000217,0x000001da,0x000000af,0x0004003d,0x00000006,0x00000218,0x00000217,0x0004003d,
0x00000006,0x00000219,0x0000020f,0x00050085,0x00000006,0x0000021a,0x00000218,0x00000219,
0x00050081,0x00000006,0x0000021b,0x00000216,0x0000021a,0x00050041,0x0000000d,0x0000021c,
0x000001da,0x00000100,0x0004003d,0x00000006,0x0000021d,0x0000021c,0x00050041,0x0000000d,
0x0000021e,0x000001da,0x000000a1,0x0004003d,0x00000006,0x0000021f,0x0000021e,0x0004007f,
0x00000006,0x00000220,0x0000021f,0x0004003d,0x00000006,0x00000221,0x0000020f,0x00050085,
0x00000006,0x00000222,0x00000220,0x00000221,0x00050041,0x0000000d,0x00000223,0x000001da,
0x000000af,0x0004003d,0x00000006,0x00000224,0x00000223,0x0004003d,0x00000006,0x00000225,
0x0000020b,0x00050085,0x00000006,0x00000226,0x00000224,0x00000225,0x00050081,0x00000006,
0x00000227,0x00000222,0x00000226,0x00060050,0x00000007,0x00000228,0x0000021b,0x0000021d,
0x00000227,0x0003003e,0x000001da,0x00000228,0x00050041,0x0000000d,0x0000022a,0x000001da,
0x000000a1,0x0004003d,0x00000006,0x0000022b,0x0000022a,0x00050041,0x0000000d,0x0000022c,
0x000001da,0x000000af,0x0004003d,0x00000006,0x0000022d,0x0000022c,0x0007000c,0x00000006,
0x0000022e,0x00000001,0x00000019,0x0000022b,0x0000022d,0x0003003e,0x00000229,0x0000022e,
0x00050041,0x0000000d,0x00000230,0x000001da,0x00000100,0x0004003d,0x00000006,0x00000231,
0x00000230,0x0008000c,0x00000006,0x00000233,0x00000001,0x0000002b,0x00000231,0x00000232,
0x00000027,0x0006000c,0x00000006,0x00000234,0x00000001,0x00000010,0x00000233,0x0003003e,
0x0000022f,0x00000234,0x0004003d,0x00000006,0x00000235,0x00000229,0x00050088,0x00000006,
0x00000237,0x00000235,0x00000236,0x00050081,0x00000006,0x00000238,0x00000237,0x0000006c,
0x0004003d,0x00000006,0x00000239,0x0000022f,0x00050088,0x00000006,0x0000023b,0x00000239,
0x0000023a,0x00050083,0x00000006,0x0000023c,0x0000006c,0x0000023b,0x00050050,0x0000001e,
0x0000023d,0x00000238,0x0000023c,0x00050041,0x0000018b,0x0000023e,0x0000009d,0x0000018a,
0x0004003d,0x0000001e,0x0000023f,0x0000023e,0x00050085,0x0000001e,0x00000240,0x0000023d,
0x0000023f,0x000200fe,0x00000240,0x00010038
};
+333 -6
View File
@@ -11,17 +11,24 @@
#include "gfx.h"
#include "image.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include "platform.h"
#include "gen/fullscreen_vert.h"
#include "gen/ui_pq_frag.h"
#ifdef VLCPS5_HOST
#include <zlib.h>
#endif
/* The console's Vulkan driver, with patches/mesa/0001 (absent elsewhere). */
extern "C" int vlcps5_wsi_videoout_set_hdr(int enable) __attribute__((weak));
extern "C" int vlcps5_wsi_videoout_dynamic_range(void) __attribute__((weak));
Gfx gfx;
namespace {
@@ -50,6 +57,26 @@ VkDeviceMemory offscreen_memory, readback_memory;
VkBuffer readback;
void *readback_mapped;
/* HDR10 output (gfx.h): the UI layer, the 10-bit frame and the pipeline that
* puts the first over the second. 10:10:10:2 with blue in the low bits: the
* framebuffers' B,G,R order (VideoOut's Bgr10A2), as their 8-bit SDR is. */
const VkFormat HDR_FORMAT = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
const float UI_NITS = 203; /* BT.2408's graphics white */
struct Hdr {
VkImage ui_image, image;
VkDeviceMemory ui_memory, memory;
VkImageView ui_view, view;
VkRenderPass ui_pass;
VkFramebuffer ui_fb, fb;
VkSampler sampler;
VkDescriptorSetLayout set_layout;
VkDescriptorPool pool;
VkDescriptorSet set;
VkPipelineLayout layout;
VkPipeline pipeline;
} hdr;
enum PassNow { PASS_NONE, PASS_MAIN, PASS_UI, PASS_HDR } pass_now;
#define CHECK(expr) \
do { \
VkResult r_ = (expr); \
@@ -168,7 +195,8 @@ bool create_swapchain()
info.imageColorSpace = chosen.colorSpace;
info.imageExtent = { gfx.width, gfx.height };
info.imageArrayLayers = 1;
info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
/* (copied into in HDR10 output: the 10-bit frame) */
info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
info.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
info.compositeAlpha = (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR)
@@ -193,8 +221,9 @@ bool create_offscreen()
VkImage image;
VkImageView view;
if (!gfx_image(gfx.width, gfx.height, gfx.format,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, &image,
&offscreen_memory, &view))
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT,
&image, &offscreen_memory, &view))
return false;
images.push_back(image);
views.push_back(view);
@@ -294,6 +323,223 @@ bool create_targets()
return true;
}
/* A pass over one colour attachment, cleared, ending in `final` and made
* visible to `next_stage`/`next_access` (what reads it next). */
bool make_pass(VkFormat format, VkImageLayout final, VkPipelineStageFlags next_stage,
VkAccessFlags next_access, VkRenderPass *pass)
{
VkAttachmentDescription color = {};
color.format = format;
color.samples = VK_SAMPLE_COUNT_1_BIT;
color.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
color.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
color.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
color.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
color.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
color.finalLayout = final;
VkAttachmentReference ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL };
VkSubpassDescription subpass = {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &ref;
VkSubpassDependency deps[3] = {};
deps[0].srcSubpass = VK_SUBPASS_EXTERNAL;
deps[0].dstSubpass = 0;
deps[0].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
deps[0].srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
deps[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
deps[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
deps[1].srcSubpass = VK_SUBPASS_EXTERNAL;
deps[1].dstSubpass = 0;
deps[1].srcStageMask = VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
deps[1].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
deps[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
deps[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
deps[2].srcSubpass = 0;
deps[2].dstSubpass = VK_SUBPASS_EXTERNAL;
deps[2].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
deps[2].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
deps[2].dstStageMask = next_stage;
deps[2].dstAccessMask = next_access;
VkRenderPassCreateInfo rp = { VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO };
rp.attachmentCount = 1;
rp.pAttachments = &color;
rp.subpassCount = 1;
rp.pSubpasses = &subpass;
rp.dependencyCount = 3;
rp.pDependencies = deps;
CHECK(vkCreateRenderPass(gfx.device, &rp, nullptr, pass));
return true;
}
bool make_framebuffer(VkRenderPass pass, VkImageView view, VkFramebuffer *fb)
{
VkFramebufferCreateInfo fi = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO };
fi.renderPass = pass;
fi.attachmentCount = 1;
fi.pAttachments = &view;
fi.width = gfx.width;
fi.height = gfx.height;
fi.layers = 1;
CHECK(vkCreateFramebuffer(gfx.device, &fi, nullptr, fb));
return true;
}
/* HDR10 output's targets and the UI layer's pipeline. Optional: without
* them the app stays SDR. */
bool create_hdr()
{
/* the UI layer: the swapchain's format, so ImGui's pipeline (made for
* gfx.render_pass) draws in its pass as well */
if (!gfx_image(gfx.width, gfx.height, gfx.format,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, &hdr.ui_image,
&hdr.ui_memory, &hdr.ui_view))
return false;
if (!gfx_image(gfx.width, gfx.height, HDR_FORMAT,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, &hdr.image,
&hdr.memory, &hdr.view))
return false;
if (!make_pass(gfx.format, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
VK_ACCESS_SHADER_READ_BIT, &hdr.ui_pass) ||
!make_pass(HDR_FORMAT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_READ_BIT, &gfx.hdr_pass) ||
!make_framebuffer(hdr.ui_pass, hdr.ui_view, &hdr.ui_fb) ||
!make_framebuffer(gfx.hdr_pass, hdr.view, &hdr.fb))
return false;
VkSamplerCreateInfo si = { VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO };
si.magFilter = si.minFilter = VK_FILTER_NEAREST;
si.addressModeU = si.addressModeV = si.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
CHECK(vkCreateSampler(gfx.device, &si, nullptr, &hdr.sampler));
VkDescriptorSetLayoutBinding b = {};
b.binding = 0;
b.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
b.descriptorCount = 1;
b.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
VkDescriptorSetLayoutCreateInfo li = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO };
li.bindingCount = 1;
li.pBindings = &b;
CHECK(vkCreateDescriptorSetLayout(gfx.device, &li, nullptr, &hdr.set_layout));
VkDescriptorPoolSize ps = { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 };
VkDescriptorPoolCreateInfo pi = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO };
pi.maxSets = 1;
pi.poolSizeCount = 1;
pi.pPoolSizes = &ps;
CHECK(vkCreateDescriptorPool(gfx.device, &pi, nullptr, &hdr.pool));
VkDescriptorSetAllocateInfo ai = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO };
ai.descriptorPool = hdr.pool;
ai.descriptorSetCount = 1;
ai.pSetLayouts = &hdr.set_layout;
CHECK(vkAllocateDescriptorSets(gfx.device, &ai, &hdr.set));
VkDescriptorImageInfo ii = { hdr.sampler, hdr.ui_view, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
VkWriteDescriptorSet w = { VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET };
w.dstSet = hdr.set;
w.dstBinding = 0;
w.descriptorCount = 1;
w.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
w.pImageInfo = &ii;
vkUpdateDescriptorSets(gfx.device, 1, &w, 0, nullptr);
VkPushConstantRange range = { VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(float) };
VkPipelineLayoutCreateInfo pl = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
pl.setLayoutCount = 1;
pl.pSetLayouts = &hdr.set_layout;
pl.pushConstantRangeCount = 1;
pl.pPushConstantRanges = &range;
CHECK(vkCreatePipelineLayout(gfx.device, &pl, nullptr, &hdr.layout));
VkShaderModule vs = gfx_shader(spv_fullscreen_vert, sizeof(spv_fullscreen_vert));
VkShaderModule fs = gfx_shader(spv_ui_pq_frag, sizeof(spv_ui_pq_frag));
VkPipelineShaderStageCreateInfo stages[2] = {};
stages[0] = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO };
stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT;
stages[0].module = vs;
stages[0].pName = "main";
stages[1] = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO };
stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
stages[1].module = fs;
stages[1].pName = "main";
VkPipelineVertexInputStateCreateInfo vi = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO };
VkPipelineInputAssemblyStateCreateInfo ia = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO };
ia.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
VkPipelineViewportStateCreateInfo vp = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
vp.viewportCount = 1;
vp.scissorCount = 1;
VkPipelineRasterizationStateCreateInfo rs = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
rs.polygonMode = VK_POLYGON_MODE_FILL;
rs.cullMode = VK_CULL_MODE_NONE;
rs.lineWidth = 1.0f;
VkPipelineMultisampleStateCreateInfo ms = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO };
ms.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
/* premultiplied over */
VkPipelineColorBlendAttachmentState att = {};
att.blendEnable = VK_TRUE;
att.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
att.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
att.colorBlendOp = VK_BLEND_OP_ADD;
att.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
att.dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
att.alphaBlendOp = VK_BLEND_OP_ADD;
att.colorWriteMask = 0xf;
VkPipelineColorBlendStateCreateInfo cb = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO };
cb.attachmentCount = 1;
cb.pAttachments = &att;
VkDynamicState dyn[2] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR };
VkPipelineDynamicStateCreateInfo ds = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO };
ds.dynamicStateCount = 2;
ds.pDynamicStates = dyn;
VkGraphicsPipelineCreateInfo gp = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO };
gp.stageCount = 2;
gp.pStages = stages;
gp.pVertexInputState = &vi;
gp.pInputAssemblyState = &ia;
gp.pViewportState = &vp;
gp.pRasterizationState = &rs;
gp.pMultisampleState = &ms;
gp.pColorBlendState = &cb;
gp.pDynamicState = &ds;
gp.layout = hdr.layout;
gp.renderPass = gfx.hdr_pass;
VkResult r = vkCreateGraphicsPipelines(gfx.device, VK_NULL_HANDLE, 1, &gp, nullptr, &hdr.pipeline);
vkDestroyShaderModule(gfx.device, vs, nullptr);
vkDestroyShaderModule(gfx.device, fs, nullptr);
CHECK(r);
return true;
}
void begin(VkCommandBuffer cmd, VkRenderPass pass, VkFramebuffer fb, float alpha)
{
VkClearValue clear = {};
clear.color = { { 0.0f, 0.0f, 0.0f, alpha } };
VkRenderPassBeginInfo rb = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO };
rb.renderPass = pass;
rb.framebuffer = fb;
rb.renderArea.extent = { gfx.width, gfx.height };
rb.clearValueCount = 1;
rb.pClearValues = &clear;
vkCmdBeginRenderPass(cmd, &rb, VK_SUBPASS_CONTENTS_INLINE);
}
#ifdef VLCPS5_HOST
/* An HDR10 frame (10:10:10:2 PQ, BT.2020) in the offscreen image, made
* viewable for the PNG: light, SDR white at 203 nits, BT.709, gamma 2.4. */
void hdr_preview(std::vector<uint8_t> &rgb, const uint32_t *px, size_t n)
{
auto nits = [](float e) {
float p = powf(e, 1 / 78.84375f);
return 10000 * powf(fmaxf(p - 0.8359375f, 0) / (18.8515625f - 18.6875f * p), 1 / 0.1593017578125f);
};
for (size_t i = 0; i < n; i++) {
uint32_t v = px[i];
float b = nits((v & 1023) / 1023.0f) / UI_NITS, g = nits(((v >> 10) & 1023) / 1023.0f) / UI_NITS,
r = nits(((v >> 20) & 1023) / 1023.0f) / UI_NITS;
float o[3] = { 1.6605f * r - 0.5876f * g - 0.0728f * b, -0.1246f * r + 1.1329f * g - 0.0083f * b,
-0.0182f * r - 0.1006f * g + 1.1187f * b };
for (int c = 0; c < 3; c++)
rgb[i * 3 + c] = (uint8_t)(powf(fminf(fmaxf(o[c], 0), 1), 1 / 2.4f) * 255 + 0.5f);
}
}
#endif
#ifdef VLCPS5_HOST
/* The offscreen image (BGRA) as an RGB PNG. */
void save_png(const char *path)
@@ -301,7 +547,9 @@ void save_png(const char *path)
uint32_t w = gfx.width, h = gfx.height;
std::vector<uint8_t> rgb((size_t)w * h * 3);
const uint8_t *src = (const uint8_t *)readback_mapped;
for (size_t i = 0; i < (size_t)w * h; i++) {
if (gfx.hdr)
hdr_preview(rgb, (const uint32_t *)src, (size_t)w * h);
for (size_t i = 0; i < (size_t)w * h && !gfx.hdr; i++) {
rgb[i * 3] = src[i * 4 + 2];
rgb[i * 3 + 1] = src[i * 4 + 1];
rgb[i * 3 + 2] = src[i * 4];
@@ -334,7 +582,65 @@ bool gfx_init()
return false;
if (gfx.offscreen ? !create_offscreen() : !create_swapchain())
return false;
return create_targets();
if (!create_targets())
return false;
if (!create_hdr()) {
fprintf(stderr, "gfx: no HDR10 output (its targets couldn't be made)\n");
gfx.hdr_pass = VK_NULL_HANDLE;
}
gfx.display_range = vlcps5_wsi_videoout_dynamic_range ? vlcps5_wsi_videoout_dynamic_range() : -1;
fprintf(stderr, "gfx: output %s, HDR10 output %s\n",
gfx.display_range == 2 ? "HDR" : gfx.display_range == 1 ? "SDR" : "unknown",
gfx.hdr_pass && (vlcps5_wsi_videoout_set_hdr || gfx.offscreen) ? "possible" : "not possible");
return true;
}
bool gfx_set_hdr(bool on)
{
if (on == gfx.hdr)
return true;
if (on && !gfx.hdr_pass)
return false;
/* nothing drawn in one format may land after the switch */
vkDeviceWaitIdle(gfx.device);
int rc;
if (vlcps5_wsi_videoout_set_hdr)
rc = vlcps5_wsi_videoout_set_hdr(on ? 1 : 0);
else
rc = gfx.offscreen && getenv("VLCPS5_HDR_TEST") ? 0 : -1; /* host: the preview */
fprintf(stderr, "gfx: HDR10 output %s: %s (%#x)\n", on ? "on" : "off", rc == 0 ? "done" : "refused",
(unsigned)rc);
if (rc != 0 && on)
return false;
/* off even if refused: SDR pixels are what is drawn from here */
gfx.hdr = on;
return true;
}
void gfx_begin_ui_pass(VkCommandBuffer cmd)
{
begin(cmd, hdr.ui_pass, hdr.ui_fb, 0.0f); /* clear: transparent */
pass_now = PASS_UI;
}
void gfx_begin_hdr_pass(VkCommandBuffer cmd)
{
if (pass_now != PASS_NONE)
vkCmdEndRenderPass(cmd);
begin(cmd, gfx.hdr_pass, hdr.fb, 1.0f);
pass_now = PASS_HDR;
}
void gfx_draw_ui_layer(VkCommandBuffer cmd)
{
VkViewport vp = { 0, 0, (float)gfx.width, (float)gfx.height, 0, 1 };
VkRect2D sc = { { 0, 0 }, { gfx.width, gfx.height } };
vkCmdSetViewport(cmd, 0, 1, &vp);
vkCmdSetScissor(cmd, 0, 1, &sc);
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, hdr.pipeline);
vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, hdr.layout, 0, 1, &hdr.set, 0, nullptr);
vkCmdPushConstants(cmd, hdr.layout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(float), &UI_NITS);
vkCmdDraw(cmd, 3, 1, 0, 0);
}
void gfx_shutdown()
@@ -383,12 +689,32 @@ void gfx_begin_pass(VkCommandBuffer cmd)
rb.clearValueCount = 1;
rb.pClearValues = &clear;
vkCmdBeginRenderPass(cmd, &rb, VK_SUBPASS_CONTENTS_INLINE);
pass_now = PASS_MAIN;
}
void gfx_end_frame(VkCommandBuffer cmd)
{
Frame &f = frames[gfx.frame_slot];
vkCmdEndRenderPass(cmd);
if (pass_now == PASS_HDR) {
/* the 10-bit frame into the framebuffer: same 32-bit pixels and tiling */
VkImage dst = images[image_index];
gfx_barrier(cmd, dst, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_TRANSFER_WRITE_BIT);
VkImageCopy region = {};
region.srcSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
region.dstSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
region.extent = { gfx.width, gfx.height, 1 };
vkCmdCopyImage(cmd, hdr.image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
gfx_barrier(cmd, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
gfx.offscreen ? VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL : VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT | VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_TRANSFER_READ_BIT);
}
pass_now = PASS_NONE;
#ifdef VLCPS5_HOST
const char *shot = plat_screenshot_path(gfx.frame_number);
if (shot) {
@@ -400,7 +726,8 @@ void gfx_end_frame(VkCommandBuffer cmd)
}
#endif
vkEndCommandBuffer(cmd);
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
/* (the HDR10 frame reaches the framebuffer by a copy) */
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_TRANSFER_BIT;
VkSubmitInfo si = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
si.commandBufferCount = 1;
si.pCommandBuffers = &cmd;
+13
View File
@@ -26,6 +26,12 @@ struct Gfx {
bool offscreen; /* host test build */
uint32_t frame_slot; /* 0..GFX_FRAMES-1, the frame being recorded */
uint64_t frame_number; /* frames presented so far */
/* HDR10 output: the frame is drawn in a 10-bit image (video as PQ,
* BT.2020, the UI layer over it) and copied into the framebuffer, which
* VideoOut then shows as HDR10. */
VkRenderPass hdr_pass; /* the 10-bit frame's pass (null: no HDR output) */
bool hdr; /* HDR10 output on now */
int display_range; /* the output at start: 1 SDR, 2 HDR, other unknown */
};
extern Gfx gfx;
@@ -38,6 +44,13 @@ VkCommandBuffer gfx_begin_frame();
void gfx_begin_pass(VkCommandBuffer cmd);
/* Ends the pass, submits, presents (or saves the host screenshot). */
void gfx_end_frame(VkCommandBuffer cmd);
/* HDR10 output on or off (waits for the GPU); false if it couldn't change. */
bool gfx_set_hdr(bool on);
/* With HDR10 output on, a frame is: the UI pass (ImGui into its own layer),
* then the HDR pass (the video, then gfx_draw_ui_layer), then gfx_end_frame. */
void gfx_begin_ui_pass(VkCommandBuffer cmd);
void gfx_begin_hdr_pass(VkCommandBuffer cmd); /* ends the UI pass */
void gfx_draw_ui_layer(VkCommandBuffer cmd);
/* The fence of the frame recorded in this slot has passed: its resources are free. */
uint64_t gfx_completed_frame();
+42 -1
View File
@@ -193,7 +193,7 @@ void scan_dir(const std::string &dir, int depth)
const char *x = *dot ? dot + 1 : dot;
bool video = has_ext(x, video_exts), audio = has_ext(x, audio_exts);
bool image = has_ext(x, image_exts), text = has_ext(x, text_exts);
bool archive = has_ext(x, archive_exts), iso = !strcasecmp(x, "iso");
bool archive = has_ext(x, archive_exts), iso = !strcasecmp(x, "iso") || !strcasecmp(x, "img"); /* a DVD image named .img */
if (image) {
/* an album's cover file isn't a photo of its own */
std::string base = std::string(e->d_name, dot - e->d_name);
@@ -664,6 +664,8 @@ void look_at(const Job &job)
libvlc_media_add_option(m, ":no-audio");
libvlc_media_add_option(m, ":no-spu");
libvlc_media_add_option(m, ":avcodec-threads=2");
/* the console's video decoder stays for the video being watched */
libvlc_media_add_option(m, ":no-ps5vdec");
Grab g;
g.frames = 0;
g.got = false;
@@ -1438,6 +1440,45 @@ std::vector<int> library_playlist_items(const std::string &path)
return out;
}
int library_playlist_count(const std::string &path)
{
FILE *f = fopen(path.c_str(), "r");
if (!f)
return 0;
bool pls = path.size() > 4 && strcasecmp(path.c_str() + path.size() - 4, ".pls") == 0;
int n = 0;
char line[4096];
while (fgets(line, sizeof(line), f)) {
const char *l = line;
while (*l == ' ' || *l == '\t' || (unsigned char)*l == 0xEF || (unsigned char)*l == 0xBB || (unsigned char)*l == 0xBF)
l++; /* indent, UTF-8 mark */
if (pls ? (!strncasecmp(l, "File", 4) && strchr(l, '=')) : (*l && *l != '#' && *l != '\r' && *l != '\n'))
n++;
}
fclose(f);
return n;
}
bool library_playlist_has_links(const std::string &path)
{
FILE *f = fopen(path.c_str(), "r");
if (!f)
return false;
bool links = false;
char line[4096];
while (!links && fgets(line, sizeof(line), f)) {
const char *l = line;
if (*l == '#')
continue;
if (!strncasecmp(l, "File", 4) && strchr(l, '='))
l = strchr(l, '=') + 1; /* .pls */
const char *scheme = strstr(l, "://");
links = scheme && scheme > l && strncasecmp(l, "file://", 7) != 0;
}
fclose(f);
return links;
}
/* ---- playlists made in VLC -------------------------------------------------------- */
namespace {
+4
View File
@@ -69,6 +69,10 @@ MediaItem *library_find(const std::string &path);
std::vector<PlaylistFile> &library_playlists();
/* The library files a playlist names, in its order (others are skipped). */
std::vector<int> library_playlist_items(const std::string &path);
/* Every entry it names, links and files alike. */
int library_playlist_count(const std::string &path);
/* It names links (http://, rtp://...): a channel list, opened in Browse. */
bool library_playlist_has_links(const std::string &path);
/* Playlists made in VLC: <media>/Playlists/<name>.m3u8, one absolute path a
* line (with #EXTINF names), so VLC on a computer reads them too. Only these
* are changed; ones found elsewhere just play. */
+27 -4
View File
@@ -78,6 +78,9 @@ int main(void)
double t = plat_time();
float dt = (float)(t - last);
last = t;
/* the interface stood still: always in the log (a freeze report) */
if (dt > 0.5f && gfx.frame_number > 10)
fprintf(stderr, "ui: a frame took %.0f ms (the interface froze)\n", dt * 1000);
PadState pad;
plat_pad_read(&pad);
library_update();
@@ -92,16 +95,36 @@ int main(void)
ImGui::Render();
double t_ui = plat_time();
/* HDR10 output while an HDR video shows (once a refusal, not again
* until the wish changes) */
static bool hdr_refused;
bool want_hdr = video_wants_hdr_output();
if (want_hdr != gfx.hdr && !(want_hdr && hdr_refused))
hdr_refused = !gfx_set_hdr(want_hdr);
if (!want_hdr)
hdr_refused = false;
VkCommandBuffer cmd = gfx_begin_frame();
if (!cmd)
continue;
double t_begin = plat_time();
video_upload(cmd);
gfx_begin_pass(cmd);
float vx, vy, vw, vh;
if (ui_video_rect(&vx, &vy, &vw, &vh))
video_draw(cmd, vx, vy, vw, vh);
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);
bool video = ui_video_rect(&vx, &vy, &vw, &vh);
if (gfx.hdr) {
/* the UI in its layer, then the video as PQ and the layer over it */
gfx_begin_ui_pass(cmd);
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);
gfx_begin_hdr_pass(cmd);
if (video)
video_draw(cmd, vx, vy, vw, vh);
gfx_draw_ui_layer(cmd);
} else {
gfx_begin_pass(cmd);
if (video)
video_draw(cmd, vx, vy, vw, vh);
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd);
}
gfx_end_frame(cmd);
double t_end = plat_time();
+8 -2
View File
@@ -287,8 +287,14 @@ void finish_listing()
libvlc_media_list_unlock(subs);
libvlc_media_list_release(subs);
}
/* Folders A-Z; a playlist (TV channels, radio) keeps its own order. */
bool playlist = list_url.compare(0, 4, "http") == 0;
/* Folders A-Z; a playlist (TV channels, radio, an .m3u on a share)
* keeps its own order. */
std::string bare = list_url.substr(0, list_url.find('?'));
size_t dot = bare.rfind('.');
std::string ext = dot == std::string::npos ? "" : bare.substr(dot + 1);
for (char &c : ext)
c = (char)tolower((unsigned char)c);
bool playlist = list_url.compare(0, 4, "http") == 0 || ext == "m3u" || ext == "m3u8" || ext == "pls";
if (!playlist)
std::stable_sort(entries.begin(), entries.end(), [](const NetEntry &a, const NetEntry &b) {
if (a.dir != b.dir)
+1 -1
View File
@@ -32,7 +32,7 @@
namespace {
const char *API_HOST = "api.opensubtitles.com";
const char *USER_AGENT = "VLC-PS5 v0.1";
const char *USER_AGENT = "VLC-PS5 v" VLC_PS5_VERSION;
/* ---- what the interface sees ---- */
+1 -1
View File
@@ -23,7 +23,7 @@ extern "C" {
#endif
#define VLC_PS5_TITLE_ID "PPSA85300"
#define VLC_PS5_VERSION "0.1"
#define VLC_PS5_VERSION "0.4"
/* DualSense buttons (scePadRead's layout, as QUICK3 and PS5_vkQuake use it),
* plus the triggers past half as buttons. */
+1 -1
View File
@@ -23,7 +23,7 @@
#include <time.h>
#include <unistd.h>
#define MAX_STEPS 512
#define MAX_STEPS 20000 /* a long stress tour has thousands */
typedef struct {
uint64_t frame;
+153 -5
View File
@@ -124,6 +124,14 @@ static void crash_handler(int sig, siginfo_t *info, void *context)
/* " name " of each import left unresolved: optional calls check it first. */
static char unresolved[2048] = " ";
/* the video decoder's import slots (imports.txt), checked once its library
* is loaded */
#define VDEC_SLOTS 16
static struct {
unsigned long offset;
char name[48];
} vdec_slots[VDEC_SLOTS];
static int vdec_slot_count;
static bool import_resolved(const char *name)
{
@@ -132,6 +140,66 @@ static bool import_resolved(const char *name)
return strstr(unresolved, key) == NULL;
}
/* settings.txt's "key=value" at start (read before full access: /app0 may
* be gone after it). */
static int boot_setting(const char *key, int fallback)
{
FILE *s = fopen(APP_DIR "/settings.txt", "r");
if (!s)
return fallback;
char line[128];
size_t n = strlen(key);
int value = fallback;
while (fgets(line, sizeof(line), s))
if (!strncmp(line, key, n) && line[n] == '=')
value = atoi(line + n + 1);
fclose(s);
return value;
}
/* The console's video decoder (ps5/modules/ps5vdec.c). Its library (sysmodule
* 207) and compute queue are made before the Helper's full access: after it
* the library is refused (0x80020063, console run 11) and the queue too
* (0x811D0111, run 12). Run 10's "no jailbreak daemon answered" with the
* library loaded first was the Helper not running then (run 12: it answered
* in 60 ms). settings.txt vdec_load=0 loads it after full access instead,
* hw_decode=0 not at all. */
int sceSysmoduleLoadModule(uint16_t id);
void vlc_ps5_vdec_prepare(void) __attribute__((weak)); /* ps5/modules/ps5vdec.c */
#define SYSMODULE_VIDEODEC2 207
static bool vdec_ready;
static double jb_wait = 2.5; /* seconds the Helper has to answer */
static void load_video_decoder(void)
{
/* (the decoder's own functions only get their addresses with the
* library: they're checked after loading it, below) */
if (!import_resolved("sceSysmoduleLoadModule")) {
fprintf(stderr, "VLC-PS5: hardware decoding off: sceSysmoduleLoadModule unresolved\n");
return;
}
int rc = sceSysmoduleLoadModule(SYSMODULE_VIDEODEC2);
vdec_ready = rc == 0;
/* now its functions must have their addresses (imports.txt known): an
* empty one would be a jump to 0 */
for (int i = 0; vdec_ready && i < vdec_slot_count; i++) {
if (*(const uint64_t *)(EBOOT_BASE + vdec_slots[i].offset) == 0) {
fprintf(stderr, "VLC-PS5: %s still unresolved after loading the library\n", vdec_slots[i].name);
vdec_ready = false;
}
}
fprintf(stderr, "VLC-PS5: video decoder library %#x: hardware decoding %s (%d functions checked)\n",
(unsigned)rc, vdec_ready ? "on" : "off", vdec_slot_count);
/* its compute queue now too, while still in the sandbox */
if (vdec_ready && vlc_ps5_vdec_prepare)
vlc_ps5_vdec_prepare();
}
int vlc_ps5_vdec_available(void)
{
return vdec_ready;
}
/* Every import the console left unresolved (a call would jump to 0), in one
* report: imports.txt lists each GOT slot's offset and symbol. */
static void report_unresolved_imports(void)
@@ -146,6 +214,16 @@ static void report_unresolved_imports(void)
int checked = 0, missing = 0;
while (fscanf(f, "%lx %127s", &offset, name) == 2) {
checked++;
/* the video decoder's are filled in when its library is loaded
* (load_video_decoder), not at start: looked at after that */
if (!strncmp(name, "sceVideodec2", 12)) {
if (vdec_slot_count < VDEC_SLOTS) {
vdec_slots[vdec_slot_count].offset = offset;
snprintf(vdec_slots[vdec_slot_count].name, sizeof(vdec_slots[0].name), "%s", name);
vdec_slot_count++;
}
continue;
}
if (*(const uint64_t *)(EBOOT_BASE + offset) == 0) {
fprintf(stderr, "VLC-PS5: unresolved import: %s\n", name);
if (strlen(unresolved) + strlen(name) + 2 < sizeof(unresolved)) {
@@ -176,11 +254,48 @@ static bool exists(const char *path)
* resolve; otherwise the sandbox's own copy of it (/mnt/sandbox/<title>_NNN/app0,
* the folder the daemon found our request in) or the folder
* ShadowMountPlus launched us from. */
/* Our folder is marked before full access (/app0 is gone after it), so the
* search below finds this launch's folder and not another: the first
* PPSA85300_ entry of /mnt/sandbox, as first done, could be an older launch's
* or another copy of the app, whose prefs.txt then came up (the look
* switching between Classic and Modern "by itself"). */
#define INSTANCE_FILE "/cache/instance.txt"
static char instance_mark[64];
static void mark_app_dir(void)
{
snprintf(instance_mark, sizeof(instance_mark), "%d-%.0f", (int)getpid(), plat_time() * 1000);
mkdir(APP_DIR "/cache", 0777);
FILE *f = fopen(APP_DIR INSTANCE_FILE, "w");
if (!f) {
instance_mark[0] = 0;
return;
}
fputs(instance_mark, f);
fclose(f);
}
static bool is_marked(const char *dir)
{
if (!instance_mark[0])
return false;
char path[300], got[64] = "";
snprintf(path, sizeof(path), "%s" INSTANCE_FILE, dir);
FILE *f = fopen(path, "r");
if (!f)
return false;
if (!fgets(got, sizeof(got), f))
got[0] = 0;
fclose(f);
return !strcmp(got, instance_mark);
}
static void find_app_dir(void)
{
if (exists(APP_DIR "/eboot.bin"))
return;
char path[256];
char path[256], first[256] = "";
int candidates = 0;
DIR *d = opendir("/mnt/sandbox");
if (d) {
struct dirent *e;
@@ -188,13 +303,27 @@ static void find_app_dir(void)
if (strncmp(e->d_name, VLC_PS5_TITLE_ID "_", sizeof(VLC_PS5_TITLE_ID)))
continue;
snprintf(path, sizeof(path), "/mnt/sandbox/%s/app0/eboot.bin", e->d_name);
if (exists(path)) {
snprintf(app_dir, sizeof(app_dir), "/mnt/sandbox/%s/app0", e->d_name);
if (!exists(path))
continue;
candidates++;
snprintf(path, sizeof(path), "/mnt/sandbox/%s/app0", e->d_name);
fprintf(stderr, "VLC-PS5: candidate folder %s%s\n", path, is_marked(path) ? " (ours)" : "");
if (!first[0])
snprintf(first, sizeof(first), "%s", path);
if (is_marked(path)) {
snprintf(app_dir, sizeof(app_dir), "%s", path);
break;
}
}
closedir(d);
}
/* no mark found: the first one, as before */
if (!strcmp(app_dir, APP_DIR) && first[0] && !(instance_mark[0] && candidates > 1))
snprintf(app_dir, sizeof(app_dir), "%s", first);
if (!strcmp(app_dir, APP_DIR) && is_marked("/data/homebrew/" VLC_PS5_TITLE_ID))
snprintf(app_dir, sizeof(app_dir), "/data/homebrew/" VLC_PS5_TITLE_ID);
if (!strcmp(app_dir, APP_DIR) && first[0])
snprintf(app_dir, sizeof(app_dir), "%s", first);
if (!strcmp(app_dir, APP_DIR) && exists("/data/homebrew/" VLC_PS5_TITLE_ID "/eboot.bin"))
snprintf(app_dir, sizeof(app_dir), "/data/homebrew/" VLC_PS5_TITLE_ID);
if (!strcmp(app_dir, APP_DIR))
@@ -224,6 +353,7 @@ static bool lifted(void)
static void request_full_access(void)
{
mark_app_dir();
if (lifted()) {
full_access = true;
fprintf(stderr, "VLC-PS5: full access already (euid %d)\n", (int)__real_geteuid());
@@ -268,12 +398,14 @@ static void request_full_access(void)
unlink(JB_STAGED);
return;
}
/* (2.5 s: a busy daemon took longer than the 1 s first allowed) */
double start = plat_time();
while (exists(JB_REQUEST) && plat_time() - start < 1.0)
while (exists(JB_REQUEST) && plat_time() - start < jb_wait)
usleep(20000);
if (exists(JB_REQUEST)) {
unlink(JB_REQUEST); /* nobody listening: don't leave it for a daemon started later */
fprintf(stderr, "VLC-PS5: sandboxed (no jailbreak daemon answered in 1 s)\n");
fprintf(stderr, "VLC-PS5: sandboxed (no jailbreak daemon answered in %.1f s): no phone/PC page, "
"no DLNA server; is etaHEN or the Helper running, PPSA85300 whitelisted?\n", jb_wait);
return;
}
/* Taken. Daemons set the effective uid (the real one can stay as it was)
@@ -310,6 +442,10 @@ static void use_app_dir(void)
snprintf(path, sizeof(path), "%s/cache/mesa", app_dir);
mkdir(path, 0777);
setenv("MESA_SHADER_CACHE_DIR", path, 1);
/* libbluray keeps its cache in $HOME/.cache/bluray and makes only the
* last folder ("Error creating directory" in every disc's log) */
snprintf(path, sizeof(path), "%s/.cache", app_dir);
mkdir(path, 0777);
fprintf(stderr, "VLC-PS5: shader caches in %s/cache\n", app_dir);
}
@@ -378,7 +514,19 @@ void plat_init(void)
signal(SIGPIPE, SIG_IGN);
report_unresolved_imports();
/* the decoder library and its compute queue first, then full access: the
* Helper answered in 60 ms with them loaded (console run 12), and both
* fail after full access (0x80020063, 0x811D0111). vdec_load=0: after. */
int hw_decode = boot_setting("hw_decode", 1), vdec_load = boot_setting("vdec_load", 1);
if (!hw_decode)
fprintf(stderr, "VLC-PS5: hardware decoding off (settings.txt): decoder library not loaded\n");
if (hw_decode && vdec_load == 1) {
load_video_decoder();
jb_wait = 6;
}
request_full_access();
if (hw_decode && vdec_load != 1)
load_video_decoder();
use_app_dir();
}
+1076 -69
View File
File diff suppressed because it is too large. Load diff
+18 -2
View File
@@ -24,6 +24,8 @@ struct VideoInfo {
uint32_t width, height; /* visible size */
float aspect; /* display aspect, sample aspect applied */
bool ten_bit;
int hdr; /* 0 SDR, 1 HDR10 (PQ), 2 HLG */
bool hardware; /* on the console's video decoder */
float fps; /* 0 if the file doesn't say */
std::string codec, audio_codec;
unsigned audio_channels;
@@ -40,12 +42,20 @@ libvlc_instance_t *player_vlc();
bool player_open(const std::string &path, int64_t start_ms, const std::vector<std::string> &options = {});
/* The same with a media VLC made (an entry of a listed playlist, with the options
* its list gave it); takes the reference. path: what it's called in the log. */
bool player_open_media(libvlc_media_t *m, const std::string &path, int64_t start_ms);
bool player_open_media(libvlc_media_t *m, const std::string &path, int64_t start_ms,
const std::vector<std::string> &options = {});
void player_stop();
bool player_active(); /* a file is open (playing, paused, buffering) */
bool player_ended(); /* the file played to its end (or failed) */
bool player_failed();
bool player_buffering(); /* opening or buffering: no picture moving yet */
/* Disc menus: the main menu (DVD root, Blu-ray Top Menu) or a Blu-ray's
* pop-up menu; whether the Blu-ray playing has one. */
/* The Blu-ray region VLC plays as (A, B, C), from the next file. */
std::string player_bluray_region();
void player_set_bluray_region(const std::string &region);
void player_disc_menu(bool popup);
bool player_disc_has_popup();
bool player_paused();
void player_toggle_pause();
int64_t player_time(); /* ms */
@@ -62,7 +72,8 @@ std::vector<Track> player_subtitle_tracks();
int player_subtitle_track();
void player_set_subtitle_track(int id);
/* Adds a subtitle file (.srt, .ass, ...) to what plays and selects it. */
bool player_add_subtitle(const std::string &path);
bool player_add_subtitle(const std::string &path); /* a local path, or a share's / a link's address */
bool player_is_subtitle_name(const std::string &name); /* .srt, .ass, .vtt... */
const VideoInfo &player_video_info();
/* A 360° video: where the view looks (degrees) and how wide it sees. */
@@ -70,6 +81,8 @@ void player_view(float yaw, float pitch, float fov);
/* A DVD / Blu-ray menu: 0 activate, 1 up, 2 down, 3 left, 4 right. */
void player_navigate(int action);
/* A disc's menu is on screen (its current title is a menu). */
bool player_in_menu();
/* The sound being heard, as n bands from bass to treble (0..1 each). */
void player_spectrum(float *bands, int n);
@@ -77,6 +90,9 @@ void player_spectrum(float *bands, int n);
/* Render thread, every frame: */
void video_upload(VkCommandBuffer cmd); /* before the render pass */
bool video_has_picture();
/* An HDR video is showing and HDR10 output is wanted for it (settings.txt
* hdr_output, the console's output). */
bool video_wants_hdr_output();
void video_draw(VkCommandBuffer cmd, float x, float y, float w, float h); /* in the pass */
void video_forget_picture(); /* back to the library */
/* One line about the player in the log (state, time, picture slots, sound queue,
+179
View File
@@ -0,0 +1,179 @@
/*
* VLC-PS5: subtitle files that aren't UTF-8, made UTF-8 for VLC (see
* subconv.h). Our own code; the conversion tables are GNU libiconv's.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "subconv.h"
#include <iconv.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include "platform.h"
namespace {
/* Valid UTF-8 (no overlongs, no surrogates, nothing past U+10FFFF). */
bool is_utf8(const std::string &s)
{
const unsigned char *p = (const unsigned char *)s.data(), *end = p + s.size();
while (p < end) {
unsigned c = *p;
if (c < 0x80) {
p++;
continue;
}
int n = c >= 0xF0 && c <= 0xF4 ? 3 : c >= 0xE0 ? 2 : c >= 0xC2 && c <= 0xDF ? 1 : -1;
if (n < 0 || c > 0xF4 || end - p <= n)
return false;
uint32_t cp = c & (0x3F >> n);
for (int i = 1; i <= n; i++) {
if ((p[i] & 0xC0) != 0x80)
return false;
cp = cp << 6 | (p[i] & 0x3F);
}
if ((n == 2 && cp < 0x800) || (n == 3 && (cp < 0x10000 || cp > 0x10FFFF)) || (cp >= 0xD800 && cp <= 0xDFFF))
return false;
p += n + 1;
}
return true;
}
/* The code page subtitles in that language are usually saved in when they
* aren't Unicode (what Windows' "ANSI" was for it). */
const char *legacy_encoding(const std::string &lang)
{
std::string l = lang.substr(0, lang.find('-'));
if (lang == "zh-TW" || lang == "zh-HK" || lang == "zht")
return "BIG5-HKSCS";
if (l == "zh" || l == "chi" || l == "zho")
return "GB18030";
if (l == "ja" || l == "jpn")
return "CP932";
if (l == "ko" || l == "kor")
return "CP949";
if (l == "ru" || l == "rus" || l == "uk" || l == "ukr" || l == "bg" || l == "bul" || l == "sr" || l == "mk" || l == "be")
return "CP1251";
if (l == "ar" || l == "ara" || l == "fa" || l == "per" || l == "fas" || l == "ur")
return "CP1256";
if (l == "he" || l == "heb")
return "CP1255";
if (l == "tr" || l == "tur")
return "CP1254";
if (l == "el" || l == "gre" || l == "ell")
return "CP1253";
if (l == "pl" || l == "pol" || l == "cs" || l == "cze" || l == "ces" || l == "sk" || l == "hu" || l == "hun" ||
l == "ro" || l == "rum" || l == "hr" || l == "sl")
return "CP1250";
if (l == "th" || l == "tha")
return "CP874";
if (l == "vi" || l == "vie")
return "CP1258";
return "CP1252";
}
bool convert(const std::string &in, const char *from, std::string *out)
{
iconv_t cd = iconv_open("UTF-8", from);
if (cd == (iconv_t)-1)
return false;
out->clear();
out->resize(in.size() * 4 + 16);
char *src = (char *)in.data(), *dst = &(*out)[0];
size_t left = in.size(), room = out->size();
bool ok = true;
while (left > 0) {
if (iconv(cd, &src, &left, &dst, &room) == (size_t)-1) {
/* a byte the code page hasn't got: U+FFFD, and on */
if (room < 3) {
ok = false;
break;
}
memcpy(dst, "\xEF\xBF\xBD", 3);
dst += 3;
room -= 3;
src++;
left--;
}
}
iconv_close(cd);
out->resize(out->size() - room);
return ok;
}
std::string copy_dir()
{
std::string d = std::string(plat_data_dir()) + "/cache";
mkdir(d.c_str(), 0777);
d += "/subtitles";
mkdir(d.c_str(), 0777);
d += "/converted";
mkdir(d.c_str(), 0777);
return d;
}
} // namespace
std::string subconv_to_utf8(const std::string &bytes, const std::string &lang, std::string *from)
{
if (from)
from->clear();
const unsigned char *b = (const unsigned char *)bytes.data();
std::string out;
if (bytes.size() >= 2 && ((b[0] == 0xFF && b[1] == 0xFE) || (b[0] == 0xFE && b[1] == 0xFF))) {
const char *enc = b[0] == 0xFF ? "UTF-16LE" : "UTF-16BE";
if (convert(bytes.substr(2), enc, &out)) {
if (from)
*from = enc;
return out;
}
return bytes;
}
if (is_utf8(bytes))
return bytes;
const char *enc = legacy_encoding(lang);
if (!convert(bytes, enc, &out))
return bytes;
if (from)
*from = enc;
return out;
}
std::string subconv_bytes(const std::string &bytes, const std::string &name, const std::string &lang)
{
std::string from;
std::string utf8 = subconv_to_utf8(bytes, lang, &from);
if (from.empty())
return "";
/* The name kept (VLC shows it, and finds the format by its extension). */
std::string base = name.substr(name.rfind('/') + 1);
std::string path = copy_dir() + "/" + base;
FILE *f = fopen(path.c_str(), "wb");
if (!f)
return "";
fwrite(utf8.data(), 1, utf8.size(), f);
fclose(f);
fprintf(stderr, "subconv: %s read as %s, UTF-8 copy %s\n", base.c_str(), from.c_str(), path.c_str());
return path;
}
std::string subconv_local(const std::string &path, const std::string &lang)
{
FILE *f = fopen(path.c_str(), "rb");
if (!f)
return path;
std::string bytes;
char buf[65536];
size_t n;
/* subtitle files are small: a big one is something else, left alone */
while ((n = fread(buf, 1, sizeof(buf), f)) > 0 && bytes.size() < (16u << 20))
bytes.append(buf, n);
fclose(f);
if (bytes.size() >= (16u << 20))
return path;
std::string copy = subconv_bytes(bytes, path, lang);
return copy.empty() ? path : copy;
}
+27
View File
@@ -0,0 +1,27 @@
/*
* VLC-PS5: subtitle files that aren't UTF-8 (Windows-1252, GBK, Big5, Shift
* JIS, Windows-1256...). The console's VLC has no iconv, so it read them as
* UTF-8 and showed mangled letters; such a file is converted here (GNU
* libiconv) to a UTF-8 copy in cache/subtitles/converted, which VLC gets
* instead.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include <string>
/* The bytes of a subtitle file made UTF-8: as they are when they already are
* (or the encoding can't be told), else converted from UTF-16 (by its BOM)
* or from the legacy code page of lang ("zh-CN", "ar", "ru"...; "" = Western).
* *from says which encoding it was read as ("" = left alone). */
std::string subconv_to_utf8(const std::string &bytes, const std::string &lang, std::string *from = nullptr);
/* A local subtitle file ready for VLC: the path itself when it's UTF-8 (or
* can't be read), else the path of a converted UTF-8 copy. */
std::string subconv_local(const std::string &path, const std::string &lang);
/* The same for bytes already read (a file on a share or a link): the copy's
* path, or "" when they're UTF-8 already and VLC can read the original. name:
* the file's name, for the copy's. */
std::string subconv_bytes(const std::string &bytes, const std::string &name, const std::string &lang);
+310 -47
View File
@@ -171,6 +171,9 @@ std::string vlc_message(const std::string &m)
}
if (m.compare(0, 14, "Please provide") == 0)
return "A Windows PC takes its own account; a NAS, the user you made on it.";
/* libbluray without a JVM (none runs on the console): not "install Java" */
if (m.compare(0, 30, "This Blu-ray disc requires Java") == 0)
return "This Blu-ray's menus are made in Java, which the PS5 can't run: it plays without them";
if (m.compare(0, 6, "Track ") == 0 && m.size() > 6 && isdigit((unsigned char)m[6]))
return trf("Track %d", atoi(m.c_str() + 6));
return m;
@@ -1042,14 +1045,73 @@ bool audio_name(const std::string &name)
return false;
}
/* A file on a share by its name, as ci_file() kinds: 0 video, 1 audio,
* 3 text, 4 image, 5 another file (subtitles, databases...). */
int name_kind(const std::string &name)
{
if (audio_name(name))
return 1;
std::string ext = name.substr(name.rfind('.') + 1);
for (char &c : ext)
c = (char)tolower((unsigned char)c);
for (const char *x : { "jpg", "jpeg", "png", "gif", "bmp", "webp", "tif", "tiff" })
if (ext == x)
return 4;
for (const char *x : { "txt", "nfo", "diz", "log", "md" })
if (ext == x)
return 3;
for (const char *x : { "srt", "ass", "ssa", "sub", "idx", "vtt", "sup", "db", "ini", "sfv", "cue", "exe", "pdf" })
if (ext == x)
return 5;
return 0;
}
/* A list of links (IPTV channels, radio), not a stream: .m3u and .pls, and
* .m3u8 unless it's online (an online .m3u8 is usually a live HLS stream). */
bool is_playlist_url(const std::string &url)
{
std::string u = url.substr(0, url.find('?'));
size_t dot = u.rfind('.');
if (dot == std::string::npos || u.find('/', dot) != std::string::npos)
return false;
const char *x = u.c_str() + dot + 1;
if (!strcasecmp(x, "m3u8"))
return u.compare(0, 4, "http") != 0;
return !strcasecmp(x, "m3u") || !strcasecmp(x, "pls");
}
/* file:///abs/path with everything but plain characters escaped. */
std::string file_uri(std::string path)
{
std::string uri = "file://";
if (path[0] != '/') { /* the test build's data folder is relative */
char cwd[1024];
if (getcwd(cwd, sizeof(cwd)))
path = std::string(cwd) + "/" + path;
}
for (unsigned char c : path) {
if (isalnum(c) || strchr("/-_.~", c)) {
uri += (char)c;
} else {
char hex[4];
snprintf(hex, sizeof(hex), "%%%02X", c);
uri += hex;
}
}
return uri;
}
void rebuild_browse()
{
browse_entries.clear();
auto &items = L();
if (!net_path.empty()) {
if (net_list_state() == NET_READY)
for (const NetEntry &e : net_list_entries())
browse_entries.push_back({ e.name, e.url, e.dir, -1, false, e.dir ? NET_DIR : NET_FILE });
for (const NetEntry &e : net_list_entries()) {
/* a channel list on a share opens like a folder */
bool list = !e.dir && is_playlist_url(e.url);
browse_entries.push_back({ e.name, e.url, e.dir, -1, list, e.dir || list ? NET_DIR : NET_FILE });
}
return;
}
if (browse_dir.empty()) {
@@ -1252,9 +1314,26 @@ int current_item()
return m ? (int)(m - &L()[0]) : -1;
}
void net_enter(const std::string &url, const std::string &name);
/* A playlist with links (IPTV channels, radio): its entries in Browse, where
* each one plays as a stream. */
void open_channel_list(const std::string &path)
{
std::string name = path.substr(path.rfind('/') + 1);
name = name.substr(0, name.rfind('.'));
screen = LIBRARY;
tab = BROWSE;
net_enter(file_uri(path), name);
}
/* A playlist file: its files, from the first (or a random one with shuffle). */
void play_playlist(const std::string &path)
{
if (library_playlist_has_links(path)) {
open_channel_list(path);
return;
}
std::vector<int> list = library_playlist_items(path);
if (list.empty()) {
toast("No files of this playlist are in the library", 3);
@@ -2032,6 +2111,23 @@ const std::vector<int> &playlist_items_cached(const std::string &path)
return c.items;
}
/* How many entries a playlist names: its library files, or every line of a
* channel list (links aren't library files). */
int playlist_count_cached(const std::string &path)
{
struct Cached {
double at;
int n;
};
static std::unordered_map<std::string, Cached> cache;
Cached &c = cache[path];
if (c.at == 0 || now - c.at > 3) {
c.n = library_playlist_has_links(path) ? library_playlist_count(path) : (int)playlist_items_cached(path).size();
c.at = now;
}
return c.n;
}
/* A picture covering (x, y, w, h): the thumbnail cropped to that shape. */
void thumb_cover(const MediaItem &m, float x, float y, float w, float h, float round, ImDrawFlags corners)
{
@@ -2118,8 +2214,7 @@ void playlist_card(float x, float y, float w, const PlaylistFile *pl, float f)
if (pl) {
playlist_cover(pl->path, cx, cy, cw, ch, 16);
/* how many, bottom right, like a video's length */
const std::vector<int> &items = playlist_items_cached(pl->path);
std::string count = std::to_string(items.size());
std::string count = std::to_string(playlist_count_cached(pl->path));
float tw = text_size(f_semi, 18, count.c_str()).x;
rect(cx + cw - tw - 54, cy + ch - 40, tw + 44, 28, IM_COL32(0, 0, 0, 170), 8);
icon_list(cx + cw - tw - 38, cy + ch - 26, 16, C_TEXT);
@@ -2164,6 +2259,8 @@ void tab_playlists()
if (pl_focus == 0) {
pl_add_file.clear();
open_playlist_name("");
} else if (library_playlist_has_links(pls[pl_focus - 1].path)) {
open_channel_list(pls[pl_focus - 1].path);
} else {
pl_open = pls[pl_focus - 1].path;
pl_item_focus = 0;
@@ -2394,26 +2491,11 @@ void net_enter(const std::string &url, const std::string &name);
void open_archive(const MediaItem &m)
{
std::string uri = "file://", path = m.path;
if (path[0] != '/') { /* the test build's data folder is relative */
char cwd[1024];
if (getcwd(cwd, sizeof(cwd)))
path = std::string(cwd) + "/" + path;
}
for (unsigned char c : path) {
if (isalnum(c) || strchr("/-_.~", c)) {
uri += (char)c;
} else {
char hex[4];
snprintf(hex, sizeof(hex), "%%%02X", c);
uri += hex;
}
}
tab = BROWSE;
std::string ext = m.ext;
for (char &c : ext)
c = (char)tolower((unsigned char)c);
net_enter(uri, m.name + "." + ext);
net_enter(file_uri(m.path), m.name + "." + ext);
}
/* Opens a network place in Browse (a server, or a folder on it). */
@@ -2426,6 +2508,80 @@ void net_enter(const std::string &url, const std::string &name)
rebuild_browse();
}
/* ---- picking a subtitle file for the video playing (Tracks › Add a
* subtitle file): Browse, from anywhere it reaches, then back to the video */
std::string link_name(const std::string &url);
bool sub_pick;
bool sub_pick_resume; /* it was playing: it plays on after */
std::string sub_pick_dir;
std::vector<std::pair<std::string, std::string>> sub_pick_net;
void start_sub_pick()
{
pressed = 0; /* the ✕ that asked is used up: the player mustn't pause on it too */
sub_pick = true;
sub_pick_resume = !player_paused();
if (sub_pick_resume)
player_toggle_pause();
fprintf(stderr, "ui: picking a subtitle file (%s)\n", sub_pick_resume ? "paused the video" : "the video was paused");
/* what Browse showed before comes back after */
sub_pick_dir = browse_dir;
sub_pick_net = net_path;
modal = NONE;
screen = LIBRARY;
screen_fade = 0;
tab = BROWSE;
library_set_busy(false);
/* It starts at the top (Sources): the media folder, drives and shares
* alike, whatever the video came from; a subtitle can be anywhere. */
net_path.clear();
browse_dir.clear();
net_list_stop();
rebuild_browse();
browse_focus = 0;
browse_scroll = 0;
}
void end_sub_pick(std::string picked) /* a copy: it may be a Browse entry, and Browse is rebuilt below */
{
pressed = 0;
sub_pick = false;
net_path = sub_pick_net;
browse_dir = sub_pick_dir;
if (!net_path.empty())
net_list(net_path.back().first);
else
net_list_stop();
rebuild_browse();
browse_focus = 0;
screen = PLAYER;
screen_fade = 0;
library_set_busy(true);
osd_until = now + 3.5;
/* playing again first: a subtitle added to a paused file left VLC paused
* after the resume */
if (sub_pick_resume && player_paused())
player_toggle_pause();
if (!picked.empty()) {
std::string name = picked.find("://") != std::string::npos ? link_name(picked)
: picked.substr(picked.rfind('/') + 1);
if (player_add_subtitle(picked))
toast(trf("Subtitles: %s", name.c_str()), 2.5);
else
toast("Couldn't load that subtitle file", 2.5);
}
fprintf(stderr, "ui: subtitle pick done (%s)\n", picked.empty() ? "none" : "picked");
}
/* ✕ on a file while picking: a subtitle file goes in, anything else says so. */
void sub_pick_file(std::string path, std::string name) /* copies, as above */
{
if (player_is_subtitle_name(name))
end_sub_pick(path);
else
toast("That isn't a subtitle file (.srt, .ass, .vtt...)", 2.5);
}
/* "1.4 GB" */
std::string size_text(int64_t bytes)
{
@@ -2454,7 +2610,9 @@ void classic_label(const BrowseEntry &e, std::string *name, std::string *type, i
*type = e.path == "tv:" ? "Channel lists (iptv-org)" : "Stations (radio-browser.info)";
*group = 2;
} else if (e.net == NET_DIR) {
*type = "File folder";
*type = e.playlist ? "Playlist" : "File folder";
if (e.playlist && e.name.rfind('.') != std::string::npos && e.name.rfind('.') > 0)
*name = e.name.substr(0, e.name.rfind('.')); /* like local playlists */
} else if (e.net == NET_FILE) {
size_t dot = e.name.rfind('.');
bool has_ext = dot != std::string::npos && dot > 0 && e.name.size() - dot <= 6;
@@ -2464,7 +2622,10 @@ void classic_label(const BrowseEntry &e, std::string *name, std::string *type, i
std::string ext = e.name.substr(dot + 1);
for (char &c : ext)
c = (char)toupper((unsigned char)c);
*type = ext + (audio_name(e.name) ? " audio" : " video");
int k = name_kind(e.name);
*type = k == 3 ? std::string(tr("Text document"))
: k == 5 ? trf("%s file", ext.c_str())
: trf(k == 4 ? "%s image" : k == 1 ? "%s audio" : "%s video", ext.c_str());
} else {
*type = "Live stream";
}
@@ -2490,7 +2651,7 @@ void classic_label(const BrowseEntry &e, std::string *name, std::string *type, i
*type = "File folder";
} else if (e.item >= 0 && L()[e.item].disc) {
const MediaItem &m = L()[e.item];
*type = m.ext == "ISO" ? "Disc image (ISO)" : m.ext == "DVD" ? "DVD (folder)" : "Blu-ray (folder)";
*type = m.ext == "ISO" || m.ext == "IMG" ? "Disc image (ISO)" : m.ext == "DVD" ? "DVD (folder)" : "Blu-ray (folder)";
} else if (e.item >= 0 && L()[e.item].archive) {
*type = trf("Compressed (%s)", L()[e.item].ext.c_str());
} else if (e.item >= 0 && L()[e.item].other) {
@@ -2511,7 +2672,7 @@ void classic_icon(const BrowseEntry &e, float cx, float cy, float s)
else if (e.net == NET_ONLINE)
e.path == "tv:" ? ci_tv(cx, cy, s) : ci_radio(cx, cy, s);
else if (e.net == NET_FILE)
ci_file(cx, cy, s, audio_name(e.name) ? 1 : 0);
ci_file(cx, cy, s, name_kind(e.name));
else if (e.dir && browse_dir.empty() && net_path.empty() && e.net == NET_NONE)
e.path == library_media_dir() ? ci_folder(cx, cy, s) : ci_drive(cx, cy, s, e.path.find("/usb") != std::string::npos);
else if (e.dir)
@@ -2548,7 +2709,7 @@ void browse_draw_classic()
tri(106, ay + ah / 2, 118, ay + ah / 2 - 10, 118, ay + ah / 2 + 10, arrow);
rect(117, ay + ah / 2 - 3.5f, 13, 7, arrow);
/* the path, in segments */
std::vector<std::string> segs = { "Sources" };
std::vector<std::string> segs = { sub_pick ? "Pick a subtitle file" : "Sources" };
/* an archive opened from a folder: the folder's path, then inside it */
bool in_archive = !net_path.empty() && net_path[0].first.compare(0, 7, "file://") == 0;
if (!net_path.empty() && !in_archive)
@@ -2803,6 +2964,14 @@ void tab_browse()
toast(std::string(1, letter_of(names[to])), 0.8);
}
}
if (sub_pick && hit(PAD_CIRCLE) && net_path.empty() && browse_dir.empty()) {
end_sub_pick(""); /* ○ at the top: back to the video, nothing picked */
return;
}
if (sub_pick && hit(PAD_CROSS) && n && browse_entries[browse_focus].net == NET_FILE) {
sub_pick_file(browse_entries[browse_focus].path, browse_entries[browse_focus].name);
return;
}
if (hit(PAD_CROSS) && n && browse_entries[browse_focus].net != NET_NONE) {
BrowseEntry e = browse_entries[browse_focus];
if (e.net == NET_ADD) {
@@ -2840,8 +3009,14 @@ void tab_browse()
rebuild_browse();
return;
}
if (sub_pick) {
std::string path = e.item >= 0 ? L()[e.item].path : e.path;
sub_pick_file(path, path.substr(path.rfind('/') + 1));
return;
}
if (e.playlist) {
play_playlist(e.path);
/* its entries, like a folder: pick a channel or a song */
net_enter(file_uri(e.path), e.name);
return;
}
std::vector<int> list;
@@ -2870,7 +3045,7 @@ void tab_browse()
return;
}
/* Breadcrumb: "Media › Movies", not the raw path. */
std::string crumb = tr("Sources");
std::string crumb = tr(sub_pick ? "Pick a subtitle file" : "Sources");
bool in_archive = !net_path.empty() && net_path[0].first.compare(0, 7, "file://") == 0;
if (!net_path.empty() && !in_archive)
crumb = tr("Network");
@@ -2909,8 +3084,17 @@ void tab_browse()
icon_radio(146, y + 33, 34, mix(C_DIM, C_ORANGE, f));
else if (e.net == NET_ADD)
icon_plus_circle(146, y + 33, 32, mix(C_DIM, C_ORANGE, f));
else if (e.net == NET_FILE)
audio_name(e.name) ? icon_note(146, y + 33, 28, C_DIM) : icon_film(146, y + 33, 34, C_DIM);
else if (e.net == NET_FILE) {
int k = name_kind(e.name);
if (k == 1)
icon_note(146, y + 33, 28, C_DIM);
else if (k == 4)
icon_picture(146, y + 33, 34, C_DIM);
else if (k == 3 || k == 5)
icon_list(146, y + 33, 30, k == 5 ? C_FAINT : C_DIM);
else
icon_film(146, y + 33, 34, C_DIM);
}
else if (e.dir)
icon_folder(146, y + 33, 34, mix(C_DIM, C_ORANGE, f));
else if (e.playlist)
@@ -3389,8 +3573,25 @@ std::string stream_name;
void start_stream(const std::string &url, const std::vector<std::string> &options, bool remember,
const std::string &name, libvlc_media_t *media)
{
if (is_playlist_url(url)) {
/* A channel list (typed, or a file on a share): its entries in Browse. */
if (remember)
remember_link(url);
screen = LIBRARY;
tab = BROWSE;
net_enter(url, name.empty() ? link_name(url) : name);
return;
}
music_bg = false;
stream_options = options;
std::vector<std::string> opts = options;
std::string bare = url.substr(0, url.find('?'));
if (bare.size() > 4 && (!strcasecmp(bare.c_str() + bare.size() - 4, ".iso") || !strcasecmp(bare.c_str() + bare.size() - 4, ".img")) && url.compare(0, 7, "file://") != 0 &&
std::find(opts.begin(), opts.end(), ":demux=dvd,any") == opts.end())
/* A disc image on a share or a link: VLC's DVD reader only tries it by
* itself on fast-seeking sources (not SMB), so ask for it first; a
* Blu-ray image falls through to the Blu-ray reader ("any"). */
opts.push_back(":demux=dvd,any");
stream_options = opts;
stream_remember = remember;
stream_name = name;
playing_path = url;
@@ -3402,11 +3603,11 @@ void start_stream(const std::string &url, const std::vector<std::string> &option
library_set_busy(true);
bool opened;
if (media) {
for (const std::string &o : options)
for (const std::string &o : opts)
libvlc_media_add_option(media, o.c_str());
opened = player_open_media(media, url, 0);
opened = player_open_media(media, url, 0, opts);
} else {
opened = player_open(url, 0, options);
opened = player_open(url, 0, opts);
}
if (!opened) {
toast("Couldn't open that link", 3);
@@ -4558,13 +4759,13 @@ void setup_begin(bool with_logo);
enum {
ST_DECODING, ST_ALANG, ST_SLANG, ST_SOUND, ST_NIGHT, ST_SPEAKERS, ST_THEME, ST_HAPTICS,
ST_SWIPES, ST_REPEAT, ST_SHUFFLE, ST_DEBUG, ST_STORAGE, ST_VERSION, ST_RELOAD, ST_ABOUT,
ST_WEB, ST_LOOK, ST_OSUB, ST_UILANG, ST_SETUP, ST_COUNT
ST_WEB, ST_LOOK, ST_OSUB, ST_UILANG, ST_SETUP, ST_BDREGION, ST_COUNT
};
const char *const st_labels[ST_COUNT] = {
"Decoding", "Audio language", "Subtitle language", "Sound output", "Night mode",
"Speaker test", "Theme", "Controller vibration", "Touchpad swipes", "Repeat the list", "Shuffle",
"Detailed log", "Storage", "Version", "Reload drives", "About VLC", "Phone access", "Look",
"Subtitle downloads", "Language", "Run setup again",
"Subtitle downloads", "Language", "Run setup again", "Blu-ray region",
};
/* One line under the focused setting: what it does. */
const char *const st_help[ST_COUNT] = {
@@ -4589,6 +4790,7 @@ const char *const st_help[ST_COUNT] = {
"Your own free OpenSubtitles API key (and account), here or from the phone page",
"The language of VLC's menus",
"Language, look and playback, chosen again",
"A: the Americas and East Asia. B: Europe, Africa and Oceania. C: China, Russia and India",
};
/* Categories: an icon, a name, and their settings. */
@@ -4599,7 +4801,7 @@ struct SettingsCat {
};
enum { SI_PLAY, SI_SOUND, SI_THEME, SI_LIST, SI_GEAR };
const SettingsCat settings_cats[] = {
{ "Playback", SI_PLAY, { ST_DECODING, ST_ALANG, ST_SLANG, ST_OSUB } },
{ "Playback", SI_PLAY, { ST_DECODING, ST_ALANG, ST_SLANG, ST_OSUB, ST_BDREGION } },
{ "Sound", SI_SOUND, { ST_SOUND, ST_NIGHT, ST_SPEAKERS } },
{ "Interface", SI_THEME, { ST_UILANG, ST_LOOK, ST_THEME, ST_SWIPES } },
{ "Playlists", SI_LIST, { ST_REPEAT, ST_SHUFFLE } },
@@ -4724,6 +4926,7 @@ void setting_icon(int id, float cx, float cy, float s, ImU32 col)
case ST_DECODING: si_chip(cx, cy, s, col); break;
case ST_ALANG: case ST_UILANG: si_globe(cx, cy, s, col); break;
case ST_SLANG: case ST_OSUB: icon_cc(cx, cy, s * 0.9f, col); break;
case ST_BDREGION: si_globe(cx, cy, s, col); break;
case ST_SOUND: icon_speaker(cx, cy, s * 0.85f, col); break;
case ST_NIGHT: si_moon(cx, cy, s, col); break;
case ST_SPEAKERS: si_surround(cx, cy, s, col); break;
@@ -4794,6 +4997,7 @@ std::string st_value(int id)
}
case ST_WEB: return web_running() ? "On" : "Off";
case ST_ABOUT: return "v" VLC_PS5_VERSION;
case ST_BDREGION: return trf("Region %s", player_bluray_region().c_str());
default: return "";
}
}
@@ -4807,6 +5011,14 @@ void st_change(int id, int step)
break;
case ST_ALANG: cycle_language(false, dir); break;
case ST_SLANG: cycle_language(true, dir); break;
case ST_BDREGION: {
static const char *const regions[3] = { "A", "B", "C" };
std::string r = player_bluray_region();
int i = r == "B" ? 1 : r == "C" ? 2 : 0;
player_set_bluray_region(regions[(i + 3 + dir) % 3]);
toast("Blu-ray region: from the next disc you open", 2.5);
break;
}
case ST_SOUND:
player_set_audio_output(!player_audio_output());
toast(player_audio_output() ? "Surround: 5.1 / 7.1 files from the next one you open" : "Stereo from the next file", 3);
@@ -5414,12 +5626,24 @@ struct PanelEntry {
std::string shown; /* kind 7: the value, right-aligned */
};
/* A disc plays: from the library, dvd:// / bluray://, or an .iso / .img
* from a share or a link. */
bool playing_disc()
{
int cur_item = current_item();
std::string bare = playing_path.substr(0, playing_path.find('?'));
return (cur_item >= 0 && L()[cur_item].disc) || playing_path.compare(0, 6, "dvd://") == 0 ||
playing_path.compare(0, 9, "bluray://") == 0 ||
(bare.size() > 4 && (!strcasecmp(bare.c_str() + bare.size() - 4, ".iso") || !strcasecmp(bare.c_str() + bare.size() - 4, ".img")));
}
/* The settings rows (PanelEntry kind 7). */
enum {
SET_AUDIO_DELAY, SET_EQ, SET_SUB_DELAY, SET_SUB_SIZE, SET_SUB_COLOUR, SET_SUB_BOX, SET_SLEEP,
SET_LOOP, SET_DEINT, SET_BRIGHT, SET_CONTRAST, SET_SAT, SET_GAMMA, SET_HUE, SET_ROTATE, SET_FLIP,
SET_SHARPEN, SET_PIC_RESET,
SET_SOUND_OUT, SET_NIGHT, SET_REPEAT, SET_SHUFFLE, SET_BOOKMARK, SET_BM_CLEAR, SET_OSUB,
SET_DISC_MENU, SET_POPUP, SET_SUB_PICK,
};
std::string ms_text(int64_t ms)
@@ -5503,6 +5727,18 @@ void setting_change(int id, int step)
if (step == 0)
open_osub_results();
return;
case SET_SUB_PICK:
if (step == 0)
start_sub_pick();
return;
case SET_DISC_MENU:
case SET_POPUP:
/* the menu shows over the film: the panel gets out of its way */
if (step == 0) {
player_disc_menu(id == SET_POPUP);
modal = NONE;
}
return;
case SET_AUDIO_DELAY:
player_set_audio_delay(step ? player_audio_delay() + step * 50 : 0);
break;
@@ -5664,12 +5900,18 @@ void modal_tracks()
}
for (const std::string &f : files)
e.push_back({ 6, 0, trf("Load %s", f.substr(f.rfind('/') + 1).c_str()), false, f });
e.push_back({ 7, SET_SUB_PICK, "Add a subtitle file", false, "" });
e.push_back({ 7, SET_OSUB, "Download subtitles", false, "" });
}
if (all || panel_section == SEC_SPEED) {
e.push_back({ 0, 0, "Playback", false, "" });
e.push_back({ 7, SET_REPEAT, "Loop this video", false, "" });
e.push_back({ 7, SET_SHUFFLE, "Shuffle", false, "" });
if (playing_disc()) {
e.push_back({ 7, SET_DISC_MENU, "Disc menu", false, "" });
if (player_disc_has_popup())
e.push_back({ 7, SET_POPUP, "Pop-up menu", false, "" });
}
e.push_back({ 7, SET_SLEEP, "Sleep timer", false, "" });
e.push_back({ 7, SET_LOOP, "A-B repeat", false, "" });
e.push_back({ 7, SET_BOOKMARK, "Add a bookmark here", false, "" });
@@ -5852,7 +6094,7 @@ void modal_tracks()
const char *act = id == SET_LOOP ? (loop_a < 0 ? "Mark A" : loop_b < 0 ? "Mark B" : "Clear")
: id == SET_SUB_BOX || id == SET_NIGHT || id == SET_SOUND_OUT || id == SET_SHUFFLE ? "Switch"
: id == SET_REPEAT ? "Switch" : id == SET_BOOKMARK ? "Add"
: id == SET_BM_CLEAR ? "Clear" : "Reset";
: id == SET_BM_CLEAR ? "Clear" : id == SET_DISC_MENU || id == SET_POPUP || id == SET_SUB_PICK ? "Open" : "Reset";
hints(1920 - 48, 1040, { { PAD_CROSS, act }, { PAD_CIRCLE, "Close" } }, a);
}
else
@@ -6614,16 +6856,23 @@ void player_screen()
}
/* A disc: the d-pad and ✕ drive its menu while the controls are hidden
* (the touchpad brings them up). */
int cur_item = current_item();
bool disc = (cur_item >= 0 && L()[cur_item].disc) || playing_path.compare(0, 6, "dvd://") == 0 ||
playing_path.compare(0, 9, "bluray://") == 0;
bool disc = playing_disc();
const uint32_t menu_keys = PAD_UP | PAD_DOWN | PAD_LEFT | PAD_RIGHT | PAD_CROSS;
bool menu_press = disc && modal == NONE && !osd_was_up && !paused && (pressed & menu_keys);
/* A disc menu with buttons on screen (in the film ✕ pauses as usual): the
* D-pad and ✕ press its buttons straight away, and the controls stay out
* of the way unless the touchpad asked for them. */
static bool osd_touch; /* the controls were brought up with the touchpad */
if (now >= osd_until)
osd_touch = false;
bool in_menu = disc && player_in_menu() && modal == NONE && !paused;
if (in_menu && !osd_touch)
osd_until = std::min(osd_until, now);
bool menu_press = in_menu && !(osd_was_up && osd_touch) && (pressed & menu_keys);
if (menu_press) {
player_navigate(hit(PAD_CROSS) ? 0 : hit(PAD_UP) ? 1 : hit(PAD_DOWN) ? 2 : hit(PAD_LEFT) ? 3 : 4);
pressed &= ~menu_keys;
}
if (pressed && modal == NONE)
if (pressed && modal == NONE && (!in_menu || osd_touch))
osd_until = now + 4.0;
bool osd = now < osd_until || paused || scrubbing;
@@ -6652,6 +6901,7 @@ void player_screen()
return;
} else if (hit(PAD_TOUCHPAD)) {
osd_until = osd ? now : now + 4.0;
osd_touch = !osd;
} else if (hit(PAD_L1) || hit(PAD_R1)) {
std::vector<Chapter> ch = player_chapters();
if (ch.empty()) {
@@ -6867,6 +7117,10 @@ void player_screen()
meta += " \xC2\xB7 " + v.codec;
if (v.ten_bit)
meta += " \xC2\xB7 10-bit";
if (v.hdr)
meta += v.hdr == 2 ? " \xC2\xB7 HLG" : " \xC2\xB7 HDR10";
if (v.hardware)
meta += " \xC2\xB7 HW";
}
if (!v.audio_codec.empty()) {
meta += (meta.empty() ? "" : " \xC2\xB7 ") + v.audio_codec;
@@ -7592,7 +7846,9 @@ void ui_frame(const PadState &pad, float frame_dt)
} else {
background();
tab_bar();
if (modal == NONE) {
if (sub_pick)
tab = BROWSE; /* picking: Browse only */
if (modal == NONE && !sub_pick) {
if (hit(PAD_L1))
tab = (Tab)((tab + TABS - 1) % TABS);
if (hit(PAD_R1))
@@ -7601,12 +7857,12 @@ void ui_frame(const PadState &pad, float frame_dt)
uint32_t keep = pressed;
if (modal != NONE)
pressed = 0;
if (modal == NONE && hit(PAD_R3)) {
if (modal == NONE && !sub_pick && hit(PAD_R3)) {
open_search();
modal_anim = 1;
pressed = 0;
}
if (modal == NONE)
if (modal == NONE && !sub_pick)
library_actions();
switch (tab) {
case HOME: tab_home(); break;
@@ -7640,8 +7896,15 @@ void ui_frame(const PadState &pad, float frame_dt)
h.push_back({ PAD_CIRCLE, "Back" });
if (tab == PLAYLISTS)
h = playlist_hints();
h.push_back({ PAD_R3, "Search" });
h.push_back({ PAD_OPTIONS, "Options" });
if (sub_pick) {
bool file = browse_focus < (int)browse_entries.size() && !browse_entries[browse_focus].dir &&
(browse_entries[browse_focus].net == NET_FILE || browse_entries[browse_focus].net == NET_NONE);
h = { { PAD_CROSS, file ? "Add" : "Open" },
{ PAD_CIRCLE, browse_dir.empty() && net_path.empty() ? "Cancel" : "Back" } };
} else {
h.push_back({ PAD_R3, "Search" });
h.push_back({ PAD_OPTIONS, "Options" });
}
if (classic_look) {
if (tab == PLAYLISTS) {
if (pl_open.empty())
+6
View File
@@ -462,6 +462,12 @@ void web_start()
a.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listen_fd, (sockaddr *)&a, sizeof(a)) == 0)
break;
if (errno == EACCES) {
/* the sandbox: no port will do */
fprintf(stderr, "web: not allowed to listen (sandboxed: the page needs full access)\n");
p = LAST_PORT + 1;
break;
}
fprintf(stderr, "web: port %d taken (errno %d)\n", p, errno);
}
if (p > LAST_PORT || listen(listen_fd, 8) != 0) {