From 7c9a0de14c8d232ddf8b3fac39a28cb68083a989 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 4 Jun 2023 00:48:45 +0200 Subject: [PATCH] add tools for USB video capture Complete with seamless VRAM/Azur transitions!! --- src/main.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/main.cpp b/src/main.cpp index fd0345a..1e23147 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,9 +13,80 @@ #include #include #include +#include #include #include +#ifdef LOG_USB_ENABLE + +#include +#include + +/* Screenshot next frame */ +bool volatile screenshot = false; +/* Send next frame as video to fxlink */ +bool volatile videocapture = false; + +static bool async_event_filter(key_event_t ev) +{ + if(ev.key == KEY_7) { + if(ev.type == KEYEV_DOWN) + screenshot = true; + return false; + } + if(ev.key == KEY_8) { + if(ev.type == KEYEV_DOWN) + videocapture = !videocapture; + return false; + } + return true; +} + +static void hook_prefrag(int id, void *fragment, int size) +{ + if(!screenshot && !videocapture) + return; + + /* Screenshot takes precedence */ + char const *type = screenshot ? "image" : "video"; + + int pipe = usb_ff_bulk_output(); + + if(id == 0) { + usb_fxlink_header_t h; + usb_fxlink_image_t sh; + int size = azrp_width * azrp_height * 2; + + usb_fxlink_fill_header(&h, "fxlink", type, size + sizeof sh); + sh.width = htole32(azrp_width); + sh.height = htole32(azrp_height); + sh.pixel_format = htole32(USB_FXLINK_IMAGE_RGB565); + + usb_write_sync(pipe, &h, sizeof h, false); + usb_write_sync(pipe, &sh, sizeof sh, false); + } + + usb_write_sync(pipe, fragment, size, false); + + if(id == azrp_frag_count - 1) { + usb_commit_sync(pipe); + screenshot = false; + } +} + +static void hook_dupdate(void) +{ + if(screenshot) { + usb_fxlink_screenshot(true); + screenshot = false; + } + else if(videocapture) { + usb_fxlink_videocapture(false); + } +} + +#endif /* LOG_USB_ENABLE */ + int play_level(int level_id) { struct game game; @@ -307,12 +378,18 @@ int main(void) extern font_t font_boson; dfont(&font_boson); + azrp_config_scale(1); + #if LOG_USB_ENABLE dclear(C_WHITE); dtext_opt(DWIDTH/2, DHEIGHT/2, C_BLACK, C_NONE, DTEXT_CENTER, DTEXT_MIDDLE, "Waiting for USB log...", -1); dupdate(); log_init(true); + + azrp_hook_set_prefrag(hook_prefrag); + dupdate_set_hook(GINT_CALL(hook_dupdate)); + keydev_set_async_filter(keydev_std(), async_event_filter); #endif while (1) {