summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2018-09-18 20:27:14 -0700
committerH. Peter Anvin <hpa@zytor.com>2018-09-18 20:27:14 -0700
commit53116aef3af8d22a3a057056ed90038240c150cf (patch)
tree713c265390a2517fcca39f90659efeda62d3873f
parentc5bb7646fd58e9e9b3976e6d553926bfe46e603e (diff)
downloadabc80sim-abc802.tar.gz
abc80sim-abc802.tar.xz
abc80sim-abc802.zip
screenshot: allow screenshots to be sent to a directoryabc802
-rw-r--r--abc80.c6
-rw-r--r--abcio.h2
-rw-r--r--configure.ac4
-rw-r--r--screenshot.c75
4 files changed, 49 insertions, 38 deletions
diff --git a/abc80.c b/abc80.c
index 9574494..b4aef34 100644
--- a/abc80.c
+++ b/abc80.c
@@ -96,7 +96,9 @@ static no_return help(void)
" -h, --help print this help message\n"
" --diskdir set directory for disk images (default abcdisk)\n"
" --filedir set directory for file sharing (default abcdir)\n"
- "\n",
+ " --scrndir set directory for screen shots (default null)\n"
+ "\n"
+ "Alt-q quits the simulator, Alt-s takes a screenshot\n",
program_name);
exit(1);
}
@@ -210,6 +212,8 @@ int main(int argc, char **argv)
disk_path = *option++;
} else if (!strcmp(optstr, "filedir")) {
fileop_path = *option++;
+ } else if (!strcmp(optstr, "scrndir")) {
+ screen_path = *option++;
} else {
fprintf(stderr, "%s: unknown option: --%s\n",
program_name, optstr);
diff --git a/abcio.h b/abcio.h
index db3b5fb..2f9dd09 100644
--- a/abcio.h
+++ b/abcio.h
@@ -40,6 +40,6 @@ extern void abc802_vsync(void);
extern char *make_path(const char *prefix, const char *filename);
/* Directories */
-extern const char *fileop_path, *disk_path;
+extern const char *fileop_path, *disk_path, *screen_path;
#endif
diff --git a/configure.ac b/configure.ac
index 4a8574a..4be1c5b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -73,6 +73,7 @@ AC_CHECK_HEADERS(unistd.h)
AC_CHECK_HEADERS(fcntl.h)
AC_CHECK_HEADERS(io.h)
AC_CHECK_HEADERS(windows.h)
+AC_CHECK_HEADERS(direct.h)
dnl These types are POSIX-specific, and Windows does it differently...
AC_CHECK_TYPES([struct _stat64])
@@ -80,7 +81,8 @@ AC_CHECK_TYPES([struct stat])
AC_CHECK_FUNCS([stat _stat64])
AC_CHECK_FUNCS([fstat _fstat64])
-dnl Windows file searching stuff (when dirent is unavailable)
+dnl Windows directory handling
+AC_CHECK_FUNCS(_mkdir)
AC_CHECK_FUNCS([_findfirst _findfirst64])
dnl Temporary file functions
diff --git a/screenshot.c b/screenshot.c
index 3cf3798..d46005e 100644
--- a/screenshot.c
+++ b/screenshot.c
@@ -3,28 +3,18 @@
*/
#include "compiler.h"
-
#include "screenshot.h"
+#include "abcio.h"
-#include <time.h>
+#include <png.h>
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#ifdef HAVE_IO_H
-# include <io.h>
-#endif
-#ifdef HAVE_FCNTL_H
-# include <fcntl.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
+const char *screen_path;
-#include <png.h>
+#ifdef HAVE__MKDIR
+# define make_dir(x) _mkdir(x)
+#else
+# define make_dir(x) mkdir((x), 0777);
+#endif
static inline void *pixel_row(const SDL_Surface *surf, size_t y)
{
@@ -170,37 +160,49 @@ err:
/*
* Open a screenshot file for writing
*/
-#ifndef O_BINARY
-# define O_BINARY 0
-#endif
-
-static FILE *open_screenshot(char *namebuf)
+static FILE *open_screenshot(char **namebuf)
{
- int fd;
+ int err, fd;
unsigned int n;
FILE *f;
+ char filename[16];
+ char *pathname;
+
+ *namebuf = NULL;
+
+ if (screen_path)
+ make_dir(screen_path); /* If a directory, create it if needed */
for (n = 1; n <= 9999; n++) {
- snprintf(namebuf, PATH_MAX, "scrn%04u.png", n);
- fd = open(namebuf, O_CREAT|O_EXCL|O_WRONLY|O_BINARY,
+ sprintf(filename, "scrn%04u.png", n);
+ pathname = make_path(screen_path, filename);
+ fd = open(pathname, O_CREAT|O_EXCL|O_WRONLY|O_BINARY,
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+ err = errno;
- if (fd >= 0 || errno != EEXIST) {
+ if (fd >= 0)
+ break;
+
+ free(pathname);
+ if (err != EEXIST)
break;
- }
}
- if (fd < 0)
+ if (fd < 0) {
+ errno = err;
return NULL;
+ }
- f = fdopen(fd, "wb");
+ f = fdopen(fd, "w");
if (!f) {
- int err = errno;
+ err = errno;
close(fd);
+ free(pathname);
errno = err;
return NULL;
}
+ *namebuf = pathname;
return f;
}
@@ -257,7 +259,7 @@ struct allocable {
png_structp png; /* PNG write structure */
png_infop png_info; /* PNG info structure */
FILE *f; /* File pointer to screenshot file */
- char filename[PATH_MAX]; /* Filename (to remove on failure) */
+ char *filename; /* Filename (to remove on failure) */
};
static int do_screenshot(SDL_Surface *surf, struct allocable *a)
@@ -327,7 +329,7 @@ static int do_screenshot(SDL_Surface *surf, struct allocable *a)
return -1;
/* Open screenshot file */
- a->f = open_screenshot(a->filename);
+ a->f = open_screenshot(&a->filename);
if (!a->f)
return -1;
png_init_io(a->png, a->f);
@@ -368,8 +370,11 @@ int screenshot(SDL_Surface *surf)
png_destroy_write_struct(&a.png, &a.png_info);
if (a.f)
fclose(a.f);
- if (a.filename[0] && rv)
- remove(a.filename);
+ if (a.filename) {
+ if (rv)
+ remove(a.filename);
+ free(a.filename);
+ }
if (a.palette)
free(a.palette);
if (a.img)