summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-08-14 10:59:42 -0400
committerAndrew Opalach <andrew@akon.city> 2025-08-14 10:59:42 -0400
commitc48a6d1e806d7bd92cad81eaffe734f8bf9e40f5 (patch)
treed4cb5610f2f7fde2e2975679721aea7e17352ada
parent7e796649557bfeae6eccba751d4a1ffae75de45c (diff)
downloadcamu-c48a6d1e806d7bd92cad81eaffe734f8bf9e40f5.tar.gz
camu-c48a6d1e806d7bd92cad81eaffe734f8bf9e40f5.tar.bz2
camu-c48a6d1e806d7bd92cad81eaffe734f8bf9e40f5.zip
Support 360 degree videos, Improve VR keybinds
- Update liana API in cdio handler. - Fix some build configurations. Signed-off-by: Andrew Opalach <andrew@akon.city>
-rw-r--r--flake.lock24
-rw-r--r--flake.nix15
-rw-r--r--src/cache/handlers/cdio.c9
-rw-r--r--src/cache/handlers/http.c9
-rw-r--r--src/codec/codecs.c16
-rw-r--r--src/liana/handlers/cdio_server.c10
-rw-r--r--src/liana/handlers/codec_server.c2
-rw-r--r--src/libsink/desktop.c4
-rw-r--r--src/render/queue_libplacebo.c6
-rw-r--r--src/render/renderer_libplacebo.c17
-rw-r--r--src/render/shaders/vr_video.h37
-rw-r--r--src/screen/screen.c46
-rw-r--r--src/screen/screen.h6
-rw-r--r--src/screen/view.c2
-rw-r--r--src/screen/view.h8
-rw-r--r--subprojects/packagefiles/libass/raw_text_fallback.diff27
-rw-r--r--subprojects/stela.wrap2
17 files changed, 160 insertions, 80 deletions
diff --git a/flake.lock b/flake.lock
index b2649b4..54cc0e7 100644
--- a/flake.lock
+++ b/flake.lock
@@ -41,11 +41,11 @@
]
},
"locked": {
- "lastModified": 1754842705,
- "narHash": "sha256-2vvncPLsBWV6dRM5LfGHMGYZ+vzqRDqSPBzxPAS0R/A=",
+ "lastModified": 1755121891,
+ "narHash": "sha256-UtYkukiGnPRJ5rpd4W/wFVrLMh8fqtNkqHTPgHEtrqU=",
"owner": "nix-community",
"repo": "home-manager",
- "rev": "91586008a23c01cc32894ee187dca8c0a7bd20a4",
+ "rev": "279ca5addcdcfa31ac852b3ecb39fc372684f426",
"type": "github"
},
"original": {
@@ -96,11 +96,11 @@
"nixpkgs": "nixpkgs_2"
},
"locked": {
- "lastModified": 1754326498,
- "narHash": "sha256-3ynDaygIzQYlBZFHGDeQzXmPkX2ILeZ0wWJ84FR4g7E=",
+ "lastModified": 1755128472,
+ "narHash": "sha256-BVjUDSHplAJKNdSVYrucM6XVYdBepv5LsuFuWcRyil8=",
"owner": "nix-community",
"repo": "NixOS-WSL",
- "rev": "ca55236cd9ef3cdea29b51a0b52a9402c60e9a27",
+ "rev": "8f9cb0d5cc32c364be4348d7bf497c51361ba5bb",
"type": "github"
},
"original": {
@@ -127,11 +127,11 @@
},
"nixpkgs_2": {
"locked": {
- "lastModified": 1754214453,
- "narHash": "sha256-Q/I2xJn/j1wpkGhWkQnm20nShYnG7TI99foDBpXm1SY=",
+ "lastModified": 1754725699,
+ "narHash": "sha256-iAcj9T/Y+3DBy2J0N+yF9XQQQ8IEb5swLFzs23CdP88=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "5b09dc45f24cf32316283e62aec81ffee3c3e376",
+ "rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054",
"type": "github"
},
"original": {
@@ -143,11 +143,11 @@
},
"nixpkgs_3": {
"locked": {
- "lastModified": 1754725699,
- "narHash": "sha256-iAcj9T/Y+3DBy2J0N+yF9XQQQ8IEb5swLFzs23CdP88=",
+ "lastModified": 1755027561,
+ "narHash": "sha256-IVft239Bc8p8Dtvf7UAACMG5P3ZV+3/aO28gXpGtMXI=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "85dbfc7aaf52ecb755f87e577ddbe6dbbdbc1054",
+ "rev": "005433b926e16227259a1843015b5b2b7f7d1fc3",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index 5217ebb..d28bf99 100644
--- a/flake.nix
+++ b/flake.nix
@@ -30,6 +30,11 @@
./subprojects/packagefiles/libplacebo/info_priv_hash.diff
];
});
+ #libass = super.libass.overrideAttrs (oldAttrs: {
+ # patches = [
+ # ./subprojects/packagefiles/libass/raw_text_fallback.diff
+ # ];
+ #});
libcue = super.libcue.overrideAttrs (oldAttrs: {
patches = [
./subprojects/packagefiles/libcue/55.diff
@@ -87,7 +92,7 @@
version = "0.01";
src = fetchgit {
url = "https://git.akon.city/camu.git";
- rev = "2cc385b71e161eae39915bf24de53d5b704e7ea0";
+ rev = "7e796649557bfeae6eccba751d4a1ffae75de45c";
postFetch = ''
export NIX_SSL_CERT_FILE=${cacert}/etc/ssl/certs/ca-bundle.crt
@@ -105,7 +110,7 @@
find subprojects -type d -name .git -prune -execdir rm -r {} +
'';
- sha256 = "LyW2Y/o4mPAA5x9wmjh4DEKFRGwbEjHp1eurEs1Xwl0=";
+ sha256 = "m1xvHoAnuWaUrV3wXhWEXHU/k+VXHPl7MIITLR2AhpI=";
};
outputs = [ "out" "dev" ];
nativeBuildInputs = [
@@ -129,8 +134,9 @@
]))
ffmpeg-headless # native input for ffprobe
] ++ lib.optionals (system == "x86_64-linux") [
- #jdk8
- #ant
+ # Blu-ray
+ jdk8
+ ant
];
buildInputs = [
(curl.override { websocketSupport = true; })
@@ -224,6 +230,7 @@
#st
#xfce.xfce4-terminal
# market research
+ #imv
#vlc
#mpv
#clapper
diff --git a/src/cache/handlers/cdio.c b/src/cache/handlers/cdio.c
index abebeb0..29126c0 100644
--- a/src/cache/handlers/cdio.c
+++ b/src/cache/handlers/cdio.c
@@ -1,6 +1,8 @@
#define AL_LOG_SECTION "cache_cdio"
#include <al/log.h>
+#include "../../codec/codec.h"
+
#include "../backings/file.h"
#include "../backings/memory.h"
#include "../threaded_waits.h"
@@ -106,6 +108,12 @@ static bool handler_cdio_wait_for_range(struct cch_handler *handler, struct cch_
return cch_threaded_wait_for_range(&cdio->waits, cdio->backing, wait);
}
+static s32 handler_cdio_guess_format(struct cch_handler *handler)
+{
+ (void)handler;
+ return CAMU_CODEC_FALLBACK;
+}
+
static void handler_cdio_free(struct cch_handler **handler)
{
struct cch_handler_cdio *cdio = (struct cch_handler_cdio *)*handler;
@@ -196,6 +204,7 @@ struct cch_entry *cch_handler_cdio_create(void)
entry->handler->can_seek = handler_cdio_can_seek;
entry->handler->maybe_spawn_worker = handler_cdio_maybe_spawn_worker;
entry->handler->wait_for_range = handler_cdio_wait_for_range;
+ entry->handler->guess_format = handler_cdio_guess_format;
entry->handler->free = handler_cdio_free;
entry->handler->entry = entry;
al_str_from(&entry->handler->handler, "cdio");
diff --git a/src/cache/handlers/http.c b/src/cache/handlers/http.c
index 1691ea9..9e99b8a 100644
--- a/src/cache/handlers/http.c
+++ b/src/cache/handlers/http.c
@@ -1,6 +1,8 @@
#define AL_LOG_SECTION "cache_http"
#include <al/log.h>
+#include "../../codec/codec.h"
+
#include "../backings/memory.h"
//#include "../backings/file.h"
#include "../threaded_waits.h"
@@ -91,6 +93,12 @@ static bool handler_http_wait_for_range(struct cch_handler *handler, struct cch_
return cch_threaded_wait_for_range(&http->waits, http->backing, wait);
}
+static s32 handler_http_guess_format(struct cch_handler *handler)
+{
+ (void)handler;
+ return CAMU_CODEC_FALLBACK;
+}
+
static void handler_http_free(struct cch_handler **handler)
{
struct cch_handler_http *http = (struct cch_handler_http *)*handler;
@@ -119,6 +127,7 @@ struct cch_entry *cch_handler_http_create(str *url, struct nn_event_loop *loop)
entry->handler->can_seek = handler_http_can_seek;
entry->handler->maybe_spawn_worker = handler_http_maybe_spawn_worker;
entry->handler->wait_for_range = handler_http_wait_for_range;
+ entry->handler->guess_format = handler_http_guess_format;
entry->handler->free = handler_http_free;
entry->handler->entry = entry;
al_str_from(&entry->handler->handler, "codec");
diff --git a/src/codec/codecs.c b/src/codec/codecs.c
index 7374517..6d830d2 100644
--- a/src/codec/codecs.c
+++ b/src/codec/codecs.c
@@ -2,20 +2,20 @@
#include "codec.h"
#ifdef LIANA_SERVER
-#include "../../codec/wuffs/demuxer.h"
-#include "../../codec/stb_image/demuxer.h"
-#include "../../codec/spng/demuxer.h"
+#include "wuffs/demuxer.h"
+#include "stb_image/demuxer.h"
+#include "spng/demuxer.h"
#ifdef CAMU_HAVE_FFMPEG
-#include "../../codec/ffmpeg/demuxer.h"
+#include "ffmpeg/demuxer.h"
#endif
#endif
#ifdef LIANA_CLIENT
-#include "../../codec/wuffs/decoder.h"
-#include "../../codec/stb_image/decoder.h"
-#include "../../codec/spng/decoder.h"
+#include "wuffs/decoder.h"
+#include "stb_image/decoder.h"
+#include "spng/decoder.h"
#ifdef CAMU_HAVE_FFMPEG
-#include "../../codec/ffmpeg/decoder.h"
+#include "ffmpeg/decoder.h"
#endif
#endif
diff --git a/src/liana/handlers/cdio_server.c b/src/liana/handlers/cdio_server.c
index 0fafae7..54c63ab 100644
--- a/src/liana/handlers/cdio_server.c
+++ b/src/liana/handlers/cdio_server.c
@@ -29,12 +29,14 @@ static bool cdio_server_init(struct lia_server_handler *handler, struct cch_hand
static void cdio_server_write_info(struct lia_server_handler *handler, struct nn_packet *packet)
{
struct lia_cdio_server *cdio = (struct lia_cdio_server *)handler;
- nn_packet_write_u64(packet, 0);
- nn_packet_write_u32(packet, 1);
+ u64 duration = cdio->handler.get_duration(&cdio->handler);
+ nn_packet_write_u64(packet, duration);
+ nn_packet_write_u32(packet, 1); // 1 stream.
+ nn_packet_write_str(packet, &al_str_c("pcm_s16le"));
nn_packet_write_u8(packet, CAMU_NORMAL);
nn_packet_write_u8(packet, CAMU_STREAM_AUDIO);
- nn_packet_write_u64(packet, cdio->handler.get_duration(&cdio->handler));
- nn_packet_write_s32(packet, 0);
+ nn_packet_write_u64(packet, duration);
+ nn_packet_write_s32(packet, 0); // index.
nn_packet_write_s32(packet, cdio->fmt.format);
nn_packet_write_s32(packet, cdio->fmt.sample_rate);
nn_packet_write_s32(packet, cdio->fmt.channel_count);
diff --git a/src/liana/handlers/codec_server.c b/src/liana/handlers/codec_server.c
index 801a3e1..fbb1e72 100644
--- a/src/liana/handlers/codec_server.c
+++ b/src/liana/handlers/codec_server.c
@@ -103,9 +103,11 @@ static bool codec_server_seek(struct lia_server_handler *handler, u64 pos)
static void codec_server_step(struct lia_server_handler *handler)
{
struct lia_codec_server *codec = (struct lia_codec_server *)handler;
+#ifdef CAMU_HAVE_FFMPEG
#ifdef CAMU_DIRECT_MODE
codec->packet.av.pkt = av_packet_alloc();
#endif
+#endif
codec->handler.status = codec->demux->get_packet(codec->demux, &codec->packet);
}
diff --git a/src/libsink/desktop.c b/src/libsink/desktop.c
index 12008fd..6dee662 100644
--- a/src/libsink/desktop.c
+++ b/src/libsink/desktop.c
@@ -133,7 +133,7 @@ static void log_sink_status(struct camu_desktop *c)
}
bool show_hour = duration > 60u * 60u * 1000000u;
- s32 offset = al_snprintf(status, sizeof(status), paused ? "⏸ " : "⏵ ");
+ s32 offset = al_snprintf(status, sizeof(status), paused ? "|| " : "|> ");
offset += al_snprintf(status + offset, sizeof(status) - offset, "[");
offset += camu_print_time(status + offset, sizeof(status) - offset, pts, show_hour, 2);
offset += al_snprintf(status + offset, sizeof(status) - offset, "/");
@@ -208,6 +208,8 @@ bool camu_desktop_open(struct camu_desktop *c, const char *window_name)
if (!camu_screen_create_renderer(&c->scr, c->renderer)) {
return false;
}
+ // Need to render twice for the window to show early.
+ c->renderer->render(c->renderer, &c->scr, true);
c->renderer->render(c->renderer, &c->scr, true);
#ifdef DESKTOP_NULL_AUDIO
if (!camu_mixer_init(&c->mixer, (struct camu_audio *)&audio_plugin_null)) {
diff --git a/src/render/queue_libplacebo.c b/src/render/queue_libplacebo.c
index 01cd366..d1f7d88 100644
--- a/src/render/queue_libplacebo.c
+++ b/src/render/queue_libplacebo.c
@@ -256,10 +256,10 @@ static bool map_av_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *
#ifdef CAMU_HAVE_SUBTITLES
if (ok && lq->has_subtitles) {
- s64 now = av_rescale_q(frame->best_effort_timestamp, stream->time_base, (AVRational){ 1, 1000 });
+ s64 pts = av_rescale_q(frame->best_effort_timestamp, stream->time_base, (AVRational){ 1, 1000 });
nn_mutex_lock(&lq->subtitle_lock);
s32 change; // 1 = different position, 2 = different content.
- ASS_Image *ass_frame = ass_render_frame(lq->ass_renderer, lq->ass_track, now, &change);
+ ASS_Image *ass_frame = ass_render_frame(lq->ass_renderer, lq->ass_track, pts, &change);
if (ass_frame) {
struct camu_overlay_lp *overlay = NULL;
if (lq->overlays.count > 0) overlay = al_array_last(lq->overlays);
@@ -272,6 +272,8 @@ static bool map_av_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *
out_frame->overlays = overlay->overlays;
out_frame->num_overlays = overlay->num;
((struct pl_source_frame *)src)->frame_data = overlay;
+ } else if (change > 0) {
+ log_error("Failed to parse or render subtitle.");
}
nn_mutex_unlock(&lq->subtitle_lock);
}
diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c
index cdf09bf..562c486 100644
--- a/src/render/renderer_libplacebo.c
+++ b/src/render/renderer_libplacebo.c
@@ -107,6 +107,8 @@ static void ass_log_callback(s32 level, const char *fmt, va_list args, void *use
(void)userdata;
if (level <= 1) {
al_logv(AL_LOG_ERROR, "ass", fmt, args);
+ } else if (level <= 3) {
+ al_logv(AL_LOG_WARN, "ass", fmt, args);
} else {
#ifdef AL_DEBUG
al_logv(AL_LOG_DEBUG, "ass", fmt, args);
@@ -247,7 +249,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid
}
lr->swapchain = pl_opengl_create_swapchain(lr->gl, pl_opengl_swapchain_params(
- //.max_swapchain_depth = 2,
+ .max_swapchain_depth = 1,
.swap_buffers = gl_swap_buffers,
.priv = priv
));
@@ -391,11 +393,14 @@ static void renderer_lp_render(struct camu_renderer *renderer, struct camu_scree
f64 mouse_x, mouse_y;
bool vr_emulation = scr->vr_emulation && lr->vr_emulation_hook[0];
if (vr_emulation) {
- mouse_x = (scr->last_pointer_x - (scr->calibrate_x - (scr->width / 2.0))) / (f64)scr->width;
- mouse_y = (scr->last_pointer_y - (scr->calibrate_y - (scr->height / 2.0))) / (f64)scr->height;
- mouse_y = 1.0 - mouse_y;
- mouse_x = CLAMP(mouse_x, -0.5, 1.5);
- mouse_y = CLAMP(mouse_y, -0.5, 1.5);
+ mouse_x = (scr->last_pointer_x / scr->width) - (scr->vr_calibrate_x - 0.5);
+ mouse_y = (scr->last_pointer_y / scr->height) - (scr->vr_calibrate_y - 0.5);
+ if (scr->vr_emulation == CAMU_VR_360) {
+ mouse_x = CLAMP(mouse_x * 2.0, -1.0, 3.0);
+ } else {
+ mouse_x = CLAMP(mouse_x, -0.5, 1.5);
+ }
+ mouse_y = CLAMP(1.0 - mouse_y, -0.5, 1.5);
lr->params.hooks = lr->vr_emulation_hook;
lr->params.num_hooks = 1;
lr->params.hooks[0]->parameters[0].data->f = (f32)mouse_x;
diff --git a/src/render/shaders/vr_video.h b/src/render/shaders/vr_video.h
index fc2d192..73869eb 100644
--- a/src/render/shaders/vr_video.h
+++ b/src/render/shaders/vr_video.h
@@ -5,12 +5,11 @@
// YAW: [any float] polar angle, one full revolution is 2*M_PI
// PITCH: [any float] vertical tilt, positive is up
// ROLL: [any float] view rotation, positive is clockwise
-//" const float yaw = M_PI*(-1.0+(mouse_x*2.0));\n" // 360
static const char vr_video_shader[] = \
"//!PARAM mouse_x\n"
"//!TYPE float\n"
-"//!MINIMUM -0.5\n"
-"//!MAXIMUM 1.5\n"
+"//!MINIMUM -1.0\n"
+"//!MAXIMUM 3.0\n"
"0.0\n"
"//!PARAM mouse_y\n"
"//!TYPE float\n"
@@ -27,20 +26,20 @@ static const char vr_video_shader[] = \
"//!DESC un360\n"
"const float M_PI = 3.141592653589793;\n"
"vec4 hook() {\n"
-" float yaw = M_PI*mouse_x;\n"
-" float pitch = M_PI*(-0.5+mouse_y);\n"
-" float roll = M_PI*0.0;\n"
-" float t = tan(fov/2);\n"
-" float c = cos(pitch);\n"
-" float s = sin(pitch);\n"
-" float r = target_size.y/target_size.x;\n"
-" float sR = sin(roll);\n"
-" float cR = cos(roll);\n"
-" mat3 m = mat3(2*t*cR, 2*sR*t*r, -t*(cR+sR*r), -2*sR*t*c, 2*cR*t*c*r, t*c*(sR-cR*r)-s, -2*sR*t*s, 2*cR*t*s*r, t*s*(sR-cR*r)+c);\n"
-" vec3 p = vec3(HOOKED_pos, 1.0) * m;\n"
-" float theta = atan(p.x, p.z) + yaw;\n"
-" float phi = atan(p.y, length(p.xz)) + M_PI/2;\n"
-" float x = fract(theta / (2*M_PI));\n"
-" float y = phi / M_PI;\n"
-" return HOOKED_tex(vec2(x, y));\n"
+" float yaw = M_PI*mouse_x;\n"
+" float pitch = M_PI*(-0.5+mouse_y);\n"
+" float roll = M_PI*0.0;\n"
+" float t = tan(fov/2);\n"
+" float c = cos(pitch);\n"
+" float s = sin(pitch);\n"
+" float r = target_size.y/target_size.x;\n"
+" float sR = sin(roll);\n"
+" float cR = cos(roll);\n"
+" mat3 m = mat3(2*t*cR, 2*sR*t*r, -t*(cR+sR*r), -2*sR*t*c, 2*cR*t*c*r, t*c*(sR-cR*r)-s, -2*sR*t*s, 2*cR*t*s*r, t*s*(sR-cR*r)+c);\n"
+" vec3 p = vec3(HOOKED_pos, 1.0) * m;\n"
+" float theta = atan(p.x, p.z) + yaw;\n"
+" float phi = atan(p.y, length(p.xz)) + M_PI/2;\n"
+" float x = fract(theta / (2*M_PI));\n"
+" float y = phi / M_PI;\n"
+" return HOOKED_tex(vec2(x, y));\n"
"}\n";
diff --git a/src/screen/screen.c b/src/screen/screen.c
index d0d78e2..ee6b1e9 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -40,8 +40,6 @@ static void do_resize(struct camu_screen *scr, u32 width, u32 height)
al_assert(width > 0 && height > 0);
scr->width = width;
scr->height = height;
- scr->calibrate_x = scr->width / 2.0;
- scr->calibrate_y = scr->height / 2.0;
struct camu_screen_video *video;
al_array_foreach_ptr(scr->videos, i, video) {
camu_view_calculate(&video->view, scr->width, scr->height);
@@ -308,8 +306,6 @@ static bool key_callback(void *userdata, u8 state, u16 button)
break;
#endif
case STELA_KEY_R: {
- scr->calibrate_x = scr->last_pointer_x;
- scr->calibrate_y = scr->last_pointer_y;
struct camu_view *view = get_view_from_mouse_pos(scr);
if (view) {
if (SCREEN_MOD2(scr)) {
@@ -344,6 +340,8 @@ static bool key_callback(void *userdata, u8 state, u16 button)
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;
}
@@ -393,19 +391,29 @@ static bool key_callback(void *userdata, u8 state, u16 button)
al_atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
return true;
case STELA_KEY_V: {
- struct camu_view *view = get_view_from_mouse_pos(scr);
- if (view) {
- view->mode = CAMU_DEFAULT_VIEW;
- camu_view_calculate(view, scr->width, scr->height);
- }
- if (!scr->vr_emulation) {
- scr->flags = (scr->flags & ~CAMU_SCREEN_ZOOM_PAN_SIMPLE) | CAMU_SCREEN_ZOOM_FOV;
- scr->window->set_cursor(scr->window, STELA_CURSOR_HIDDEN);
- scr->vr_emulation = true;
+ if (SCREEN_MOD1(scr)) {
+ scr->vr_calibrate_x = scr->last_pointer_x / scr->width;
+ scr->vr_calibrate_y = scr->last_pointer_y / scr->height;
} else {
- scr->flags = (scr->flags & ~CAMU_SCREEN_ZOOM_FOV) | CAMU_SCREEN_ZOOM_PAN_SIMPLE;
- scr->window->set_cursor(scr->window, STELA_CURSOR_NORMAL);
- scr->vr_emulation = false;
+ struct camu_view *view = get_view_from_mouse_pos(scr);
+ if (SCREEN_MOD2(scr) && scr->vr_emulation == CAMU_VR_180) {
+ scr->vr_emulation = CAMU_VR_360;
+ break;
+ }
+ if (!scr->vr_emulation) {
+ if (view) view->mode = CAMU_VIEW_AUTOFIT;
+ scr->flags = (scr->flags & ~CAMU_SCREEN_ZOOM_PAN_SIMPLE) | CAMU_SCREEN_ZOOM_FOV;
+ scr->window->set_cursor(scr->window, STELA_CURSOR_HIDDEN);
+ scr->vr_emulation = SCREEN_MOD2(scr) ? CAMU_VR_360 : CAMU_VR_180;
+ } else {
+ if (view) view->mode = CAMU_DEFAULT_VIEW;
+ scr->flags = (scr->flags & ~CAMU_SCREEN_ZOOM_FOV) | CAMU_SCREEN_ZOOM_PAN_SIMPLE;
+ scr->window->set_cursor(scr->window, STELA_CURSOR_NORMAL);
+ scr->vr_emulation = CAMU_VR_DISABLED;
+ }
+ if (view) {
+ camu_view_calculate(view, scr->width, scr->height);
+ }
}
break;
}
@@ -466,7 +474,9 @@ bool camu_screen_init(struct camu_screen *scr)
#ifdef CAMU_SCREEN_DRAG_SEEK
scr->last_seek_ts = 0;
#endif
- scr->vr_emulation = false;
+ scr->vr_emulation = CAMU_VR_DISABLED;
+ scr->vr_calibrate_x = 0.5;
+ scr->vr_calibrate_y = 0.5;
al_array_init(scr->videos);
#ifdef CAMU_SCREEN_THREADED
al_array_init(scr->add_queue);
@@ -499,8 +509,6 @@ bool camu_screen_create_window(struct camu_screen *scr, const char *name)
}
scr->width = scr->window->width;
scr->height = scr->window->height;
- scr->calibrate_x = scr->width / 2.0;
- scr->calibrate_y = scr->height / 2.0;
scr->fullscreen = false;
scr->scaling_disabled = false;
scr->transparent_background = false;
diff --git a/src/screen/screen.h b/src/screen/screen.h
index 4c6e205..e03fdb3 100644
--- a/src/screen/screen.h
+++ b/src/screen/screen.h
@@ -75,9 +75,9 @@ struct camu_screen {
#ifdef CAMU_SCREEN_DRAG_SEEK
u64 last_seek_ts;
#endif
- f64 calibrate_x;
- f64 calibrate_y;
- bool vr_emulation;
+ u8 vr_emulation;
+ f64 vr_calibrate_x;
+ f64 vr_calibrate_y;
array(struct camu_screen_video) videos;
#ifdef CAMU_SCREEN_THREADED
array(struct camu_video_buffer *) add_queue;
diff --git a/src/screen/view.c b/src/screen/view.c
index 4719062..81d19a9 100644
--- a/src/screen/view.c
+++ b/src/screen/view.c
@@ -27,7 +27,7 @@ void camu_view_init(struct camu_view *view, u32 width, u32 height)
view->height = height;
view->zindex = 0;
view->stretch = 1.0;
- view->fov = AL_TO_RADIANS(80.0);
+ view->fov = AL_TO_RADIANS(CAMU_DEFAULT_FOV);
}
void camu_view_calculate(struct camu_view *view, u32 window_width, u32 window_height)
diff --git a/src/screen/view.h b/src/screen/view.h
index 2fc1742..5fd86c0 100644
--- a/src/screen/view.h
+++ b/src/screen/view.h
@@ -17,8 +17,16 @@ enum {
CAMU_VIEW_ROTATION_360
};
+enum {
+ CAMU_VR_DISABLED = 0,
+ CAMU_VR_180,
+ CAMU_VR_360
+};
+
#define CAMU_DEFAULT_VIEW CAMU_VIEW_AUTOFIT
+#define CAMU_DEFAULT_FOV 80.0
+
struct camu_view {
u8 mode;
u8 rotation;
diff --git a/subprojects/packagefiles/libass/raw_text_fallback.diff b/subprojects/packagefiles/libass/raw_text_fallback.diff
new file mode 100644
index 0000000..8974cce
--- /dev/null
+++ b/subprojects/packagefiles/libass/raw_text_fallback.diff
@@ -0,0 +1,27 @@
+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/stela.wrap b/subprojects/stela.wrap
index f91a1ce..e193667 100644
--- a/subprojects/stela.wrap
+++ b/subprojects/stela.wrap
@@ -1,4 +1,4 @@
[wrap-git]
url = https://git.akon.city/stela.git
-revision = 88d24e4caa0211b78d3d86d9fab5ec9e11d9b66d
+revision = a4be897cf71e2e6d4a98c0be612da7e01e3273f5
depth = 1