summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--flake.lock18
-rw-r--r--flake.nix21
-rwxr-xr-xpackage/build_flatpak.sh3
-rw-r--r--package/city.akon.Sink.yml36
-rw-r--r--package/sink.desktop14
-rwxr-xr-xscripts/adb_logcat.sh8
-rwxr-xr-xscripts/shaderc_deps.sh21
-rw-r--r--src/buffer/common.h3
-rw-r--r--src/buffer/video.c2
-rw-r--r--src/cache/handlers/http.c2
-rw-r--r--src/codec/codecs.c16
-rw-r--r--src/codec/codecs.h3
-rw-r--r--src/codec/ffmpeg/decoder.c9
-rw-r--r--src/codec/ffmpeg/meson.build4
-rw-r--r--src/fruits/cmc/ui/widgets/now_playing.c21
-rw-r--r--src/fruits/cmsrv/cmsrv.c76
-rw-r--r--src/fruits/cmv/cmv.c22
-rwxr-xr-xsrc/fruits/cmv/create_icon.sh4
-rw-r--r--src/fruits/cmv/meson.build10
-rw-r--r--src/liana/common.h4
-rw-r--r--src/liana/handlers/codec_server.c4
-rw-r--r--src/liana/list.h12
-rw-r--r--src/liana/vcr.c2
-rw-r--r--src/libsink/desktop.c14
-rw-r--r--src/portal/py/modules/__init__.py8
-rw-r--r--src/portal/py/modules/instagram.py4
-rw-r--r--src/render/meson.build8
-rw-r--r--src/render/renderer_libplacebo.c130
-rw-r--r--src/render/renderer_libplacebo.h2
-rw-r--r--src/render/renderer_momo.c6
-rw-r--r--src/render/shaders/osd.h22
-rw-r--r--src/render/shaders/osd_binds.h575
-rw-r--r--src/render/shaders/osd_header.h28
-rw-r--r--src/screen/screen.c250
-rw-r--r--src/screen/screen.h22
-rw-r--r--src/screen/view.c3
-rw-r--r--src/screen/view.h1
-rw-r--r--src/server/server.c7
-rw-r--r--src/server/server.h2
-rw-r--r--src/util/color_palette.c3
-rw-r--r--src/util/color_palette.h1
-rw-r--r--subprojects/SPIRV-Cross.wrap5
-rw-r--r--subprojects/SPIRV-Headers.wrap3
-rw-r--r--subprojects/ffmpeg2.wrap2
-rw-r--r--subprojects/ffmpeg5.wrap10
-rw-r--r--subprojects/ffmpeg6.wrap10
-rw-r--r--subprojects/ffmpeg7.wrap10
-rw-r--r--subprojects/ffmpeg8.wrap15
-rw-r--r--subprojects/harfbuzz.wrap5
-rw-r--r--subprojects/libalabaster.wrap4
-rw-r--r--subprojects/libplacebo.wrap10
-rw-r--r--subprojects/notcurses.wrap2
-rw-r--r--subprojects/packagefiles/ffmpeg/meson.build20
-rw-r--r--subprojects/packagefiles/ffmpeg/version_2.8.22.diff57
-rw-r--r--subprojects/packagefiles/ffmpeg/version_3.3.9.diff40
-rw-r--r--subprojects/packagefiles/ffmpeg/version_3.4.14.diff32
-rw-r--r--subprojects/packagefiles/ffmpeg/version_4.2.11.diff35
-rw-r--r--subprojects/packagefiles/ffmpeg/version_5.1.10.diff (renamed from subprojects/packagefiles/ffmpeg/version_5.1.7.diff)8
-rw-r--r--subprojects/packagefiles/ffmpeg/version_5.1.8.diff29
-rw-r--r--subprojects/packagefiles/ffmpeg/version_6.1.3.diff29
-rw-r--r--subprojects/packagefiles/ffmpeg/version_6.1.6.diff (renamed from subprojects/packagefiles/ffmpeg/version_6.1.4.diff)8
-rw-r--r--subprojects/packagefiles/ffmpeg/version_7.1.3.diff29
-rw-r--r--subprojects/packagefiles/ffmpeg/version_7.1.5.diff (renamed from subprojects/packagefiles/ffmpeg/version_7.1.1.diff)8
-rw-r--r--subprojects/packagefiles/ffmpeg/version_8.0.1.diff29
-rw-r--r--subprojects/packagefiles/ffmpeg/version_8.0.diff29
-rw-r--r--subprojects/packagefiles/ffmpeg/version_8.1.1.diff29
-rw-r--r--subprojects/packagefiles/ffmpeg/version_8.1.2.diff6
-rw-r--r--subprojects/packagefiles/ffmpeg/version_8.1.diff29
-rw-r--r--subprojects/packagefiles/libass/raw_text_fallback.diff27
-rw-r--r--subprojects/packagefiles/shaderc/deps_from_cmake.diff16
-rw-r--r--subprojects/packagefiles/shaderc/no_hlsl_compile.diff13
-rwxr-xr-xsubprojects/packagefiles/shaderc/shaderc_deps.sh27
-rw-r--r--subprojects/packagefiles/shaderc/third_party_fix_build.diff6
-rw-r--r--subprojects/shaderc.wrap1
-rw-r--r--subprojects/stela.wrap4
-rwxr-xr-xtests/runner.sh99
77 files changed, 1123 insertions, 967 deletions
diff --git a/.gitignore b/.gitignore
index 4bc6259..3379763 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,13 +6,16 @@ compile_commands.json
data/
docs/**/*.html
env/msvc-root/
+package/sink.flatpak
result
scripts/host_code
scripts/host_ip
+src/fruits/cmv/sink-*.png
src/portal/cpy/portal.c
src/portal/cpy/portal.h
src/portal/py/config.py
src/portal/vendor/*
+src/render/shaders/*.glsl
subprojects/.wraplock
subprojects/BLAKE3-*/
subprojects/SPIRV-Cross-*/
diff --git a/flake.lock b/flake.lock
index ded0125..2e6b030 100644
--- a/flake.lock
+++ b/flake.lock
@@ -41,11 +41,11 @@
]
},
"locked": {
- "lastModified": 1787778830,
- "narHash": "sha256-GnLPpDT727E6VpDlALP8JeP1BbSQ17H0HiEEYq6Ql4w=",
+ "lastModified": 1788651960,
+ "narHash": "sha256-v9wJd32eZ2bvhBzVOd7TIjLQd011P7nwOhjKtWlci5I=",
"owner": "nix-community",
"repo": "home-manager",
- "rev": "6b449e35980e1b75dd17da2d6d9b66e757194f1c",
+ "rev": "2c0350c759688177331b8f5242311fae8877bdb3",
"type": "github"
},
"original": {
@@ -79,11 +79,11 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
- "lastModified": 1787144466,
- "narHash": "sha256-HHfv2/HkNSKbbSyU9iD/g8lbP6r4tl33sSw1W4rXCk0=",
+ "lastModified": 1788335262,
+ "narHash": "sha256-3jBEq8avfzlrsY4UpW4d5TOmm7ocseZfnitEJhqauyc=",
"owner": "NixOS",
"repo": "nixos-hardware",
- "rev": "0471accf8d0a8210b31d947497d179ecc99e0021",
+ "rev": "44d95795ee2d475b3d687325e26dcf4ca9104557",
"type": "github"
},
"original": {
@@ -159,11 +159,11 @@
},
"nixpkgs_4": {
"locked": {
- "lastModified": 1787498568,
- "narHash": "sha256-9i/VTdusq/+NM/tz+J1Re+ojkMB8MBf0QshnYfzHz30=",
+ "lastModified": 1788614874,
+ "narHash": "sha256-7QYjT2vHLuX9Z1pdxHXDKCbh1CR3D/2rywB9Tx0MPRg=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "56c02bc00adcf003215cc4bd996d6efaf4cff188",
+ "rev": "c043004d1c6985732bcc1cbc5a9c9aecbbb4e0f0",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index 83361d2..842bb7f 100644
--- a/flake.nix
+++ b/flake.nix
@@ -466,26 +466,23 @@
};
android = with pkgs; let
- cmakeVersion = "3.22.1";
+ cmakeVersion = "4.1.2";
androidComposition = androidenv.composeAndroidPackages {
- cmdLineToolsVersion = "19.0";
+ cmdLineToolsVersion = "22.0";
toolsVersion = "26.1.1";
platformToolsVersion = "37.0.1";
- buildToolsVersions = [ "36.1.0" ];
- includeEmulator = false;
- emulatorVersion = "35.2.5";
- platformVersions = [ "34" ];
- includeSources = false;
- includeSystemImages = false;
- systemImageTypes = [ "google_apis_playstore" ];
+ buildToolsVersions = [ "37.0.0" ];
+ platformVersions = [ "37.1" ];
abiVersions = [ "armeabi-v7a" "arm64-v8a" ];
cmakeVersions = [ cmakeVersion ];
- includeNDK = true;
- # latest = 28.0.13004108, _counted_by conflict.
ndkVersion = "29.0.14206865";
+ includeNDK = true;
+ includeEmulator = false;
+ includeSources = false;
+ includeSystemImages = false;
+ includeExtras = [ "extras;google;gcm" ];
useGoogleAPIs = false;
useGoogleTVAddOns = false;
- includeExtras = [ "extras;google;gcm" ];
};
in pkgs.mkShell rec {
NIX_HARDENING_ENABLE = "";
diff --git a/package/build_flatpak.sh b/package/build_flatpak.sh
new file mode 100755
index 0000000..a8916a0
--- /dev/null
+++ b/package/build_flatpak.sh
@@ -0,0 +1,3 @@
+#! /usr/bin/sh
+flatpak-builder --force-clean --user --install-deps-from=flathub --repo=repo --install builddir city.akon.Sink.yml
+flatpak build-bundle repo sink.flatpak city.akon.Sink --runtime-repo=https://dl.flathub.org/repo/flathub.flatpakrepo
diff --git a/package/city.akon.Sink.yml b/package/city.akon.Sink.yml
new file mode 100644
index 0000000..3354e87
--- /dev/null
+++ b/package/city.akon.Sink.yml
@@ -0,0 +1,36 @@
+id: city.akon.Sink
+runtime: org.kde.Platform
+runtime-version: '6.11'
+sdk: org.kde.Sdk
+rename-desktop-file: sink.desktop
+rename-icon: sink
+finish-args:
+ - --device=all
+ - --filesystem=host
+ - --socket=pulseaudio
+ - --socket=x11
+ - --socket=wayland
+ - --share=network
+ - --share=ipc
+command: cmv
+modules:
+ - name: sink
+ buildsystem: meson
+ builddir: true
+ build-options:
+ cflags: ''
+ cflags-override: true
+ cxxflags: ''
+ cxxflags-override: true
+ config-opts:
+ - --buildtype=release
+ - -Dfruits=cmv
+ - -Dsources=file
+ - -Dcodecs=ffmpeg,stb_image
+ - -Dwindow=wayland
+ post-install:
+ - desktop-file-edit --set-key=Exec --set-value='/app/bin/cmv %U'
+ /app/share/applications/sink.desktop
+ sources:
+ - type: dir
+ path: ..
diff --git a/package/sink.desktop b/package/sink.desktop
new file mode 100644
index 0000000..f25e210
--- /dev/null
+++ b/package/sink.desktop
@@ -0,0 +1,14 @@
+[Desktop Entry]
+Version=1.0
+Icon=sink
+Exec=cmv %U
+Terminal=false
+Type=Application
+Categories=AudioVideo;Player
+Name=Sink
+GenericName=Media Player
+Comment=The Sink
+# Copied from vlc.desktop.
+MimeType=application/ogg;application/x-ogg;audio/ogg;audio/vorbis;audio/x-vorbis;audio/x-vorbis+ogg;video/ogg;video/x-ogm;video/x-ogm+ogg;video/x-theora+ogg;video/x-theora;audio/x-speex;audio/opus;application/x-flac;audio/flac;audio/x-flac;audio/x-ms-asf;audio/x-ms-asx;audio/x-ms-wax;audio/x-ms-wma;video/x-ms-asf;video/x-ms-asf-plugin;video/x-ms-asx;video/x-ms-wm;video/x-ms-wmv;video/x-ms-wmx;video/x-ms-wvx;video/x-msvideo;audio/x-pn-windows-acm;video/divx;video/msvideo;video/vnd.divx;video/avi;video/x-avi;application/vnd.rn-realmedia;application/vnd.rn-realmedia-vbr;audio/vnd.rn-realaudio;audio/x-pn-realaudio;audio/x-pn-realaudio-plugin;audio/x-real-audio;audio/x-realaudio;video/vnd.rn-realvideo;audio/mpeg;audio/mpg;audio/mp1;audio/mp2;audio/mp3;audio/x-mp1;audio/x-mp2;audio/x-mp3;audio/x-mpeg;audio/x-mpg;video/mp2t;video/mpeg;video/mpeg-system;video/x-mpeg;video/x-mpeg2;video/x-mpeg-system;application/mpeg4-iod;application/mpeg4-muxcodetable;application/x-extension-m4a;application/x-extension-mp4;audio/aac;audio/m4a;audio/mp4;audio/x-m4a;audio/x-aac;video/mp4;video/mp4v-es;video/x-m4v;application/x-quicktime-media-link;application/x-quicktimeplayer;video/quicktime;application/x-matroska;audio/x-matroska;video/x-matroska;video/webm;audio/webm;audio/3gpp;audio/3gpp2;audio/AMR;audio/AMR-WB;video/3gp;video/3gpp;video/3gpp2;x-scheme-handler/mms;x-scheme-handler/mmsh;x-scheme-handler/rtsp;x-scheme-handler/rtp;x-scheme-handler/rtmp;x-scheme-handler/icy;x-scheme-handler/icyx;application/x-cd-image;x-content/audio-player;application/ram;application/xspf+xml;audio/mpegurl;audio/x-mpegurl;audio/scpls;audio/x-scpls;text/google-video-pointer;text/x-google-video-pointer;video/vnd.mpegurl;application/vnd.apple.mpegurl;application/vnd.ms-asf;application/vnd.ms-wpl;application/sdp;audio/dv;video/dv;audio/x-aiff;audio/x-pn-aiff;video/x-anim;video/x-nsv;video/fli;video/flv;video/x-flc;video/x-fli;video/x-flv;audio/wav;audio/x-pn-au;audio/x-pn-wav;audio/x-wav;audio/x-adpcm;audio/ac3;audio/eac3;audio/vnd.dts;audio/vnd.dts.hd;audio/vnd.dolby.heaac.1;audio/vnd.dolby.heaac.2;audio/vnd.dolby.mlp;audio/basic;audio/midi;audio/atrac3;audio/x-ape;audio/x-gsm;audio/x-musepack;audio/x-tta;audio/x-wavpack;audio/x-shorten;application/x-shockwave-flash;application/x-flash-video;misc/ultravox;image/vnd.rn-realpix;audio/x-it;audio/x-mod;audio/x-s3m;audio/x-xm;application/mxf
+X-KDE-Protocols=http,https
+Keywords=Player;DVD;Audio;Video;
diff --git a/scripts/adb_logcat.sh b/scripts/adb_logcat.sh
index 64aac3d..e72aaba 100755
--- a/scripts/adb_logcat.sh
+++ b/scripts/adb_logcat.sh
@@ -1,2 +1,8 @@
#! /usr/bin/env sh
-adb logcat *:S CTV DEBUG
+if [[ $1 == "d" ]]; then
+ adb -d logcat *:S CTV DEBUG
+elif [[ $1 == "e" ]]; then
+ adb -e logcat *:S CTV DEBUG
+else
+ adb logcat *:S CTV DEBUG
+fi
diff --git a/scripts/shaderc_deps.sh b/scripts/shaderc_deps.sh
deleted file mode 100755
index fb3991a..0000000
--- a/scripts/shaderc_deps.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#! /usr/bin/env sh
-
-# We need a better way to do this.
-
-# https://github.com/google/shaderc/blob/known-good/known_good.json
-
-git clone https://github.com/KhronosGroup/glslang.git glslang
-cd glslang
-git checkout 168d452a4f460d24b588fed08477a81c44ee27a1
-cd ../
-
-git clone https://github.com/KhronosGroup/SPIRV-Tools.git spirv-tools
-cd spirv-tools
-git checkout b707790a898e44038547df54580022fc1cf89c3d
-git apply ../../../packagefiles/shaderc/spirv_tools_build_version.diff
-cd ../
-
-git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-headers
-cd spirv-headers
-git checkout 29981f65241605e08b0ede4cfeb999fe3b723c6a
-cd ../
diff --git a/src/buffer/common.h b/src/buffer/common.h
index 701969f..aaf53ea 100644
--- a/src/buffer/common.h
+++ b/src/buffer/common.h
@@ -5,7 +5,8 @@
#include <al/random.h>
#define ROLL_FOR_BUFFER_ERROR(buf) do { \
if (al_random_int(0, 254) == 72) { \
- al_atomic_store(u32)(&(buf)->flow, FLUSHED_ERROR, AL_ATOMIC_RELAXED); \
+ log_warn("Random buffer error proc."); \
+ atomic_store(u32)(&(buf)->flow, FLUSHED_ERROR, AL_ATOMIC_RELAXED); \
} \
} while (0)
#endif
diff --git a/src/buffer/video.c b/src/buffer/video.c
index f7d5e98..19d7aa7 100644
--- a/src/buffer/video.c
+++ b/src/buffer/video.c
@@ -178,7 +178,7 @@ void camu_video_buffer_push(struct camu_video_buffer *buf, struct camu_codec_fra
if (flow != FLOWING) {
// A static buffer will be FLUSHED after any push().
if (buf->is_static) {
- log_warn("Unexpected duplicate frame received.");
+ log_error("Unexpected duplicate frame received.");
}
camu_codec_frame_discard(frame);
return;
diff --git a/src/cache/handlers/http.c b/src/cache/handlers/http.c
index 4fe82e2..ed366fa 100644
--- a/src/cache/handlers/http.c
+++ b/src/cache/handlers/http.c
@@ -1,5 +1,5 @@
#define AL_LOG_SECTION "cache_http"
-#define AL_LOG_ENABLE_TRACE
+//#define AL_LOG_ENABLE_TRACE
#include <al/log.h>
#include <nnwt/common.h>
diff --git a/src/codec/codecs.c b/src/codec/codecs.c
index a373daf..de0a785 100644
--- a/src/codec/codecs.c
+++ b/src/codec/codecs.c
@@ -18,7 +18,8 @@
struct camu_codec_info codec_information[] = {
#ifdef CAMU_HAVE_WUFFS
{
- .name = al_str_c("wuffs"),
+ .id = al_str_c("wuffs"),
+ .name = al_str_c("Wuffs"),
.supported = (s32[]){ CAMU_CODEC_PNG, CAMU_CODEC_NONE },
#ifdef LIANA_SERVER
.create_demuxer = camu_wuffs_demuxer_create,
@@ -30,7 +31,12 @@ struct camu_codec_info codec_information[] = {
#endif
#ifdef CAMU_HAVE_STB_IMAGE
{
+ .id = al_str_c("stbi"),
+#ifdef CAMU_STBI_USE_WUFFS
+ .name = al_str_c("Wuffs (via stb_image API)"),
+#else
.name = al_str_c("stb_image"),
+#endif
.supported = (s32[]){ CAMU_CODEC_PNG, CAMU_CODEC_JPEG, CAMU_CODEC_NONE },
#ifdef LIANA_SERVER
.create_demuxer = camu_stbi_demuxer_create,
@@ -42,6 +48,7 @@ struct camu_codec_info codec_information[] = {
#endif
#ifdef CAMU_HAVE_SPNG
{
+ .id = al_str_c("spng"),
.name = al_str_c("spng"),
.supported = (s32[]){ CAMU_CODEC_PNG, CAMU_CODEC_NONE },
#ifdef LIANA_SERVER
@@ -54,6 +61,7 @@ struct camu_codec_info codec_information[] = {
#endif
#ifdef CAMU_HAVE_FFMPEG
{
+ .id = al_str_c("ff"),
.name = al_str_c("FFmpeg"),
.supported = (s32[]){ CAMU_CODEC_FALLBACK },
#ifdef LIANA_SERVER
@@ -81,13 +89,13 @@ struct camu_codec_info *camu_codec_info_by_type(s32 type)
return NULL;
}
-struct camu_codec_info *camu_codec_info_by_name(str *name)
+struct camu_codec_info *camu_codec_info_by_id(str *id)
{
- if (al_str_eq(name, &al_str_c("pcm_s16le"))) {
+ if (al_str_eq(id, &al_str_c("pcm_s16le"))) {
return (struct camu_codec_info *)0xcdda;
}
for (u32 i = 0; i < ARRAY_SIZE(codec_information); i++) {
- if (al_str_eq(&codec_information[i].name, name)) {
+ if (al_str_eq(&codec_information[i].id, id)) {
return &codec_information[i];
}
}
diff --git a/src/codec/codecs.h b/src/codec/codecs.h
index d383eec..e61ee42 100644
--- a/src/codec/codecs.h
+++ b/src/codec/codecs.h
@@ -3,6 +3,7 @@
#include <al/str.h>
struct camu_codec_info {
+ str id;
str name;
s32 *supported;
struct camu_demuxer *(*create_demuxer)(void);
@@ -12,4 +13,4 @@ struct camu_codec_info {
extern struct camu_codec_info codec_information[];
struct camu_codec_info *camu_codec_info_by_type(s32 type);
-struct camu_codec_info *camu_codec_info_by_name(str *name);
+struct camu_codec_info *camu_codec_info_by_id(str *id);
diff --git a/src/codec/ffmpeg/decoder.c b/src/codec/ffmpeg/decoder.c
index d24677a..95fb0bf 100644
--- a/src/codec/ffmpeg/decoder.c
+++ b/src/codec/ffmpeg/decoder.c
@@ -81,7 +81,7 @@ static s32 init_hwframe_context(struct camu_ff_decoder *av, AVCodecContext *cont
static bool fallback_to_sw_codec(struct camu_ff_decoder *av, const AVCodec *codec)
{
- log_warn("Attempting software decoding fallback...");
+ log_warn("Falling back to software decoding.");
// Remake AVCodecContext as a software decoder.
AVCodecParameters *codecpar = av->codecpar;
av->errored_hw_context = av->codec_context;
@@ -96,7 +96,7 @@ static bool fallback_to_sw_codec(struct camu_ff_decoder *av, const AVCodec *code
return false;
}
log_codec_name(codec, NULL);
- log_info("Using software fallback with %i threads for decoder.", av->thread_count);
+ log_debug("Using software fallback with %i threads for decoder.", av->thread_count);
return true;
}
@@ -248,8 +248,7 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend
}
#ifdef CAMU_FF_DECODER_HWACCEL
av->sw_codec = codec;
- // @TODO: How do you correctly probe avcodec_get_hw_config() if find_decoder()
- // always returns libdav1d first?
+ // @TODO: How to correctly probe avcodec_get_hw_config() if find_decoder() always returns libdav1d first?
if (al_strscmp(codec->name, "libdav1d") == 0) {
if (!(codec = avcodec_find_decoder_by_name("av1"))) {
codec = av->sw_codec;
@@ -333,7 +332,7 @@ static bool ff_decoder_init(struct camu_decoder *dec, struct camu_renderer *rend
// - https://ffmpeg.org/ffmpeg-codecs.html#Codec-Options
av->codec_context->thread_type = FF_THREAD_FRAME;
av->codec_context->thread_count = av->thread_count;
- log_info("Using %i threads for decoder.", av->thread_count);
+ log_debug("Using %i threads for decoder.", av->thread_count);
#ifdef CAMU_FF_DECODER_HWACCEL
}
#endif
diff --git a/src/codec/ffmpeg/meson.build b/src/codec/ffmpeg/meson.build
index 1691c29..401c93a 100644
--- a/src/codec/ffmpeg/meson.build
+++ b/src/codec/ffmpeg/meson.build
@@ -64,13 +64,13 @@ if not ffmpeg_force_fallback
ffmpeg_args += ['-DCAMU_TRY_HWACCEL']
endif
elif ffmpeg_version_option == 'system'
- error('System FFmpeg requested but not found. Add \'--force-fallback-for=ffmpeg\' or \'-Dcodec-ffmpeg-version=[8,7,6,...]\'.')
+ error('System FFmpeg requested but not found. Add \'--force-fallback-for=ffmpeg\' or \'-Dcodec-ffmpeg-version=[9,8,7,...]\'.')
endif
endif
# Fallback if requested or necessary.
if ffmpeg_force_fallback or not libavutil.found()
if ffmpeg_version_option == 'system'
- ffmpeg_version_option = '8' # Default to current latest.
+ ffmpeg_version_option = '9' # Default to current latest.
endif
subproject('ffmpeg' + ffmpeg_version_option) # Override libav dependencies.
endif
diff --git a/src/fruits/cmc/ui/widgets/now_playing.c b/src/fruits/cmc/ui/widgets/now_playing.c
index 56405b3..1a4303d 100644
--- a/src/fruits/cmc/ui/widgets/now_playing.c
+++ b/src/fruits/cmc/ui/widgets/now_playing.c
@@ -162,23 +162,28 @@ void cmc_now_playing_render(struct cmc_now_playing *np, struct cmc_list_entry *e
ncplane_putstr_yx(np->n, 1, x1 + 2, timestr);
if (entry) {
- u32 rslash = al_str_rfind(&entry->brief, '/');
str part;
+ u32 rslash = al_str_rfind(&entry->brief, '/');
if (rslash != AL_STR_NO_POS) {
part = al_str_substr(&entry->brief, rslash + 1, entry->brief.length);
} else {
part = entry->brief;
}
- char *c_str = al_str_to_c_str(&part);
+ // x1 = Position of right side "|".
+ // x2 = First character of entry brief.
s32 x2 = 6 + width1;
- // @TODO: Can mid be negative.
s32 mid = x1 - x2;
- ncplane_putnstr_yx(np->n, 1, x2, MIN(al_strlen(c_str), (size_t)mid), c_str);
- if (part.length >= mid) {
- ncplane_putnstr_yx(np->n, 1, x2 + mid - 1, 1, ".");
- ncplane_putnstr_yx(np->n, 1, x2 + mid - 2, 1, ".");
+ if (mid >= 1) {
+ char *c_str = al_str_to_c_str(&part);
+ ncplane_putnstr_yx(np->n, 1, x2, MIN(al_strlen(c_str), (size_t)mid), c_str);
+ if (part.length >= (u32)mid) {
+ ncplane_putnstr_yx(np->n, 1, x2 + mid - 1, 1, ".");
+ if (mid >= 2) {
+ ncplane_putnstr_yx(np->n, 1, x2 + mid - 2, 1, ".");
+ }
+ }
+ al_free(c_str);
}
- al_free(c_str);
bool visual_cached = false;
struct cmc_now_playing_visual *visual;
diff --git a/src/fruits/cmsrv/cmsrv.c b/src/fruits/cmsrv/cmsrv.c
index b0793d1..452254b 100644
--- a/src/fruits/cmsrv/cmsrv.c
+++ b/src/fruits/cmsrv/cmsrv.c
@@ -30,6 +30,7 @@ struct cmsrv {
struct nn_line_processor cli;
} local;
#endif
+ bool use_ui;
#ifdef CMSRV_USE_UI
struct cmsrv_ui ui;
struct nn_poll input_poll;
@@ -43,14 +44,27 @@ static void close_cmsrv(struct cmsrv *s)
nn_line_processor_stop(&s->local.cli);
#endif
#ifdef CMSRV_USE_UI
- nn_poll_stop(&s->input_poll);
- nn_timer_stop(&s->render_timer);
+ if (s->use_ui) {
+ nn_poll_stop(&s->input_poll);
+ nn_timer_stop(&s->render_timer);
+ }
#endif
camu_server_close(&s->server);
nn_signal_stop(&s->quit_signal);
}
#ifdef CMSRV_LOCAL_SOCKET
+static inline void try_parse_arg_from_line(str *line, u32 offset, s32 *n)
+{
+ str arg = al_str_substr(line, offset, line->length);
+ bool error;
+ s64 i = al_str_to_long(&arg, 10, &error);
+ if (!error) {
+ if (*n < 0) i = -i;
+ *n = CLAMP(i, (s64)INT32_MIN, (s64)INT32_MAX);
+ }
+}
+
static u8 server_line_callback(void *userdata, str *line)
{
struct cmsrv *s = (struct cmsrv *)userdata;
@@ -60,19 +74,13 @@ static u8 server_line_callback(void *userdata, str *line)
} else if (al_str_cmp(line, &al_str_c(";NEXT"), 0, 5) == 0) {
s32 n = 1;
if (line->length > 6) {
- str arg = al_str_substr(line, 6, line->length);
- bool error;
- s64 i = al_str_to_long(&arg, 10, &error);
- if (!error) n = CLAMP(i, (s64)INT32_MIN, (s64)INT32_MAX);
+ try_parse_arg_from_line(line, 6, &n);
}
lia_list_skip(list, LIANA_SEQUENCE_ANY, n);
} else if (al_str_cmp(line, &al_str_c(";PREV"), 0, 5) == 0) {
s32 n = -1;
if (line->length > 6) {
- str arg = al_str_substr(line, 6, line->length);
- bool error;
- s64 i = -al_str_to_long(&arg, 10, &error);
- if (!error) n = CLAMP(i, (s64)INT32_MIN, (s64)INT32_MAX);
+ try_parse_arg_from_line(line, 6, &n);
}
lia_list_skip(list, LIANA_SEQUENCE_ANY, n);
} else if (al_str_cmp(line, &al_str_c(";SEEK"), 0, 5) == 0) {
@@ -93,8 +101,18 @@ static u8 server_line_callback(void *userdata, str *line)
lia_list_reverse(list);
} else if (al_str_eq(line, &al_str_c(";CLEAR"))) {
lia_list_clear(list);
+ } else if (al_str_cmp(line, &al_str_c(";START_AT"), 0, 9) == 0) {
+ if (line->length > 6) {
+ s32 n = 0;
+ try_parse_arg_from_line(line, 10, &n);
+ if (n > 0) {
+ camu_server_local_start_at(&s->server, n);
+ }
+ }
} else if (al_str_eq(line, &al_str_c(";DISCONNECT"))) {
lia_server_force_disconnect_nodes(&s->server.data.server);
+ } else if (al_str_eq(line, &al_str_c(";QUIT"))) {
+ close_cmsrv(s);
} else {
struct nn_packet *packet = nn_packet_create();
nn_packet_write_str(packet, line);
@@ -156,10 +174,17 @@ static void quit_signal_callback(void *userdata)
static struct cmsrv s = { 0 };
+static bool sigint_force = false;
static void sigint_handler(s32 signum)
{
(void)signum;
- nn_signal_send(&s.quit_signal);
+ if (sigint_force) {
+ exit(128 + SIGINT);
+ } else {
+ nn_signal_send(&s.quit_signal);
+ log_warn("Attempting graceful exit. ^C again to force exit.");
+ sigint_force = true;
+ }
}
#ifdef NAUNET_ON_WINDOWS
@@ -172,11 +197,16 @@ s32 main(s32 argc, char *argv[])
return EXIT_FAILURE;
}
+ s.use_ui = false;
#ifdef CMSRV_USE_UI
- if (!cmsrv_ui_init(&s.ui, &s.server)) {
- return EXIT_FAILURE;
+ char *CMSRV_UI = getenv("CMSRV_UI");
+ if (CMSRV_UI) s.use_ui = al_strscmp(CMSRV_UI, "1") == 0;
+ if (s.use_ui) {
+ if (!cmsrv_ui_init(&s.ui, &s.server)) {
+ return EXIT_FAILURE;
+ }
+ al_set_print(log_callback, &s);
}
- al_set_print(log_callback, &s);
#endif
#ifdef CAMU_HAVE_FFMPEG
@@ -194,7 +224,7 @@ s32 main(s32 argc, char *argv[])
if (CMSRV_IP) addr = al_str_cr(CMSRV_IP);
log_info("Serving from %.*s.", al_str_x(&addr));
- camu_server_init(&s.server, &s.loop);
+ camu_server_init(&s.server, &s.loop, false);
if (!camu_server_listen(&s.server, NNWT_SOCKET_TCP, &addr, CAMU_PORT)) {
return EXIT_FAILURE;
}
@@ -212,12 +242,14 @@ s32 main(s32 argc, char *argv[])
#endif
#ifdef CMSRV_USE_UI
- nn_poll_init(&s.input_poll, input_poll_callback, &s);
- nn_poll_set(&s.input_poll, cmsrv_ui_get_input_fd(&s.ui), NNWT_POLL_READ);
- nn_poll_start(&s.input_poll, &s.loop);
- nn_timer_init(&s.render_timer, &s.loop, render_timer_callback, &s);
- nn_timer_set_repeat(&s.render_timer, NNWT_TS_FROM_USEC(100000));
- nn_timer_again(&s.render_timer);
+ if (s.use_ui) {
+ nn_poll_init(&s.input_poll, input_poll_callback, &s);
+ nn_poll_set(&s.input_poll, cmsrv_ui_get_input_fd(&s.ui), NNWT_POLL_READ);
+ nn_poll_start(&s.input_poll, &s.loop);
+ nn_timer_init(&s.render_timer, &s.loop, render_timer_callback, &s);
+ nn_timer_set_repeat(&s.render_timer, NNWT_TS_FROM_USEC(100000));
+ nn_timer_again(&s.render_timer);
+ }
#endif
nn_event_loop_run(&s.loop);
@@ -226,7 +258,7 @@ s32 main(s32 argc, char *argv[])
nn_socket_close(&s.local.sock);
#endif
#ifdef CMSRV_USE_UI
- cmsrv_ui_close(&s.ui);
+ if (s.use_ui) cmsrv_ui_close(&s.ui);
#endif
camu_server_free(&s.server);
nn_event_loop_destroy(&s.loop);
diff --git a/src/fruits/cmv/cmv.c b/src/fruits/cmv/cmv.c
index 74e3555..333588e 100644
--- a/src/fruits/cmv/cmv.c
+++ b/src/fruits/cmv/cmv.c
@@ -18,7 +18,7 @@
#include "icon.h"
#endif
-#ifndef NAUNET_ON_WINDOWS
+#if !defined NAUNET_ON_WINDOWS && !defined NAUNET_ON_ANDROID
// https://unix.stackexchange.com/a/16884
#define PID_MAX_STR 7 // 0x400000 (2^22).
static str CMV_UNIX_PATH = al_str_c("/tmp/cmv_sock_");
@@ -45,6 +45,7 @@ static void exit_callback(void *userdata, struct camu_desktop *desktop)
static nn_thread_result NNWT_THREADCALL event_loop_thread(void *userdata)
{
+ nn_thread_set_priority(NNWT_THREAD_SCHED_FIFO, 40);
struct cmv *c = (struct cmv *)userdata;
nn_thread_set_name("event_loop");
nn_event_loop_run(&c->loop);
@@ -174,9 +175,16 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
prefs->language.audio = CAMU_LANG_JAPANESE;
prefs->language.subtitles = CAMU_LANG_ENGLISH;
+#ifdef CAMU_DIRECT_MODE
+#ifdef CAMU_SINK_ONLY
+#error "Sink-only and DIRECT_MODE are incompatible"
+#endif
+ if (!local) al_assert("Cannot connect to a server in DIRECT_MODE" && false);
+#endif
+
#ifndef CAMU_SINK_ONLY
if (local) {
- camu_server_init(&c.server, &c.loop);
+ camu_server_init(&c.server, &c.loop, local);
#ifdef CAMU_DIRECT_MODE
camu_server_bind_direct(&c.server);
#else
@@ -212,8 +220,8 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
c.desktop.userdata = &c;
}
char *SINK_FORCE_LOCAL = getenv("SINK_FORCE_LOCAL");
- if (SINK_FORCE_LOCAL && al_strscmp(SINK_FORCE_LOCAL, "1") == 0) {
- c.desktop.sink.local = true;
+ if (SINK_FORCE_LOCAL) {
+ c.desktop.sink.local = al_strscmp(SINK_FORCE_LOCAL, "1") == 0;
} else {
c.desktop.sink.local = local;
}
@@ -232,9 +240,9 @@ s32 window_system_main(u32 argc, str *argv, void *extra)
nn_packet_free(packet);
}
if (extra) {
- u32 start_index = *(u32 *)extra;
+ s32 start_index = *(s32 *)extra;
if (start_index != 0) {
- camu_server_local_set_index(&c.server, start_index);
+ camu_server_local_start_at(&c.server, start_index);
}
}
}
@@ -306,7 +314,7 @@ s32 main(s32 argc, char *argv[])
for (s32 i = 0; i < argc; i++) {
str arg;
#ifdef NAUNET_ON_WINDOWS
- if (!al_str_from_wstr(&arg, &al_wstr_cr(argv[i]))) { // This is so broken.
+ if (!al_str_from_wstr(&arg, &al_wstr_cr(argv[i]))) {
log_error("Failed to convert argument #%i from a wide string.", i);
continue;
}
diff --git a/src/fruits/cmv/create_icon.sh b/src/fruits/cmv/create_icon.sh
new file mode 100755
index 0000000..08aa8eb
--- /dev/null
+++ b/src/fruits/cmv/create_icon.sh
@@ -0,0 +1,4 @@
+#! /usr/bin/env sh
+for size in {16,32,64,128}; do
+ magick sink.png -resize $sizex$size -set filename:f "%[t]-%[w]x%[h]" "%[filename:f].png"
+done
diff --git a/src/fruits/cmv/meson.build b/src/fruits/cmv/meson.build
index 301fa58..a9eda61 100644
--- a/src/fruits/cmv/meson.build
+++ b/src/fruits/cmv/meson.build
@@ -21,10 +21,20 @@ elif is_windows
windows = import('windows')
cmv_src += [windows.compile_resources('icon.rc')]
if not is_msvc
+ cmv_args += ['-mwindows', '-municode']
cmv_link_args += ['-mwindows', '-municode', '-static', '-static-libgcc', '-static-libstdc++']
endif
endif
+install_data(join_paths(meson.source_root(), 'package/sink.desktop'), install_tag: 'xdg',
+ install_dir: join_paths(get_option('datadir'), 'applications'))
+
+foreach size: ['16x16', '32x32', '64x64', '128x128', '256x256']
+ icon_dir = join_paths(get_option('datadir'), 'icons', 'hicolor', size, 'apps')
+ install_data('sink-' + size + '.png', install_tag: 'xdg',
+ install_dir: icon_dir, rename: 'sink.png')
+endforeach
+
if is_android
cmv_args += ['-DAPPLICATION_NAME="CTV"']
shared_library('ctv', cmv_src, dependencies: cmv_deps, c_args: cmv_args, link_args: cmv_link_args)
diff --git a/src/liana/common.h b/src/liana/common.h
index ec6d50a..7776218 100644
--- a/src/liana/common.h
+++ b/src/liana/common.h
@@ -1,3 +1,7 @@
#pragma once
#define LIANA_TIMESTAMP_INVALID ((u64)-1)
+
+#define LIANA_BASE_DELAY ((u64)1600000) // 1600ms
+#define LIANA_BASE_PING ((u64)600000) // 600ms
+#define LIANA_PAUSE_DELAY LIANA_BASE_PING
diff --git a/src/liana/handlers/codec_server.c b/src/liana/handlers/codec_server.c
index 31fbef8..ddba182 100644
--- a/src/liana/handlers/codec_server.c
+++ b/src/liana/handlers/codec_server.c
@@ -20,7 +20,7 @@ static bool codec_server_init(struct lia_server_handler *handler, struct cch_han
log_warn("No codec for this format.");
return false;
}
- log_info("Selected demuxer: %.*s.", al_str_x(&codec->codec_info->name));
+ log_debug("Selected demuxer: %.*s.", al_str_x(&codec->codec_info->name));
codec->demux = codec->codec_info->create_demuxer();
if (!codec->demux->init(codec->demux, handle)) {
return false;
@@ -55,7 +55,7 @@ static void codec_server_write_info(struct lia_server_handler *handler, struct n
nn_packet_write_u32(packet, codec->demux->streams.count);
struct camu_codec_stream *stream;
al_array_foreach_ptr(codec->demux->streams, i, stream) {
- nn_packet_write_str(packet, &codec->codec_info->name);
+ nn_packet_write_str(packet, &codec->codec_info->id);
nn_packet_write_u8(packet, stream->mode);
nn_packet_write_u8(packet, stream->type);
nn_packet_write_u64(packet, stream->duration);
diff --git a/src/liana/list.h b/src/liana/list.h
index 32715bd..580198f 100644
--- a/src/liana/list.h
+++ b/src/liana/list.h
@@ -8,20 +8,8 @@
#define LIANA_SEQUENCE_ANY -1
-#define LIANA_BASE_DELAY ((u64)2000000) // 2000ms
-#define LIANA_BASE_PING ((u64)500000) // 500ms
-#define LIANA_PAUSE_DELAY LIANA_BASE_PING
-#define LIANA_DELAY_IGNORE ((u64)0)
-
-#define LIANA_BUFFER_AHEAD 2
-
//#define LIANA_LIST_SCUFFED_LOOP
-// @TODO:
-// To handle an entry being queued right before a skip, keep a global
-// "max time until all sinks buffered" and used that instead of LIANA_PAUSE_DELAY (if greater).
-// Factor in LIANA_BASE_PING.
-
enum {
LIANA_SINK_SET = 0,
LIANA_SINK_UNSET,
diff --git a/src/liana/vcr.c b/src/liana/vcr.c
index 3a61e32..3b4866c 100644
--- a/src/liana/vcr.c
+++ b/src/liana/vcr.c
@@ -314,7 +314,7 @@ static void cork_if_buffered(struct lia_vcr *vcr, u64 buffer)
if (vcr->expand == VCR_EXPAND_UNTOUCHED) {
vcr->mark.buffered = buffer * VCR_BUFFER_GROW_FACTOR;
vcr->expand = VCR_EXPAND_GROWN;
- log_info("Expanded buffer to size %.2fMB.", vcr->mark.buffered / (f32)MB(1));
+ log_debug("Expanded buffer to size %.2fMB.", vcr->mark.buffered / (f32)MB(1));
return;
}
if (!vcr->corked) {
diff --git a/src/libsink/desktop.c b/src/libsink/desktop.c
index 2707f34..427a6f4 100644
--- a/src/libsink/desktop.c
+++ b/src/libsink/desktop.c
@@ -66,11 +66,11 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque)
case CAMU_SINK_START:
switch (type) {
case CAMU_SINK_AUDIO:
- log_info("Starting audio.");
+ log_debug("Starting audio.");
camu_mixer_resume(mixer);
break;
case CAMU_SINK_VIDEO:
- log_info("Starting video.");
+ log_debug("Starting video.");
camu_screen_set_state(scr, CAMU_SCREEN_PLAYING);
camu_screen_wake(scr);
break;
@@ -79,11 +79,11 @@ static u8 sink_callback(void *userdata, u8 op, u8 type, void *opaque)
case CAMU_SINK_STOP:
switch (type) {
case CAMU_SINK_AUDIO:
- log_info("Stopping audio.");
+ log_debug("Stopping audio.");
camu_mixer_pause(mixer);
break;
case CAMU_SINK_VIDEO:
- log_info("Stopping video.");
+ log_debug("Stopping video.");
camu_screen_set_state(scr, CAMU_SCREEN_PAUSED);
break;
}
@@ -187,6 +187,12 @@ static void screen_callback(void *userdata, u8 op, void *opaque)
case CAMU_SCREEN_RESEEK:
camu_sink_reseek(&c->sink);
break;
+ case CAMU_SCREEN_AUDIO_TRACK:
+ camu_sink_adjust_audio_track(&c->sink, *(s32 *)opaque);
+ break;
+ case CAMU_SCREEN_SUBTITLE_TRACK:
+ camu_sink_adjust_subtitle_track(&c->sink, *(s32 *)opaque);
+ break;
case CAMU_SCREEN_SHUFFLE:
camu_sink_shuffle(&c->sink);
break;
diff --git a/src/portal/py/modules/__init__.py b/src/portal/py/modules/__init__.py
index 480ff3c..f63ed56 100644
--- a/src/portal/py/modules/__init__.py
+++ b/src/portal/py/modules/__init__.py
@@ -5,9 +5,9 @@ from modules.youtube import YoutubeModule
#from modules.twitter import TwitterModule
#from modules.pixiv_app import PixivAppModule
#from modules.pixiv_web import PixivWebModule
-from modules.fanbox import FanboxModule
+#from modules.fanbox import FanboxModule
#from modules.instagram import InstagramModule
-from modules.patreon import PatreonModule
+#kfrom modules.patreon import PatreonModule
ALL_MODULES = {
'youtube': (YoutubeModule(), []),
@@ -15,9 +15,9 @@ ALL_MODULES = {
# 'twitter': (TwitterModule(config.TWITTER_COOKIES_PATH), []),
# 'pixiv_web': (PixivWebModule(config.PIXIV_SESSID, config.PIXIV_USERID), []),
# 'pixiv_app': (PixivAppModule(config.PIXIV_REFRESH_TOKEN), []),
- 'fanbox': (FanboxModule(config.FANBOX_SESSID, config.FANBOX_CF_CLEARANCE), []),
+# 'fanbox': (FanboxModule(config.FANBOX_SESSID, config.FANBOX_CF_CLEARANCE), []),
# 'instagram': (InstagramModule(
# config.INSTAGRAM_USER_AGENT, config.INSTAGRAM_SETTINGS_PATH,
# config.INSTAGRAM_SESSION_ID), []),
- 'patreon': (PatreonModule(config.PATREON_SESSION_ID, config.PATREON_UUID, config.PATREON_USER_ID), [])
+# 'patreon': (PatreonModule(config.PATREON_SESSION_ID, config.PATREON_UUID, config.PATREON_USER_ID), [])
}
diff --git a/src/portal/py/modules/instagram.py b/src/portal/py/modules/instagram.py
index 7d71f9f..fbf75d3 100644
--- a/src/portal/py/modules/instagram.py
+++ b/src/portal/py/modules/instagram.py
@@ -74,8 +74,8 @@ class InstagramSearch(Search):
kwargs['views'] = m.play_count
media[str(0)] = Video(url=Url(str(m.video_url)), thumbnail_url=Url(str(m.thumbnail_url)))
elif m.media_type == 1: # Photo
- candidates = sorted(m.image_versions2['candidates'], key=lambda x: x['width'], reverse=True)
- media[str(0)] = Image(url=Url(candidates[0]['url']), thumbnail_url=Url(candidates[1]['url']))
+ candidates = sorted(m.image_versions2.candidates, key=lambda x: x.width, reverse=True)
+ media[str(0)] = Image(url=Url(candidates[0].url), thumbnail_url=Url(candidates[1].url))
kwargs['media'] = media
post = Post(**kwargs)
self.module.add_to_map(unique_id, post)
diff --git a/src/render/meson.build b/src/render/meson.build
index ee0017a..3cbca4c 100644
--- a/src/render/meson.build
+++ b/src/render/meson.build
@@ -56,9 +56,8 @@ elif get_option('renderer') == 'libplacebo'
shaderc_opts.add_cmake_defines({ 'SPIRV_COLOR_TERMINAL': false })
shaderc_opts.add_cmake_defines({ 'ENABLE_EXCEPTIONS_ON_MSVC': false })
shaderc_proj = cmake.subproject('shaderc', options: shaderc_opts)
- shaderc = shaderc_proj.dependency('shaderc')
- meson.override_dependency('shaderc', declare_dependency(dependencies: shaderc, version: '2026.2'))
- render_deps += [
+ shaderc_deps = [
+ shaderc_proj.dependency('shaderc'),
shaderc_proj.dependency('shaderc_util'),
shaderc_proj.dependency('MachineIndependent'),
shaderc_proj.dependency('OSDependent'),
@@ -68,8 +67,9 @@ elif get_option('renderer') == 'libplacebo'
shaderc_proj.dependency('SPIRV-Tools-static')
]
if spirv_optimizer
- render_deps += [shaderc_proj.dependency('SPIRV-Tools-opt')]
+ shaderc_deps += [shaderc_proj.dependency('SPIRV-Tools-opt')]
endif
+ meson.override_dependency('shaderc', declare_dependency(dependencies: shaderc_deps, version: '2026.3'))
endif
libplacebo_opts += ['shaderc=enabled', 'glslang=disabled']
else
diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c
index 8c28162..c0a413a 100644
--- a/src/render/renderer_libplacebo.c
+++ b/src/render/renderer_libplacebo.c
@@ -117,7 +117,7 @@ static void log_callback(void *userdata, enum pl_log_level level, const char *me
// will be shot anyway so allow it.
log_info(message);
} else {
- log_info(message);
+ log_debug(message);
}
}
@@ -166,9 +166,11 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid
struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer;
#ifndef CRT_BACKGROUND
- clear_color[0] = ((global_color_palette.colors[0] >> 16) & 0xff) / 255.f;
- clear_color[1] = ((global_color_palette.colors[0] >> 8) & 0xff) / 255.f;
- clear_color[2] = ((global_color_palette.colors[0]) & 0xff) / 255.f;
+ if (global_color_palette.supplied) {
+ clear_color[0] = ((global_color_palette.colors[CAMU_COLOR_BACKGROUND] >> 16) & 0xff) / 255.f;
+ clear_color[1] = ((global_color_palette.colors[CAMU_COLOR_BACKGROUND] >> 8) & 0xff) / 255.f;
+ clear_color[2] = (global_color_palette.colors[CAMU_COLOR_BACKGROUND] & 0xff) / 255.f;
+ }
#endif
lr->logger = pl_log_create(PL_API_VER, pl_log_params(
@@ -319,7 +321,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid
al_memset(&lr->params, 0, sizeof(struct pl_render_params));
lr->params = default_params;
- lr->params.deband_params = NULL;
+ //lr->params.deband_params = NULL;
//lr->params.frame_mixer = NULL;
// Clear manually so we can draw multiple images per frame.
@@ -331,26 +333,28 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid
lr->params.correct_subpixel_offsets = true;
lr->osd.vars[0].var = pl_var_uvec2("screen");
- lr->osd.vars[1].var = pl_var_uint("scale");
- lr->osd.vars[2].var = pl_var_float("time");
- lr->osd.vars[3].var = pl_var_uint("show_osd");
- lr->osd.vars[4].var = pl_var_uint("connecting");
- lr->osd.vars[5].var = pl_var_uint("paused");
- lr->osd.vars[6].var = pl_var_uint("bar_mode");
- lr->osd.vars[7].var = pl_var_float("bar");
- lr->osd.vars[8].var = pl_var_float("dbar");
- lr->osd.vars[9].var = pl_var_float("bbar");
- lr->osd.vars[10].var = pl_var_uint("show_hour");
- lr->osd.vars[11].var = pl_var_uint("negative");
+ lr->osd.vars[1].var = pl_var_vec4("tcolor");
+ lr->osd.vars[2].var = pl_var_vec4("bcolor");
+ lr->osd.vars[3].var = pl_var_uint("scale");
+ lr->osd.vars[4].var = pl_var_float("time");
+ lr->osd.vars[5].var = pl_var_uint("show_osd");
+ lr->osd.vars[6].var = pl_var_uint("connecting");
+ lr->osd.vars[7].var = pl_var_uint("paused");
+ lr->osd.vars[8].var = pl_var_uint("bar_mode");
+ lr->osd.vars[9].var = pl_var_float("bar");
+ lr->osd.vars[10].var = pl_var_float("dbar");
+ lr->osd.vars[11].var = pl_var_float("bbar");
+ lr->osd.vars[12].var = pl_var_uint("show_hour");
+ lr->osd.vars[13].var = pl_var_uint("negative");
static const char num_names[9][6] = {
"num1", "num2", "num3", "num4",
"num5", "num6", "num7", "num8",
"num9"
};
for (u32 i = 0; i < 9; i++) {
- lr->osd.vars[12 + i].var = pl_var_uint(num_names[i]);
+ lr->osd.vars[14 + i].var = pl_var_uint(num_names[i]);
}
- for (u32 i = 0; i < 21; i++) {
+ for (u32 i = 0; i < 23; i++) {
lr->osd.vars[i].dynamic = true;
}
@@ -491,7 +495,7 @@ static inline intptr_t float_64_hash(f64 value)
static inline bool render_osd(struct camu_renderer_lp *lr, struct camu_screen *scr)
{
f64 duration = scr->osd.duration / 1000000.0;
- f32 bar, dbar, bbar;
+ static f32 bar, dbar, bbar;
f32 progress = ((duration != 0) ? scr->osd.pts / duration : 0.f);
if (scr->osd.bar_mode != CAMU_OSD_BAR_VOLUME) {
dbar = progress;
@@ -504,68 +508,84 @@ static inline bool render_osd(struct camu_renderer_lp *lr, struct camu_screen *s
lr->osd.screen_size[0] = scr->width;
lr->osd.screen_size[1] = scr->height;
lr->osd.vars[0].data = lr->osd.screen_size;
- u32 scale = 1;
- lr->osd.vars[1].data = &scale;
+ static float tcolor[4] = { 0.89f, 0.87f, 0.87f, 1.f };
+ if (global_color_palette.supplied) {
+ tcolor[0] = ((global_color_palette.colors[CAMU_COLOR_FOREGROUND] >> 16) & 0xff) / 255.f;
+ tcolor[1] = ((global_color_palette.colors[CAMU_COLOR_FOREGROUND] >> 8) & 0xff) / 255.f;
+ tcolor[2] = (global_color_palette.colors[CAMU_COLOR_FOREGROUND] & 0xff) / 255.f;
+ }
+ lr->osd.vars[1].data = tcolor;
+ static float bcolor[4] = { 0.04f, 0.04f, 0.04f, 0.575f };
+ if (global_color_palette.supplied) {
+ bcolor[0] = ((global_color_palette.colors[CAMU_COLOR_BACKGROUND] >> 16) & 0xff) / 255.f;
+ bcolor[1] = ((global_color_palette.colors[CAMU_COLOR_BACKGROUND] >> 8) & 0xff) / 255.f;
+ bcolor[2] = (global_color_palette.colors[CAMU_COLOR_BACKGROUND] & 0xff) / 255.f;
+ }
+ lr->osd.vars[2].data = bcolor;
+ static u32 scale = 1;
+ lr->osd.vars[3].data = &scale;
f64 tick = nn_get_tick();
if (lr->osd.tick_time == -1.0) lr->osd.tick_time = tick;
lr->osd.time = (f32)(tick - lr->osd.tick_time);
- lr->osd.vars[2].data = &lr->osd.time;
- lr->osd.vars[3].data = &scr->osd.show;
- lr->osd.vars[4].data = &scr->osd.connecting;
- lr->osd.vars[5].data = &scr->osd.paused;
- lr->osd.vars[6].data = &scr->osd.bar_mode;
- lr->osd.vars[7].data = &bar;
- lr->osd.vars[8].data = &dbar;
- lr->osd.vars[9].data = &bbar;
- u32 hours1, minutes1, seconds1, hundredths;
- u32 show_hour;
+ lr->osd.vars[4].data = &lr->osd.time;
+ lr->osd.vars[5].data = &scr->osd.show;
+ lr->osd.vars[6].data = &scr->osd.connecting;
+ lr->osd.vars[7].data = &scr->osd.paused;
+ lr->osd.vars[8].data = &scr->osd.bar_mode;
+ lr->osd.vars[9].data = &bar;
+ lr->osd.vars[10].data = &dbar;
+ lr->osd.vars[11].data = &bbar;
+ static u32 hours1, minutes1, seconds1, hundredths;
+ static u32 show_hour;
show_hour = camu_split_time(scr->osd.duration, &hours1, &minutes1, &seconds1, &hundredths);
ROUND_SECONDS(hours1, minutes1, seconds1, hundredths);
- lr->osd.vars[10].data = &show_hour;
- u32 negative;
+ lr->osd.vars[12].data = &show_hour;
+ static u32 negative;
negative = scr->osd.pts < 0.0f;
- lr->osd.vars[11].data = &negative;
- lr->osd.vars[15].data = &hours1;
- lr->osd.vars[16].data = &minutes1;
- lr->osd.vars[17].data = &seconds1;
- u32 hours2, minutes2, seconds2;
- camu_split_time(fabs(scr->osd.pts) * 1000000u, &hours2, &minutes2, &seconds2, &hundredths);
+ lr->osd.vars[13].data = &negative;
+ lr->osd.vars[17].data = &hours1;
+ lr->osd.vars[18].data = &minutes1;
+ lr->osd.vars[19].data = &seconds1;
+ static u32 hours2, minutes2, seconds2;
+ u64 time = fabs(scr->osd.pts) * 1000000u;
+ time = MIN(time, scr->osd.duration);
+ camu_split_time(time, &hours2, &minutes2, &seconds2, &hundredths);
// The trade-off of rounding PTS is that if we do, second 0 will be shown for only half a second.
// If we don't, more noticeably, PTS will never equal duration if duration rounds up.
// There's also the option of not rounding either.
ROUND_SECONDS(hours2, minutes2, seconds2, hundredths);
- lr->osd.vars[12].data = &hours2;
- lr->osd.vars[13].data = &minutes2;
- lr->osd.vars[14].data = &seconds2;
- u32 zero = 0;
- lr->osd.vars[18].data = &zero;
- lr->osd.vars[19].data = &zero;
+ lr->osd.vars[14].data = &hours2;
+ lr->osd.vars[15].data = &minutes2;
+ lr->osd.vars[16].data = &seconds2;
+ static u32 zero = 0;
lr->osd.vars[20].data = &zero;
+ lr->osd.vars[21].data = &zero;
+ lr->osd.vars[22].data = &zero;
if (scr->osd.bar_mode == CAMU_OSD_BAR_SEEK) {
- u32 hours3, minutes3, seconds3;
+ static u32 hours3, minutes3, seconds3;
camu_split_time(fabs(duration * bar) * 1000000u, &hours3, &minutes3, &seconds3, &hundredths);
ROUND_SECONDS(hours3, minutes3, seconds3, hundredths);
- lr->osd.vars[18].data = &hours3;
- lr->osd.vars[19].data = &minutes3;
- lr->osd.vars[20].data = &seconds3;
+ lr->osd.vars[20].data = &hours3;
+ lr->osd.vars[21].data = &minutes3;
+ lr->osd.vars[22].data = &seconds3;
} else {
f64 whole = floor(bar);
f64 frac = (bar - whole) * 100.0;
- u32 num1, num2;
+ static u32 num1, num2;
num1 = (u32)whole;
num2 = (u32)round(frac);
- lr->osd.vars[19].data = &num1;
- lr->osd.vars[20].data = &num2;
+ lr->osd.vars[21].data = &num1;
+ lr->osd.vars[22].data = &num2;
}
lr->osd.sh = pl_dispatch_begin(lr->dispatch);
pl_shader_custom(lr->osd.sh, &(struct pl_custom_shader){
.description = "osd",
.prelude = lr->osd.prelude,
- .header = scr->osd.show_binds ? lr->osd.binds : lr->osd.header,
+ .header = scr->osd.alt ? lr->osd.binds : lr->osd.header,
.body = "color = (show_osd == 0u) ? vec4(0.) : draw_osd();",
.output = PL_SHADER_SIG_COLOR,
- .num_variables = 21,
+ .num_variables = 23,
.variables = lr->osd.vars
});
@@ -703,7 +723,7 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
target->rotation = mix.frames[0]->rotation - video->view.rotation;
//lr->params.color_map_params = pl_color_map_params(.inverse_tone_mapping = true);
/*
- if () {
+ if (1) {
target->color = pl_color_space_srgb;
target->color.hdr.max_luma = PL_COLOR_SDR_WHITE - 50.f;
target->color.hdr.min_luma = (PL_COLOR_SDR_WHITE - 50.f) / PL_COLOR_SDR_CONTRAST;
diff --git a/src/render/renderer_libplacebo.h b/src/render/renderer_libplacebo.h
index a8a5001..dba71bb 100644
--- a/src/render/renderer_libplacebo.h
+++ b/src/render/renderer_libplacebo.h
@@ -51,7 +51,7 @@ struct camu_renderer_lp {
pl_shader sh;
u32 screen_size[2];
f32 time;
- struct pl_shader_var vars[21];
+ struct pl_shader_var vars[23];
f32 vertices[24];
struct pl_vertex_attrib attribs[2];
f64 tick_time;
diff --git a/src/render/renderer_momo.c b/src/render/renderer_momo.c
index 02ccaee..2372213 100644
--- a/src/render/renderer_momo.c
+++ b/src/render/renderer_momo.c
@@ -21,7 +21,11 @@ static void renderer_momo_set(struct camu_renderer *renderer, u8 option, u8 valu
}
static bool renderer_momo_create_renderer(struct camu_renderer *renderer, u32 *width, u32 *height,
-#if defined STELA_API_OPENGL
+#if defined STELA_API_VULKAN
+#error "MOMO cannot support Vulkan"
+#elif defined STELA_API_DX11
+ HWND win32_window,
+#elif defined STELA_API_OPENGL
#ifdef STELA_USE_EGL
EGLDisplay display,
EGLContext context,
diff --git a/src/render/shaders/osd.h b/src/render/shaders/osd.h
index 1109a50..8a5fd6c 100644
--- a/src/render/shaders/osd.h
+++ b/src/render/shaders/osd.h
@@ -5,32 +5,32 @@ static char osd_shader[] = \
" if (connecting != 0u) {\n"
" float t = mod(time,1.8);\n"
" for (int i = 0; i < 3; i++) {\n"
-" col += char(ch_per,uv)*float(t >= float(i)*0.6);\n"
+" col += ch(ch_per,uv)*float(t >= float(i)*0.6);\n"
" }\n"
" } else if (paused != 0u) {\n"
-" col = char(ch_p,uv)+char(ch_a,uv)+char(ch_u,uv)+char(ch_s,uv)+char(ch_e,uv)+char(ch_d,uv);\n"
+" col = ch(ch_p,uv)+ch(ch_a,uv)+ch(ch_u,uv)+ch(ch_s,uv)+ch(ch_e,uv)+ch(ch_d,uv);\n"
" }\n"
" pp = pos2;\n"
" if (negative != 0u) {\n"
-" col += char(ch_dsh,uv);\n"
+" col += ch(ch_dsh,uv);\n"
" }\n"
" if (show_hour != 0u) {\n"
-" col += integer(num1,uv)+char(ch_col,uv);\n"
+" col += integer(num1,uv)+ch(ch_col,uv);\n"
" }\n"
-" col += integer(num2,uv)+char(ch_col,uv)+integer(num3,uv)+char(ch_lsl,uv);\n"
+" col += integer(num2,uv)+ch(ch_col,uv)+integer(num3,uv)+ch(ch_lsl,uv);\n"
" if (show_hour != 0u) {\n"
-" col += integer(num4,uv)+char(ch_col,uv);\n"
+" col += integer(num4,uv)+ch(ch_col,uv);\n"
" }\n"
-" col += integer(num5,uv)+char(ch_col,uv)+integer(num6,uv);\n"
+" col += integer(num5,uv)+ch(ch_col,uv)+integer(num6,uv);\n"
" return col;\n"
"}\n"
"float text_over(vec2 uv, vec2 pos3) {\n"
" float col = 0.;\n"
" pp = pos3;\n"
" if (show_hour != 0u && bar_mode == 1u) {\n"
-" col = integer(num7,uv)+char(ch_col,uv);\n"
+" col = integer(num7,uv)+ch(ch_col,uv);\n"
" }\n"
-" col += integer(num8,uv)+((bar_mode == 2u) ? char(ch_per,uv) : char(ch_col,uv))+integer(num9,uv);\n"
+" col += integer(num8,uv)+((bar_mode == 2u) ? ch(ch_per,uv) : ch(ch_col,uv))+integer(num9,uv);\n"
" return col;\n"
"}\n"
"vec4 draw_osd() {\n"
@@ -45,7 +45,7 @@ static char osd_shader[] = \
" pos2.x -= STRW(0.5) * float(negative);\n"
" float ov = fract(bar);\n"
" ov = (-1.+(bar-ov)+float(c.x < ov))/1.5;\n"
-" vec4 color = mix(bcolor,mix(tcolor,vec4(0.7,0.45,0.,1.),ov),float(c.x < bar));\n"
+" vec4 color = mix(bcolor,mix(tcolor-0.075,vec4(0.7,0.45,0.,1.),ov),float(c.x < bar));\n"
" float alpha = (c.x >= bar) ? 0.7 : 1.;\n"
" color = mix(color,vec4(tcolor.xyz,alpha)+float(bar > dbar)*0.15,float(c.x < dbar));\n"
" color = mix(color,vec4(tcolor.xyz,alpha-0.1)+float(bar > bbar)*0.15,float(c.x < bbar)*0.5);\n"
@@ -62,7 +62,7 @@ static char osd_shader[] = \
" uv = c*ss;\n"
" float width2 = (show_hour != 0u && bar_mode == 1u) ? 8. : 5.;\n"
" vec2 pos3 = floor(vec2(ss.x/2.-STRW(width2)/2.,11.));\n"
-" float box = in_box(uv,pos3-vec2(2.,2.),pos3+vec2(STRW(width2)+1.,STRH(1.)+3.));\n"
+" float box = in_box(uv,pos3-vec2(4.,2.),pos3+vec2(STRW(width2)+3.,STRH(1.)+3.));\n"
" color.xyz = mix(color.xyz,bcolor.xyz,box);\n"
" color.w = color.w+(bcolor.w*box);\n"
" pixel = text_over(uv,pos3);\n"
diff --git a/src/render/shaders/osd_binds.h b/src/render/shaders/osd_binds.h
index 5d6806a..0f5ff19 100644
--- a/src/render/shaders/osd_binds.h
+++ b/src/render/shaders/osd_binds.h
@@ -2,298 +2,363 @@ static char osd_binds_shader[] = \
"float text(vec2 uv, vec2 pos) {\n"
" float col = 0.;\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_L,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_f,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_lsl,uv);\n"
-" col += char(ch_R,uv);\n"
-" col += char(ch_i,uv);\n"
-" col += char(ch_g,uv);\n"
-" col += char(ch_h,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_col,uv);\n"
-" spaces(1)\n"
-" col += char(ch_N,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_x,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_lsl,uv);\n"
-" col += char(ch_P,uv);\n"
-" col += char(ch_r,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_v,uv);\n"
-" col += char(ch_i,uv);\n"
-" col += char(ch_o,uv);\n"
-" col += char(ch_u,uv);\n"
-" col += char(ch_s,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_lpa,uv);\n"
-" col += char(ch_C,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_r,uv);\n"
-" col += char(ch_l,uv);\n"
-" col += char(ch_col,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_crs,uv);\n"
-" col += char(ch_lsl,uv);\n"
-" col += char(ch_dsh,uv);\n"
-" col += char(ch_1,uv);\n"
-" col += char(ch_0,uv);\n"
-" col += char(ch_s,uv);\n"
-" col += char(ch_rpa,uv);\n"
+" col += ch(ch_L,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_f,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_lsl,uv);\n"
+" col += ch(ch_R,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_g,uv);\n"
+" col += ch(ch_h,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_col,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_N,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_x,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_lsl,uv);\n"
+" col += ch(ch_P,uv);\n"
+" col += ch(ch_r,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_v,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_o,uv);\n"
+" col += ch(ch_u,uv);\n"
+" col += ch(ch_s,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_lpa,uv);\n"
+" col += ch(ch_C,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_r,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_col,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_crs,uv);\n"
+" col += ch(ch_lsl,uv);\n"
+" col += ch(ch_dsh,uv);\n"
+" col += ch(ch_1,uv);\n"
+" col += ch(ch_0,uv);\n"
+" col += ch(ch_s,uv);\n"
+" col += ch(ch_rpa,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_p,uv);\n"
-" col += char(ch_a,uv);\n"
-" col += char(ch_c,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_p,uv);\n"
+" col += ch(ch_a,uv);\n"
+" col += ch(ch_c,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(6)\n"
-" col += char(ch_P,uv);\n"
-" col += char(ch_a,uv);\n"
-" col += char(ch_u,uv);\n"
-" col += char(ch_s,uv);\n"
-" col += char(ch_e,uv);\n"
+" col += ch(ch_P,uv);\n"
+" col += ch(ch_a,uv);\n"
+" col += ch(ch_u,uv);\n"
+" col += ch(ch_s,uv);\n"
+" col += ch(ch_e,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_M,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_M,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(10)\n"
-" col += char(ch_M,uv);\n"
-" col += char(ch_u,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_lpa,uv);\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_h,uv);\n"
-" col += char(ch_i,uv);\n"
-" col += char(ch_f,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_col,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_1,uv);\n"
-" col += char(ch_0,uv);\n"
-" col += char(ch_0,uv);\n"
-" col += char(ch_pct,uv);\n"
-" col += char(ch_rpa,uv);\n"
+" col += ch(ch_M,uv);\n"
+" col += ch(ch_u,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_lpa,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_h,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_f,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_col,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_1,uv);\n"
+" col += ch(ch_0,uv);\n"
+" col += ch(ch_0,uv);\n"
+" col += ch(ch_pct,uv);\n"
+" col += ch(ch_rpa,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_T,uv);\n"
-" col += char(ch_a,uv);\n"
-" col += char(ch_b,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_T,uv);\n"
+" col += ch(ch_a,uv);\n"
+" col += ch(ch_b,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(8)\n"
-" col += char(ch_T,uv);\n"
-" col += char(ch_o,uv);\n"
-" col += char(ch_g,uv);\n"
-" col += char(ch_g,uv);\n"
-" col += char(ch_l,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_O,uv);\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_D,uv);\n"
+" col += ch(ch_T,uv);\n"
+" col += ch(ch_o,uv);\n"
+" col += ch(ch_g,uv);\n"
+" col += ch(ch_g,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_O,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_D,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_C,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_r,uv);\n"
-" col += char(ch_l,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_C,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_r,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(7)\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_h,uv);\n"
-" col += char(ch_o,uv);\n"
-" col += char(ch_w,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_O,uv);\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_D,uv);\n"
-" col += char(ch_lsl,uv);\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_k,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_lpa,uv);\n"
-" col += char(ch_C,uv);\n"
-" col += char(ch_l,uv);\n"
-" col += char(ch_i,uv);\n"
-" col += char(ch_c,uv);\n"
-" col += char(ch_k,uv);\n"
-" col += char(ch_rpa,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_h,uv);\n"
+" col += ch(ch_o,uv);\n"
+" col += ch(ch_w,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_O,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_D,uv);\n"
+" col += ch(ch_lsl,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_k,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_lpa,uv);\n"
+" col += ch(ch_C,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_c,uv);\n"
+" col += ch(ch_k,uv);\n"
+" col += ch(ch_rpa,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(10)\n"
-" col += char(ch_T,uv);\n"
-" col += char(ch_o,uv);\n"
-" col += char(ch_g,uv);\n"
-" col += char(ch_g,uv);\n"
-" col += char(ch_l,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_u,uv);\n"
-" col += char(ch_b,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_i,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_l,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_s,uv);\n"
+" col += ch(ch_T,uv);\n"
+" col += ch(ch_o,uv);\n"
+" col += ch(ch_g,uv);\n"
+" col += ch(ch_g,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_u,uv);\n"
+" col += ch(ch_b,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_s,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_E,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_U,uv);\n"
+" col += ch(ch_p,uv);\n"
+" col += ch(ch_lsl,uv);\n"
+" col += ch(ch_D,uv);\n"
+" col += ch(ch_o,uv);\n"
+" col += ch(ch_w,uv);\n"
+" col += ch(ch_n,uv);\n"
+" col += ch(ch_col,uv);\n"
+" spaces(4)\n"
+" col += ch(ch_T,uv);\n"
+" col += ch(ch_r,uv);\n"
+" col += ch(ch_a,uv);\n"
+" col += ch(ch_c,uv);\n"
+" col += ch(ch_k,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_lpa,uv);\n"
+" col += ch(ch_C,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_r,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_col,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_A,uv);\n"
+" col += ch(ch_u,uv);\n"
+" col += ch(ch_d,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_o,uv);\n"
+" col += ch(ch_com,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_h,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_f,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_col,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_u,uv);\n"
+" col += ch(ch_b,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_s,uv);\n"
+" col += ch(ch_rpa,uv);\n"
+" pos.y -= STRH(1.2);\n"
+" pp = vec2(pos.x,pos.y);\n"
+" col += ch(ch_E,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(10)\n"
-" col += char(ch_R,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_s,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_k,uv);\n"
+" col += ch(ch_R,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_s,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_k,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_crs,uv);\n"
-" col += char(ch_lsl,uv);\n"
-" col += char(ch_dsh,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_crs,uv);\n"
+" col += ch(ch_lsl,uv);\n"
+" col += ch(ch_dsh,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(8)\n"
-" col += char(ch_Z,uv);\n"
-" col += char(ch_o,uv);\n"
-" col += char(ch_o,uv);\n"
-" col += char(ch_m,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_I,uv);\n"
-" col += char(ch_n,uv);\n"
-" col += char(ch_lsl,uv);\n"
-" col += char(ch_O,uv);\n"
-" col += char(ch_u,uv);\n"
-" col += char(ch_t,uv);\n"
+" col += ch(ch_Z,uv);\n"
+" col += ch(ch_o,uv);\n"
+" col += ch(ch_o,uv);\n"
+" col += ch(ch_m,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_I,uv);\n"
+" col += ch(ch_n,uv);\n"
+" col += ch(ch_lsl,uv);\n"
+" col += ch(ch_O,uv);\n"
+" col += ch(ch_u,uv);\n"
+" col += ch(ch_t,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_N,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_N,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(10)\n"
-" col += char(ch_D,uv);\n"
-" col += char(ch_i,uv);\n"
-" col += char(ch_s,uv);\n"
-" col += char(ch_a,uv);\n"
-" col += char(ch_b,uv);\n"
-" col += char(ch_l,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_c,uv);\n"
-" col += char(ch_a,uv);\n"
-" col += char(ch_l,uv);\n"
-" col += char(ch_i,uv);\n"
-" col += char(ch_n,uv);\n"
-" col += char(ch_g,uv);\n"
+" col += ch(ch_D,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_s,uv);\n"
+" col += ch(ch_a,uv);\n"
+" col += ch(ch_b,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_c,uv);\n"
+" col += ch(ch_a,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_n,uv);\n"
+" col += ch(ch_g,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_C,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_C,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(10)\n"
-" col += char(ch_T,uv);\n"
-" col += char(ch_r,uv);\n"
-" col += char(ch_a,uv);\n"
-" col += char(ch_n,uv);\n"
-" col += char(ch_s,uv);\n"
-" col += char(ch_p,uv);\n"
-" col += char(ch_a,uv);\n"
-" col += char(ch_r,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_n,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_B,uv);\n"
-" col += char(ch_a,uv);\n"
-" col += char(ch_c,uv);\n"
-" col += char(ch_k,uv);\n"
-" col += char(ch_g,uv);\n"
-" col += char(ch_r,uv);\n"
-" col += char(ch_o,uv);\n"
-" col += char(ch_u,uv);\n"
-" col += char(ch_n,uv);\n"
-" col += char(ch_d,uv);\n"
+" col += ch(ch_T,uv);\n"
+" col += ch(ch_r,uv);\n"
+" col += ch(ch_a,uv);\n"
+" col += ch(ch_n,uv);\n"
+" col += ch(ch_s,uv);\n"
+" col += ch(ch_p,uv);\n"
+" col += ch(ch_a,uv);\n"
+" col += ch(ch_r,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_n,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_W,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_n,uv);\n"
+" col += ch(ch_d,uv);\n"
+" col += ch(ch_o,uv);\n"
+" col += ch(ch_w,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_V,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_V,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(10)\n"
-" col += char(ch_V,uv);\n"
-" col += char(ch_R,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_lpa,uv);\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_h,uv);\n"
-" col += char(ch_i,uv);\n"
-" col += char(ch_f,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_col,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_3,uv);\n"
-" col += char(ch_6,uv);\n"
-" col += char(ch_0,uv);\n"
-" col += char(ch_dgr,uv);\n"
-" col += char(ch_com,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_C,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_r,uv);\n"
-" col += char(ch_l,uv);\n"
-" col += char(ch_col,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_C,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_n,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_r,uv);\n"
-" col += char(ch_rpa,uv);\n"
+" col += ch(ch_V,uv);\n"
+" col += ch(ch_R,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_lpa,uv);\n"
+" col += ch(ch_C,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_r,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_col,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_C,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_n,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_r,uv);\n"
+" col += ch(ch_com,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_h,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_f,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_col,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_3,uv);\n"
+" col += ch(ch_6,uv);\n"
+" col += ch(ch_0,uv);\n"
+" col += ch(ch_dgr,uv);\n"
+" col += ch(ch_rpa,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_B,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_B,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(10)\n"
-" col += char(ch_S,uv);\n"
-" col += char(ch_w,uv);\n"
-" col += char(ch_a,uv);\n"
-" col += char(ch_p,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_E,uv);\n"
-" col += char(ch_y,uv);\n"
-" col += char(ch_e,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_w,uv);\n"
+" col += ch(ch_a,uv);\n"
+" col += ch(ch_p,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_E,uv);\n"
+" col += ch(ch_y,uv);\n"
+" col += ch(ch_e,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_R,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_R,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(10)\n"
-" col += char(ch_R,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_s,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_t,uv);\n"
-" col += char(ch_spc,uv);\n"
-" col += char(ch_V,uv);\n"
-" col += char(ch_i,uv);\n"
-" col += char(ch_e,uv);\n"
-" col += char(ch_w,uv);\n"
+" col += ch(ch_R,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_s,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_V,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_w,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_lpa,uv);\n"
+" col += ch(ch_C,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_r,uv);\n"
+" col += ch(ch_l,uv);\n"
+" col += ch(ch_lsl,uv);\n"
+" col += ch(ch_S,uv);\n"
+" col += ch(ch_h,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_f,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_col,uv);\n"
+" col += ch(ch_spc,uv);\n"
+" col += ch(ch_R,uv);\n"
+" col += ch(ch_o,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_a,uv);\n"
+" col += ch(ch_t,uv);\n"
+" col += ch(ch_e,uv);\n"
+" col += ch(ch_rpa,uv);\n"
" pos.y -= STRH(1.2);\n"
" pp = vec2(pos.x,pos.y);\n"
-" col += char(ch_Q,uv);\n"
-" col += char(ch_col,uv);\n"
+" col += ch(ch_Q,uv);\n"
+" col += ch(ch_col,uv);\n"
" spaces(10)\n"
-" col += char(ch_Q,uv);\n"
-" col += char(ch_u,uv);\n"
-" col += char(ch_i,uv);\n"
-" col += char(ch_t,uv);\n"
+" col += ch(ch_Q,uv);\n"
+" col += ch(ch_u,uv);\n"
+" col += ch(ch_i,uv);\n"
+" col += ch(ch_t,uv);\n"
" return col;\n"
"}\n"
"vec4 draw_osd() {\n"
@@ -301,9 +366,9 @@ static char osd_binds_shader[] = \
" vec2 ss = sf/2.;\n"
" vec2 c = vec2(coord.x,1.-coord.y);\n"
" vec2 uv = c*ss;\n"
-" vec2 pos = floor(vec2(ss.x/2.-STRW(43.)/2.,(ss.y/2.)+STRH(1.2*10.)));\n"
+" vec2 pos = floor(vec2(ss.x/2.-STRW(49.)/2.,(ss.y/1.25)));\n"
" float pixel = text(uv, pos);\n"
-" float box = in_box(uv,pos-vec2(8.,STRH(1.2*13.)+8.),pos+vec2(STRW(43.)+8.,STRH(1.2)+8.));\n"
+" float box = in_box(uv,pos-vec2(8.,STRH(1.2*14.)+8.),pos+vec2(STRW(49.)+8.,STRH(1.2)+8.));\n"
" vec4 color = bcolor*box;\n"
" color = mix(color,tcolor,pixel);\n"
" color -= pixel*float(mod(c.y*sf.y,3.) < 1.)*0.5;\n"
diff --git a/src/render/shaders/osd_header.h b/src/render/shaders/osd_header.h
index 5ba6491..fad6921 100644
--- a/src/render/shaders/osd_header.h
+++ b/src/render/shaders/osd_header.h
@@ -95,11 +95,9 @@ static char osd_header_shader[] = \
"#define ch_rpa uvec4(0x00E030,0x30180C,0x183030,0xE00000)\n"
"#define ch_tid uvec4(0x0073DA,0xCE0000,0x000000,0x000000)\n"
"#define ch_lar uvec4(0x000000,0x10386C,0xC6C6FE,0x000000)\n"
-"#define spaces(n) for (int i = 0; i < n; i++) { col += char(ch_spc,uv); }\n"
+"#define spaces(n) for (int i = 0; i < n; i++) { col += ch(ch_spc,uv); }\n"
"#define STRW(c) (c*8.)\n"
"#define STRH(c) (c*12.)\n"
-"const vec4 tcolor = vec4(0.78,0.76,0.76,1.);\n"
-"const vec4 bcolor = vec4(0.1,0.1,0.1,0.65);\n"
"vec2 pp = vec2(0.);\n"
"float in_box(vec2 v, vec2 bl, vec2 tr) {\n"
" vec2 s = step(bl,v)-step(tr,v);\n"
@@ -117,30 +115,30 @@ static char osd_header_shader[] = \
" return in_box(uv,vec2(0.),vec2(8.,12.))*float(bv.x+bv.y+bv.z+bv.w);\n"
#endif
"}\n"
-"float char(uvec4 ch, vec2 uv) {\n"
+"float ch(uvec4 ch, vec2 uv) {\n"
" float px = sprite(ch,floor(uv-pp));\n"
" pp += vec2(8.,0.);\n"
" return px;\n"
"}\n"
"uvec4 digit(uint d) {\n"
" switch (d) {\n"
-" case 0: return ch_0;\n"
-" case 1: return ch_1;\n"
-" case 2: return ch_2;\n"
-" case 3: return ch_3;\n"
-" case 4: return ch_4;\n"
-" case 5: return ch_5;\n"
-" case 6: return ch_6;\n"
-" case 7: return ch_7;\n"
-" case 8: return ch_8;\n"
-" case 9:\n"
+" case 0u: return ch_0;\n"
+" case 1u: return ch_1;\n"
+" case 2u: return ch_2;\n"
+" case 3u: return ch_3;\n"
+" case 4u: return ch_4;\n"
+" case 5u: return ch_5;\n"
+" case 6u: return ch_6;\n"
+" case 7u: return ch_7;\n"
+" case 8u: return ch_8;\n"
+" case 9u:\n"
" default: return ch_9;\n"
" }\n"
"}\n"
"float integer(uint number, vec2 uv) {\n"
" float r = 0.;\n"
" for (int i = 1; i >= 0; i--) {\n"
-" r += char(digit(uint(mod(float(number)/max(1.,float(i)*10.),10.))),uv);\n"
+" r += ch(digit(uint(mod(float(number)/max(1.,float(i)*10.),10.))),uv);\n"
" }\n"
" return r;\n"
"}\n";
diff --git a/src/screen/screen.c b/src/screen/screen.c
index 29868d3..841fe0a 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -37,8 +37,10 @@ static void render_callback(void *userdata)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
bool force;
- if (scr->renderer && camu_screen_tick(scr, &force)) {
- scr->renderer->render(scr->renderer, scr, force);
+ if (camu_screen_tick(scr, &force)) {
+ if (scr->renderer) {
+ scr->renderer->render(scr->renderer, scr, force);
+ }
}
}
@@ -276,7 +278,7 @@ static bool mouse_button_callback(void *userdata, u8 state, u8 button)
bool want_crosshair = MOUSE_MOD(scr) && scr->fullscreen;
scr->window->set_cursor(scr->window, want_crosshair ? STELA_CURSOR_CROSSHAIR : DEFAULT_CURSOR(scr));
if (LAST_CLICK_WITHIN(200000)) {
- if (MOD1(scr)) {
+ if (MOD1(scr) || (scr->osd.show && scr->last_pointer_y >= scr->height - OSD_BAR_HEIGHT)) {
seek_to_percent_at_pointer(scr, scr->last_pointer_x);
} else {
s32 n = (scr->last_pointer_x >= scr->width / 2.0) ? 1 : -1;
@@ -351,10 +353,7 @@ static bool key_callback(void *userdata, u8 state, u16 button)
case STELA_KEY_Q:
scr->window->close(scr->window);
scr->callback(scr->userdata, CAMU_SCREEN_CLOSE, NULL);
- break;
- case STELA_KEY_SLASH:
- scr->osd.show_binds = !scr->osd.show_binds;
- break;
+ return true;
case STELA_KEY_RIGHT:
if (MOD1(scr)) {
if (MOD2(scr)) {
@@ -389,33 +388,58 @@ static bool key_callback(void *userdata, u8 state, u16 button)
scr->callback(scr->userdata, CAMU_SCREEN_SKIP, &n);
break;
}
- case STELA_KEY_LEFT_CONTROL:
- case STELA_KEY_RIGHT_CONTROL:
- if (scr->osd.shown_for & CAMU_OSD_VOLUME) {
- scr->osd.shown_for &= ~CAMU_OSD_VOLUME;
- scr->osd.shown_for |= CAMU_OSD_SEEK;
- } else if (!scr->osd.show) {
+ case STELA_KEY_SPACE:
+ scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
+ break;
+ case STELA_KEY_M: {
+ f32 volume = MOD2(scr) ? 1.f : -1.f;
+ scr->callback(scr->userdata, CAMU_SCREEN_SET_VOLUME, &volume);
+ scr->osd.bar_mode = CAMU_OSD_BAR_VOLUME;
+ scr->osd.bar = volume;
+ if (!scr->osd.show) {
+ scr->osd.flash = CAMU_OSD_FLASH_FOR(0.75);
scr->osd.show = true;
- scr->osd.shown_for |= CAMU_OSD_SEEK;
- }
- if (scr->osd.duration > 0 && scr->last_pointer_y >= scr->height - OSD_BAR_HEIGHT) {
- scr->osd.bar_mode = CAMU_OSD_BAR_SEEK;
}
break;
- case STELA_KEY_TAB:
- if (!(scr->osd.shown_for & CAMU_OSD_SEEK)) {
- if (scr->osd.flash >= 0.0) {
- scr->osd.flash = 0.0;
+ }
+ case STELA_KEY_SLASH:
+ if (scr->osd.show) {
+ if (scr->osd.alt == CAMU_OSD_ALT_BINDS) {
+ if (scr->osd.shown_for & CAMU_OSD_TOGGLED) {
+ scr->osd.shown_for &= ~CAMU_OSD_ALT_TOGGLED;
+ } else {
+ scr->osd.show = false;
+ scr->osd.shown_for = 0;
+ atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
+ }
+ scr->osd.alt = 0;
} else {
- scr->osd.show = !scr->osd.show;
- scr->osd.shown_for = 0;
- atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
+ scr->osd.alt = CAMU_OSD_ALT_BINDS;
}
- return true;
+ } else {
+ scr->osd.show = true;
+ scr->osd.shown_for |= CAMU_OSD_ALT_TOGGLED;
+ scr->osd.alt = CAMU_OSD_ALT_BINDS;
+ }
+ return true;
+ case STELA_KEY_TAB:
+ if (scr->osd.show) {
+ scr->osd.show = false;
+ scr->osd.shown_for = 0;
+ scr->osd.alt = 0;
+ atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
+ } else {
+ scr->osd.show = true;
+ scr->osd.shown_for |= CAMU_OSD_TOGGLED;
+ }
+ return true;
+ case STELA_KEY_LEFT_CONTROL:
+ case STELA_KEY_RIGHT_CONTROL:
+ scr->osd.show = true;
+ scr->osd.shown_for |= CAMU_OSD_KEY_HELD;
+ if (scr->osd.duration > 0 && scr->last_pointer_y >= scr->height - OSD_BAR_HEIGHT) {
+ scr->osd.bar_mode = CAMU_OSD_BAR_SEEK;
}
- break;
- case STELA_KEY_SPACE:
- scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
break;
case STELA_KEY_S:
if (MOD1(scr)) {
@@ -428,81 +452,27 @@ static bool key_callback(void *userdata, u8 state, u16 button)
#endif
}
break;
- case STELA_KEY_E:
- scr->callback(scr->userdata, CAMU_SCREEN_RESEEK, NULL);
- break;
- case STELA_KEY_M: {
- f32 volume = MOD2(scr) ? 1.f : -1.f;
- scr->callback(scr->userdata, CAMU_SCREEN_SET_VOLUME, &volume);
- scr->osd.bar_mode = CAMU_OSD_BAR_VOLUME;
- scr->osd.bar = volume;
- scr->osd.flash = CAMU_OSD_FLASH_FOR(0.75);
- if (!scr->osd.show) {
- scr->osd.show = true;
- scr->osd.shown_for |= CAMU_OSD_VOLUME;
+ case STELA_KEY_UP: {
+ s32 n = -1;
+ if (MOD1(scr)) {
+ scr->callback(scr->userdata, CAMU_SCREEN_AUDIO_TRACK, &n);
+ } else if (MOD2(scr)) {
+ scr->callback(scr->userdata, CAMU_SCREEN_SUBTITLE_TRACK, &n);
}
break;
}
- case STELA_KEY_0:
- scr->callback(scr->userdata, CAMU_SCREEN_PRINT, NULL);
- break;
-#ifdef CAMU_SCREEN_DEBUG_KEY
- case STELA_KEY_P:
- scr->callback(scr->userdata, CAMU_SCREEN_DEBUG, NULL);
- break;
-#endif
- case STELA_KEY_R: {
- struct camu_view *view = get_view_from_mouse_pos(scr);
- if (view) {
- if (MOD2(scr)) {
- switch (view->rotation) {
- case CAMU_VIEW_ROTATION_0:
- case CAMU_VIEW_ROTATION_360:
- view->rotation = CAMU_VIEW_ROTATION_90;
- break;
- case CAMU_VIEW_ROTATION_270:
- view->rotation = CAMU_VIEW_ROTATION_0;
- break;
- case CAMU_VIEW_ROTATION_180:
- view->rotation = CAMU_VIEW_ROTATION_270;
- break;
- case CAMU_VIEW_ROTATION_90:
- view->rotation = CAMU_VIEW_ROTATION_180;
- break;
- }
- } else if (MOD1(scr)) {
- switch (view->rotation) {
- case CAMU_VIEW_ROTATION_0:
- case CAMU_VIEW_ROTATION_360:
- view->rotation = CAMU_VIEW_ROTATION_270;
- break;
- case CAMU_VIEW_ROTATION_270:
- view->rotation = CAMU_VIEW_ROTATION_180;
- break;
- case CAMU_VIEW_ROTATION_180:
- view->rotation = CAMU_VIEW_ROTATION_90;
- break;
- case CAMU_VIEW_ROTATION_90:
- view->rotation = CAMU_VIEW_ROTATION_0;
- break;
- }
- } else if (scr->vr_emulation) {
- view->fov = AL_TO_RADIANS(CAMU_DEFAULT_FOV);
- } else {
- view->mode = CAMU_DEFAULT_VIEW;
- }
- camu_view_calculate(view, scr->width, scr->height);
- return true;
+ case STELA_KEY_DOWN: {
+ s32 n = 1;
+ if (MOD1(scr)) {
+ scr->callback(scr->userdata, CAMU_SCREEN_AUDIO_TRACK, &n);
+ } else if (MOD2(scr)) {
+ scr->callback(scr->userdata, CAMU_SCREEN_SUBTITLE_TRACK, &n);
}
break;
}
- case STELA_KEY_T: {
- struct camu_view *view = get_view_from_mouse_pos(scr);
- if (view) {
- scr->window->resize(scr->window, ceil(view->width * view->zoom), ceil(view->height * view->zoom));
- }
+ case STELA_KEY_E:
+ scr->callback(scr->userdata, CAMU_SCREEN_RESEEK, NULL);
break;
- }
case STELA_KEY_EQUAL: {
struct camu_view *view = get_view_from_mouse_pos(scr);
if (view) {
@@ -578,6 +548,69 @@ static bool key_callback(void *userdata, u8 state, u16 button)
}
break;
}
+ case STELA_KEY_R: {
+ struct camu_view *view = get_view_from_mouse_pos(scr);
+ if (view) {
+ if (MOD2(scr)) {
+ switch (view->rotation) {
+ case CAMU_VIEW_ROTATION_0:
+ case CAMU_VIEW_ROTATION_360:
+ view->rotation = CAMU_VIEW_ROTATION_90;
+ break;
+ case CAMU_VIEW_ROTATION_270:
+ view->rotation = CAMU_VIEW_ROTATION_0;
+ break;
+ case CAMU_VIEW_ROTATION_180:
+ view->rotation = CAMU_VIEW_ROTATION_270;
+ break;
+ case CAMU_VIEW_ROTATION_90:
+ view->rotation = CAMU_VIEW_ROTATION_180;
+ break;
+ }
+ } else if (MOD1(scr)) {
+ switch (view->rotation) {
+ case CAMU_VIEW_ROTATION_0:
+ case CAMU_VIEW_ROTATION_360:
+ view->rotation = CAMU_VIEW_ROTATION_270;
+ break;
+ case CAMU_VIEW_ROTATION_270:
+ view->rotation = CAMU_VIEW_ROTATION_180;
+ break;
+ case CAMU_VIEW_ROTATION_180:
+ view->rotation = CAMU_VIEW_ROTATION_90;
+ break;
+ case CAMU_VIEW_ROTATION_90:
+ view->rotation = CAMU_VIEW_ROTATION_0;
+ break;
+ }
+ } else {
+ if (scr->vr_emulation) {
+ view->fov = AL_TO_RADIANS(CAMU_DEFAULT_FOV);
+ } else {
+ view->mode = CAMU_DEFAULT_VIEW;
+ }
+ view->rotation = view->default_rotation;
+ }
+ camu_view_calculate(view, scr->width, scr->height);
+ return true;
+ }
+ break;
+ }
+ case STELA_KEY_T: {
+ struct camu_view *view = get_view_from_mouse_pos(scr);
+ if (view) {
+ scr->window->resize(scr->window, ceil(view->width * view->zoom), ceil(view->height * view->zoom));
+ }
+ break;
+ }
+ case STELA_KEY_0:
+ scr->callback(scr->userdata, CAMU_SCREEN_PRINT, NULL);
+ break;
+#ifdef CAMU_SCREEN_DEBUG_KEY
+ case STELA_KEY_P:
+ scr->callback(scr->userdata, CAMU_SCREEN_DEBUG, NULL);
+ break;
+#endif
default:
break;
}
@@ -586,8 +619,8 @@ static bool key_callback(void *userdata, u8 state, u16 button)
switch (button) {
case STELA_KEY_LEFT_CONTROL:
case STELA_KEY_RIGHT_CONTROL:
- if (scr->osd.shown_for & CAMU_OSD_SEEK) {
- scr->osd.shown_for &= ~CAMU_OSD_SEEK;
+ scr->osd.shown_for &= ~CAMU_OSD_KEY_HELD;
+ if (scr->osd.shown_for == 0) {
scr->osd.show = false;
atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
}
@@ -681,9 +714,9 @@ bool camu_screen_init(struct camu_screen *scr)
scr->last_seek_ts = 0;
#endif
scr->touch_mode = false;
- scr->osd.show_binds = false;
- scr->osd.bar = -1.0;
+ scr->osd.show = false;
scr->osd.flash = -1.0;
+ scr->osd.bar = -1.0;
scr->vr_emulation = CAMU_VR_DISABLED;
scr->vr_left_eye = false;
scr->vr_calibrate_x = 0.5;
@@ -954,17 +987,14 @@ bool camu_screen_tick(struct camu_screen *scr, bool *force)
}
bool was_paused = scr->osd.paused;
scr->callback(scr->userdata, CAMU_SCREEN_STATUS, &scr->osd);
- if (!MOD1(scr)) {
- if (scr->osd.flash >= 0.0) {
- if (nn_get_tick() >= scr->osd.flash) {
- scr->osd.flash = -1.0;
- scr->osd.shown_for = 0;
+ if (scr->osd.flash >= 0.0) {
+ if (nn_get_tick() >= scr->osd.flash) {
+ scr->osd.flash = -1.0;
+ if (scr->osd.shown_for == 0) {
scr->osd.show = false;
- scr->osd.bar_mode = CAMU_OSD_BAR_PROGRESS;
*force = true;
- } else {
- scr->osd.show = true;
}
+ scr->osd.bar_mode = CAMU_OSD_BAR_PROGRESS;
}
}
if (scr->osd.bar_mode == CAMU_OSD_BAR_SEEK) {
@@ -977,7 +1007,9 @@ bool camu_screen_tick(struct camu_screen *scr, bool *force)
scr->osd.shown_for |= CAMU_OSD_PAUSE;
} else if (scr->osd.shown_for & CAMU_OSD_PAUSE) {
scr->osd.shown_for &= ~CAMU_OSD_PAUSE;
- scr->osd.show = false;
+ if (scr->osd.shown_for == 0) {
+ scr->osd.show = false;
+ }
}
*force = true;
}
diff --git a/src/screen/screen.h b/src/screen/screen.h
index c3dcd7d..0be414f 100644
--- a/src/screen/screen.h
+++ b/src/screen/screen.h
@@ -17,7 +17,7 @@
// Interpret click and drag as seeking. Mainly a seek performance test.
//#define CAMU_SCREEN_DRAG_SEEK
-#define CAMU_SCREEN_WIDTH 700
+#define CAMU_SCREEN_WIDTH 840
#define CAMU_SCREEN_HEIGHT 700
enum {
@@ -45,6 +45,8 @@ enum {
CAMU_SCREEN_PERCENT_SEEK, // f64
CAMU_SCREEN_RELATIVE_SEEK, // f64
CAMU_SCREEN_RESEEK,
+ CAMU_SCREEN_AUDIO_TRACK, // s32
+ CAMU_SCREEN_SUBTITLE_TRACK, // s32
CAMU_SCREEN_SHUFFLE,
CAMU_SCREEN_STATUS,
CAMU_SCREEN_PRINT,
@@ -60,10 +62,16 @@ struct camu_screen_video {
};
enum {
- CAMU_OSD_PAUSE = 1,
- CAMU_OSD_SEEK = 1 << 1,
- CAMU_OSD_VOLUME = 1 << 2,
- CAMU_OSD_EMPTY = 1 << 3
+ CAMU_OSD_CONNECTING = 1,
+ CAMU_OSD_PAUSE = 1 << 1,
+ CAMU_OSD_EMPTY = 1 << 2,
+ CAMU_OSD_TOGGLED = 1 << 3,
+ CAMU_OSD_ALT_TOGGLED = 1 << 4,
+ CAMU_OSD_KEY_HELD = 1 << 5
+};
+
+enum {
+ CAMU_OSD_ALT_BINDS = 1
};
enum {
@@ -76,13 +84,13 @@ enum {
struct camu_osd {
u32 show;
+ u8 alt;
u8 shown_for;
- bool show_binds;
+ f64 flash;
u32 connecting;
u32 paused;
u32 bar_mode;
f64 bar;
- f64 flash;
f64 pts;
u64 duration;
};
diff --git a/src/screen/view.c b/src/screen/view.c
index fadc81c..07b2c71 100644
--- a/src/screen/view.c
+++ b/src/screen/view.c
@@ -22,7 +22,8 @@
void camu_view_init(struct camu_view *view, u32 width, u32 height, u8 rotation)
{
view->mode = CAMU_DEFAULT_VIEW;
- view->rotation = rotation;
+ view->default_rotation = rotation;
+ view->rotation = view->default_rotation;
view->width = width;
view->height = height;
view->zindex = 0;
diff --git a/src/screen/view.h b/src/screen/view.h
index ae6a357..c1a0ed7 100644
--- a/src/screen/view.h
+++ b/src/screen/view.h
@@ -29,6 +29,7 @@ enum {
struct camu_view {
u8 mode;
+ u8 default_rotation;
u8 rotation;
u32 width;
u32 height;
diff --git a/src/server/server.c b/src/server/server.c
index 7781c05..513e22e 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -225,7 +225,7 @@ void handle_toggle_sink(struct camu_server *server, str *name, struct camu_serve
// One list_pump() call at a single point should be equivalent to any amount in succession.
// There are two things to consider while within list_pump().
-// 1. An entry that was pending may be freed, making entry->list an invalid statement.
+// 1. An entry that was pending may be freed, making entry->list invalid.
// 2. resource->pending may be edited (added to).
// So, we create an array of every list that needs to be pumped and operate on that.
static void process_pending(struct camu_resource *resource)
@@ -922,6 +922,7 @@ bool camu_server_listen(struct camu_server *server, u8 type, str *addr, u16 port
void camu_server_bind_direct(struct camu_server *server)
{
+ al_str_from(&server->addr, "[direct]");
nn_multiplex_direct_init(multiplex_callback, server);
}
@@ -1025,7 +1026,7 @@ void camu_server_local_add(struct camu_server *server, struct nn_packet *packet)
handle_add_command(server, al_array_last(server->lists), packet);
}
-void camu_server_local_set_index(struct camu_server *server, u32 index)
+void camu_server_local_start_at(struct camu_server *server, s32 index)
{
- lia_list_skipto(al_array_last(server->lists), LIANA_SEQUENCE_ANY, index);
+ lia_list_start_at(al_array_last(server->lists), index);
}
diff --git a/src/server/server.h b/src/server/server.h
index 6552413..3112679 100644
--- a/src/server/server.h
+++ b/src/server/server.h
@@ -57,4 +57,4 @@ void camu_server_free(struct camu_server *server);
// Local compat.
void camu_server_local_add(struct camu_server *server, struct nn_packet *packet);
-void camu_server_local_set_index(struct camu_server *server, u32 index);
+void camu_server_local_start_at(struct camu_server *server, s32 index);
diff --git a/src/util/color_palette.c b/src/util/color_palette.c
index f12d1f8..ca14c55 100644
--- a/src/util/color_palette.c
+++ b/src/util/color_palette.c
@@ -36,6 +36,7 @@ static char *normal_colors[16] = {
bool camu_colors_maybe_init(str *path)
{
+ al_memset(&global_color_palette, 0, sizeof(global_color_palette));
#ifdef NAUNET_HAS_JSON
struct nn_file file;
if (!nn_file_exists(path) || !nn_file_open(&file, path, NNWT_FILE_READONLY)) {
@@ -110,6 +111,8 @@ bool camu_colors_maybe_init(str *path)
out:
json_decref(root);
+ global_color_palette.supplied = parsed;
+
return parsed;
#else
(void)path;
diff --git a/src/util/color_palette.h b/src/util/color_palette.h
index b0cc9f4..5943147 100644
--- a/src/util/color_palette.h
+++ b/src/util/color_palette.h
@@ -28,6 +28,7 @@ enum {
#define CAMU_COLOR_PALETTE_COUNT 18
struct camu_color_palette {
+ bool supplied;
u32 colors[CAMU_COLOR_PALETTE_COUNT];
};
diff --git a/subprojects/SPIRV-Cross.wrap b/subprojects/SPIRV-Cross.wrap
index a0aa44a..f295148 100644
--- a/subprojects/SPIRV-Cross.wrap
+++ b/subprojects/SPIRV-Cross.wrap
@@ -1,8 +1,7 @@
[wrap-git]
-directory = SPIRV-Cross-6c09849
+directory = SPIRV-Cross-83fa691
url = https://github.com/KhronosGroup/SPIRV-Cross.git
-revision = 6c09849fe88c48eaed08413aa022aaa136a3a057
+revision = 83fa691cb8606ca4b3af7f13bfcbedd5668f2a3a
depth = 1
method = cmake
-patch_directory = SPIRV-Cross
diff_files = SPIRV-Cross/msvc_static_build.diff
diff --git a/subprojects/SPIRV-Headers.wrap b/subprojects/SPIRV-Headers.wrap
index 06b420c..9b0b3f2 100644
--- a/subprojects/SPIRV-Headers.wrap
+++ b/subprojects/SPIRV-Headers.wrap
@@ -4,6 +4,3 @@ url = https://github.com/KhronosGroup/SPIRV-Headers.git
revision = b824a462d4256d720bebb40e78b9eb8f78bbb305
depth = 1
method = cmake
-
-[provide]
-dependency_names = SPIRV-Headers
diff --git a/subprojects/ffmpeg2.wrap b/subprojects/ffmpeg2.wrap
index 753e7de..500614d 100644
--- a/subprojects/ffmpeg2.wrap
+++ b/subprojects/ffmpeg2.wrap
@@ -5,4 +5,4 @@ source_filename = ffmpeg-2.8.22.tar.gz
source_hash = d1adc01d275cc15978afc78cc6e2c98a07a8dd6ba96b6217aeb9a1a26d89d213
patch_directory = ffmpeg
-diff_files = ffmpeg/version_2.8.22.diff, ffmpeg/msvc_build_conform.diff, ffmpeg/ffmpeg.git-effadce6c756247ea8bae32dc13bb3e6f464f0eb.patch
+diff_files = ffmpeg/version_2.8.22.diff, ffmpeg/msvc_build_conform_old.diff, ffmpeg/ffmpeg.git-effadce6c756247ea8bae32dc13bb3e6f464f0eb.patch
diff --git a/subprojects/ffmpeg5.wrap b/subprojects/ffmpeg5.wrap
index 6c063cf..fd30a94 100644
--- a/subprojects/ffmpeg5.wrap
+++ b/subprojects/ffmpeg5.wrap
@@ -1,8 +1,8 @@
[wrap-file]
-directory = ffmpeg-5.1.8
-source_url = https://ffmpeg.org/releases/ffmpeg-5.1.8.tar.gz
-source_filename = ffmpeg-5.1.8.tar.gz
-source_hash = 79781c24721427f1855e18b1bebea84f34e86f96e6ccb7a11be7e006d63215dc
+directory = ffmpeg-5.1.10
+source_url = https://ffmpeg.org/releases/ffmpeg-5.1.10.tar.gz
+source_filename = ffmpeg-5.1.10.tar.gz
+source_hash = 710559221ba9ce9e51273f172c073db7e9b9bbd2195597540b837716301191b8
patch_directory = ffmpeg
-diff_files = ffmpeg/version_5.1.8.diff, ffmpeg/msvc_build_conform.diff
+diff_files = ffmpeg/version_5.1.10.diff, ffmpeg/msvc_build_conform.diff
diff --git a/subprojects/ffmpeg6.wrap b/subprojects/ffmpeg6.wrap
index 4a6cdf0..8aba3a8 100644
--- a/subprojects/ffmpeg6.wrap
+++ b/subprojects/ffmpeg6.wrap
@@ -1,8 +1,8 @@
[wrap-file]
-directory = ffmpeg-6.1.4
-source_url = https://ffmpeg.org/releases/ffmpeg-6.1.4.tar.gz
-source_filename = ffmpeg-6.1.4.tar.gz
-source_hash = e21c2624978f56b2030a0cc138cdf67f0b8888b471665907be16b598d85b98ad
+directory = ffmpeg-6.1.6
+source_url = https://ffmpeg.org/releases/ffmpeg-6.1.6.tar.gz
+source_filename = ffmpeg-6.1.6.tar.gz
+source_hash = e8be3fdcf272685f18c9334d4d2122e11164448bfc358fe0be2a1a97ef1f94d8
patch_directory = ffmpeg
-diff_files = ffmpeg/version_6.1.4.diff, ffmpeg/msvc_build_conform.diff
+diff_files = ffmpeg/version_6.1.6.diff, ffmpeg/msvc_build_conform.diff
diff --git a/subprojects/ffmpeg7.wrap b/subprojects/ffmpeg7.wrap
index adc4807..ebf9f8b 100644
--- a/subprojects/ffmpeg7.wrap
+++ b/subprojects/ffmpeg7.wrap
@@ -1,8 +1,8 @@
[wrap-file]
-directory = ffmpeg-7.1.3
-source_url = https://ffmpeg.org/releases/ffmpeg-7.1.3.tar.gz
-source_filename = ffmpeg-7.1.3.tar.gz
-source_hash = 81b452c5afe327a19a6a27e28ff09f6bf217b1d1fca988fc451c4717d8fe8ba7
+directory = ffmpeg-7.1.5
+source_url = https://ffmpeg.org/releases/ffmpeg-7.1.5.tar.gz
+source_filename = ffmpeg-7.1.5.tar.gz
+source_hash = a3cc1c02de1e25e7ff988600c901a4f5c5303651565a2feaf8e59a25d5af782d
patch_directory = ffmpeg
-diff_files = ffmpeg/version_7.1.3.diff, ffmpeg/msvc_build_conform.diff
+diff_files = ffmpeg/version_7.1.5.diff, ffmpeg/msvc_build_conform.diff
diff --git a/subprojects/ffmpeg8.wrap b/subprojects/ffmpeg8.wrap
index f8ee90f..9e6b9d8 100644
--- a/subprojects/ffmpeg8.wrap
+++ b/subprojects/ffmpeg8.wrap
@@ -1,23 +1,8 @@
[wrap-file]
-#directory = ffmpeg-8.0.1
-#directory = ffmpeg-8.1
-#directory = ffmpeg-8.1.1
directory = ffmpeg-8.1.2
-#source_url = https://ffmpeg.org/releases/ffmpeg-8.0.1.tar.gz
-#source_url = https://ffmpeg.org/releases/ffmpeg-8.1.tar.gz
-#source_url = https://ffmpeg.org/releases/ffmpeg-8.1.1.tar.gz
source_url = https://ffmpeg.org/releases/ffmpeg-8.1.2.tar.gz
-#source_filename = ffmpeg-8.0.1.tar.gz
-#source_filename = ffmpeg-8.1.tar.gz
-#source_filename = ffmpeg-8.1.1.tar.gz
source_filename = ffmpeg-8.1.2.tar.gz
-#source_hash = ed1cfade43aab7711c88937a0afc15b7b22efdc528c6ff074b4027c55a3c175c
-#source_hash = b13510e7a6a4ca28fa04307f2be54ef5a31e168eb2bbe055a7f4e4d2cadd51b1
-#source_hash = 1b856f26a07082b6879f3e5300d81e8c7ce3b410ade5898b14382d90c2904634
source_hash = 32faba5ef67340d54724941eae1425580791195312a4fd13bf6f820a2818bf22
patch_directory = ffmpeg
-#diff_files = ffmpeg/version_8.0.1.diff, ffmpeg/msvc_build_conform.diff
-#diff_files = ffmpeg/version_8.1.diff
-#diff_files = ffmpeg/version_8.1.1.diff
diff_files = ffmpeg/version_8.1.2.diff
diff --git a/subprojects/harfbuzz.wrap b/subprojects/harfbuzz.wrap
index a497a7d..f579644 100644
--- a/subprojects/harfbuzz.wrap
+++ b/subprojects/harfbuzz.wrap
@@ -1,7 +1,6 @@
[wrap-git]
-directory = harfbuzz-14.3.1
+directory = harfbuzz-14.4.0
url = https://github.com/harfbuzz/harfbuzz.git
-revision = 14.3.1
+revision = 14.4.0
depth = 1
-patch_directory = harfbuzz
diff_files = harfbuzz/no_bigobj_windows.diff
diff --git a/subprojects/libalabaster.wrap b/subprojects/libalabaster.wrap
index f2c94fd..4ff483e 100644
--- a/subprojects/libalabaster.wrap
+++ b/subprojects/libalabaster.wrap
@@ -1,5 +1,5 @@
[wrap-git]
-directory = libalabaster-b617e3c
+directory = libalabaster-81a7b4b
url = https://git.akon.city/libalabaster.git
push-url = git@git.akon.city:libalabaster.git
-revision = b617e3ccb25a0ac3c22f8c02722c8108b2f78d6e
+revision = 81a7b4ba322aeddf52207fdcd2213e5f5a493471
diff --git a/subprojects/libplacebo.wrap b/subprojects/libplacebo.wrap
index e960982..4f7bd30 100644
--- a/subprojects/libplacebo.wrap
+++ b/subprojects/libplacebo.wrap
@@ -1,11 +1,7 @@
[wrap-git]
-directory = libplacebo-22ee762
+directory = libplacebo-3330a51
url = https://code.videolan.org/videolan/libplacebo.git
-revision = 22ee762e8e0890fc54068beb670310f0edce7263
+revision = 3330a515d62139259c26239014f286e233bd3a5c
clone-recursive = true
depth = 1
-
-diff_files = libplacebo/cache_ref_rect.diff, libplacebo/fix_rotate.diff, libplacebo/glClientWaitSync_0_return.diff, libplacebo/info_priv_hash.diff, libplacebo/d3d11_scaling_none.diff
-
-[provide]
-dependency_names = libplacebo
+diff_files = libplacebo/cache_ref_rect.diff, libplacebo/fix_rotate.diff, libplacebo/glClientWaitSync_0_return.diff, libplacebo/info_priv_hash.diff, libplacebo/d3d11_scaling_none.diff, libplacebo/android_opengl_custom_dispatch.diff
diff --git a/subprojects/notcurses.wrap b/subprojects/notcurses.wrap
index 8d8e41d..8c33f0b 100644
--- a/subprojects/notcurses.wrap
+++ b/subprojects/notcurses.wrap
@@ -4,8 +4,6 @@ url = https://github.com/dankamongmen/notcurses.git
revision = b26048eebc74d5d254717d3332fa484718f9efe6
depth = 1
method = cmake
-
-patch_directory = notcurses
diff_files = notcurses/duration_and_ffmpeg_fix.diff
[provide]
diff --git a/subprojects/packagefiles/ffmpeg/meson.build b/subprojects/packagefiles/ffmpeg/meson.build
index aa881bc..f19204a 100644
--- a/subprojects/packagefiles/ffmpeg/meson.build
+++ b/subprojects/packagefiles/ffmpeg/meson.build
@@ -77,20 +77,18 @@ decoders += ',av1'
if get_option('subtitles').enabled()
decoders += ',ass,srt,webvtt'
endif
-#if get_option('codec-hwaccels').length() == 0
- libdav1d = dependency('dav1d', required: false)
- if libdav1d.found()
- decoders += ',libdav1d'
- extra_options += ['--enable-libdav1d']
- deps += [libdav1d]
- endif
-#endif
+libdav1d = dependency('dav1d', required: false)
+if libdav1d.found()
+ decoders += ',libdav1d'
+ extra_options += ['--enable-libdav1d']
+ deps += [libdav1d]
+endif
demuxers = ''
muxers = ''
parsers = ''
if not get_option('sink-only')
- demuxers += 'flac,mp3,aac,wav,matroska,mov,avi'
+ demuxers += ',flac,mp3,aac,wav,matroska,mov,avi'
demuxers += ',pcm_s32be,pcm_s32le,pcm_s24be,pcm_s24le,pcm_s16be,pcm_s16le'
#demuxers += ',pcm_f32be,pcm_f32le,pcm_s32le_planar,pcm_s16be_planar,pcm_s16le_planar'
demuxers += ',eac3'
@@ -99,7 +97,7 @@ if not get_option('sink-only')
demuxers += ',ass,srt,webvtt'
muxers += ',ass,srt,webvtt'
endif
- parsers += 'aac,opus,h264,hevc,av1,vp9'
+ parsers += ',aac,opus,h264,hevc,av1,vp9'
parsers += ',dca'
parsers += ',mpegaudio,mpegvideo,dvd_nav'
bzlib = dependency('bzip2', required: false)
@@ -128,7 +126,7 @@ extra_options += ['--disable-xlib']
bsfs = ''
if not get_option('sink-only')
- bsfs += 'extract_extradata,mp3_header_decompress'
+ bsfs += ',extract_extradata,mp3_header_decompress'
endif
hwaccels = ''
diff --git a/subprojects/packagefiles/ffmpeg/version_2.8.22.diff b/subprojects/packagefiles/ffmpeg/version_2.8.22.diff
index 8530b6d..443b12d 100644
--- a/subprojects/packagefiles/ffmpeg/version_2.8.22.diff
+++ b/subprojects/packagefiles/ffmpeg/version_2.8.22.diff
@@ -1,14 +1,12 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:47:10.979206957 -0400
-@@ -1,4 +1,6 @@
+--- a/meson.build 2026-09-07 10:14:49.222935216 -0400
++++ b/meson.build 2026-09-07 10:16:24.138586490 -0400
+@@ -1,4 +1,4 @@
-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
+project('ffmpeg', 'c', version: '2.8.22', meson_version: '>=0.57.0')
-+
-+error('FFmpeg version 2.x currently unsupported.')
compiler = meson.get_compiler('c')
-@@ -35,10 +37,6 @@
+@@ -38,10 +38,6 @@
extra_options += ['--nm=' + meson.get_external_property('nm', 'nm')]
endif
@@ -17,25 +15,60 @@
-endif
-
extra_options += ['--enable-static', '--disable-shared']
+ if is_static_shared_lib
+ extra_options += ['--enable-pic']
+@@ -77,12 +73,6 @@
+ if get_option('subtitles').enabled()
+ decoders += ',ass,srt,webvtt'
+ endif
+-libdav1d = dependency('dav1d', required: false)
+-if libdav1d.found()
+- decoders += ',libdav1d'
+- extra_options += ['--enable-libdav1d']
+- deps += [libdav1d]
+-endif
+
+ demuxers = ''
+ muxers = ''
+@@ -191,7 +181,7 @@
+ deps += [compiler.find_library('mediandk')]
+ args += ['-DCAMU_HAVE_MEDIACODEC']
+ else
+- extra_options += ['--disable-jni', '--disable-mediacodec']
++ extra_options += []
+ endif
+
+ if get_option('codec-hwaccels').length() == 0
+@@ -202,12 +192,6 @@
- if is_windows
-@@ -229,7 +227,6 @@
+ # Disable unused hwaccels.
+ extra_options += [
+- '--disable-amf',
+- '--disable-audiotoolbox',
+- '--disable-cuda-llvm',
+- '--disable-cuvid',
+- '--disable-ffnvcodec',
+- '--disable-nvdec',
+ '--disable-nvenc',
+ '--disable-vdpau',
+ '--disable-videotoolbox'
+@@ -261,7 +245,6 @@
+ '--libdir=@PREFIX@/@LIBDIR@',
'--incdir=@PREFIX@/@INCLUDEDIR@',
- '--enable-pic',
'--disable-all',
- '--disable-autodetect',
'--disable-everything',
'--disable-programs',
'--disable-doc',
-@@ -238,7 +235,6 @@
+@@ -269,7 +252,6 @@
+ '--disable-manpages',
'--disable-podpages',
'--disable-txtpages',
- '--disable-safe-bitstream-reader',
- '--disable-schannel',
'--disable-network',
'--disable-securetransport',
'--enable-gpl',
-@@ -268,14 +264,14 @@
+@@ -299,14 +281,14 @@
swscale = proj.dependency('swscale')
include = include_directories('.', 'build/')
meson.override_dependency('libavutil', declare_dependency(
diff --git a/subprojects/packagefiles/ffmpeg/version_3.3.9.diff b/subprojects/packagefiles/ffmpeg/version_3.3.9.diff
index bf31274..1ea98d9 100644
--- a/subprojects/packagefiles/ffmpeg/version_3.3.9.diff
+++ b/subprojects/packagefiles/ffmpeg/version_3.3.9.diff
@@ -1,12 +1,12 @@
---- a/meson.build 2026-07-04 12:03:17.942564661 -0400
-+++ b/meson.build 2026-07-04 15:10:51.305639404 -0400
+--- a/meson.build 2026-09-07 10:14:49.222935216 -0400
++++ b/meson.build 2026-09-07 10:19:35.891881943 -0400
@@ -1,4 +1,4 @@
-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
+project('ffmpeg', 'c', version: '3.3.9', meson_version: '>=0.57.0')
compiler = meson.get_compiler('c')
-@@ -40,10 +40,6 @@
+@@ -38,10 +38,6 @@
extra_options += ['--nm=' + meson.get_external_property('nm', 'nm')]
endif
@@ -15,24 +15,22 @@
-endif
-
extra_options += ['--enable-static', '--disable-shared']
-
- if is_windows
-@@ -76,14 +72,6 @@
+ if is_static_shared_lib
+ extra_options += ['--enable-pic']
+@@ -77,12 +73,6 @@
if get_option('subtitles').enabled()
decoders += ',ass,srt,webvtt'
endif
--#if get_option('codec-hwaccels').length() == 0
-- libdav1d = dependency('dav1d', required: false)
-- if libdav1d.found()
-- decoders += ',libdav1d'
-- extra_options += ['--enable-libdav1d']
-- deps += [libdav1d]
-- endif
--#endif
+-libdav1d = dependency('dav1d', required: false)
+-if libdav1d.found()
+- decoders += ',libdav1d'
+- extra_options += ['--enable-libdav1d']
+- deps += [libdav1d]
+-endif
demuxers = ''
muxers = ''
-@@ -203,12 +191,8 @@
+@@ -202,12 +192,8 @@
# Disable unused hwaccels.
extra_options += [
@@ -44,8 +42,8 @@
- '--disable-nvdec',
'--disable-nvenc',
'--disable-vdpau',
- '--disable-audiotoolbox',
-@@ -255,6 +239,15 @@
+ '--disable-videotoolbox'
+@@ -253,6 +239,15 @@
args += ['-DCAMU_HAVE_SOXR']
endif
@@ -61,15 +59,15 @@
ext_proj = import('unstable-external_project')
proj = ext_proj.add_project('configure',
-@@ -264,7 +257,6 @@
+@@ -261,7 +256,6 @@
+ '--libdir=@PREFIX@/@LIBDIR@',
'--incdir=@PREFIX@/@INCLUDEDIR@',
- '--enable-pic',
'--disable-all',
- '--disable-autodetect',
'--disable-everything',
'--disable-programs',
'--disable-doc',
-@@ -289,11 +281,14 @@
+@@ -286,11 +280,14 @@
'--enable-swscale',
'--disable-indevs',
'--disable-outdevs',
@@ -84,7 +82,7 @@
avutil = proj.dependency('avutil')
avformat = proj.dependency('avformat')
avcodec = proj.dependency('avcodec')
-@@ -302,14 +297,14 @@
+@@ -299,14 +296,14 @@
swscale = proj.dependency('swscale')
include = include_directories('.', 'build/')
meson.override_dependency('libavutil', declare_dependency(
diff --git a/subprojects/packagefiles/ffmpeg/version_3.4.14.diff b/subprojects/packagefiles/ffmpeg/version_3.4.14.diff
index fa3622a..538a777 100644
--- a/subprojects/packagefiles/ffmpeg/version_3.4.14.diff
+++ b/subprojects/packagefiles/ffmpeg/version_3.4.14.diff
@@ -1,12 +1,38 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:58:06.264562637 -0400
+--- a/meson.build 2026-09-07 10:14:49.222935216 -0400
++++ b/meson.build 2026-09-07 10:22:28.874228365 -0400
@@ -1,4 +1,4 @@
-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
+project('ffmpeg', 'c', version: '3.4.14', meson_version: '>=0.57.0')
compiler = meson.get_compiler('c')
-@@ -268,14 +268,14 @@
+@@ -77,12 +77,6 @@
+ if get_option('subtitles').enabled()
+ decoders += ',ass,srt,webvtt'
+ endif
+-libdav1d = dependency('dav1d', required: false)
+-if libdav1d.found()
+- decoders += ',libdav1d'
+- extra_options += ['--enable-libdav1d']
+- deps += [libdav1d]
+-endif
+
+ demuxers = ''
+ muxers = ''
+@@ -202,12 +196,8 @@
+
+ # Disable unused hwaccels.
+ extra_options += [
+- '--disable-amf',
+ '--disable-audiotoolbox',
+- '--disable-cuda-llvm',
+ '--disable-cuvid',
+- '--disable-ffnvcodec',
+- '--disable-nvdec',
+ '--disable-nvenc',
+ '--disable-vdpau',
+ '--disable-videotoolbox'
+@@ -299,14 +289,14 @@
swscale = proj.dependency('swscale')
include = include_directories('.', 'build/')
meson.override_dependency('libavutil', declare_dependency(
diff --git a/subprojects/packagefiles/ffmpeg/version_4.2.11.diff b/subprojects/packagefiles/ffmpeg/version_4.2.11.diff
index cce132d..94decd2 100644
--- a/subprojects/packagefiles/ffmpeg/version_4.2.11.diff
+++ b/subprojects/packagefiles/ffmpeg/version_4.2.11.diff
@@ -1,32 +1,21 @@
---- a/meson.build 2025-11-30 11:51:43.747121512 -0500
-+++ b/meson.build 2025-11-30 12:52:39.981254464 -0500
+--- a/meson.build 2026-09-07 10:14:49.222935216 -0400
++++ b/meson.build 2026-09-07 10:32:24.949964575 -0400
@@ -1,4 +1,4 @@
-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
+project('ffmpeg', 'c', version: '4.2.11', meson_version: '>=0.57.0')
compiler = meson.get_compiler('c')
-@@ -68,18 +68,7 @@
- decoders += ',dca,eac3'
- decoders += ',pcm_dvd,mpegvideo,mpeg2video'
- #decoders += ',ass,srt'
--if get_option('codec-hwaccels').length() == 0
-- if not is_msvc
-- libdav1d = dependency('dav1d', required: false)
-- if libdav1d.found()
-- decoders += ',libdav1d'
-- extra_options += ['--enable-libdav1d']
-- deps += [libdav1d]
-- endif
-- endif
--else
-- decoders += ',av1'
--endif
-+decoders += ',av1'
-
- demuxers = ''
- parsers = ''
-@@ -290,14 +279,14 @@
+@@ -77,7 +77,7 @@
+ if get_option('subtitles').enabled()
+ decoders += ',ass,srt,webvtt'
+ endif
+-libdav1d = dependency('dav1d', required: false)
++libdav1d = dependency('dav1d', version: '<1.0.0', required: false)
+ if libdav1d.found()
+ decoders += ',libdav1d'
+ extra_options += ['--enable-libdav1d']
+@@ -299,14 +299,14 @@
swscale = proj.dependency('swscale')
include = include_directories('.', 'build/')
meson.override_dependency('libavutil', declare_dependency(
diff --git a/subprojects/packagefiles/ffmpeg/version_5.1.7.diff b/subprojects/packagefiles/ffmpeg/version_5.1.10.diff
index f48d522..0b9f4d6 100644
--- a/subprojects/packagefiles/ffmpeg/version_5.1.7.diff
+++ b/subprojects/packagefiles/ffmpeg/version_5.1.10.diff
@@ -1,12 +1,12 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:40:17.065798145 -0400
+--- a/meson.build 2026-09-07 10:14:49.222935216 -0400
++++ b/meson.build 2026-09-07 10:41:24.437290827 -0400
@@ -1,4 +1,4 @@
-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
-+project('ffmpeg', 'c', version: '5.1.7', meson_version: '>=0.57.0')
++project('ffmpeg', 'c', version: '5.1.10', meson_version: '>=0.57.0')
compiler = meson.get_compiler('c')
-@@ -268,14 +268,14 @@
+@@ -299,14 +299,14 @@
swscale = proj.dependency('swscale')
include = include_directories('.', 'build/')
meson.override_dependency('libavutil', declare_dependency(
diff --git a/subprojects/packagefiles/ffmpeg/version_5.1.8.diff b/subprojects/packagefiles/ffmpeg/version_5.1.8.diff
deleted file mode 100644
index 784c8a1..0000000
--- a/subprojects/packagefiles/ffmpeg/version_5.1.8.diff
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:40:17.065798145 -0400
-@@ -1,4 +1,4 @@
--project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
-+project('ffmpeg', 'c', version: '5.1.8', meson_version: '>=0.57.0')
-
- compiler = meson.get_compiler('c')
-
-@@ -268,14 +268,14 @@
- swscale = proj.dependency('swscale')
- include = include_directories('.', 'build/')
- meson.override_dependency('libavutil', declare_dependency(
-- dependencies: [avutil, deps], compile_args: args, include_directories: include, version: ''))
-+ dependencies: [avutil, deps], compile_args: args, include_directories: include, version: '57.28.100'))
- meson.override_dependency('libavformat', declare_dependency(
-- dependencies: [avformat], include_directories: include, version: ''))
-+ dependencies: [avformat], include_directories: include, version: '59.27.100'))
- meson.override_dependency('libavcodec', declare_dependency(
-- dependencies: [avcodec], include_directories: include, version: ''))
-+ dependencies: [avcodec], include_directories: include, version: '59.37.100'))
- meson.override_dependency('libavdevice', declare_dependency(
-- dependencies: [avdevice], include_directories: include, version: ''))
-+ dependencies: [avdevice], include_directories: include, version: '59.7.100'))
- meson.override_dependency('libswresample', declare_dependency(
-- dependencies: [swresample], include_directories: include, version: ''))
-+ dependencies: [swresample], include_directories: include, version: '4.7.100'))
- meson.override_dependency('libswscale', declare_dependency(
-- dependencies: [swscale], include_directories: include, version: ''))
-+ dependencies: [swscale], include_directories: include, version: '6.7.100'))
diff --git a/subprojects/packagefiles/ffmpeg/version_6.1.3.diff b/subprojects/packagefiles/ffmpeg/version_6.1.3.diff
deleted file mode 100644
index 6193dfe..0000000
--- a/subprojects/packagefiles/ffmpeg/version_6.1.3.diff
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:37:56.556303265 -0400
-@@ -1,4 +1,4 @@
--project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
-+project('ffmpeg', 'c', version: '6.1.3', meson_version: '>=0.57.0')
-
- compiler = meson.get_compiler('c')
-
-@@ -268,14 +268,14 @@
- swscale = proj.dependency('swscale')
- include = include_directories('.', 'build/')
- meson.override_dependency('libavutil', declare_dependency(
-- dependencies: [avutil, deps], compile_args: args, include_directories: include, version: ''))
-+ dependencies: [avutil, deps], compile_args: args, include_directories: include, version: '58.29.100'))
- meson.override_dependency('libavformat', declare_dependency(
-- dependencies: [avformat], include_directories: include, version: ''))
-+ dependencies: [avformat], include_directories: include, version: '60.16.100'))
- meson.override_dependency('libavcodec', declare_dependency(
-- dependencies: [avcodec], include_directories: include, version: ''))
-+ dependencies: [avcodec], include_directories: include, version: '60.31.102'))
- meson.override_dependency('libavdevice', declare_dependency(
-- dependencies: [avdevice], include_directories: include, version: ''))
-+ dependencies: [avdevice], include_directories: include, version: '60.3.100'))
- meson.override_dependency('libswresample', declare_dependency(
-- dependencies: [swresample], include_directories: include, version: ''))
-+ dependencies: [swresample], include_directories: include, version: '4.12.100'))
- meson.override_dependency('libswscale', declare_dependency(
-- dependencies: [swscale], include_directories: include, version: ''))
-+ dependencies: [swscale], include_directories: include, version: '7.5.100'))
diff --git a/subprojects/packagefiles/ffmpeg/version_6.1.4.diff b/subprojects/packagefiles/ffmpeg/version_6.1.6.diff
index 5f54fe5..524e369 100644
--- a/subprojects/packagefiles/ffmpeg/version_6.1.4.diff
+++ b/subprojects/packagefiles/ffmpeg/version_6.1.6.diff
@@ -1,12 +1,12 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:37:56.556303265 -0400
+--- a/meson.build 2026-09-07 10:14:49.222935216 -0400
++++ b/meson.build 2026-09-07 10:45:44.998194363 -0400
@@ -1,4 +1,4 @@
-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
-+project('ffmpeg', 'c', version: '6.1.4', meson_version: '>=0.57.0')
++project('ffmpeg', 'c', version: '6.1.6', meson_version: '>=0.57.0')
compiler = meson.get_compiler('c')
-@@ -268,14 +268,14 @@
+@@ -299,14 +299,14 @@
swscale = proj.dependency('swscale')
include = include_directories('.', 'build/')
meson.override_dependency('libavutil', declare_dependency(
diff --git a/subprojects/packagefiles/ffmpeg/version_7.1.3.diff b/subprojects/packagefiles/ffmpeg/version_7.1.3.diff
deleted file mode 100644
index 554ef02..0000000
--- a/subprojects/packagefiles/ffmpeg/version_7.1.3.diff
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:35:33.498781349 -0400
-@@ -1,4 +1,4 @@
--project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
-+project('ffmpeg', 'c', version: '7.1.3', meson_version: '>=0.57.0')
-
- compiler = meson.get_compiler('c')
-
-@@ -268,14 +268,14 @@
- swscale = proj.dependency('swscale')
- include = include_directories('.', 'build/')
- meson.override_dependency('libavutil', declare_dependency(
-- dependencies: [avutil, deps], compile_args: args, include_directories: include, version: ''))
-+ dependencies: [avutil, deps], compile_args: args, include_directories: include, version: '59.39.100'))
- meson.override_dependency('libavformat', declare_dependency(
-- dependencies: [avformat], include_directories: include, version: ''))
-+ dependencies: [avformat], include_directories: include, version: '61.7.100'))
- meson.override_dependency('libavcodec', declare_dependency(
-- dependencies: [avcodec], include_directories: include, version: ''))
-+ dependencies: [avcodec], include_directories: include, version: '61.19.100'))
- meson.override_dependency('libavdevice', declare_dependency(
-- dependencies: [avdevice], include_directories: include, version: ''))
-+ dependencies: [avdevice], include_directories: include, version: '61.3.100'))
- meson.override_dependency('libswresample', declare_dependency(
-- dependencies: [swresample], include_directories: include, version: ''))
-+ dependencies: [swresample], include_directories: include, version: '5.3.100'))
- meson.override_dependency('libswscale', declare_dependency(
-- dependencies: [swscale], include_directories: include, version: ''))
-+ dependencies: [swscale], include_directories: include, version: '8.3.100'))
diff --git a/subprojects/packagefiles/ffmpeg/version_7.1.1.diff b/subprojects/packagefiles/ffmpeg/version_7.1.5.diff
index 74a41fe..6b25cf2 100644
--- a/subprojects/packagefiles/ffmpeg/version_7.1.1.diff
+++ b/subprojects/packagefiles/ffmpeg/version_7.1.5.diff
@@ -1,12 +1,12 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:35:33.498781349 -0400
+--- a/meson.build 2026-09-07 10:14:49.222935216 -0400
++++ b/meson.build 2026-09-07 10:50:23.103988360 -0400
@@ -1,4 +1,4 @@
-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
-+project('ffmpeg', 'c', version: '7.1.1', meson_version: '>=0.57.0')
++project('ffmpeg', 'c', version: '7.1.5', meson_version: '>=0.57.0')
compiler = meson.get_compiler('c')
-@@ -268,14 +268,14 @@
+@@ -299,14 +299,14 @@
swscale = proj.dependency('swscale')
include = include_directories('.', 'build/')
meson.override_dependency('libavutil', declare_dependency(
diff --git a/subprojects/packagefiles/ffmpeg/version_8.0.1.diff b/subprojects/packagefiles/ffmpeg/version_8.0.1.diff
deleted file mode 100644
index b222001..0000000
--- a/subprojects/packagefiles/ffmpeg/version_8.0.1.diff
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:33:36.209533531 -0400
-@@ -1,4 +1,4 @@
--project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
-+project('ffmpeg', 'c', version: '8.0.1', meson_version: '>=0.57.0')
-
- compiler = meson.get_compiler('c')
-
-@@ -268,14 +268,14 @@
- swscale = proj.dependency('swscale')
- include = include_directories('.', 'build/')
- meson.override_dependency('libavutil', declare_dependency(
-- dependencies: [avutil, deps], compile_args: args, include_directories: include, version: ''))
-+ dependencies: [avutil, deps], compile_args: args, include_directories: include, version: '60.8.100'))
- meson.override_dependency('libavformat', declare_dependency(
-- dependencies: [avformat], include_directories: include, version: ''))
-+ dependencies: [avformat], include_directories: include, version: '62.3.100'))
- meson.override_dependency('libavcodec', declare_dependency(
-- dependencies: [avcodec], include_directories: include, version: ''))
-+ dependencies: [avcodec], include_directories: include, version: '62.11.100'))
- meson.override_dependency('libavdevice', declare_dependency(
-- dependencies: [avdevice], include_directories: include, version: ''))
-+ dependencies: [avdevice], include_directories: include, version: '62.1.100'))
- meson.override_dependency('libswresample', declare_dependency(
-- dependencies: [swresample], include_directories: include, version: ''))
-+ dependencies: [swresample], include_directories: include, version: '6.1.100'))
- meson.override_dependency('libswscale', declare_dependency(
-- dependencies: [swscale], include_directories: include, version: ''))
-+ dependencies: [swscale], include_directories: include, version: '9.1.100'))
diff --git a/subprojects/packagefiles/ffmpeg/version_8.0.diff b/subprojects/packagefiles/ffmpeg/version_8.0.diff
deleted file mode 100644
index ad3b77b..0000000
--- a/subprojects/packagefiles/ffmpeg/version_8.0.diff
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:33:36.209533531 -0400
-@@ -1,4 +1,4 @@
--project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
-+project('ffmpeg', 'c', version: '8.0', meson_version: '>=0.57.0')
-
- compiler = meson.get_compiler('c')
-
-@@ -268,14 +268,14 @@
- swscale = proj.dependency('swscale')
- include = include_directories('.', 'build/')
- meson.override_dependency('libavutil', declare_dependency(
-- dependencies: [avutil, deps], compile_args: args, include_directories: include, version: ''))
-+ dependencies: [avutil, deps], compile_args: args, include_directories: include, version: '60.8.100'))
- meson.override_dependency('libavformat', declare_dependency(
-- dependencies: [avformat], include_directories: include, version: ''))
-+ dependencies: [avformat], include_directories: include, version: '62.3.100'))
- meson.override_dependency('libavcodec', declare_dependency(
-- dependencies: [avcodec], include_directories: include, version: ''))
-+ dependencies: [avcodec], include_directories: include, version: '62.11.100'))
- meson.override_dependency('libavdevice', declare_dependency(
-- dependencies: [avdevice], include_directories: include, version: ''))
-+ dependencies: [avdevice], include_directories: include, version: '62.1.100'))
- meson.override_dependency('libswresample', declare_dependency(
-- dependencies: [swresample], include_directories: include, version: ''))
-+ dependencies: [swresample], include_directories: include, version: '6.1.100'))
- meson.override_dependency('libswscale', declare_dependency(
-- dependencies: [swscale], include_directories: include, version: ''))
-+ dependencies: [swscale], include_directories: include, version: '9.1.100'))
diff --git a/subprojects/packagefiles/ffmpeg/version_8.1.1.diff b/subprojects/packagefiles/ffmpeg/version_8.1.1.diff
deleted file mode 100644
index 8976dd2..0000000
--- a/subprojects/packagefiles/ffmpeg/version_8.1.1.diff
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:33:36.209533531 -0400
-@@ -1,4 +1,4 @@
--project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
-+project('ffmpeg', 'c', version: '8.1.1', meson_version: '>=0.57.0')
-
- compiler = meson.get_compiler('c')
-
-@@ -268,14 +268,14 @@
- swscale = proj.dependency('swscale')
- include = include_directories('.', 'build/')
- meson.override_dependency('libavutil', declare_dependency(
-- dependencies: [avutil, deps], compile_args: args, include_directories: include, version: ''))
-+ dependencies: [avutil, deps], compile_args: args, include_directories: include, version: '60.26.101'))
- meson.override_dependency('libavformat', declare_dependency(
-- dependencies: [avformat], include_directories: include, version: ''))
-+ dependencies: [avformat], include_directories: include, version: '62.12.101'))
- meson.override_dependency('libavcodec', declare_dependency(
-- dependencies: [avcodec], include_directories: include, version: ''))
-+ dependencies: [avcodec], include_directories: include, version: '62.28.101'))
- meson.override_dependency('libavdevice', declare_dependency(
-- dependencies: [avdevice], include_directories: include, version: ''))
-+ dependencies: [avdevice], include_directories: include, version: '62.3.101'))
- meson.override_dependency('libswresample', declare_dependency(
-- dependencies: [swresample], include_directories: include, version: ''))
-+ dependencies: [swresample], include_directories: include, version: '6.3.101'))
- meson.override_dependency('libswscale', declare_dependency(
-- dependencies: [swscale], include_directories: include, version: ''))
-+ dependencies: [swscale], include_directories: include, version: '9.5.101'))
diff --git a/subprojects/packagefiles/ffmpeg/version_8.1.2.diff b/subprojects/packagefiles/ffmpeg/version_8.1.2.diff
index e1b52a4..036e9a3 100644
--- a/subprojects/packagefiles/ffmpeg/version_8.1.2.diff
+++ b/subprojects/packagefiles/ffmpeg/version_8.1.2.diff
@@ -1,12 +1,12 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:33:36.209533531 -0400
+--- a/meson.build 2026-09-07 10:14:49.222935216 -0400
++++ b/meson.build 2026-09-07 10:57:13.560928426 -0400
@@ -1,4 +1,4 @@
-project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
+project('ffmpeg', 'c', version: '8.1.2', meson_version: '>=0.57.0')
compiler = meson.get_compiler('c')
-@@ -268,14 +268,14 @@
+@@ -299,14 +299,14 @@
swscale = proj.dependency('swscale')
include = include_directories('.', 'build/')
meson.override_dependency('libavutil', declare_dependency(
diff --git a/subprojects/packagefiles/ffmpeg/version_8.1.diff b/subprojects/packagefiles/ffmpeg/version_8.1.diff
deleted file mode 100644
index 9b87011..0000000
--- a/subprojects/packagefiles/ffmpeg/version_8.1.diff
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/meson.build 2025-08-23 18:44:34.634014892 -0400
-+++ b/meson.build 2025-08-25 15:33:36.209533531 -0400
-@@ -1,4 +1,4 @@
--project('ffmpeg', 'c', version: '', meson_version: '>=0.57.0')
-+project('ffmpeg', 'c', version: '8.1', meson_version: '>=0.57.0')
-
- compiler = meson.get_compiler('c')
-
-@@ -268,14 +268,14 @@
- swscale = proj.dependency('swscale')
- include = include_directories('.', 'build/')
- meson.override_dependency('libavutil', declare_dependency(
-- dependencies: [avutil, deps], compile_args: args, include_directories: include, version: ''))
-+ dependencies: [avutil, deps], compile_args: args, include_directories: include, version: '60.26.100'))
- meson.override_dependency('libavformat', declare_dependency(
-- dependencies: [avformat], include_directories: include, version: ''))
-+ dependencies: [avformat], include_directories: include, version: '62.12.100'))
- meson.override_dependency('libavcodec', declare_dependency(
-- dependencies: [avcodec], include_directories: include, version: ''))
-+ dependencies: [avcodec], include_directories: include, version: '62.28.100'))
- meson.override_dependency('libavdevice', declare_dependency(
-- dependencies: [avdevice], include_directories: include, version: ''))
-+ dependencies: [avdevice], include_directories: include, version: '62.3.100'))
- meson.override_dependency('libswresample', declare_dependency(
-- dependencies: [swresample], include_directories: include, version: ''))
-+ dependencies: [swresample], include_directories: include, version: '6.3.100'))
- meson.override_dependency('libswscale', declare_dependency(
-- dependencies: [swscale], include_directories: include, version: ''))
-+ dependencies: [swscale], include_directories: include, version: '9.5.100'))
diff --git a/subprojects/packagefiles/libass/raw_text_fallback.diff b/subprojects/packagefiles/libass/raw_text_fallback.diff
deleted file mode 100644
index 8974cce..0000000
--- a/subprojects/packagefiles/libass/raw_text_fallback.diff
+++ /dev/null
@@ -1,27 +0,0 @@
-diff --git a/libass/ass.c b/libass/ass.c
-index 0b44649..d13eb8d 100644
---- a/libass/ass.c
-+++ b/libass/ass.c
-@@ -1345,15 +1345,16 @@ void ass_process_chunk(ASS_Track *track, const char *data, int size,
- if (process_event_tail(track, event, p, 3))
- break;
-
-- event->Start = timecode;
-- event->Duration = duration;
-- update_prune_ts(track, event->Start + event->Duration);
-- goto cleanup;
-+ break;
- // dump_events(tid);
- } while (0);
- // some error
-- ass_free_event(track, eid);
-- track->n_events--;
-+ //ass_free_event(track, eid);
-+ //track->n_events--;
-+ event->Start = timecode;
-+ event->Duration = duration;
-+ update_prune_ts(track, event->Start + event->Duration);
-+ if (!event->Text) event->Text = strdup(str);
-
- cleanup:
- free(str);
diff --git a/subprojects/packagefiles/shaderc/deps_from_cmake.diff b/subprojects/packagefiles/shaderc/deps_from_cmake.diff
new file mode 100644
index 0000000..b3ea15b
--- /dev/null
+++ b/subprojects/packagefiles/shaderc/deps_from_cmake.diff
@@ -0,0 +1,16 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 51b5469..fa84982 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -17,6 +17,11 @@ cmake_minimum_required(VERSION 3.22.1)
+ project(shaderc)
+ enable_testing()
+
++execute_process(COMMAND ./shaderc_deps.sh
++ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
++ COMMAND_ERROR_IS_FATAL ANY
++)
++
+ if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
+ message(STATUS "No build type selected, default to Debug")
+ set(CMAKE_BUILD_TYPE "Debug")
diff --git a/subprojects/packagefiles/shaderc/no_hlsl_compile.diff b/subprojects/packagefiles/shaderc/no_hlsl_compile.diff
deleted file mode 100644
index ef96592..0000000
--- a/subprojects/packagefiles/shaderc/no_hlsl_compile.diff
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/libshaderc_util/src/compiler.cc b/libshaderc_util/src/compiler.cc
-index 9bf9a43..507e669 100644
---- a/libshaderc_util/src/compiler.cc
-+++ b/libshaderc_util/src/compiler.cc
-@@ -286,7 +286,7 @@ std::tuple<bool, std::vector<uint32_t>, size_t> Compiler::Compile(
- bases[static_cast<int>(UniformKind::StorageBuffer)]);
- shader.setShiftUavBinding(
- bases[static_cast<int>(UniformKind::UnorderedAccessView)]);
-- shader.setHlslIoMapping(hlsl_iomap_);
-+ //shader.setHlslIoMapping(hlsl_iomap_);
- shader.setResourceSetBinding(
- hlsl_explicit_bindings_[static_cast<int>(used_shader_stage)]);
- shader.setEnvClient(target_client_info.client,
diff --git a/subprojects/packagefiles/shaderc/shaderc_deps.sh b/subprojects/packagefiles/shaderc/shaderc_deps.sh
new file mode 100755
index 0000000..03fd718
--- /dev/null
+++ b/subprojects/packagefiles/shaderc/shaderc_deps.sh
@@ -0,0 +1,27 @@
+#! /usr/bin/env sh
+
+# https://github.com/google/shaderc/blob/known-good/known_good.json
+
+cd third_party
+
+if [ ! -d glslang ]; then
+ git clone https://github.com/KhronosGroup/glslang.git glslang
+ cd glslang
+ git checkout 168d452a4f460d24b588fed08477a81c44ee27a1
+ cd ../
+fi
+
+if [ ! -d spirv-tools ]; then
+ git clone https://github.com/KhronosGroup/SPIRV-Tools.git spirv-tools
+ cd spirv-tools
+ git checkout b707790a898e44038547df54580022fc1cf89c3d
+ git apply ../../../packagefiles/shaderc/spirv_tools_build_version.diff
+ cd ../
+fi
+
+if [ ! -d spirv-headers ]; then
+ git clone https://github.com/KhronosGroup/SPIRV-Headers.git spirv-headers
+ cd spirv-headers
+ git checkout 29981f65241605e08b0ede4cfeb999fe3b723c6a
+ cd ../
+fi
diff --git a/subprojects/packagefiles/shaderc/third_party_fix_build.diff b/subprojects/packagefiles/shaderc/third_party_fix_build.diff
index 03a1e11..f567b6e 100644
--- a/subprojects/packagefiles/shaderc/third_party_fix_build.diff
+++ b/subprojects/packagefiles/shaderc/third_party_fix_build.diff
@@ -1,13 +1,13 @@
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
-index d44f62a..608accd 100644
+index 9e9d8b1..b31b800 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
-@@ -87,7 +87,7 @@ if (NOT TARGET glslang)
+@@ -92,7 +92,7 @@ if (NOT TARGET glslang)
# Glslang tests are off by default. Turn them on if testing Shaderc.
set(GLSLANG_TESTS ON)
endif()
- set(GLSLANG_ENABLE_INSTALL $<NOT:${SKIP_GLSLANG_INSTALL}>)
+ #set(GLSLANG_ENABLE_INSTALL $<NOT:${SKIP_GLSLANG_INSTALL}>)
+ set(ENABLE_HLSL "${SHADERC_ENABLE_HLSL}")
add_subdirectory(${SHADERC_GLSLANG_DIR} glslang)
endif()
- if (NOT TARGET glslang)
diff --git a/subprojects/shaderc.wrap b/subprojects/shaderc.wrap
index 9bbe1d7..8ed638d 100644
--- a/subprojects/shaderc.wrap
+++ b/subprojects/shaderc.wrap
@@ -5,3 +5,4 @@ revision = v2026.3
depth = 1
method = cmake
patch_directory = shaderc
+diff_files = shaderc/third_party_fix_build.diff, shaderc/deps_from_cmake.diff
diff --git a/subprojects/stela.wrap b/subprojects/stela.wrap
index bafd02c..73b3afd 100644
--- a/subprojects/stela.wrap
+++ b/subprojects/stela.wrap
@@ -1,5 +1,5 @@
[wrap-git]
-directory = stela-9c4a7eb
+directory = stela-e72c336
url = https://git.akon.city/stela.git
push-url = git@git.akon.city:stela.git
-revision = 9c4a7eb845126f068aaac0173453e803e5ea6bf8
+revision = e72c336d01b32bee304c8a2989e2335fcc26c143
diff --git a/tests/runner.sh b/tests/runner.sh
new file mode 100755
index 0000000..f6aae5b
--- /dev/null
+++ b/tests/runner.sh
@@ -0,0 +1,99 @@
+#! /usr/bin/env bash
+
+BUILD=$1
+
+USE_GDB=0
+USE_WINE=0
+
+export CMSRV_UI=0
+export SINK_IP=127.0.0.1
+
+CMV_ADD=../scripts/cmv_add.sh
+
+ERRORED=0
+CURRENT_TEST="None"
+
+START_TEST() {
+ CURRENT_TEST=$1
+ echo "---- TEST: $1 ----"
+}
+
+run_cmsrv() {
+ if [ $USE_WINE -eq 1 ]; then
+ ../build/src/fruits/cmsrv/cmsrv &
+ elif [ $USE_GDB -eq 1 ]; then
+ gdb --ex run $BUILD/src/fruits/cmsrv/cmsrv &
+ else
+ $BUILD/src/fruits/cmsrv/cmsrv &
+ fi
+ CMSRV_PID=$!
+}
+
+run_cmv() {
+ if [ $USE_WINE -eq 1 ]; then
+ wine $BUILD/src/fruits/cmv/cmv.exe &
+ elif [ $USE_GDB -eq 1 ]; then
+ gdb --ex run $BUILD/src/fruits/cmv/cmv &
+ else
+ $BUILD/src/fruits/cmv/cmv &
+ fi
+ SINK_PID=$!
+}
+
+check_for_crash() {
+ if ps -p $1 > /dev/null; then
+ echo "---- PASS: $CURRENT_TEST ----"
+ else
+ wait $1
+ echo "---- FAIL: $CURRENT_TEST ----"
+ $CMV_ADD "QUIT"
+ exit 1
+ fi
+}
+
+run_cmsrv
+
+sleep 0.5
+
+START_TEST "Backskip target fails to load + immediate pause"
+
+$CMV_ADD "START_AT 1"
+$CMV_ADD resources/empty_file.mp4
+$CMV_ADD resources/1626892672495.mp4
+
+run_cmv
+
+sleep 4
+
+$CMV_ADD "PREV"
+$CMV_ADD "PAUSE"
+
+sleep 3
+
+check_for_crash $SINK_PID
+
+$CMV_ADD "CLEAR"
+
+START_TEST "Server restart liana client RECONNECT_RECOVER"
+
+$CMV_ADD resources/1612970595357.mp4
+
+sleep 2
+
+kill -s SIGKILL $CMSRV_PID
+
+run_cmsrv
+
+$CMV_ADD resources/1612970595357.mp4
+
+sleep 10
+
+check_for_crash $SINK_PID
+
+if ps -p $SINK_PID > /dev/null; then
+ kill -s SIGINT $SINK_PID
+fi
+
+$CMV_ADD "QUIT"
+
+wait $CMSRV_PID