#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
+#include <errno.h>
#include "image.h"
#include "dynarr.h"
void print_usage(const char *argv0);
int proc_image(const char *fname);
+void wrtiles_carr(FILE *fp, const char *name, struct image *timg, int ntiles);
+void wrtilemap_carr(FILE *fp, const char *name, int *tmap, int xtiles, int ytiles);
+void wrpalette_carr(FILE *fp, const char *name, struct cmapent *cmap, int ncol);
enum { OUT_IMG, OUT_C, OUT_ASM } outmode;
int tile_xsz = 8, tile_ysz = 8;
int proc_image(const char *fname)
{
int i, j, k, idx, xtiles, ytiles, ntiles, result = -1;
+ FILE *fp;
struct image img, tile;
struct image *tiles = 0;
unsigned char *tiles_pixels, *tptr;
unsigned char *sptr;
int *tilemap = 0, *mapptr;
+ char *basename, *suffix, *outfile;
if(load_image(&img, fname) == -1) {
fprintf(stderr, "failed to load image: %s\n", fname);
return -1;
}
+ basename = alloca(strlen(fname) + 1);
+ strcpy(basename, fname);
+ if((suffix = strchr(basename, '.'))) {
+ *suffix = 0;
+ }
xtiles = img.width / tile_xsz;
ytiles = img.height / tile_ysz;
fprintf(stderr, "%s (%dx%d) -> %d tiles, %d unique\n", fname, img.width, img.height,
xtiles * ytiles, ntiles);
+ assert(ntiles > 0);
+
+ /* make a big image out of the tiles and write it out */
+ tile = tiles[0];
+ tile.height = ntiles * tile_ysz;
+
+ outfile = alloca(strlen(basename) + 5);
- if(ntiles > 0) {
- FILE *fp;
+ switch(outmode) {
+ case OUT_IMG:
+ sprintf(outfile, "%s.png", basename);
- /* make a big image out of the tiles and write it out */
- tile = tiles[0];
- tile.height = ntiles * tile_ysz;
- if(save_image(&tile, "test.png") == -1) {
+ if(save_image(&tile, outfile) == -1) {
fprintf(stderr, "failed to write output image\n");
goto err;
}
+ break;
+
+ case OUT_C:
+ sprintf(outfile, "%s.c", basename);
+
+ if(!(fp = fopen(outfile, "w"))) {
+ fprintf(stderr, "failed to open output file: %s: %s\n", outfile, strerror(errno));
+ goto err;
+ }
+ wrtiles_carr(fp, basename, &tile, ntiles);
+ wrtilemap_carr(fp, basename, tilemap, xtiles, ytiles);
+ wrpalette_carr(fp, basename, tile.cmap, tile.cmap_ncolors);
+ break;
+
+ case OUT_ASM:
+ sprintf(outfile, "%s.s", basename);
+ /* TODO */
+ break;
}
- /* TODO cont. */
result = 0;
free(img.pixels);
return result;
}
+
+void wrtiles_carr(FILE *fp, const char *name, struct image *timg, int ntiles)
+{
+ int i, j, curx = 0;
+ unsigned char *ptr = timg->pixels;
+
+ fprintf(fp, "\nint %s_num_tiles = %d;\n", name, ntiles);
+ fprintf(fp, "int %s_tiles_width = %d;\n", name, timg->width);
+ fprintf(fp, "int %s_tiles_height = %d;\n", name, timg->height);
+ fprintf(fp, "int %s_tiles_bpp = %d;\n", name, timg->bpp);
+ fprintf(fp, "unsigned char %s_tiles[] = {\n", name);
+
+ for(i=0; i<timg->height; i++) {
+ for(j=0; j<timg->scansz; j++) {
+ if(curx == 0) {
+ curx = 3 + fprintf(fp, "\t%u", (unsigned int)*ptr++);
+ } else {
+ curx += fprintf(fp, ", %u", (unsigned int)*ptr++);
+ }
+ if(curx >= 80) {
+ fprintf(fp, ",\n");
+ curx = 0;
+ }
+ }
+ ptr += timg->pitch - timg->scansz;
+ }
+
+ fprintf(fp, "\n};\n\n");
+}
+
+void wrtilemap_carr(FILE *fp, const char *name, int *tmap, int xtiles, int ytiles)
+{
+ int i, sz, curx = 0;
+
+ fprintf(fp, "\nint %s_tilemap_cols = %d;\n", name, xtiles);
+ fprintf(fp, "int %s_tilemap_rows = %d;\n", name, ytiles);
+ fprintf(fp, "unsigned int %s_tilemap[] = {\n", name);
+
+ sz = xtiles * ytiles;
+ for(i=0; i<sz; i++) {
+ if(curx == 0) {
+ curx = 3 + fprintf(fp, "\t%u", (unsigned int)tmap[i]);
+ } else {
+ curx += fprintf(fp, ", %u", (unsigned int)tmap[i]);
+ }
+ if(curx >= 80) {
+ fprintf(fp, ",\n");
+ curx = 0;
+ }
+ }
+
+ fprintf(fp, "\n};\n\n");
+}
+
+void wrpalette_carr(FILE *fp, const char *name, struct cmapent *cmap, int ncol)
+{
+ int i;
+
+ fprintf(fp, "\nint %s_cmap_colors = %d;\n", name, ncol);
+ fprintf(fp, "unsigned char %s_cmap[][3] = {\n", name);
+ for(i=0; i<ncol; i++) {
+ fprintf(fp, "\t{%u, %u, %u}", cmap[i].r, cmap[i].g, cmap[i].b);
+ if(i < ncol - 1) {
+ fputs(",\n", fp);
+ } else {
+ fputc('\n', fp);
+ }
+ }
+ fprintf(fp, "};\n\n");
+}