From b5480372a1b83212fc97f1c58184ecbeb3e95e54 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 10 Feb 2015 20:58:33 +0100 Subject: [PATCH] Move screenshot code to screenshot.c and out of retroarch.c --- retroarch.c | 130 ------------------------------------------------- screenshot.c | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++ screenshot.h | 2 + 3 files changed, 136 insertions(+), 130 deletions(-) diff --git a/retroarch.c b/retroarch.c index 80f029bf3b..53292f843b 100644 --- a/retroarch.c +++ b/retroarch.c @@ -67,136 +67,6 @@ #endif #endif -static bool take_screenshot_viewport(void) -{ - char screenshot_path[PATH_MAX_LENGTH]; - const char *screenshot_dir = NULL; - uint8_t *buffer = NULL; - bool retval = false; - struct rarch_viewport vp = {0}; - - if (driver.video && driver.video->viewport_info) - driver.video->viewport_info(driver.video_data, &vp); - - if (!vp.width || !vp.height) - return false; - - if (!(buffer = (uint8_t*)malloc(vp.width * vp.height * 3))) - return false; - - if (driver.video && driver.video->read_viewport) - if (!driver.video->read_viewport(driver.video_data, buffer)) - goto done; - - screenshot_dir = g_settings.screenshot_directory; - - if (!*g_settings.screenshot_directory) - { - fill_pathname_basedir(screenshot_path, g_extern.basename, - sizeof(screenshot_path)); - screenshot_dir = screenshot_path; - } - - /* Data read from viewport is in bottom-up order, suitable for BMP. */ - if (!screenshot_dump(screenshot_dir, buffer, vp.width, vp.height, - vp.width * 3, true)) - goto done; - - retval = true; - -done: - if (buffer) - free(buffer); - return retval; -} - -static bool take_screenshot_raw(void) -{ - char screenshot_path[PATH_MAX_LENGTH]; - const void *data = g_extern.frame_cache.data; - unsigned width = g_extern.frame_cache.width; - unsigned height = g_extern.frame_cache.height; - int pitch = g_extern.frame_cache.pitch; - const char *screenshot_dir = g_settings.screenshot_directory; - - if (!*g_settings.screenshot_directory) - { - fill_pathname_basedir(screenshot_path, g_extern.basename, - sizeof(screenshot_path)); - screenshot_dir = screenshot_path; - } - - /* Negative pitch is needed as screenshot takes bottom-up, - * but we use top-down. - */ - return screenshot_dump(screenshot_dir, - (const uint8_t*)data + (height - 1) * pitch, - width, height, -pitch, false); -} - -/** - * take_screenshot: - * - * Returns: true (1) if successful, otherwise false (0). - **/ -static bool take_screenshot(void) -{ - bool viewport_read = false; - bool ret = true; - const char *msg = NULL; - - /* No way to infer screenshot directory. */ - if ((!*g_settings.screenshot_directory) && (!*g_extern.basename)) - return false; - - viewport_read = (g_settings.video.gpu_screenshot || - g_extern.system.hw_render_callback.context_type - != RETRO_HW_CONTEXT_NONE) && driver.video->read_viewport && - driver.video->viewport_info; - - /* Clear out message queue to avoid OSD fonts to appear on screenshot. */ - msg_queue_clear(g_extern.msg_queue); - - if (viewport_read) - { -#ifdef HAVE_MENU - /* Avoid taking screenshot of GUI overlays. */ - if (driver.video_poke && driver.video_poke->set_texture_enable) - driver.video_poke->set_texture_enable(driver.video_data, - false, false); -#endif - - if (driver.video) - rarch_render_cached_frame(); - } - - if (viewport_read) - ret = take_screenshot_viewport(); - else if (g_extern.frame_cache.data && - (g_extern.frame_cache.data != RETRO_HW_FRAME_BUFFER_VALID)) - ret = take_screenshot_raw(); - else - RARCH_ERR(RETRO_LOG_TAKE_SCREENSHOT_ERROR); - - if (ret) - { - RARCH_LOG(RETRO_LOG_TAKE_SCREENSHOT); - msg = RETRO_MSG_TAKE_SCREENSHOT; - } - else - { - RARCH_WARN(RETRO_LOG_TAKE_SCREENSHOT_FAILED); - msg = RETRO_MSG_TAKE_SCREENSHOT_FAILED; - } - - msg_queue_push(g_extern.msg_queue, msg, 1, g_extern.is_paused ? 1 : 180); - - if (g_extern.is_paused) - rarch_render_cached_frame(); - - return ret; -} - void rarch_recording_dump_frame(const void *data, unsigned width, unsigned height, size_t pitch) { diff --git a/screenshot.c b/screenshot.c index 953b8ee888..127b20d1f0 100644 --- a/screenshot.c +++ b/screenshot.c @@ -22,8 +22,12 @@ #include #include #include "general.h" +#include "intl/intl.h" #include #include "gfx/scaler/scaler.h" +#include "retroarch.h" +#include "retroarch_logger.h" +#include "screenshot.h" #ifdef HAVE_CONFIG_H #include "config.h" @@ -165,6 +169,136 @@ end: } #endif +static bool take_screenshot_viewport(void) +{ + char screenshot_path[PATH_MAX_LENGTH]; + const char *screenshot_dir = NULL; + uint8_t *buffer = NULL; + bool retval = false; + struct rarch_viewport vp = {0}; + + if (driver.video && driver.video->viewport_info) + driver.video->viewport_info(driver.video_data, &vp); + + if (!vp.width || !vp.height) + return false; + + if (!(buffer = (uint8_t*)malloc(vp.width * vp.height * 3))) + return false; + + if (driver.video && driver.video->read_viewport) + if (!driver.video->read_viewport(driver.video_data, buffer)) + goto done; + + screenshot_dir = g_settings.screenshot_directory; + + if (!*g_settings.screenshot_directory) + { + fill_pathname_basedir(screenshot_path, g_extern.basename, + sizeof(screenshot_path)); + screenshot_dir = screenshot_path; + } + + /* Data read from viewport is in bottom-up order, suitable for BMP. */ + if (!screenshot_dump(screenshot_dir, buffer, vp.width, vp.height, + vp.width * 3, true)) + goto done; + + retval = true; + +done: + if (buffer) + free(buffer); + return retval; +} + +static bool take_screenshot_raw(void) +{ + char screenshot_path[PATH_MAX_LENGTH]; + const void *data = g_extern.frame_cache.data; + unsigned width = g_extern.frame_cache.width; + unsigned height = g_extern.frame_cache.height; + int pitch = g_extern.frame_cache.pitch; + const char *screenshot_dir = g_settings.screenshot_directory; + + if (!*g_settings.screenshot_directory) + { + fill_pathname_basedir(screenshot_path, g_extern.basename, + sizeof(screenshot_path)); + screenshot_dir = screenshot_path; + } + + /* Negative pitch is needed as screenshot takes bottom-up, + * but we use top-down. + */ + return screenshot_dump(screenshot_dir, + (const uint8_t*)data + (height - 1) * pitch, + width, height, -pitch, false); +} + +/** + * take_screenshot: + * + * Returns: true (1) if successful, otherwise false (0). + **/ +bool take_screenshot(void) +{ + bool viewport_read = false; + bool ret = true; + const char *msg = NULL; + + /* No way to infer screenshot directory. */ + if ((!*g_settings.screenshot_directory) && (!*g_extern.basename)) + return false; + + viewport_read = (g_settings.video.gpu_screenshot || + g_extern.system.hw_render_callback.context_type + != RETRO_HW_CONTEXT_NONE) && driver.video->read_viewport && + driver.video->viewport_info; + + /* Clear out message queue to avoid OSD fonts to appear on screenshot. */ + msg_queue_clear(g_extern.msg_queue); + + if (viewport_read) + { +#ifdef HAVE_MENU + /* Avoid taking screenshot of GUI overlays. */ + if (driver.video_poke && driver.video_poke->set_texture_enable) + driver.video_poke->set_texture_enable(driver.video_data, + false, false); +#endif + + if (driver.video) + rarch_render_cached_frame(); + } + + if (viewport_read) + ret = take_screenshot_viewport(); + else if (g_extern.frame_cache.data && + (g_extern.frame_cache.data != RETRO_HW_FRAME_BUFFER_VALID)) + ret = take_screenshot_raw(); + else + RARCH_ERR(RETRO_LOG_TAKE_SCREENSHOT_ERROR); + + if (ret) + { + RARCH_LOG(RETRO_LOG_TAKE_SCREENSHOT); + msg = RETRO_MSG_TAKE_SCREENSHOT; + } + else + { + RARCH_WARN(RETRO_LOG_TAKE_SCREENSHOT_FAILED); + msg = RETRO_MSG_TAKE_SCREENSHOT_FAILED; + } + + msg_queue_push(g_extern.msg_queue, msg, 1, g_extern.is_paused ? 1 : 180); + + if (g_extern.is_paused) + rarch_render_cached_frame(); + + return ret; +} + /* Take frame bottom-up. */ bool screenshot_dump(const char *folder, const void *frame, diff --git a/screenshot.h b/screenshot.h index 594ece9de4..a28cf5def7 100644 --- a/screenshot.h +++ b/screenshot.h @@ -26,4 +26,6 @@ bool screenshot_dump(const char *folder, const void *frame, void screenshot_generate_filename(char *filename, size_t size); +bool take_screenshot(void); + #endif