summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--img2gba/Makefile (renamed from sprite2gba/Makefile)2
-rw-r--r--img2gba/src/main.c (renamed from sprite2gba/src/main.c)130
-rw-r--r--img2gba/src/shorthand.h (renamed from sprite2gba/src/shorthand.h)0
-rw-r--r--img2gba/src/stb_image.h (renamed from sprite2gba/src/stb_image.h)4
4 files changed, 97 insertions, 39 deletions
diff --git a/sprite2gba/Makefile b/img2gba/Makefile
index 0d6dc07..f374ea9 100644
--- a/sprite2gba/Makefile
+++ b/img2gba/Makefile
@@ -9,7 +9,7 @@ WATCH_SRC := $(wildcard $(SRC_DIR)/*.c)
9WATCH_SRC += $(wildcard $(SRC_DIR)/*.h) 9WATCH_SRC += $(wildcard $(SRC_DIR)/*.h)
10 10
11# Output library names and executables. 11# Output library names and executables.
12BIN_NAME := sprite2gba 12BIN_NAME := img2gba
13BUILD_DIR := build 13BUILD_DIR := build
14BIN := $(BUILD_DIR)/$(BIN_NAME) 14BIN := $(BUILD_DIR)/$(BIN_NAME)
15 15
diff --git a/sprite2gba/src/main.c b/img2gba/src/main.c
index f91ecd0..8a5edfc 100644
--- a/sprite2gba/src/main.c
+++ b/img2gba/src/main.c
@@ -6,8 +6,9 @@
6#include "stb_image.h" 6#include "stb_image.h"
7 7
8#define TILE_SIZE 8 8#define TILE_SIZE 8
9#define DEFAULT_PALETTE_SIZE 16 9#define PALETTE_SIZE 16
10#define DEFAULT_BG_COLOR 0x0000 10#define DEFAULT_BG_COLOR 0x0000
11#define MAX_FILE_NAME 1024
11 12
12typedef u16 Color; 13typedef u16 Color;
13 14
@@ -32,7 +33,7 @@ typedef struct Tiles {
32} Tiles; 33} Tiles;
33 34
34typedef struct Palette { 35typedef struct Palette {
35 Color *data; 36 Color data[PALETTE_SIZE];
36 size_t size; 37 size_t size;
37 size_t capacity; 38 size_t capacity;
38} Palette; 39} Palette;
@@ -48,22 +49,22 @@ u8
48pack_1bb(u32 hex) { 49pack_1bb(u32 hex) {
49 u32 low_nibble = hex & 0xFFFF; 50 u32 low_nibble = hex & 0xFFFF;
50 u32 high_nibble = (hex >> 16) & 0xFFFF; 51 u32 high_nibble = (hex >> 16) & 0xFFFF;
51 u32 low = (low_nibble & 0x1); 52 u32 low = ((low_nibble >> 12) & 0x1);
52 low += 2 * ((low_nibble >> 4) & 0x1); 53 low += 2 * ((low_nibble >> 8) & 0x1);
53 low += 4 * ((low_nibble >> 8) & 0x1); 54 low += 4 * ((low_nibble >> 4) & 0x1);
54 low += 8 * ((low_nibble >> 12) & 0x1); 55 low += 8 * ((low_nibble >> 0) & 0x1);
55 u32 high = (high_nibble & 0x1); 56 u32 high = ((high_nibble >> 12) & 0x1);
56 high += 2 * ((high_nibble >> 4) & 0x1); 57 high += 2 * ((high_nibble >> 8) & 0x1);
57 high += 4 * ((high_nibble >> 8) & 0x1); 58 high += 4 * ((high_nibble >> 4) & 0x1);
58 high += 8 * ((high_nibble >> 12) & 0x1); 59 high += 8 * ((high_nibble >> 0) & 0x1);
59 return (high << 4) | low; 60 return (low << 4) | high;
60} 61}
61 62
62void 63void
63export_c_file(Tiles *tiles, Palette *palette, FILE *file, bool pack_1bpp) { 64export_c_file(Tiles *tiles, Palette *palette, FILE *file, bool pack_1bpp) {
64 // Output tiles. 65 // Output tiles.
65 if (pack_1bpp) { 66 if (pack_1bpp) {
66 fprintf(file, "u32 packed_tiles[] = {\n "); 67 fprintf(file, "static const u32 packed_tiles[] = {\n ");
67 size_t counter = 0; 68 size_t counter = 0;
68 for (size_t i = 0; i < tiles->capacity; ++i) { 69 for (size_t i = 0; i < tiles->capacity; ++i) {
69 for (size_t j = 0; j < TILE_SIZE; j += 4, counter++) { 70 for (size_t j = 0; j < TILE_SIZE; j += 4, counter++) {
@@ -75,10 +76,10 @@ export_c_file(Tiles *tiles, Palette *palette, FILE *file, bool pack_1bpp) {
75 u32 tile_b = tiles->data[i][j + 1]; 76 u32 tile_b = tiles->data[i][j + 1];
76 u32 tile_c = tiles->data[i][j + 2]; 77 u32 tile_c = tiles->data[i][j + 2];
77 u32 tile_d = tiles->data[i][j + 3]; 78 u32 tile_d = tiles->data[i][j + 3];
78 u32 packed = pack_1bb(tile_d); 79 u32 packed = pack_1bb(tile_d) << 0;
79 packed |= pack_1bb(tile_c) << 8; 80 packed |= pack_1bb(tile_c) << 8;
80 packed |= pack_1bb(tile_b) << 16; 81 packed |= pack_1bb(tile_b) << 16;
81 packed |= pack_1bb(tile_a) << 24; 82 packed |= pack_1bb(tile_a) << 24;
82 fprintf(file, "0x%08x,", packed); 83 fprintf(file, "0x%08x,", packed);
83 if (counter < 3) { 84 if (counter < 3) {
84 fprintf(file, " "); 85 fprintf(file, " ");
@@ -88,7 +89,7 @@ export_c_file(Tiles *tiles, Palette *palette, FILE *file, bool pack_1bpp) {
88 fprintf(file, "\n};\n"); 89 fprintf(file, "\n};\n");
89 fprintf(file, "\n"); 90 fprintf(file, "\n");
90 } else { 91 } else {
91 fprintf(file, "u32 tiles[%lu][%u] = {\n", tiles->capacity, TILE_SIZE); 92 fprintf(file, "static const u32 tiles[%lu][%u] = {\n", tiles->capacity, TILE_SIZE);
92 for (size_t i = 0; i < tiles->capacity; ++i) { 93 for (size_t i = 0; i < tiles->capacity; ++i) {
93 fprintf(file, " {"); 94 fprintf(file, " {");
94 for (size_t j = 0; j < TILE_SIZE; ++j) { 95 for (size_t j = 0; j < TILE_SIZE; ++j) {
@@ -122,6 +123,36 @@ export_c_file(Tiles *tiles, Palette *palette, FILE *file, bool pack_1bpp) {
122} 123}
123 124
124void 125void
126export_bin_file(Tiles *tiles, Palette *palette, FILE *file, FILE *filepal, bool pack_1bpp) {
127 if (pack_1bpp) {
128 u64 counter = 0;
129 for (size_t i = 0; i < tiles->capacity; ++i) {
130 for (size_t j = 0; j < TILE_SIZE; j += 4, counter++) {
131 u32 tile_a = tiles->data[i][j];
132 u32 tile_b = tiles->data[i][j + 1];
133 u32 tile_c = tiles->data[i][j + 2];
134 u32 tile_d = tiles->data[i][j + 3];
135 u32 packed = pack_1bb(tile_a) << 0;
136 packed |= pack_1bb(tile_b) << 8;
137 packed |= pack_1bb(tile_c) << 16;
138 packed |= pack_1bb(tile_d) << 24;
139 fwrite(&packed, sizeof(u32), 1, file);
140 }
141 }
142 // Pad with zeros to avoid alignment issues.
143 if (counter) {
144 u32 zero = 0;
145 fwrite(&zero, sizeof(u32), counter % 8, file);
146 }
147 } else {
148 for (size_t i = 0; i < tiles->capacity; ++i) {
149 fwrite(&tiles->data[i][0], sizeof(u32), TILE_SIZE, file);
150 }
151 fwrite(palette->data, sizeof(u16), PALETTE_SIZE, filepal);
152 }
153}
154
155void
125extract_tile(Tiles *tiles, Palette *palette, Image *img, 156extract_tile(Tiles *tiles, Palette *palette, Image *img,
126 size_t offset_x, size_t offset_y) { 157 size_t offset_x, size_t offset_y) {
127 for (size_t j = 0; j < TILE_SIZE; ++j) { 158 for (size_t j = 0; j < TILE_SIZE; ++j) {
@@ -191,24 +222,24 @@ void
191print_usage(void) { 222print_usage(void) {
192 printf("Usage: %s [options] <filename>\n", BIN_NAME); 223 printf("Usage: %s [options] <filename>\n", BIN_NAME);
193 printf("\n"); 224 printf("\n");
194 printf("\t-b <RRGGBB>\tSelects the background color used for transparency.\n"); 225 printf("\t-b <RRGGBB> Selects the background color used for transparency.\n");
195 printf("\t-o <out_file.c>\tPath to the output file. If blank, stdout will be used.\n"); 226 printf("\t-o <out_file> Path to the output file. If blank, stdout will be used with C array export.\n");
196 printf("\t-x <0>\tStart x position (in pixels).\n"); 227 printf("\t-x <0> Start x position (in pixels).\n");
197 printf("\t-y <0>\tStart y position (in pixels).\n"); 228 printf("\t-y <0> Start y position (in pixels).\n");
198 printf("\t-W <8>\tSelect the sprite width in pixels. Must be a multiple of the tile size.\n"); 229 printf("\t-W <8> Select the sprite width in pixels. Must be a multiple of the tile size.\n");
199 printf("\t-H <8>\tSelect the sprite height in pixels. Must be a multiple of the tile size.\n"); 230 printf("\t-H <8> Select the sprite height in pixels. Must be a multiple of the tile size.\n");
200 printf("\t-1\tBit pack the output to 1bbp (4x size reduction).\n"); 231 printf("\t-1 Bit pack the output to 1bbp (4x size reduction).\n");
201 printf("\t-w <0>\tWidth of region to extract from (x0,y0). Defaults to image width.\n"); 232 printf("\t-w <0> Width of region to extract from (x0,y0). Defaults to image width.\n");
202 printf("\t-h <0>\tHeight of region to extract from (x0,y0). Defaults to image height.\n"); 233 printf("\t-h <0> Height of region to extract from (x0,y0). Defaults to image height.\n");
234 printf("\t-v Verbose mode\n");
203 printf("\n"); 235 printf("\n");
204} 236}
205 237
206// TODO: Support multiple files at once?
207int 238int
208main(int argc, char *argv[]) { 239main(int argc, char *argv[]) {
209 // Initialize default parameters. 240 // Initialize default parameters.
210 u16 background_color = DEFAULT_BG_COLOR; 241 u16 background_color = DEFAULT_BG_COLOR;
211 u16 palette_size = DEFAULT_PALETTE_SIZE; 242 u16 palette_size = PALETTE_SIZE;
212 size_t sprite_width = TILE_SIZE; 243 size_t sprite_width = TILE_SIZE;
213 size_t sprite_height = TILE_SIZE; 244 size_t sprite_height = TILE_SIZE;
214 char *out_file_path = NULL; 245 char *out_file_path = NULL;
@@ -217,9 +248,10 @@ main(int argc, char *argv[]) {
217 size_t start_y = 0; 248 size_t start_y = 0;
218 size_t width = 0; 249 size_t width = 0;
219 size_t height = 0; 250 size_t height = 0;
251 bool verbose = false;
220 252
221 int option; 253 int option;
222 while ((option = getopt(argc, argv, "b:o:W:H:1x:y:w:h:")) != -1) { 254 while ((option = getopt(argc, argv, "b:o:W:H:1x:y:w:h:v")) != -1) {
223 switch (option) { 255 switch (option) {
224 case 'b': { 256 case 'b': {
225 // Background color. 257 // Background color.
@@ -298,6 +330,9 @@ main(int argc, char *argv[]) {
298 // Height of region to extract from (x0,y0). 330 // Height of region to extract from (x0,y0).
299 height = atoi(optarg); 331 height = atoi(optarg);
300 } break; 332 } break;
333 case 'v': {
334 verbose = true;
335 } break;
301 default: { 336 default: {
302 print_usage(); 337 print_usage();
303 return EXIT_FAILURE; 338 return EXIT_FAILURE;
@@ -315,7 +350,6 @@ main(int argc, char *argv[]) {
315 350
316 // Fill the palette with the background color if one was given. 351 // Fill the palette with the background color if one was given.
317 Palette palette = { 352 Palette palette = {
318 .data = malloc(palette_size * sizeof(Color)),
319 .size = 1, 353 .size = 1,
320 .capacity = palette_size, 354 .capacity = palette_size,
321 }; 355 };
@@ -357,8 +391,6 @@ main(int argc, char *argv[]) {
357 .capacity = n_tiles, 391 .capacity = n_tiles,
358 }; 392 };
359 393
360 int offset_x = start_x;
361 int offset_y = start_y;
362 size_t n_sprites_x = width / sprite_width; 394 size_t n_sprites_x = width / sprite_width;
363 size_t n_sprites_y = height / sprite_height; 395 size_t n_sprites_y = height / sprite_height;
364 size_t n_sprite_tiles_x = sprite_width / TILE_SIZE; 396 size_t n_sprite_tiles_x = sprite_width / TILE_SIZE;
@@ -379,18 +411,42 @@ main(int argc, char *argv[]) {
379 if (out_file_path == NULL) { 411 if (out_file_path == NULL) {
380 export_c_file(&tiles, &palette, stdout, pack_1bpp); 412 export_c_file(&tiles, &palette, stdout, pack_1bpp);
381 } else { 413 } else {
382 FILE *file = fopen(out_file_path, "w"); 414 char file_name[MAX_FILE_NAME] = {0};
415 char file_name_pal[MAX_FILE_NAME] = {0};
416 strncpy(file_name, out_file_path, MAX_FILE_NAME - 1);
417 strncpy(file_name_pal, out_file_path, MAX_FILE_NAME - 1);
418 FILE *file = fopen(strcat(file_name, ".img.bin"), "w");
383 if (!file) { 419 if (!file) {
384 fprintf(stderr, "%s: can't open output file: %s\n", BIN_NAME, out_file_path); 420 fprintf(stderr, "%s: can't open output file: %s\n", BIN_NAME, file_name);
385 return EXIT_FAILURE; 421 return EXIT_FAILURE;
386 } 422 }
387 export_c_file(&tiles, &palette, file, pack_1bpp); 423 if (pack_1bpp) {
388 fclose(file); 424 export_bin_file(&tiles, &palette, file, NULL, pack_1bpp);
425 fclose(file);
426 if (verbose) {
427 printf("Exporting binary file (1bpp packed)\n");
428 printf("FILE IMG: %s\n", file_name);
429 }
430 } else {
431 FILE *file_pal = fopen(strcat(file_name_pal, ".pal.bin"), "w");
432 if (!file_pal) {
433 fprintf(stderr, "%s: can't open output file: %s\n", BIN_NAME, file_name_pal);
434 fclose(file);
435 return EXIT_FAILURE;
436 }
437 if (verbose) {
438 printf("Exporting binary file\n");
439 printf("FILE IMG: %s\n", file_name);
440 printf("FILE PAL: %s\n", file_name_pal);
441 }
442 export_bin_file(&tiles, &palette, file, file_pal, pack_1bpp);
443 fclose(file);
444 fclose(file_pal);
445 }
389 } 446 }
390 447
391 // Cleanup resources and exit. 448 // Cleanup resources and exit.
392 free(tiles.data); 449 free(tiles.data);
393 free(palette.data);
394 stbi_image_free(img.data); 450 stbi_image_free(img.data);
395 return EXIT_SUCCESS; 451 return EXIT_SUCCESS;
396} 452}
diff --git a/sprite2gba/src/shorthand.h b/img2gba/src/shorthand.h
index 9c2e2f0..9c2e2f0 100644
--- a/sprite2gba/src/shorthand.h
+++ b/img2gba/src/shorthand.h
diff --git a/sprite2gba/src/stb_image.h b/img2gba/src/stb_image.h
index accef48..3448d5f 100644
--- a/sprite2gba/src/stb_image.h
+++ b/img2gba/src/stb_image.h
@@ -4120,7 +4120,7 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
4120 if (s >= 16) return -1; // invalid code! 4120 if (s >= 16) return -1; // invalid code!
4121 // code size is s, so: 4121 // code size is s, so:
4122 b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; 4122 b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
4123 if (b >= sizeof (z->size)) return -1; // some data was corrupt somewhere! 4123 if ((size_t)b >= sizeof (z->size)) return -1; // some data was corrupt somewhere!
4124 if (z->size[b] != s) return -1; // was originally an assert, but report failure instead. 4124 if (z->size[b] != s) return -1; // was originally an assert, but report failure instead.
4125 a->code_buffer >>= s; 4125 a->code_buffer >>= s;
4126 a->num_bits -= s; 4126 a->num_bits -= s;
@@ -6777,6 +6777,8 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
6777 int stride; 6777 int stride;
6778 int out_size = 0; 6778 int out_size = 0;
6779 int delays_size = 0; 6779 int delays_size = 0;
6780 (void)out_size;
6781 (void)delays_size;
6780 memset(&g, 0, sizeof(g)); 6782 memset(&g, 0, sizeof(g));
6781 if (delays) { 6783 if (delays) {
6782 *delays = 0; 6784 *delays = 0;