// wfctool // // Author: Krystian Samp (samp.krystian at gmail.component) // License: MIT // Version: 0.01 // // Wave Function Collapse command-line tool based on khuwfc. The tool // can be used to generate WFC images. // // COMPILING // ============================================================================= // // wfctool depends on stb_image.h and stb_write.h. Place both files in the // same directory as wfctool.c. // // make // ./wfc // // Run ./wfc to see available options // // // Basic usage: // // ./wfc -m overlapping -w 128 -h 128 input.png output.png // // // THANKS // ============================================================================= // // Thanks for using wfctool. If you find any bugs, have questions, or miss // a feature please let me know. Also, if you'd like to share your works // it's very appreciated. Please use my email at the top of the file. // #include #define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image.h" #include "stb_image_write.h" #define WFC_IMPLEMENTATION #define WFC_USE_STB #include "wfc.h" void print_summary(struct wfc *wfc, const char *input_image, const char *output_image) { printf("\n"); printf("method: %s\n", wfc->method == WFC_METHOD_OVERLAPPING ? "overlapping" : "tiled"); printf("seed: %u\n\n", wfc->seed); printf("input image: %s\n", input_image); printf("input size: %dx%d\n", wfc->image->width, wfc->image->height); printf("input components: %d\n", wfc->image->component_cnt); printf("tile size: %dx%d\n", wfc->tile_width, wfc->tile_height); printf("expand input: %d\n", wfc->expand_input); printf("xflip tiles: %d\n", wfc->xflip_tiles); printf("yflip tiles: %d\n", wfc->yflip_tiles); printf("rotate tiles: %d\n", wfc->rotate_tiles); printf("tile count: %d\n", wfc->tile_cnt); printf("\n"); printf("output image: %s\n", output_image); printf("output size: %dx%d\n", wfc->output_width, wfc->output_height); printf("cell count: %d\n", wfc->cell_cnt); printf("\n"); } void usage(const char *program_name, int exit_code) { if (exit_code != EXIT_SUCCESS) { printf("Wrong input\n\n"); } printf("\ Wave Function Collapse image generator.\ \n\n\ "); printf("\ Usage:\n\ %s -m METHOD [OPTIONS] input_image output_image\n\n", program_name); printf("\ Following options are available:\n\n\ -m METHOD, --method=METHOD Must be 'overlapping'\n\ -w num, --width=num Output width in pixels\n\ -h num, --height=num Output height in pixels\n\ -W num, --tile-width=num Tile width in pixels\n\ -H num, --tile-height=num Tile height in pixels\n\ -e 0|1, --expand-image=0|1 Wrap input image on right and bottom\n\ -x 0|1, --xflip=0|1 Add horizontal flips of all tiles\n\ -y 0|1, --yflip=0|1 Add vertical flips of all tiles\n\ -r 0|1, --rotate=0|1 Add n*90deg rotations of all tiles\n\ \n\ "); printf("\ The only supported METHOD at the moment is the 'overlapping' method.\n\n"); printf("\ Example:\n\ ./wfc -m overlapping -w 128 -h 128 -W 3 -H 3 -e 1 -x 1 -y 1 -r 1 plant.png output.png\n\n\ "); exit(exit_code); } int arg_method(int argc, const char **argv, int *i, enum wfc__method *method) { if (strcmp(argv[*i], "-m")==0) { (*i)++; if (*i==argc || strcmp(argv[*i], "overlapping")!=0) { usage(argv[0], EXIT_FAILURE); } (*i)++; *method = WFC_METHOD_OVERLAPPING; return 0; } else if (strcmp(argv[*i], "--method=overlapping")==0) { *method = WFC_METHOD_OVERLAPPING; (*i)++; return 0; } return -1; } int arg_num(int argc, const char **argv, int *i, const char *short_name, const char *long_name, int *num) { int n; char str[128]; sprintf(str, "-%s", short_name); if (strcmp(argv[*i], str)==0) { (*i)++; if (*i==argc) { usage(argv[0], EXIT_FAILURE); } if (sscanf(argv[*i], "%d", &n) != 1) { usage(argv[0], EXIT_FAILURE); } (*i)++; *num = n; return 0; } else { sprintf(str, "--%s=%%d", long_name); if (sscanf(argv[*i], str, &n) != 1) { return -1; } (*i)++; *num = n; return 0; } } // Can terminate the program if the arguments are incorrect void read_args(int argc, const char **argv, enum wfc__method *method, const char **input, const char **output, int *width, int *height, int *tile_width, int *tile_height, int *expand_image, int *xflip_tiles, int *yflip_tiles, int *rotate_tiles) { if (argc<2) { usage(argv[0], EXIT_FAILURE); } *method = 99999; int i=1; while (i