From 798c996c6edfa71a71e5621803c2b7012ab13563 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Thu, 9 May 2019 21:41:33 +0800 Subject: [PATCH] Update screenshot code. --- MiSTer.vcxproj | 6 +++- MiSTer.vcxproj.filters | 12 +++++++ file_io.cpp | 73 ++++++++++++++++-------------------------- file_io.h | 4 ++- menu.cpp | 1 + scaler.cpp | 48 +++++++++++++-------------- scaler.h | 10 +++--- user_io.cpp | 71 ++++++++++++++++++++-------------------- user_io.h | 2 ++ 9 files changed, 118 insertions(+), 109 deletions(-) diff --git a/MiSTer.vcxproj b/MiSTer.vcxproj index f22e153..870f043 100644 --- a/MiSTer.vcxproj +++ b/MiSTer.vcxproj @@ -30,7 +30,7 @@ MiSTer git.lnk ./clean.sh __arm__;__GNUC__;__USE_GNU ;_GNU_SOURCE;VDATE="000000";_FILE_OFFSET_BITS=64;_LARGEFILE64_SOURCE;$(NMakePreprocessorDefinitions) - c:\Work\Git\opt\gcc54\arm-linux-gnueabihf\libc\usr\include;c:\Work\Git\opt\gcc54\lib\gcc\arm-linux-gnueabihf\5.4.1\include;c:\Work\Git\opt\gcc54\arm-linux-gnueabihf\include\c++\5.4.1;$(NMakeIncludeSearchPath);lib\libco;lib\miniz + c:\Work\Git\opt\gcc54\arm-linux-gnueabihf\libc\usr\include;c:\Work\Git\opt\gcc54\lib\gcc\arm-linux-gnueabihf\5.4.1\include;c:\Work\Git\opt\gcc54\arm-linux-gnueabihf\include\c++\5.4.1;$(NMakeIncludeSearchPath);lib\libco;lib\miniz;lib\lodepng $(TEMP) $(TEMP) @@ -62,6 +62,7 @@ + @@ -69,6 +70,7 @@ + @@ -106,6 +108,7 @@ + @@ -114,6 +117,7 @@ + diff --git a/MiSTer.vcxproj.filters b/MiSTer.vcxproj.filters index 577c994..e8118cd 100644 --- a/MiSTer.vcxproj.filters +++ b/MiSTer.vcxproj.filters @@ -136,6 +136,12 @@ Source Files + + Source Files + + + Source Files + @@ -273,5 +279,11 @@ Header Files + + Header Files + + + Header Files + \ No newline at end of file diff --git a/file_io.cpp b/file_io.cpp index 4054655..7abe7d0 100644 --- a/file_io.cpp +++ b/file_io.cpp @@ -587,57 +587,40 @@ int FileCanWrite(const char *name) return ((st.st_mode & S_IWUSR) != 0); } - -//http://nion.modprobe.de/blog/archives/357-Recursive-directory-creation.html -static void mkdirs(const char *dir) { - char tmp[256]; - char *p = NULL; - size_t len; - - snprintf(tmp, sizeof(tmp),"%s",dir); - len = strlen(tmp); - if(tmp[len - 1] == '/') - tmp[len - 1] = 0; - for(p = tmp + 1; *p; p++) - if(*p == '/') { - *p = 0; - mkdir(tmp, S_IRWXU); - *p = '/'; - } - mkdir(tmp, S_IRWXU); -} - -void FileGenerateScreenshotName(const char *path, const char *postfix,char *buffer, int buflen) +static void create_path(const char *base_dir, const char* sub_dir) { - int curnum=1; - int done=false; - // create the full path, ie: /media/fat/screenshot/NES/ - mkdirs(getFullPath(path)); - // create - do - { - snprintf(buffer,buflen,"%s/%s_%04d.png",path,postfix,curnum); - if (getFileType(buffer)==0) - { - done=true; - } - else - { - curnum++; - } - - - } while(curnum<10000 && done==false); + make_fullpath(base_dir); + mkdir(full_path, S_IRWXU | S_IRWXG | S_IRWXO); + strcat(full_path, "/"); + strcat(full_path, sub_dir); + mkdir(full_path, S_IRWXU | S_IRWXG | S_IRWXO); } +void FileGenerateScreenshotName(const char *name, char *out_name, int buflen) +{ + create_path(SCREENSHOT_DIR, HomeDir); + + time_t t = time(NULL); + struct tm tm = *localtime(&t); + char datecode[32] = {}; + if (tm.tm_year >= 119) // 2019 or up considered valid time + { + strftime(datecode, 31, "%Y%m%d_%H%M%S", &tm); + snprintf(out_name, buflen, "%s/%s/%s-%s.png", SCREENSHOT_DIR, HomeDir, 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, HomeDir, name[0] ? name : SCREENSHOT_DEFAULT, i); + if (!getFileType(out_name)) return; + } + } +} void FileGenerateSavePath(const char *name, char* out_name) { - make_fullpath(SAVE_DIR); - mkdir(full_path, S_IRWXU | S_IRWXG | S_IRWXO); - strcat(full_path, "/"); - strcat(full_path, HomeDir); - mkdir(full_path, S_IRWXU | S_IRWXG | S_IRWXO); + create_path(SAVE_DIR, HomeDir); sprintf(out_name, "%s/%s/", SAVE_DIR, HomeDir); char *fname = out_name + strlen(out_name); diff --git a/file_io.h b/file_io.h index 653dcdf..3762ac5 100644 --- a/file_io.h +++ b/file_io.h @@ -66,7 +66,9 @@ int FileCanWrite(const char *name); #define SAVE_DIR "saves" void FileGenerateSavePath(const char *name, char* out_name); -void FileGenerateScreenshotName(const char *path, const char *postfix,char *buffer, int buflen); +#define SCREENSHOT_DIR "screenshots" +#define SCREENSHOT_DEFAULT "screen" +void FileGenerateScreenshotName(const char *name, char *out_name, int buflen); int FileSave(const char *name, void *pBuffer, int size); int FileLoad(const char *name, void *pBuffer, int size); // supply pBuffer = 0 to get the file size without loading diff --git a/menu.cpp b/menu.cpp index 76e106f..501f264 100644 --- a/menu.cpp +++ b/menu.cpp @@ -1411,6 +1411,7 @@ void HandleUI(void) case MENU_8BIT_MAIN_FILE_SELECTED: printf("File selected: %s\n", SelectedPath); + user_io_store_filename(SelectedPath); user_io_file_tx(SelectedPath, user_io_ext_idx(SelectedPath, fs_pFileExt) << 6 | (menusub + 1), opensave); cheats_init(SelectedPath); menustate = MENU_NONE1; diff --git a/scaler.cpp b/scaler.cpp index 27ac7de..939018d 100644 --- a/scaler.cpp +++ b/scaler.cpp @@ -17,21 +17,18 @@ with help from the MiSTer contributors including Grabulosaure #include #include - - #include "scaler.h" - mister_scaler * mister_scaler_init() { mister_scaler *ms =(mister_scaler *) calloc(sizeof(mister_scaler),1); int pagesize = sysconf(_SC_PAGE_SIZE); if (pagesize==0) pagesize=4096; - int offset = MISTER_SCALAR_BASEADDR; + int offset = MISTER_SCALER_BASEADDR; int map_start = offset & ~(pagesize - 1); ms->map_off = offset - map_start; - ms->num_bytes=MISTER_SCALAR_BUFFERSIZE; + ms->num_bytes=MISTER_SCALER_BUFFERSIZE; //printf("map_start = %d map_off=%d offset=%d\n",map_start,ms->map_off,offset); unsigned char *buffer; @@ -68,6 +65,7 @@ mister_scaler * mister_scaler_init() return ms; } + void mister_scaler_free(mister_scaler *ms) { munmap(ms->map,ms->num_bytes+ms->map_off); @@ -75,7 +73,8 @@ void mister_scaler_free(mister_scaler *ms) free(ms); } -int mister_scaler_read_yuv(mister_scaler *ms,int lineY,unsigned char *bufY, int lineU, unsigned char *bufU, int lineV, unsigned char *bufV) { +int mister_scaler_read_yuv(mister_scaler *ms,int lineY,unsigned char *bufY, int lineU, unsigned char *bufU, int lineV, unsigned char *bufV) +{ unsigned char *buffer; buffer = (unsigned char *)(ms->map+ms->map_off); @@ -84,28 +83,29 @@ int mister_scaler_read_yuv(mister_scaler *ms,int lineY,unsigned char *bufY, int unsigned char *outbufy; unsigned char *outbufU; unsigned char *outbufV; - for (int y=0; y< ms->height ; y++) { - pixbuf=&buffer[ms->header + y*ms->line]; - outbufy=&bufY[y*(lineY)]; - outbufU=&bufU[y*(lineU)]; - outbufV=&bufV[y*(lineV)]; - for (int x = 0; x < ms->width ; x++) { - int R,G,B; - R = *pixbuf++; - G = *pixbuf++; - B = *pixbuf++; - int Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16; - int U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128; - int V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128; + for (int y=0; y< ms->height ; y++) + { + pixbuf=&buffer[ms->header + y*ms->line]; + outbufy=&bufY[y*(lineY)]; + outbufU=&bufU[y*(lineU)]; + outbufV=&bufV[y*(lineV)]; + for (int x = 0; x < ms->width ; x++) + { + int R,G,B; + R = *pixbuf++; + G = *pixbuf++; + B = *pixbuf++; + int Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16; + int U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128; + int V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128; - *outbufy++ = Y; - *outbufU++ = U; - *outbufV++ = V; - } + *outbufy++ = Y; + *outbufU++ = U; + *outbufV++ = V; + } } return 0; - } int mister_scaler_read(mister_scaler *ms,unsigned char *gbuf) diff --git a/scaler.h b/scaler.h index 95c89f7..9103e92 100644 --- a/scaler.h +++ b/scaler.h @@ -3,6 +3,8 @@ Copyright 2019 alanswx with help from the MiSTer contributors including Grabulosaure */ +#ifndef SCALER_H +#define SCALER_H typedef struct { int header; @@ -16,12 +18,12 @@ typedef struct { int fd; } mister_scaler; - -#define MISTER_SCALAR_BASEADDR 536870912 -#define MISTER_SCALAR_BUFFERSIZE 2048*3*1024 - +#define MISTER_SCALER_BASEADDR 0x20000000 +#define MISTER_SCALER_BUFFERSIZE 2048*3*1024 mister_scaler *mister_scaler_init(); int mister_scaler_read(mister_scaler *,unsigned char *buffer); int mister_scaler_read_yuv(mister_scaler *ms,int,unsigned char *y,int, unsigned char *U,int, unsigned char *V); void mister_scaler_free(mister_scaler *); + +#endif diff --git a/user_io.cpp b/user_io.cpp index e6cc0da..5780291 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -69,6 +69,17 @@ static bool scrl_status = 0; static char minimig_adjust = 0; +static char last_filename[1024] = {}; +void user_io_store_filename(char *filename) +{ + char *p = strrchr(filename, '/'); + if (p) strcpy(last_filename, p + 1); + else strcpy(last_filename, filename); + + p = strrchr(last_filename, '.'); + if (p) *p = 0; +} + const char *get_image_name(int i) { if (!sd_image[i].size) return NULL; @@ -2482,42 +2493,39 @@ void user_io_kbd(uint16_t key, int press) { if(is_menu_core()) spi_uio_cmd(UIO_KEYBOARD); //ping the Menu core to wakeup - // ALT - Print Screen - screen shot - if (key==0x63 && (get_key_mod() & (LALT | RALT | RGUI | LGUI))) - { - if (press==1) - { - printf("print key pressed - do screen shot\n"); - mister_scaler *ms=mister_scaler_init(); - if (ms==NULL) + // Win+PrnScr or Alt/Win+ScrLk - screen shot + if ((key == KEY_SYSRQ && (get_key_mod() & (RGUI | LGUI))) || (key == KEY_SCROLLLOCK && (get_key_mod() & (LALT | RALT | RGUI | LGUI)))) + { + 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"); + Info("Scaler not compatible"); } else { - unsigned char *outputbuf = (unsigned char *)calloc(ms->width*ms->height*3,1); - mister_scaler_read(ms,outputbuf); - char path[1024]; - char filename[1024]; - //user_io_get_core_name() - snprintf(path,1024,"screenshot/%s",HomeDir); - FileGenerateScreenshotName(path,"shot",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"); + 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); } - free(outputbuf); - mister_scaler_free(ms); - char msg[1024]; - snprintf(msg,1024,"Saving screen shot\n %s\n",filename+strlen("screenshot/")); - Info(msg); - } - } + } - } + } else if (key == KEY_MUTE) { @@ -2550,11 +2558,6 @@ void user_io_kbd(uint16_t key, int press) PrintDirectory(); } else - if ((core_type == CORE_TYPE_MINIMIG2) || - (core_type == CORE_TYPE_MIST) || - (core_type == CORE_TYPE_ARCHIE) || - (core_type == CORE_TYPE_SHARPMZ) || - (core_type == CORE_TYPE_8BIT)) { if (key) { diff --git a/user_io.h b/user_io.h index 8af8718..94a4fa6 100644 --- a/user_io.h +++ b/user_io.h @@ -250,4 +250,6 @@ void SetMidiLinkMode(int mode); void set_volume(int cmd); int get_volume(); +void user_io_store_filename(char *filename); + #endif // USER_IO_H