summaryrefslogtreecommitdiff
path: root/src/screen
diff options
context:
space:
mode:
Diffstat (limited to 'src/screen')
-rw-r--r--src/screen/screen.c148
-rw-r--r--src/screen/screen.h15
-rw-r--r--src/screen/view.c12
-rw-r--r--src/screen/view.h2
4 files changed, 115 insertions, 62 deletions
diff --git a/src/screen/screen.c b/src/screen/screen.c
index 09fbe64..965088f 100644
--- a/src/screen/screen.c
+++ b/src/screen/screen.c
@@ -6,8 +6,8 @@
#include "view.h"
#include "screen.h"
-#define SCREEN_MOD1(scr) ((scr)->flags & CAMU_SCREEN_MOD_CONTROL)
-#define SCREEN_MOD2(scr) ((scr)->flags & CAMU_SCREEN_MOD_SHIFT)
+#define SCREEN_MOD1(scr) ((scr)->window->held_modifiers & (STELA_MOD_LCONTROL | STELA_MOD_RCONTROL))
+#define SCREEN_MOD2(scr) ((scr)->window->held_modifiers & (STELA_MOD_LSHIFT | STELA_MOD_RSHIFT))
#define SCREEN_IS_DRAGGING(scr) ((scr)->flags & CAMU_SCREEN_DRAGGING)
#define SCREEN_IS_ZOOMING(scr) ((scr)->flags & CAMU_SCREEN_ZOOMING)
#define SCREEN_ZOOM_MODE(scr, mode) ((scr)->flags & mode)
@@ -18,6 +18,7 @@
static void should_close_callback(void *userdata)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
+ scr->window->close(scr->window);
scr->callback(scr->userdata, CAMU_SCREEN_CLOSE, NULL);
}
@@ -38,6 +39,8 @@ 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);
@@ -68,23 +71,40 @@ static struct camu_view *get_view_from_mouse_pos(struct camu_screen *scr)
return view;
}
+static void seek_to_percent_at_pointer(struct camu_screen *scr, f64 x)
+{
+ f64 percent = x / scr->width;
+ percent = CLAMP(percent, 0.0, 100.0);
+ scr->callback(scr->userdata, CAMU_SCREEN_PERCENT_SEEK, &percent);
+}
+
static bool pointer_pos_callback(void *userdata, f64 x, f64 y)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
struct camu_view *view = get_view_from_mouse_pos(scr);
bool queue_refresh = false;
if (SCREEN_IS_DRAGGING(scr)) {
- if (view && SCREEN_ZOOM_MODE(scr, CAMU_SCREEN_ZOOM_PAN_SIMPLE)) {
- f64 dx = x - scr->last_pointer_x;
- f64 dy = y - scr->last_pointer_y;
- if (camu_view_pan_simple(view, scr->width, scr->height, dx, dy)) {
- view->mode = CAMU_VIEW_DETACHED;
- queue_refresh = true;
- }
- if (fabs(dx) + fabs(dy) > 3.0) {
- scr->last_click_ts = SCREEN_INVALID_TS;
+#ifdef CAMU_SCREEN_DRAG_SEEK
+ u64 now = nn_get_timestamp();
+ if (view && now - scr->last_seek_ts > 110000) {
+ seek_to_percent_at_pointer(scr, x);
+ scr->last_seek_ts = now;
+ }
+#else
+ if (view) {
+ if (SCREEN_ZOOM_MODE(scr, CAMU_SCREEN_ZOOM_PAN_SIMPLE)) {
+ f64 dx = x - scr->last_pointer_x;
+ f64 dy = y - scr->last_pointer_y;
+ if (camu_view_pan_simple(view, scr->width, scr->height, dx, dy)) {
+ view->mode = CAMU_VIEW_DETACHED;
+ queue_refresh = true;
+ }
+ if (fabs(dx) + fabs(dy) > 3.0) {
+ scr->last_click_ts = SCREEN_INVALID_TS;
+ }
}
}
+#endif
}
scr->last_pointer_x = x;
scr->last_pointer_y = y;
@@ -144,13 +164,6 @@ static bool touch_callback(void *userdata, s32 index, u8 phase, f64 x, f64 y)
return false;
}
-static void seek_to_percent_at_pointer(struct camu_screen *scr)
-{
- f64 percent = scr->last_pointer_x / scr->width;
- percent = CLAMP(percent, 0.0, 100.0);
- scr->callback(scr->userdata, CAMU_SCREEN_PERCENT_SEEK, &percent);
-}
-
static bool mouse_button_callback(void *userdata, u8 state, u8 button)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
@@ -159,13 +172,22 @@ static bool mouse_button_callback(void *userdata, u8 state, u8 button)
switch (state) {
case STELA_BUTTON_PRESSED:
scr->flags |= CAMU_SCREEN_DRAGGING;
+ scr->window->set_cursor(scr->window, STELA_CURSOR_CROSSHAIR);
+#ifdef CAMU_SCREEN_DRAG_SEEK
+ //scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
+#endif
scr->last_click_ts = nn_get_timestamp();
break;
case STELA_BUTTON_RELEASED:
scr->flags &= ~CAMU_SCREEN_DRAGGING;
+ scr->window->set_cursor(scr->window, (scr->fullscreen || scr->vr_emulation) ?
+ STELA_CURSOR_HIDDEN : STELA_CURSOR_NORMAL);
+#ifdef CAMU_SCREEN_DRAG_SEEK
+ //scr->callback(scr->userdata, CAMU_SCREEN_TOGGLE_PAUSE, NULL);
+#endif
if (SCREEN_LAST_CLICK_WITHIN(200000)) {
if (SCREEN_MOD1(scr)) {
- seek_to_percent_at_pointer(scr);
+ seek_to_percent_at_pointer(scr, scr->last_pointer_x);
} else {
s32 n = (scr->last_pointer_x >= scr->width / 2.0) ? 1 : -1;
scr->callback(scr->userdata, CAMU_SCREEN_SKIP, &n);
@@ -177,7 +199,7 @@ static bool mouse_button_callback(void *userdata, u8 state, u8 button)
case STELA_MOUSE3: {
switch (state) {
case STELA_BUTTON_RELEASED: {
- seek_to_percent_at_pointer(scr);
+ seek_to_percent_at_pointer(scr, scr->last_pointer_x);
break;
}
}
@@ -205,10 +227,14 @@ bool scroll_callback(void *userdata, f64 y)
y = -y / 20.0;
#endif
struct camu_view *view = get_view_from_mouse_pos(scr);
- if (view && SCREEN_ZOOM_MODE(scr, CAMU_SCREEN_ZOOM_PAN_SIMPLE)) {
- if (camu_view_zoom_simple(view, scr->width, scr->height, scr->last_pointer_x, scr->last_pointer_y, y)) {
- view->mode = CAMU_VIEW_DETACHED;
- return true;
+ if (view) {
+ if (SCREEN_ZOOM_MODE(scr, CAMU_SCREEN_ZOOM_PAN_SIMPLE)) {
+ if (camu_view_zoom_simple(view, scr->width, scr->height, scr->last_pointer_x, scr->last_pointer_y, y)) {
+ view->mode = CAMU_VIEW_DETACHED;
+ return true;
+ }
+ } else if (SCREEN_ZOOM_MODE(scr, CAMU_SCREEN_ZOOM_FOV)) {
+ view->fov -= y;
}
}
}
@@ -221,15 +247,8 @@ static bool key_callback(void *userdata, u8 state, u16 button)
switch (state) {
case STELA_BUTTON_PRESSED:
switch (button) {
- case STELA_KEY_LEFT_SHIFT:
- case STELA_KEY_RIGHT_SHIFT:
- scr->flags |= CAMU_SCREEN_MOD_SHIFT;
- break;
- case STELA_KEY_LEFT_CONTROL:
- case STELA_KEY_RIGHT_CONTROL:
- scr->flags |= CAMU_SCREEN_MOD_CONTROL;
- break;
case STELA_KEY_Q:
+ scr->window->close(scr->window);
scr->callback(scr->userdata, CAMU_SCREEN_CLOSE, NULL);
break;
case STELA_KEY_RIGHT:
@@ -285,6 +304,8 @@ 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)) {
@@ -367,21 +388,29 @@ static bool key_callback(void *userdata, u8 state, u16 button)
// Force refresh for if there's no video buffer.
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;
+ } 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;
+ }
+ break;
+ }
default:
break;
}
break;
case STELA_BUTTON_RELEASED:
- switch (button) {
- case STELA_KEY_LEFT_SHIFT:
- case STELA_KEY_RIGHT_SHIFT:
- scr->flags &= ~CAMU_SCREEN_MOD_SHIFT;
- break;
- case STELA_KEY_LEFT_CONTROL:
- case STELA_KEY_RIGHT_CONTROL:
- scr->flags &= ~CAMU_SCREEN_MOD_CONTROL;
- break;
- }
+ break;
default:
break;
}
@@ -396,6 +425,7 @@ static void key_immediate_callback(void *userdata, u8 state, u16 button)
switch (button) {
case STELA_KEY_F:
scr->fullscreen = !scr->fullscreen;
+ scr->window->set_cursor(scr->window, scr->fullscreen ? STELA_CURSOR_HIDDEN : STELA_CURSOR_NORMAL);
#ifdef STELA_API_DX11
scr->renderer->set(scr->renderer, CAMU_RENDERER_FULLSCREEN, scr->fullscreen);
#else
@@ -429,6 +459,10 @@ bool camu_screen_init(struct camu_screen *scr)
scr->last_click_ts = SCREEN_INVALID_TS;
scr->last_pointer_x = 0.0;
scr->last_pointer_y = 0.0;
+#ifdef CAMU_SCREEN_DRAG_SEEK
+ scr->last_seek_ts = 0;
+#endif
+ scr->vr_emulation = false;
al_array_init(scr->videos);
#ifdef CAMU_SCREEN_THREADED
al_array_init(scr->add_queue);
@@ -444,7 +478,9 @@ static nn_thread_result NNWT_THREADCALL event_thread(void *userdata)
{
struct camu_screen *scr = (struct camu_screen *)userdata;
nn_thread_set_name("window_events");
- while (scr->window->poll(scr->window, true) && al_atomic_load(s32)(&scr->state, AL_ATOMIC_RELAXED) != CAMU_SCREEN_STOPPED) {
+ // If we decide to close within a poll, we must not expect any
+ // window events after that point.
+ while (scr->window->poll(scr->window, true)) {
scr->window->process_events(scr->window);
}
return 0;
@@ -459,6 +495,8 @@ 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;
@@ -510,12 +548,7 @@ static void add_buffer_internal(struct camu_screen *scr, struct camu_video_buffe
video.view.height = fmt->height;
#endif
} else {
- video.view.mode = CAMU_DEFAULT_VIEW;
- video.view.rotation = CAMU_VIEW_ROTATION_0;
- video.view.width = fmt->width;
- video.view.height = fmt->height;
- video.view.zindex = 0;
- video.view.stretch = 1.0;
+ camu_view_init(&video.view, fmt->width, fmt->height);
}
camu_view_calculate(&video.view, scr->width, scr->height);
#ifdef CAMU_SCREEN_THREADED
@@ -644,11 +677,9 @@ void camu_screen_clear(struct camu_screen *scr)
void camu_screen_set_state(struct camu_screen *scr, s32 state)
{
// @TODO: What to do if a buffer is queued for removal and we pause here.
- if (al_atomic_load(s32)(&scr->state, AL_ATOMIC_ACQUIRE) != CAMU_SCREEN_STOPPED) {
- al_atomic_store(s32)(&scr->state, state, AL_ATOMIC_RELEASE);
- if (state == CAMU_SCREEN_PAUSED) {
- al_atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
- }
+ al_atomic_store(s32)(&scr->state, state, AL_ATOMIC_RELEASE);
+ if (state == CAMU_SCREEN_PAUSED) {
+ al_atomic_add(u32)(&scr->force_refresh, 1, AL_ATOMIC_RELAXED);
}
}
@@ -668,8 +699,9 @@ bool camu_screen_poll(struct camu_screen *scr, bool block)
}
stl_window_read_events(scr->window);
#else
- scr->window->poll(scr->window, block);
- scr->window->process_events(scr->window);
+ if (scr->window->poll(scr->window, block)) {
+ scr->window->process_events(scr->window);
+ }
#endif
#ifdef STELA_PAUSE
return scr->window->should_refresh(scr->window);
@@ -681,9 +713,8 @@ bool camu_screen_poll(struct camu_screen *scr, bool block)
bool camu_screen_tick(struct camu_screen *scr, bool *force)
{
s32 state = al_atomic_load(s32)(&scr->state, AL_ATOMIC_RELAXED);
- al_assert(state != CAMU_SCREEN_STOPPED);
u32 force_refresh = al_atomic_load(u32)(&scr->force_refresh, AL_ATOMIC_ACQUIRE);
- bool paused = state == CAMU_SCREEN_PAUSED && force_refresh == 0;
+ bool paused = !scr->vr_emulation && state == CAMU_SCREEN_PAUSED && force_refresh == 0;
bool do_render = camu_screen_poll(scr, paused) || !paused;
// Should be AL_ATOMIC_ACQ_REL.
force_refresh = al_atomic_load(u32)(&scr->force_refresh, AL_ATOMIC_ACQUIRE);
@@ -712,7 +743,6 @@ void camu_screen_close(struct camu_screen *scr)
nn_mutex_destroy(&scr->mutex);
#endif
al_array_free(scr->videos);
- al_atomic_store(s32)(&scr->state, CAMU_SCREEN_STOPPED, AL_ATOMIC_RELAXED);
#ifdef STELA_EVENT_BUFFER
nn_thread_join(&scr->thread);
#endif
diff --git a/src/screen/screen.h b/src/screen/screen.h
index dacf756..4c6e205 100644
--- a/src/screen/screen.h
+++ b/src/screen/screen.h
@@ -14,6 +14,9 @@
//#define CAMU_SCREEN_DEBUG_KEY
+// Interpret click and drag as seeking. This is mainly a seek performance test.
+//#define CAMU_SCREEN_DRAG_SEEK
+
#define CAMU_SCREEN_WIDTH 700
#define CAMU_SCREEN_HEIGHT 700
@@ -22,13 +25,13 @@ enum {
CAMU_SCREEN_MOD_CONTROL = 1 << 1,
CAMU_SCREEN_DRAGGING = 1 << 2,
CAMU_SCREEN_ZOOMING = 1 << 3,
- CAMU_SCREEN_ZOOM_PAN_SIMPLE = 1 << 4
+ CAMU_SCREEN_ZOOM_PAN_SIMPLE = 1 << 4,
+ CAMU_SCREEN_ZOOM_FOV = 1 << 5
};
enum {
CAMU_SCREEN_PAUSED = 0,
- CAMU_SCREEN_PLAYING,
- CAMU_SCREEN_STOPPED
+ CAMU_SCREEN_PLAYING
};
enum {
@@ -69,6 +72,12 @@ struct camu_screen {
u64 last_click_ts;
f64 last_pointer_y;
f64 last_pointer_x;
+#ifdef CAMU_SCREEN_DRAG_SEEK
+ u64 last_seek_ts;
+#endif
+ f64 calibrate_x;
+ f64 calibrate_y;
+ bool vr_emulation;
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 b5fade2..1676084 100644
--- a/src/screen/view.c
+++ b/src/screen/view.c
@@ -1,4 +1,5 @@
#include <al/lib.h>
+#include <math.h>
#include "view.h"
@@ -15,6 +16,17 @@
#define VIEW_ON_ITS_SIDE(view) \
(view->rotation % CAMU_VIEW_ROTATION_180 == CAMU_VIEW_ROTATION_90)
+void camu_view_init(struct camu_view *view, u32 width, u32 height)
+{
+ view->mode = CAMU_DEFAULT_VIEW;
+ view->rotation = CAMU_VIEW_ROTATION_0;
+ view->width = width;
+ view->height = height;
+ view->zindex = 0;
+ view->stretch = 1.0;
+ view->fov = M_PI / 2.25; // 80 degrees
+}
+
void camu_view_calculate(struct camu_view *view, u32 window_width, u32 window_height)
{
u32 width, height;
diff --git a/src/screen/view.h b/src/screen/view.h
index 30b6f64..b5f948e 100644
--- a/src/screen/view.h
+++ b/src/screen/view.h
@@ -29,8 +29,10 @@ struct camu_view {
f64 x_offset;
f64 y_offset;
f64 stretch;
+ f64 fov;
};
+void camu_view_init(struct camu_view *view, u32 width, u32 height);
void camu_view_calculate(struct camu_view *view, u32 window_width, u32 window_height);
bool camu_view_pan_simple(struct camu_view *view, u32 window_width, u32 window_height, f64 dx, f64 dy);
bool camu_view_zoom_simple(struct camu_view *view, u32 window_width, u32 window_height, f64 x, f64 y, f64 v);