From aa3ef264ac9de693ae640f79493b4b3b08cacdac Mon Sep 17 00:00:00 2001 From: Martin Donlon Date: Wed, 6 Oct 2021 22:11:01 -0700 Subject: [PATCH] Add /dev/MiSTer_cmd screenshot support (#472) Sending "screenshot" to the MiSTer_cmd device will trigger a screenshot. An exact png filename can be specified if desired. --- file_io.cpp | 39 ++++++++++++++++++++-------- input.cpp | 4 +++ user_io.cpp | 74 +++++++++++++++++++++++++++++++++++------------------ user_io.h | 3 +++ 4 files changed, 84 insertions(+), 36 deletions(-) diff --git a/file_io.cpp b/file_io.cpp index 9129ef5..135e778 100644 --- a/file_io.cpp +++ b/file_io.cpp @@ -756,22 +756,39 @@ int FileCreatePath(const char *dir) void FileGenerateScreenshotName(const char *name, char *out_name, int buflen) { - create_path(SCREENSHOT_DIR, CoreName); - - time_t t = time(NULL); - struct tm tm = *localtime(&t); - char datecode[32] = {}; - if (tm.tm_year >= 119) // 2019 or up considered valid time + // If the name ends with .png then don't modify it + if( !strcasecmp(name + strlen(name) - 4, ".png") ) { - strftime(datecode, 31, "%Y%m%d_%H%M%S", &tm); - snprintf(out_name, buflen, "%s/%s/%s-%s.png", SCREENSHOT_DIR, CoreName, datecode, name[0] ? name : SCREENSHOT_DEFAULT); + const char *p = strrchr(name, '/'); + make_fullpath(SCREENSHOT_DIR); + if( p ) + { + snprintf(out_name, buflen, "%s%s", SCREENSHOT_DIR, p); + } + else + { + snprintf(out_name, buflen, "%s/%s", SCREENSHOT_DIR, name); + } } else { - for (int i = 1; i < 10000; i++) + create_path(SCREENSHOT_DIR, CoreName); + + time_t t = time(NULL); + struct tm tm = *localtime(&t); + char datecode[32] = {}; + if (tm.tm_year >= 119) // 2019 or up considered valid time { - snprintf(out_name, buflen, "%s/%s/NODATE-%s_%04d.png", SCREENSHOT_DIR, CoreName, name[0] ? name : SCREENSHOT_DEFAULT, i); - if (!getFileType(out_name)) return; + strftime(datecode, 31, "%Y%m%d_%H%M%S", &tm); + snprintf(out_name, buflen, "%s/%s/%s-%s.png", SCREENSHOT_DIR, CoreName, datecode, name[0] ? name : SCREENSHOT_DEFAULT); + } + else + { + for (int i = 1; i < 10000; i++) + { + snprintf(out_name, buflen, "%s/%s/NODATE-%s_%04d.png", SCREENSHOT_DIR, CoreName, name[0] ? name : SCREENSHOT_DEFAULT, i); + if (!getFileType(out_name)) return; + } } } } diff --git a/input.cpp b/input.cpp index 823e740..7297edb 100644 --- a/input.cpp +++ b/input.cpp @@ -4387,6 +4387,10 @@ int input_test(int getchar) if (len > 4 && !strcasecmp(cmd + len - 4, ".mra")) arcade_load(cmd + 10); else fpga_load_rbf(cmd + 10); } + else if (!strncmp(cmd, "screenshot", 10)) + { + user_io_screenshot_cmd(cmd); + } } } diff --git a/user_io.cpp b/user_io.cpp index a7fc5d8..85484a9 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -3360,32 +3360,8 @@ void user_io_kbd(uint16_t key, int press) if (press == 1) { printf("print key pressed - do screen shot\n"); - mister_scaler *ms = mister_scaler_init(); - if (ms == NULL) - { - printf("problem with scaler, maybe not a new enough version\n"); - Info("Scaler not compatible"); - } - else - { - unsigned char *outputbuf = (unsigned char *)calloc(ms->width*ms->height * 3, 1); - mister_scaler_read(ms, outputbuf); - static char filename[1024]; - FileGenerateScreenshotName(last_filename, filename, 1024); - unsigned error = lodepng_encode24_file(getFullPath(filename), outputbuf, ms->width, ms->height); - if (error) { - printf("error %u: %s\n", error, lodepng_error_text(error)); - printf("%s", filename); - Info("error in saving png"); - } - free(outputbuf); - mister_scaler_free(ms); - char msg[1024]; - snprintf(msg, 1024, "Screen saved to\n%s", filename + strlen(SCREENSHOT_DIR"/")); - Info(msg); - } + user_io_screenshot(nullptr); } - } else if (key == KEY_MUTE) @@ -3544,3 +3520,51 @@ uint16_t user_io_get_sdram_cfg() { return sdram_cfg; } + +bool user_io_screenshot(const char *pngname) +{ + mister_scaler *ms = mister_scaler_init(); + if (ms == NULL) + { + printf("problem with scaler, maybe not a new enough version\n"); + Info("Scaler not compatible"); + return false; + } + else + { + const char *basename = last_filename; + if( pngname && *pngname ) + basename = pngname; + unsigned char *outputbuf = (unsigned char *)calloc(ms->width*ms->height * 3, 1); + mister_scaler_read(ms, outputbuf); + static char filename[1024]; + FileGenerateScreenshotName(basename, filename, 1024); + unsigned error = lodepng_encode24_file(getFullPath(filename), outputbuf, ms->width, ms->height); + if (error) { + printf("error %u: %s\n", error, lodepng_error_text(error)); + printf("%s", filename); + Info("error in saving png"); + return false; + } + free(outputbuf); + mister_scaler_free(ms); + char msg[1024]; + snprintf(msg, 1024, "Screen saved to\n%s", filename + strlen(SCREENSHOT_DIR"/")); + Info(msg); + } + return true; +} + +void user_io_screenshot_cmd(const char *cmd) +{ + if( strncmp( cmd, "screenshot", 10 )) + { + return; + } + + cmd += 10; + while( *cmd != '\0' && ( *cmd == '\t' || *cmd == ' ' || *cmd == '\n' ) ) + cmd++; + + user_io_screenshot(cmd); +} \ No newline at end of file diff --git a/user_io.h b/user_io.h index 01fd271..46c8725 100644 --- a/user_io.h +++ b/user_io.h @@ -238,6 +238,9 @@ void user_io_check_reset(unsigned short modifiers, char useKeys); void user_io_rtc_reset(); +void user_io_screenshot_cmd(const char *cmd); +bool user_io_screenshot(const char *pngname); + const char* get_rbf_dir(); const char* get_rbf_name(); const char* get_rbf_path();