3 * Author : Robin Krens <robin@robinkrens.nl>
5 * Last Modified Date: 15.06.2022
6 * Last Modified By : Robin Krens <robin@robinkrens.nl>
17 #include <SDL2/SDL_image.h>
31 unsigned short outpal[8];
34 int set_info(swan_gfx_t * gfx, SDL_Surface * img)
38 gfx->bpp = img->format->BitsPerPixel;
41 fprintf(stderr, "error: %d bpp format detected\n", img->format->BitsPerPixel);
45 if (gfx->width % 8 | gfx->height % 8) {
46 fprintf(stderr, "error: image not multiple of 16x16 tiles\n \
47 width: %d\theight: %d\n", gfx->width, gfx->height);
51 gfx->row_tiles = gfx->height / 8;
52 gfx->col_tiles = gfx->width / 8;
54 /* set userdata to iterate over
57 img->userdata = img->pixels;
58 gfx->data = (unsigned char *) img->userdata;
59 gfx->palette = img->format->palette->colors;
60 SDL_UnlockSurface(img);
65 void generate_4bpp_tile(unsigned char *buf, swan_gfx_t * gfx,
68 unsigned char * ptr = gfx->data;
69 for (int i = 0; i < TILE_SZ; i+=4) {
70 for (int j = 0; j < 4; ++j) {
71 if (packed) { /* packed format */
72 //printf("%d %d ", ptr[0], ptr[1]);
73 if (ptr[0] >= 8 || ptr[1] >= 8)
74 fprintf(stdout, "warning: too many colors detected\n");
75 gfx->outpal[ptr[0]] = (gfx->palette[ptr[0]].r >> 4) << 8 |
76 (gfx->palette[ptr[0]].g >> 4) << 4 |
77 gfx->palette[ptr[0]].b >> 4;
78 buf[i+j] = ptr[0] << 4;
81 } else { /* TODO: planar format */
82 for (int x = 0; x < 8; ++x) {
84 fprintf(stdout, "warning: too many colors detected\n");
85 buf[i + j] = ptr[x] << j;
92 ptr += (8 * (gfx->col_tiles-1));
97 FILE * openstream(const char * name, const char * prefix,
98 unsigned tile_nr, bool append)
100 assert(strlen(name) < 200);
104 unsigned buf_len = 256;
106 snprintf(buf, buf_len, "%s%d.%s", name, tile_nr, prefix);
108 //printf("%s\n", buf);
110 stream = fopen(buf, "w");
112 stream = fopen(buf, "a");
118 int main(int argc, char *argv[])
120 SDL_Surface * rawbmp;
127 const short fill = 0xFFFF;
128 bool seperate_gfx = false;
129 bool seperate_pal = false;
131 while ((opt = getopt(argc, argv, "po:sv")) != -1) {
135 printf("generate individual .pal for each tile");
138 printf("output file %s\n", optarg);
139 strcpy(outfile, optarg);
144 printf("generate .gfx for each tile\n");
150 fprintf(stderr, "Usage: %s [-s] [-o output] file \n", argv[0]);
155 if (optind >= argc) {
156 fprintf(stderr, "Expected input .bmp file!\n");
157 fprintf(stderr, "Usage: %s [-s] [-o output] [file]\n", argv[0]);
161 infile = argv[optind];
163 rawbmp = SDL_LoadBMP(infile);
165 fprintf(stderr, "can not load %s file\n", infile);
169 swan_gfx_t * gfx = calloc(1, sizeof(swan_gfx_t));
170 int ret = set_info(gfx, rawbmp);
175 unsigned char *tile_buf = calloc(TILE_SZ, sizeof(unsigned char));
178 sprintf(outfile, "out");
181 fprintf(stdout, "generating %d tile(s) \
183 with %d pal file(s)\n",
184 gfx->row_tiles * gfx->col_tiles,
185 seperate_gfx ? gfx->row_tiles * gfx->col_tiles : 1,
186 seperate_pal ? gfx->row_tiles * gfx->col_tiles : 1);
189 for (int i = 0, cnt = 0; i < gfx->row_tiles; ++i) {
190 for (int j = 0; j < gfx->col_tiles; ++j, ++cnt) {
192 if (i == 0 && j == 0) {
193 gfxstream = openstream(outfile, "gfx", 0, false);
194 palstream = openstream(outfile, "pal", 0, false);
197 gfxstream = openstream(outfile, "gfx", cnt, false);
200 palstream = openstream(outfile, "pal", cnt, false);
204 generate_4bpp_tile(tile_buf, gfx, true);
205 int ret = fwrite(tile_buf, sizeof(unsigned char), TILE_SZ, gfxstream);
206 if (ret != TILE_SZ) {
207 fprintf(stderr, "failed to convert, only write %d instead of %d\n", ret, TILE_SZ);
212 fwrite(gfx->outpal, sizeof(unsigned short), 8, palstream);
213 for (int i = 0; i < 8; ++i)
214 ret += fwrite(&fill, sizeof(unsigned short), 1, palstream);
216 gfx->data += 8; /* next column */
218 if (gfx->row_tiles == (i-1) && gfx->col_tiles == (j-1)) {
228 gfx->data += (gfx->col_tiles * 64) - (8 * gfx->col_tiles);
234 SDL_FreeSurface(rawbmp);