diff --git a/README.md b/README.md index 5c6d70b..1d1c85b 100644 --- a/README.md +++ b/README.md @@ -174,10 +174,11 @@ It primarily is used for the TI-84+CE and related calculator series, however can : of 16 pixels. Tile numbers are determined : starting from the top left, moving right : to the bottom-right. - : Another optional boolean field is - : 'pointer-table', which will output - : pointers to each tile. - : Default is 'true'. + : Optional fields are: + : 'tile-rotate': rotate tiles 90, 180, 270. + : 'tile-flip-x': flip tiles across x axis. + : 'tile-flip-y': flip tiles across y axis. + : 'pointer-table': output tile pointers transparent-index: : Transparent color index in the palette : that represents a transparent color. diff --git a/src/convert.c b/src/convert.c index cb3ec53..59b09cc 100644 --- a/src/convert.c +++ b/src/convert.c @@ -34,6 +34,7 @@ #include "memory.h" #include "tileset.h" #include "log.h" +#include "image.h" #include #include @@ -68,6 +69,9 @@ struct convert *convert_alloc(void) convert->nr_tilesets = 0; convert->tile_height = 0; convert->tile_width = 0; + convert->tile_rotate = 0; + convert->tile_flip_x = false; + convert->tile_flip_y = false; convert->p_table = true; return convert; @@ -342,7 +346,7 @@ static int convert_image(struct convert *convert, struct image *image) } image->uncompressed_size = image->data_size; - + if (convert->compress != COMPRESS_NONE) { if (image_compress(image, convert->compress)) @@ -395,7 +399,7 @@ static int convert_tileset(struct convert *convert, struct tileset *tileset) uint32_t tile_data_size = tile_dim * sizeof(uint32_t); uint32_t tile_stride = tileset->tile_width * sizeof(uint32_t); uint32_t image_stride = tileset->image.width * sizeof(uint32_t); - uint8_t *tile_data; + void *tile_data; uint8_t *dst; tile_data = memory_alloc(tile_data_size); @@ -425,6 +429,48 @@ static int convert_tileset(struct convert *convert, struct tileset *tileset) dst += tile_stride; } + if (tileset->tile_flip_x) + { + image_flip_x(tile_data, tile.width, tile.height); + } + + if (tileset->tile_flip_y) + { + image_flip_y(tile_data, tile.width, tile.height); + } + + switch (tileset->tile_rotate) + { + default: + case 0: + break; + + case 90: + tile.width = tileset->tile_height; + tile.height = tileset->tile_width; + if (image_rotate_90(tile_data, tile.width, tile.height)) + { + goto error; + } + break; + + case 180: + image_flip_y(tile_data, tile.width, tile.height); + image_flip_x(tile_data, tile.width, tile.height); + break; + + case 270: + tile.width = tileset->tile_height; + tile.height = tileset->tile_width; + if (image_rotate_90(tile_data, tile.width, tile.height)) + { + goto error; + } + image_flip_y(tile_data, tile.width, tile.height); + image_flip_x(tile_data, tile.width, tile.height); + break; + } + x += tile_stride; if (x >= image_stride) @@ -435,6 +481,7 @@ static int convert_tileset(struct convert *convert, struct tileset *tileset) if (convert_image(convert, &tile)) { +error: free(tile.data); return -1; } @@ -468,7 +515,7 @@ int convert_generate(struct convert *convert, struct palette **palettes, uint32_ for (uint32_t i = 0; i < convert->nr_images; ++i) { struct image *image = &convert->images[i]; - + /* assign image constants from convert */ image->quantize_speed = convert->quantize_speed; image->dither = convert->dither; @@ -524,6 +571,9 @@ int convert_generate(struct convert *convert, struct palette **palettes, uint32_ /* assign tileset constants from convert */ tileset->tile_height = convert->tile_height; tileset->tile_width = convert->tile_width; + tileset->tile_rotate = convert->tile_rotate; + tileset->tile_flip_x = convert->tile_flip_x; + tileset->tile_flip_y = convert->tile_flip_y; tileset->p_table = convert->p_table; /* assign image constants from convert */ diff --git a/src/convert.h b/src/convert.h index a691422..453f5c8 100644 --- a/src/convert.h +++ b/src/convert.h @@ -74,6 +74,9 @@ struct convert bool add_width_height; bool flip_x; bool flip_y; + uint32_t tile_rotate; + bool tile_flip_x; + bool tile_flip_y; bpp_t bpp; }; diff --git a/src/image.c b/src/image.c index c99bcfd..d05c748 100644 --- a/src/image.c +++ b/src/image.c @@ -46,7 +46,7 @@ static void swap_pixel(uint32_t *a, uint32_t *b) *b = temp; } -static void image_flip_y(uint32_t *data, uint32_t width, uint32_t height) +void image_flip_y(uint32_t *data, uint32_t width, uint32_t height) { for (uint32_t r = 0; r < height; ++r) { @@ -60,7 +60,7 @@ static void image_flip_y(uint32_t *data, uint32_t width, uint32_t height) } } -static void image_flip_x(uint32_t *data, uint32_t width, uint32_t height) +void image_flip_x(uint32_t *data, uint32_t width, uint32_t height) { for (uint32_t c = 0; c < width; ++c) { @@ -72,7 +72,7 @@ static void image_flip_x(uint32_t *data, uint32_t width, uint32_t height) } } -static int image_rotate_90(uint32_t *data, uint32_t width, uint32_t height) +int image_rotate_90(uint32_t *data, uint32_t width, uint32_t height) { uint32_t *new_data; uint32_t data_size; @@ -323,7 +323,7 @@ int image_set_bpp(struct image *image, bpp_t bpp, uint32_t nr_palette_entries) shift_mult = 1; inc = 8; break; - + case BPP_2: if (nr_palette_entries > 4) { @@ -422,7 +422,7 @@ int image_remove_omits(struct image *image, const uint8_t *omit_indices, uint32_ } for (uint32_t i = 0; i < image->data_size; ++i) - { + { for (uint32_t j = 0; j < nr_omit_indices; ++j) { if (image->data[i] == omit_indices[j]) @@ -665,7 +665,7 @@ int image_direct_convert(struct image *image, color_format_t fmt) *dst++ = target & 255; *dst++ = (target >> 8) & 255; break; - + case COLOR_565_BGR: target = color_to_565_bgr(&color); *dst++ = target & 255; diff --git a/src/image.h b/src/image.h index 3689387..bc46557 100644 --- a/src/image.h +++ b/src/image.h @@ -91,6 +91,12 @@ int image_direct_convert(struct image *image, color_format_t fmt); void image_free(struct image *image); +void image_flip_y(uint32_t *data, uint32_t width, uint32_t height); + +void image_flip_x(uint32_t *data, uint32_t width, uint32_t height); + +int image_rotate_90(uint32_t *data, uint32_t width, uint32_t height); + #ifdef __cplusplus } #endif diff --git a/src/options.c b/src/options.c index b057709..481af1e 100644 --- a/src/options.c +++ b/src/options.c @@ -213,10 +213,11 @@ static void options_show(const char *prgm) LOG_PRINT(" : of 16 pixels. Tile numbers are determined\n"); LOG_PRINT(" : starting from the top left, moving right\n"); LOG_PRINT(" : to the bottom-right.\n"); - LOG_PRINT(" : Another optional boolean field is\n"); - LOG_PRINT(" : \'pointer-table\', which will output\n"); - LOG_PRINT(" : pointers to each tile.\n"); - LOG_PRINT(" : Default is \'true\'.\n"); + LOG_PRINT(" : Optional fields are:\n"); + LOG_PRINT(" : \'tile-rotate\': rotate tiles 90, 180, 270.\n"); + LOG_PRINT(" : \'tile-flip-x\': flip tiles across x axis.\n"); + LOG_PRINT(" : \'tile-flip-y\': flip tiles across y axis.\n"); + LOG_PRINT(" : \'pointer-table\': output tile pointers\n"); LOG_PRINT("\n"); LOG_PRINT(" transparent-index: : Transparent color index in the palette\n"); LOG_PRINT(" : that represents a transparent color.\n"); @@ -457,7 +458,7 @@ static int options_clean(const char *path) LOG_ERROR("Clean failed.\n"); return -1; } - + LOG_INFO("Clean complete.\n"); return 0; diff --git a/src/parser.c b/src/parser.c index e656a33..5d835c9 100644 --- a/src/parser.c +++ b/src/parser.c @@ -874,6 +874,25 @@ static int parse_convert_tilesets(struct convert *convert, yaml_document_t *doc, { convert->p_table = parse_str_bool(value); } + else if (parse_str_cmp("tile-rotate", key)) + { + int tmpi = strtol(value, NULL, 10); + if (tmpi != 0 && tmpi != 90 && tmpi != 180 && tmpi != 270) + { + LOG_ERROR("Invalid rotate parameter, must be 0, 90, 180, or 270.\n"); + parser_show_mark_error(keyn->start_mark); + return -1; + } + convert->tile_rotate = tmpi; + } + else if (parse_str_cmp("tile-flip-x", key)) + { + convert->tile_flip_x = parse_str_bool(value); + } + else if (parse_str_cmp("tile-flip-y", key)) + { + convert->tile_flip_y = parse_str_bool(value); + } else if (parse_str_cmp("images", key)) { if (parse_convert_tilesets_images(convert, doc, valuen)) @@ -1680,7 +1699,7 @@ int parser_open(struct yaml *yaml, const char *path) { ret = parser_validate(yaml); } - + return ret; } diff --git a/src/tileset.h b/src/tileset.h index d101ae5..c3b21cb 100644 --- a/src/tileset.h +++ b/src/tileset.h @@ -62,6 +62,9 @@ struct tileset bool gfx; bool compressed; bool bad_alpha; + uint32_t tile_rotate; + bool tile_flip_x; + bool tile_flip_y; /* set by output */ uint32_t appvar_index;