Update screenshot code.

This commit is contained in:
sorgelig
2019-05-09 21:41:33 +08:00
parent 92dcdba832
commit 798c996c6e
9 changed files with 118 additions and 109 deletions

View File

@@ -30,7 +30,7 @@
<NMakeOutput>MiSTer</NMakeOutput>
<NMakeCleanCommandLine>git.lnk ./clean.sh</NMakeCleanCommandLine>
<NMakePreprocessorDefinitions>__arm__;__GNUC__;__USE_GNU ;_GNU_SOURCE;VDATE="000000";_FILE_OFFSET_BITS=64;_LARGEFILE64_SOURCE;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
<NMakeIncludeSearchPath>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</NMakeIncludeSearchPath>
<NMakeIncludeSearchPath>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</NMakeIncludeSearchPath>
<OutDir>$(TEMP)</OutDir>
<IntDir>$(TEMP)</IntDir>
<AdditionalOptions>
@@ -62,6 +62,7 @@
<ClCompile Include="input.cpp" />
<ClCompile Include="lib\libco\arm.c" />
<ClCompile Include="lib\libco\libco.c" />
<ClCompile Include="lib\lodepng\lodepng.cpp" />
<ClCompile Include="lib\miniz\miniz.c" />
<ClCompile Include="lib\miniz\miniz_tdef.c" />
<ClCompile Include="lib\miniz\miniz_tinfl.c" />
@@ -69,6 +70,7 @@
<ClCompile Include="main.cpp" />
<ClCompile Include="menu.cpp" />
<ClCompile Include="osd.cpp" />
<ClCompile Include="scaler.cpp" />
<ClCompile Include="scheduler.cpp" />
<ClCompile Include="spi.cpp" />
<ClCompile Include="support\archie\archie.cpp" />
@@ -106,6 +108,7 @@
<ClInclude Include="input.h" />
<ClInclude Include="lib\libco\libco.h" />
<ClInclude Include="lib\libco\settings.h" />
<ClInclude Include="lib\lodepng\lodepng.h" />
<ClInclude Include="lib\miniz\miniz.h" />
<ClInclude Include="lib\miniz\miniz_common.h" />
<ClInclude Include="lib\miniz\miniz_tdef.h" />
@@ -114,6 +117,7 @@
<ClInclude Include="logo.h" />
<ClInclude Include="menu.h" />
<ClInclude Include="osd.h" />
<ClInclude Include="scaler.h" />
<ClInclude Include="scheduler.h" />
<ClInclude Include="spi.h" />
<ClInclude Include="support.h" />

View File

@@ -136,6 +136,12 @@
<ClCompile Include="cheats.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="lib\lodepng\lodepng.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="scaler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="battery.h">
@@ -273,5 +279,11 @@
<ClInclude Include="cheats.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="lib\lodepng\lodepng.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="scaler.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -17,21 +17,18 @@ with help from the MiSTer contributors including Grabulosaure
#include <sys/mman.h>
#include <err.h>
#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)

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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