242 lines
5.9 KiB
C
242 lines
5.9 KiB
C
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <unistd.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <errno.h>
|
||
|
|
||
|
#include <cammy/image.h>
|
||
|
#include <cammy/screen.h>
|
||
|
#include <cammy/photo.h>
|
||
|
#include <cammy/sram.h>
|
||
|
|
||
|
#include "pnglite.h"
|
||
|
#include "png.h"
|
||
|
#include "commands.h"
|
||
|
|
||
|
static cammy_tile_palette palette = {
|
||
|
.colors = {
|
||
|
{ 0, 0, 0 },
|
||
|
{ 85, 85, 85 },
|
||
|
{ 171, 171, 171 },
|
||
|
{ 255, 255, 255 }
|
||
|
}
|
||
|
};
|
||
|
|
||
|
int cammy_command_import_tile(int argc, char **argv) {
|
||
|
cammy_sram *sram;
|
||
|
cammy_image *dest, *src;
|
||
|
int photo;
|
||
|
|
||
|
if (argc < 2) {
|
||
|
cammy_command_usage(argc, argv, "No camera SRAM file provided");
|
||
|
} else if (argc < 3) {
|
||
|
cammy_command_usage(argc, argv, "No picture number provided");
|
||
|
} else if (argc < 4) {
|
||
|
cammy_command_usage(argc, argv,
|
||
|
"No Game Boy screen tile data file provided");
|
||
|
}
|
||
|
|
||
|
photo = atoi(argv[3]);
|
||
|
|
||
|
if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) {
|
||
|
cammy_command_usage(argc, argv, "Invalid photo number");
|
||
|
}
|
||
|
|
||
|
if ((sram = cammy_sram_open(argv[2])) == NULL) {
|
||
|
fprintf(stderr, "%s: %s: %s: %s\n",
|
||
|
argv[0], "cammy_sram_open()", argv[2], strerror(errno));
|
||
|
|
||
|
goto error_sram_open;
|
||
|
}
|
||
|
|
||
|
if ((src = cammy_image_open_tile(argv[4], CAMMY_SCREEN_WIDTH,
|
||
|
CAMMY_SCREEN_HEIGHT)) == NULL) {
|
||
|
fprintf(stderr, "%s: %s: %s: %s\n",
|
||
|
argv[0], "cammy_image_open_tile()", argv[4], strerror(errno));
|
||
|
|
||
|
goto error_image_open_tile;
|
||
|
}
|
||
|
|
||
|
if ((dest = malloc(sizeof(*dest))) == NULL) {
|
||
|
goto error_malloc_dest;
|
||
|
}
|
||
|
|
||
|
dest->format = CAMMY_IMAGE_TILE;
|
||
|
dest->tiles = (cammy_tile *)&sram->data->photos[photo-1].tiles;
|
||
|
dest->width = CAMMY_PHOTO_WIDTH;
|
||
|
dest->height = CAMMY_PHOTO_HEIGHT;
|
||
|
|
||
|
cammy_image_copy(dest, src,
|
||
|
0, 0, 16, 16, CAMMY_PHOTO_WIDTH, CAMMY_PHOTO_HEIGHT);
|
||
|
|
||
|
free(dest);
|
||
|
|
||
|
cammy_image_close(src);
|
||
|
|
||
|
cammy_sram_close(sram);
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
error_malloc_dest:
|
||
|
cammy_image_close(src);
|
||
|
|
||
|
error_image_open_tile:
|
||
|
cammy_sram_close(sram);
|
||
|
|
||
|
error_sram_open:
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int cammy_command_export_tile(int argc, char **argv) {
|
||
|
cammy_sram *sram;
|
||
|
cammy_image *dest, *src;
|
||
|
int photo;
|
||
|
|
||
|
if (argc < 2) {
|
||
|
cammy_command_usage(argc, argv, "No camera SRAM file provided");
|
||
|
} else if (argc < 3) {
|
||
|
cammy_command_usage(argc, argv, "No picture number provided");
|
||
|
} else if (argc < 4) {
|
||
|
cammy_command_usage(argc, argv,
|
||
|
"No Game Boy screen tile data file provided");
|
||
|
}
|
||
|
|
||
|
photo = atoi(argv[3]);
|
||
|
|
||
|
if (photo < 1 || photo > CAMMY_SRAM_PHOTO_COUNT) {
|
||
|
cammy_command_usage(argc, argv, "Invalid photo number");
|
||
|
}
|
||
|
|
||
|
if ((sram = cammy_sram_open(argv[2])) == NULL) {
|
||
|
fprintf(stderr, "%s: %s: %s: %s\n",
|
||
|
argv[0], "cammy_sram_open()", argv[2], strerror(errno));
|
||
|
|
||
|
goto error_sram_open;
|
||
|
}
|
||
|
|
||
|
if ((src = malloc(sizeof(*src))) == NULL) {
|
||
|
fprintf(stderr, "%s: %s: %s\n",
|
||
|
argv[0], "malloc()", strerror(errno));
|
||
|
|
||
|
goto error_malloc_src;
|
||
|
}
|
||
|
|
||
|
src->format = CAMMY_IMAGE_TILE;
|
||
|
src->size = CAMMY_PHOTO_SIZE;
|
||
|
src->width = CAMMY_PHOTO_WIDTH;
|
||
|
src->height = CAMMY_PHOTO_HEIGHT;
|
||
|
src->tiles = (cammy_tile *)&sram->data->photos[photo-1].tiles;
|
||
|
|
||
|
if ((dest = cammy_image_new(CAMMY_IMAGE_TILE,
|
||
|
CAMMY_SCREEN_WIDTH,
|
||
|
CAMMY_SCREEN_HEIGHT)) == NULL) {
|
||
|
fprintf(stderr, "%s: %s: %s\n",
|
||
|
argv[0], "cammy_image_new()", strerror(errno));
|
||
|
|
||
|
goto error_image_new_dest;
|
||
|
}
|
||
|
|
||
|
memset(dest->buf, '\0', dest->size);
|
||
|
|
||
|
cammy_image_copy(dest, src,
|
||
|
16, 16, 0, 0, CAMMY_PHOTO_WIDTH, CAMMY_PHOTO_HEIGHT);
|
||
|
|
||
|
if (cammy_image_save_tile(dest, argv[4]) < 0) {
|
||
|
fprintf(stderr, "%s: %s: %s: %s\n",
|
||
|
argv[0], "cammy_image_save_tile()", argv[4], strerror(errno));
|
||
|
|
||
|
goto error_image_save_tile_dest;
|
||
|
}
|
||
|
|
||
|
free(dest);
|
||
|
|
||
|
cammy_image_close(src);
|
||
|
|
||
|
cammy_sram_close(sram);
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
error_image_save_tile_dest:
|
||
|
cammy_image_destroy(dest);
|
||
|
|
||
|
error_image_new_dest:
|
||
|
free(src);
|
||
|
|
||
|
error_malloc_src:
|
||
|
cammy_sram_close(sram);
|
||
|
|
||
|
error_sram_open:
|
||
|
return errno || 1;
|
||
|
}
|
||
|
|
||
|
int cammy_command_convert_tile(int argc, char **argv) {
|
||
|
int fd;
|
||
|
void *in, *out;
|
||
|
|
||
|
if (argc < 3) {
|
||
|
cammy_command_usage(argc, argv,
|
||
|
"No input Game Boy screen tile data file provided");
|
||
|
} else if (argc < 4) {
|
||
|
cammy_command_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;
|
||
|
}
|
||
|
|
||
|
cammy_image_copy_from_tile(out, in,
|
||
|
CAMMY_SCREEN_WIDTH,
|
||
|
CAMMY_SCREEN_HEIGHT, 3, &palette);
|
||
|
|
||
|
if (cammy_png_save(argv[3], out,
|
||
|
CAMMY_SCREEN_WIDTH,
|
||
|
CAMMY_SCREEN_HEIGHT, 8, PNG_TRUECOLOR) < 0) {
|
||
|
fprintf(stderr, "%s: %s: %s: %s\n",
|
||
|
argv[0], "cammy_png_save()", argv[3], strerror(errno));
|
||
|
|
||
|
goto error_png_save;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
error_png_save:
|
||
|
free(out);
|
||
|
|
||
|
error_malloc_out:
|
||
|
error_read:
|
||
|
free(in);
|
||
|
|
||
|
error_malloc_in:
|
||
|
close(fd);
|
||
|
|
||
|
error_open:
|
||
|
return errno;
|
||
|
}
|