#define VasEBoot_video_render_target VasEBoot_video_fbrender_target #include #include #include #include static struct { struct VasEBoot_video_mode_info mode_info; struct VasEBoot_video_render_target *render_target; VasEBoot_uint8_t *ptr; } framebuffer; void (*VasEBoot_video_capture_refresh_cb) (void); static VasEBoot_err_t VasEBoot_video_capture_swap_buffers (void) { if (VasEBoot_video_capture_refresh_cb) VasEBoot_video_capture_refresh_cb (); return VAS_EBOOT_ERR_NONE; } static VasEBoot_err_t VasEBoot_video_capture_set_active_render_target (struct VasEBoot_video_render_target *target) { if (target == VAS_EBOOT_VIDEO_RENDER_TARGET_DISPLAY) target = framebuffer.render_target; return VasEBoot_video_fb_set_active_render_target (target); } static VasEBoot_err_t VasEBoot_video_capture_fini (void) { return VAS_EBOOT_ERR_NONE; } static struct VasEBoot_video_adapter VasEBoot_video_capture_adapter = { .name = "Render capture", .prio = 0, .id = VAS_EBOOT_VIDEO_ADAPTER_CAPTURE, .fini = VasEBoot_video_capture_fini, .get_info = VasEBoot_video_fb_get_info, .get_info_and_fini = 0, .set_palette = VasEBoot_video_fb_set_palette, .get_palette = VasEBoot_video_fb_get_palette, .set_viewport = VasEBoot_video_fb_set_viewport, .get_viewport = VasEBoot_video_fb_get_viewport, .set_region = VasEBoot_video_fb_set_region, .get_region = VasEBoot_video_fb_get_region, .set_area_status = VasEBoot_video_fb_set_area_status, .get_area_status = VasEBoot_video_fb_get_area_status, .map_color = VasEBoot_video_fb_map_color, .map_rgb = VasEBoot_video_fb_map_rgb, .map_rgba = VasEBoot_video_fb_map_rgba, .unmap_color = VasEBoot_video_fb_unmap_color, .fill_rect = VasEBoot_video_fb_fill_rect, .blit_bitmap = VasEBoot_video_fb_blit_bitmap, .blit_render_target = VasEBoot_video_fb_blit_render_target, .scroll = VasEBoot_video_fb_scroll, .swap_buffers = VasEBoot_video_capture_swap_buffers, .create_render_target = VasEBoot_video_fb_create_render_target, .delete_render_target = VasEBoot_video_fb_delete_render_target, .set_active_render_target = VasEBoot_video_capture_set_active_render_target, .get_active_render_target = VasEBoot_video_fb_get_active_render_target, .next = 0 }; static struct VasEBoot_video_adapter *saved; static struct VasEBoot_video_mode_info saved_mode_info; VasEBoot_err_t VasEBoot_video_capture_start (const struct VasEBoot_video_mode_info *mode_info, struct VasEBoot_video_palette_data *palette, unsigned int palette_size) { VasEBoot_err_t err; VasEBoot_memset (&framebuffer, 0, sizeof (framebuffer)); VasEBoot_video_fb_init (); framebuffer.mode_info = *mode_info; framebuffer.mode_info.blit_format = VasEBoot_video_get_blit_format (&framebuffer.mode_info); framebuffer.ptr = VasEBoot_calloc (framebuffer.mode_info.height, framebuffer.mode_info.pitch); if (!framebuffer.ptr) return VasEBoot_errno; err = VasEBoot_video_fb_create_render_target_from_pointer (&framebuffer.render_target, &framebuffer.mode_info, framebuffer.ptr); if (err) return err; err = VasEBoot_video_fb_set_active_render_target (framebuffer.render_target); if (err) return err; err = VasEBoot_video_fb_set_palette (0, palette_size, palette); if (err) return err; saved = VasEBoot_video_adapter_active; if (saved) { VasEBoot_video_get_info (&saved_mode_info); if (saved->fini) saved->fini (); } VasEBoot_video_adapter_active = &VasEBoot_video_capture_adapter; return VAS_EBOOT_ERR_NONE; } void * VasEBoot_video_capture_get_framebuffer (void) { return framebuffer.ptr; } void VasEBoot_video_capture_end (void) { VasEBoot_video_fb_delete_render_target (framebuffer.render_target); VasEBoot_free (framebuffer.ptr); VasEBoot_video_fb_fini (); VasEBoot_video_adapter_active = saved; if (saved) { if (saved->init) saved->init (); if (saved->setup) saved->setup (saved_mode_info.width, saved_mode_info.height, 0, 0); } }