From 47e09e532cd0dbd1471ac140804658532f6f715d Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Tue, 31 May 2016 21:19:57 -0500 Subject: [PATCH] Add support for converting screen tile grabs to PNG --- bin/main.c | 117 +++++++++++++++++++++++++++++++++++++---- include/cammy/screen.h | 15 ++++++ 2 files changed, 121 insertions(+), 11 deletions(-) create mode 100644 include/cammy/screen.h diff --git a/bin/main.c b/bin/main.c index e3ab884..66821c3 100644 --- a/bin/main.c +++ b/bin/main.c @@ -2,10 +2,15 @@ #include #include #include +#include +#include +#include +#include #include #include "pnglite.h" #include +#include #include #include @@ -28,11 +33,12 @@ static void usage(int argc, char **argv, const char *message, ...) { fprintf(stderr, "\n"); } - fprintf(stderr, "usage: %1$s import file.sav photo1..30 input.png\n" - " %1$s export file.sav photo1..30 output.png\n" - " %1$s dither input.png output.png\n" - " %1$s split file.sav rn gn bn input.png\n" - " %1$s merge file.sav rn gn bn output.png\n", + fprintf(stderr, "usage: %1$s import file.sav photo1..30 input.png\n" + " %1$s export file.sav photo1..30 output.png\n" + " %1$s dither input.png output.png\n" + " %1$s split file.sav rn gn bn input.png\n" + " %1$s merge file.sav rn gn bn output.png\n" + " %1$s convert printer.tile output.png\n", argv[0]); exit(1); @@ -521,16 +527,105 @@ error_sram_open: return 1; } +static int convert(int argc, char **argv) { + int fd; + void *in, *out; + png_t *png; + int error; + + if (argc < 3) { + usage(argc, argv, "No input Game Boy screen tile data file provided"); + } else if (argc < 4) { + usage(argc, argv, "No output PNG filename provided"); + } + + if ((fd = open(argv[2], O_RDONLY)) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "open()", argv[2], strerror(errno)); + + goto error_open; + } + + if ((in = malloc(CAMMY_SCREEN_SIZE)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "malloc()", strerror(errno)); + + goto error_malloc_in; + } + + if (read(fd, in, CAMMY_SCREEN_SIZE) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "read()", argv[2], strerror(errno)); + + goto error_read; + } + + if ((out = malloc(CAMMY_SCREEN_WIDTH * CAMMY_SCREEN_HEIGHT * 3)) == NULL) { + fprintf(stderr, "%s: %s: %s\n", + argv[0], "malloc()", strerror(errno)); + + goto error_malloc_out; + } + + png_init(malloc, free); + + if ((png = malloc(sizeof(*png))) == NULL) { + goto error_malloc_png; + } + + if ((error = png_open_file_write(png, argv[3])) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "png_open_file_write()", argv[3], png_error_string(error)); + + goto error_png_open_file_write; + } + + cammy_image_copy_from_tile(out, in, + CAMMY_SCREEN_WIDTH, + CAMMY_SCREEN_HEIGHT, 3, &palette); + + if ((error = png_set_data(png, CAMMY_SCREEN_WIDTH, CAMMY_SCREEN_HEIGHT, 8, PNG_TRUECOLOR, out)) < 0) { + fprintf(stderr, "%s: %s: %s: %s\n", + argv[0], "png_set_data()", argv[3], png_error_string(error)); + + goto error_png_set_data; + } + + png_close_file(png); + + return 0; + +error_png_set_data: + png_close_file(png); + +error_png_open_file_write: + free(png); + +error_malloc_png: + free(out); + +error_malloc_out: +error_read: + free(in); + +error_malloc_in: + close(fd); + +error_open: + return errno; +} + static struct { char *name; int (*fun)(int, char **); } commands[] = { - { "import", import }, - { "export", export }, - { "dither", dither }, - { "split", split }, - { "merge", merge }, - { NULL, NULL } + { "import", import }, + { "export", export }, + { "dither", dither }, + { "split", split }, + { "merge", merge }, + { "convert", convert }, + { NULL, NULL } }; int main(int argc, char **argv) { diff --git a/include/cammy/screen.h b/include/cammy/screen.h new file mode 100644 index 0000000..d982601 --- /dev/null +++ b/include/cammy/screen.h @@ -0,0 +1,15 @@ +#ifndef _CAMMY_SCREEN_H +#define _CAMMY_SCREEN_H + +#include + +#define CAMMY_SCREEN_TILE_WIDTH 20 +#define CAMMY_SCREEN_TILE_HEIGHT 18 + +#define CAMMY_SCREEN_WIDTH (CAMMY_TILE_WIDTH * CAMMY_SCREEN_TILE_WIDTH) +#define CAMMY_SCREEN_HEIGHT (CAMMY_TILE_HEIGHT * CAMMY_SCREEN_TILE_HEIGHT) + +#define CAMMY_SCREEN_SIZE \ + (CAMMY_TILE_SIZE * CAMMY_SCREEN_TILE_WIDTH * CAMMY_SCREEN_TILE_HEIGHT) + +#endif /* _CAMMY_SCREEN_H */