diff options
| -rwxr-xr-x | build.sh | 30 | ||||
| -rwxr-xr-x | download-tilesets.sh | 12 | ||||
| -rwxr-xr-x | files-ppmtopng.sh | 9 | ||||
| -rwxr-xr-x | ppmtopng.sh | 14 | ||||
| -rw-r--r-- | src/gen_tiles.c | 26 | ||||
| -rw-r--r-- | src/main.c | 148 | ||||
| -rw-r--r-- | src/tilemap.c | 59 | ||||
| -rw-r--r-- | src/tilemap.h | 8 | ||||
| -rw-r--r-- | src/tiles.c | 76 | ||||
| -rw-r--r-- | src/tiles.h | 11 | ||||
| -rw-r--r-- | src/typedef.h | 2 | ||||
| -rw-r--r-- | src/wfc.c | 159 | ||||
| -rw-r--r-- | src/wfc.h | 18 | 
13 files changed, 327 insertions, 245 deletions
| @@ -2,12 +2,11 @@  cd ${0%/*} # go to project root -FLAGS="-Wall -Wextra -g -pedantic" +FLAGS="-std=c99 -Wall -Wextra -g -pedantic"  SRCD="src"  ODIR="obj"  BIN="bin"  FILES="files" -VALGRND=""  RUN=0  function __run__ { @@ -23,27 +22,38 @@ function __clean__ {      rm -rf $BIN      rm -rf $ODIR      rm -rf $FILES -    kill $( ps -q $$ -o pgid= ) # exit +    exit 0 +} + +function __setup__ { +    ./download-tilesets.sh $FILES +    exit 0 +} + +function __topng__ { +    ./ppmtopng.sh $FILES +    exit 0  }  set -xe +mkdir -p $BIN +mkdir -p $ODIR +mkdir -p $FILES +  if ! { [[ $# -eq 0 ]]; } 2> /dev/null  then      __$1__  fi -mkdir -p $BIN -mkdir -p $ODIR -mkdir -p $FILES - -gcc -c $SRCD/gen_tiles.c -o $ODIR/gen_tiles.o $FLAGS -DPATH=files/tilesets +gcc -c $SRCD/gen_tiles.c -o $ODIR/gen_tiles.o $FLAGS -DPATH=$FILES  gcc -c $SRCD/ppm.c       -o $ODIR/ppm.o       $FLAGS  gcc -c $SRCD/tilemap.c   -o $ODIR/tilemap.o   $FLAGS -gcc -c $SRCD/tiles.c     -o $ODIR/tiles.o     $FLAGS +gcc -c $SRCD/tiles.c     -o $ODIR/tiles.o     $FLAGS -DPATH=\"$FILES\" +gcc -c $SRCD/wfc.c       -o $ODIR/wfc.o       $FLAGS -DPATH=\"$FILES\"  gcc -c $SRCD/main.c      -o $ODIR/main.o      $FLAGS -gcc -o $BIN/wfc $ODIR/main.o $ODIR/ppm.o $ODIR/tiles.o $ODIR/tilemap.o $FLAGS +gcc -o $BIN/wfc $ODIR/main.o $ODIR/wfc.o $ODIR/tiles.o $ODIR/tilemap.o $ODIR/ppm.o $FLAGS  gcc -o $BIN/gen_tiles $ODIR/gen_tiles.o $FLAGS  if ! { [[ $RUN -eq 0 ]]; } 2> /dev/null diff --git a/download-tilesets.sh b/download-tilesets.sh index f6e477b..a97031b 100755 --- a/download-tilesets.sh +++ b/download-tilesets.sh @@ -2,14 +2,18 @@  cd ${0%/*} # go to project root +if [ $# -eq 0 ]; then +      echo "Please provide the path" +      exit 1 +fi +  URL="https://ftp.batnako.net/tilesets" +FILES=$1 -mkdir -p "files" -mkdir -p "files/tilesets" +mkdir -p "$FILES/tilesets"  function download { -    path="files/tilesets/$name" - +    path="$FILES/tilesets/$name"      rm -rf "$path"      mkdir "$path" diff --git a/files-ppmtopng.sh b/files-ppmtopng.sh deleted file mode 100755 index df33236..0000000 --- a/files-ppmtopng.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh - -cd ${0%/*} # go to project root -set -xe - -for i in files/file*.ppm -do -    pnmtopng "$i" >> "${i%.*}.png" -done diff --git a/ppmtopng.sh b/ppmtopng.sh new file mode 100755 index 0000000..f73dcd1 --- /dev/null +++ b/ppmtopng.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +cd ${0%/*} # go to project root + +if [ $# -eq 0 ]; then +      echo "Please provide the path" +      exit 1 +fi + +set -xe + +for i in $1/file*.ppm; do +    pnmtopng "$i" >> "${i/ppm/png}" +done diff --git a/src/gen_tiles.c b/src/gen_tiles.c index 5d6cba3..22b385f 100644 --- a/src/gen_tiles.c +++ b/src/gen_tiles.c @@ -1,40 +1,42 @@  #include <stdio.h>  #include <stdlib.h>  #include <string.h> -#include <sys/stat.h>  #include "typedef.h" +#define TILESET_NAME (STR(TILESET)) +  typedef struct tile {      char name[64];      char symetry;      small_t connections[SIDES_MAX];  } tile; -#include "config.h"  #define STR_AUX(a) #a  #define STR(a) STR_AUX(a) -#define TILESET_PATH(name) STR(../PATH/name/tileset.h) -// include the tileset header configuration +#define TILESET_PATH(name) STR(../PATH/tilesets/name/tileset.h) + +#include "config.h"  #include TILESET_PATH(TILESET) -#define TILESET_NAME STR(TILESET) +#define MKDIR_FILES_SLASH_TILES STR(mkdir PATH/tiles) +#define TILES_DOT_DAT STR(PATH/tiles/tiles.dat) +#define COMMAND STR(cp PATH/tilesets/%s/%s.ppm PATH/tiles/tile_%d.ppm)  void copy(char *tile_set, char *name, int n)  {      char command[512]; -    sprintf(command, "cp files/tilesets/%s/%s.ppm files/tiles/tile_%d.ppm", +    sprintf(command, COMMAND,              tile_set, name, n);      system(command);  }  void gen()  { -    system("mkdir files"); -    system("mkdir files/tiles"); +    system(MKDIR_FILES_SLASH_TILES); -    FILE *fp = fopen("files/tiles/tiles.dat", "wb"); +    FILE *fp = fopen(TILES_DOT_DAT, "wb");      if(!fp) { -        fprintf(stderr, "ERROR: Could not open file files/tiles/tiles.dat"); +        err("Could not open file: %s", TILES_DOT_DAT);          exit(EXIT_FAILURE);      } @@ -58,8 +60,8 @@ void gen()  int main(void)  { -    puts("INFO: Generating Tile Data"); +    info("Generating Tile Data");      gen(); -    puts("INFO: Successful"); +    info("INFO: Successful");      return 0;  } @@ -1,95 +1,9 @@  #include <stdio.h>  #include <stdlib.h>  #include <string.h> -#include <time.h> -#include <unistd.h> +#include <getopt.h>  #include "typedef.h" -#include "ppm.h" -#include "tiles.h" -#include "tilemap.h" - -// amount of different tiles and their rotations -size_t TILES; - -// width and height of a single tile -size_t TILE_WIDTH; -size_t TILE_HEIGHT; - -// width and height of the tilemap -// to generate -size_t SWIDTH  = 15; -size_t SHEIGHT = 15; - -time_t SEED; -size_t SCALE = 9; - -int get_least_entropy_index() -{ -    // array of indexes with the least entropy -    size_t least_entpy[TILEMAP_CAP]; -    size_t least_entpy_sz = 0; - -    for(size_t i = 0; i < SHEIGHT; i++) -    { -        for (size_t j = 0; j < SWIDTH; j++) -        { -            size_t index = i * SWIDTH + j; - -            if(least_entpy_sz == 0) { -                least_entpy[least_entpy_sz++] = index; -                continue; -            } - -            size_t b1s = count_entropy(index); -            size_t l1s = count_entropy(least_entpy[least_entpy_sz-1]); - -            if(b1s == l1s) { -                if(least_entpy_sz >= TILEMAP_CAP) exit(69); -                least_entpy[least_entpy_sz++] = index; -            } else if(b1s < l1s) { -                least_entpy[0] = index; -                least_entpy_sz = 1; -            } -        } -    } - -    return least_entpy[rand() % least_entpy_sz]; - -} - -void collapse_this(int i) -{ -    if(count_entropy(i) == 0) { -        err("No possible tiles for this position: %d\n", i); -        exit(EXIT_FAILURE); -    } - -    small_t possibilities[TILES]; -    size_t psz = 0; - -    for(size_t n = 0; n < TILES; n++) -        if(is_set(i, n)) possibilities[psz++] = n; - -    size_t t = possibilities[rand() % psz]; -    collapse(i, t); // collapse a random tile - -    // apply a bitmask, on tiles around the newly collapsed tile -    if(i / SWIDTH != 0) // up -        if(!(has_collapsed(i-SWIDTH))) -            mask(i-SWIDTH, t, 0); - -    if(i % SWIDTH != (SWIDTH - 1)) // right -        if(!(has_collapsed(i+1))) -            mask(i+1, t, 1); - -    if(i % SWIDTH != 0) // left -        if(!(has_collapsed(i-1))) -            mask(i-1, t, 2); - -    if(i / SWIDTH != (SHEIGHT - 1)) // down -        if(!(has_collapsed(i+SWIDTH))) -            mask(i+SWIDTH, t, 3); -} +#include "wfc.h"  void manage_arguments(int argc, char **argv)  { @@ -99,14 +13,14 @@ void manage_arguments(int argc, char **argv)          switch(opt)          {          case 'd': -            SWIDTH  = atoi(strtok(optarg, "x")); -            SHEIGHT = atoi(strtok(NULL, "x")); +            width  = atoll(strtok(optarg, "x")); +            height = atoll(strtok(NULL, "x"));              break;          case 's': -            SEED = atoi(optarg); +            SEED = atoll(optarg);              break;          case 'm': -            SCALE = atoi(optarg); +            SCALE = atoll(optarg);              break;          case 'h':          default: @@ -128,54 +42,22 @@ void manage_arguments(int argc, char **argv)  int main(int argc, char **argv)  { -    SEED = time(0); +    default_values(); +      manage_arguments(argc, argv);      srand(SEED); -    info("Starting With:\n\tWidth: %ld\n\tHeight: %ld\n\tSeed: %ld\n\tScale: %ld", SWIDTH, SHEIGHT, SEED, SCALE); - -    load_tiles(); -    info("Tiles Loaded"); -    init_tilemap(); -    info("Tilemap Initiated"); -    generate_tile_masks(get_tile_connections()); -    info("Tile Masks Generated"); +    info("Starting With:\n\tWidth: %ld\n\tHeight: %ld\n\tSeed: %ld\n\tScale: %ld", width, height, SEED, SCALE); -    // print_tiles(); -    // printf("%ld\n", TILES); - -    for(int lei = get_least_entropy_index(); !has_collapsed(lei); lei = get_least_entropy_index()) -        collapse_this(lei); +    init_wfc(); +    info("WFC Initialized"); +    wfc();      info("Tilemap Successfully Generated"); -    size_t  img_wdt = TILE_WIDTH  * SWIDTH; -    size_t  img_hgt = TILE_HEIGHT * SHEIGHT; -    small_t *image = malloc(img_wdt * img_hgt * 3); - -    for(size_t i = 0; i < SHEIGHT; i++) -    { -        for(size_t j = 0; j < SWIDTH; j++) -        { -            size_t t = get_collapsed_tile(i * SWIDTH + j); - -            for(size_t y = 0; y < TILE_HEIGHT; y++) -                for(size_t x = 0; x < TILE_WIDTH; x++) -                    for(int k = 0; k < 3; k++) -                        image[((y+(i*TILE_HEIGHT))*img_wdt+(x+(j*TILE_WIDTH)))*3 + k] = -                            get_tile_pixel(t, x, y, k); -        } -    } - -    free_tiles(); -    destroy_tilemap(); - -    char file_name[64] = {0}; - -    sprintf(file_name, "files/file_%ld.ppm", SEED); -    save_as_ppm(file_name, image, img_wdt, img_hgt, SCALE); -    info("Saved file with name: %s\n", file_name); +    save_wfc(); -    free(image); +    deinit_wfc(); +    info("WFC Deinitialized");      return 0;  } diff --git a/src/tilemap.c b/src/tilemap.c index df1c1c6..8cb78f9 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -7,12 +7,15 @@  #define MIN(x, y) (((x) < (y)) ? (x) : (y))  #define BIG_SZ (sizeof(big_t) * 8) -#define INDEX  (typeof(n))(n / BIG_SZ) -#define OFFSET (typeof(n))(n % BIG_SZ) +#define INDEX  ((__typeof(n))(n / BIG_SZ)) +#define OFFSET ((__typeof(n))(n % BIG_SZ)) +// from tiles.c  extern size_t TILES; -extern size_t SWIDTH; -extern size_t SHEIGHT; +extern small_t tile_connections[TILES_CAP][SIDES_MAX]; + +size_t SWIDTH; +size_t SHEIGHT;  big_t (*tilemap)[TILEMAP_CAP];  size_t tsz = 0; @@ -25,6 +28,27 @@ size_t tsz = 0;  // least significant bit is tile index 0  big_t (*tile_masks)[TILES_CAP][SIDES_MAX]; +void generate_tile_masks() +{ +    tile_masks = malloc(sizeof(big_t[tsz][TILES_CAP][SIDES_MAX])); +    memset(tile_masks, 0, sizeof(big_t[tsz][TILES_CAP][SIDES_MAX])); + +    for(size_t n = 0; n < TILES; n++) +    { +        for(size_t j = 0; j < TILES; j++) { +            for(size_t i = 0; i < SIDES; i++) { +                // current solution for circuits :( +                // if(n == j && (n == 3 || n == 4 || n == 5 || n ==6)) +                //     tile_masks[INDEX][j][i] |= (tc[n][3-i] != tc[j][i]) << OFFSET; +                // else if(n == j && (n == 7|| n == 8 || n == 9 || n == 10)) +                //     tile_masks[INDEX][j][i] |= 0 << OFFSET; +                // else +                    tile_masks[INDEX][j][i] |= (tile_connections[n][3-i] == tile_connections[j][i]) << OFFSET; +            } +        } +    } +} +  void set(int t, int n)  {      tilemap[INDEX][t] |= ((big_t)1 << OFFSET); @@ -35,8 +59,11 @@ int is_set(int t, int n)      return (tilemap[INDEX][t] >> OFFSET) & 1;  } -void init_tilemap() +void init_tilemap(size_t width, size_t height)  { +    SWIDTH  = width; +    SHEIGHT = height; +      tsz = (TILES/BIG_SZ) + 1;      tilemap = malloc(sizeof(big_t[tsz][TILEMAP_CAP])); @@ -44,6 +71,8 @@ void init_tilemap()      for(size_t n = 0; n < SWIDTH * SHEIGHT; n++)          for(size_t i = 0; i < tsz; i++)              tilemap[i][n] = (((big_t)1 << MIN(BIG_SZ, (TILES - (i*BIG_SZ)))) - 1); + +    generate_tile_masks();  }  void destroy_tilemap() @@ -90,26 +119,6 @@ void mask(int t, int m, int r)          tilemap[i][t] &= tile_masks[i][m][r];  } -void generate_tile_masks(small_t (*tc)[SIDES_MAX]) -{ -    tile_masks = malloc(sizeof(big_t[tsz][TILES_CAP][SIDES_MAX])); -    memset(tile_masks, 0, sizeof(big_t[tsz][TILES_CAP][SIDES_MAX])); - -    for(size_t n = 0; n < TILES; n++) -    { -        for(size_t j = 0; j < TILES; j++) { -            for(size_t i = 0; i < SIDES; i++) { -                // current solution for circuits :( -                // if(n == j && (n == 3 || n == 4 || n == 5 || n ==6)) -                //     tile_masks[INDEX][j][i] |= (tc[n][3-i] != tc[j][i]) << OFFSET; -                // else if(n == j && (n == 7|| n == 8 || n == 9 || n == 10)) -                //     tile_masks[INDEX][j][i] |= 0 << OFFSET; -                // else -                    tile_masks[INDEX][j][i] |= (tc[n][3-i] == tc[j][i]) << OFFSET; -            } -        } -    } -}  // void print_tilemap()  // {  //     printf("tsz: %ld\n", tsz); diff --git a/src/tilemap.h b/src/tilemap.h index 533c3d5..a8154e1 100644 --- a/src/tilemap.h +++ b/src/tilemap.h @@ -1,6 +1,9 @@  #ifndef TILEMAP_H  #define TILEMAP_H +extern size_t SWIDTH; +extern size_t SHEIGHT; +  // set bit n in tile t in tilemap  void set(int t, int n);  // is bit n set in tile t in tilemap @@ -15,10 +18,11 @@ size_t count_entropy(int t);  void init_tilemap();  void destroy_tilemap(); -void generate_tile_masks(small_t (*tile_connections)[SIDES_MAX]); -  // applly a mask m, r (from tile_masks)  // to tile t in tilemap  void mask(int t, int m, int r); +void print_tilemap(); + +  #endif diff --git a/src/tiles.c b/src/tiles.c index 0c31c05..61fa98f 100644 --- a/src/tiles.c +++ b/src/tiles.c @@ -4,12 +4,10 @@  #include "tiles.h"  #include "ppm.h" -extern size_t TILES; +size_t TILES; +size_t TILE_WIDTH; +size_t TILE_HEIGHT; -extern size_t TILE_WIDTH; -extern size_t TILE_HEIGHT; - -small_t DIMENTIONS = 0;  small_t *(tiles[TILES_CAP]);  small_t tile_connections[TILES_CAP][SIDES_MAX]; @@ -46,43 +44,29 @@ static void rotate_connections(small_t (*tc)[SIDES_MAX], int i, int n, int r)              tile_connections[n][y*2 + x] = tc[i][rotate(x, y, r, 2)];  } -static void load_tile_data(small_t (*tc)[SIDES_MAX], char *ts, size_t *tid) -{ -    char file_path[32] = "files/tiles/tiles.dat"; -    FILE *fp = fopen(file_path, "rb"); -    if(!fp) { -        err("Could not open file: %s\n", file_path); -        exit(EXIT_FAILURE); -    } - -    fread(&DIMENTIONS, sizeof(DIMENTIONS), 1, fp); -    fread(tid, sizeof(size_t), 1, fp); - -    for(size_t i = 0; i < *tid; i++) { -        fread(tc[i], sizeof(small_t), SIDES, fp); -        fread(&(ts[i]), sizeof(char), 1, fp); -    } - -    fclose(fp); -} - -void load_tiles() +void load_tiles(FILE *fp)  {      size_t tid = 0;      small_t tile_con[TILES_CAP][SIDES_MAX] = {0};      char tile_sym[TILES_CAP]; -    load_tile_data(tile_con, tile_sym, &tid); +    fread(&tid, sizeof(size_t), 1, fp);      if(tid == 0) { -        fprintf(stderr, "ERROR: No tiles could be loaded\n"); +        err("Tiles could not be loaded");          exit(EXIT_FAILURE);      } +    for(size_t i = 0; i < tid; i++) { +        fread(tile_con[i], sizeof(small_t), SIDES, fp); +        fread(&(tile_sym[i]), sizeof(char), 1, fp); +    } + +      size_t n = 0;      for(size_t i = 0; i < tid; i++, n++)      {          char file_path[128]; -        sprintf(file_path, "files/tiles/tile_%ld.ppm", i); +        sprintf(file_path, "%s/tiles/tile_%ld.ppm", PATH, i);          char *t = load_from_ppm(file_path, &TILE_WIDTH, &TILE_HEIGHT);          switch(tile_sym[i]) @@ -134,23 +118,23 @@ void free_tiles()          free(tiles[i]);  } -void print_tiles() -{ -    for(size_t i = 0; i < TILES; i++) -    { -        printf("Tile: %ld\n", i); -        for(int n = 0; n < 4; n++) { -            printf("%d", tile_connections[i][n]); -        } printf("\n"); -        for(size_t y = 0; y < TILE_HEIGHT; y++) -        { -            for(size_t x = 0; x < TILE_WIDTH; x++) -                putchar((tiles[i][(y * TILE_WIDTH + x)*3 + 0]) == 0 ? '#' : '.'); -            putchar('\n'); -        } -        putchar('\n'); -    } -} +// void print_tiles() +// { +//     for(size_t i = 0; i < TILES; i++) +//     { +//         printf("Tile: %ld\n", i); +//         for(int n = 0; n < 4; n++) { +//             printf("%d", tile_connections[i][n]); +//         } printf("\n"); +//         for(size_t y = 0; y < TILE_HEIGHT; y++) +//         { +//             for(size_t x = 0; x < TILE_WIDTH; x++) +//                 putchar((tiles[i][(y * TILE_WIDTH + x)*3 + 0]) == 0 ? '#' : '.'); +//             putchar('\n'); +//         } +//         putchar('\n'); +//     } +// }  int get_tile_pixel(size_t t, size_t x, size_t y, int k)  { diff --git a/src/tiles.h b/src/tiles.h index 6a4a223..ce67ea5 100644 --- a/src/tiles.h +++ b/src/tiles.h @@ -1,10 +1,15 @@  #ifndef TILES_H  #define TILES_H -void load_tiles(); -void free_tiles(); +extern size_t TILES; +extern size_t TILE_WIDTH; +extern size_t TILE_HEIGHT; + +extern small_t tile_connections[TILES_CAP][SIDES_MAX]; +extern small_t *(tiles[]); -void print_tiles(); +void load_tiles(FILE *fp); +void free_tiles();  int get_tile_pixel(size_t t, size_t x, size_t y, int k);  small_t (*get_tile_connections())[SIDES_MAX]; diff --git a/src/typedef.h b/src/typedef.h index 5dff622..8189240 100644 --- a/src/typedef.h +++ b/src/typedef.h @@ -1,7 +1,7 @@  #ifndef TYPEDEF_H  #define TYPEDEF_H -// useful definitions +// useful definition  #include <stdint.h>  #include <stddef.h>  typedef unsigned char small_t; diff --git a/src/wfc.c b/src/wfc.c new file mode 100644 index 0000000..e12d6de --- /dev/null +++ b/src/wfc.c @@ -0,0 +1,159 @@ +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include "typedef.h" +#include "wfc.h" +#include "tilemap.h" +#include "tiles.h" +#include "ppm.h" + +small_t DIMENTIONS; + +size_t width; +size_t height; + +size_t SEED; +size_t SCALE; + +void default_values() +{ +    SEED = time(0); +    width = 15; +    height = 15; +    SCALE = 9; +} + +int get_least_entropy_index() +{ +    // array of indexes with the least entropy +    size_t least_entpy[TILEMAP_CAP]; +    size_t least_entpy_sz = 0; + +    for(size_t i = 0; i < SHEIGHT; i++) +    { +        for (size_t j = 0; j < SWIDTH; j++) +        { +            size_t index = i * SWIDTH + j; + +            if(least_entpy_sz == 0) { +                least_entpy[least_entpy_sz++] = index; +                continue; +            } + +            size_t b1s = count_entropy(index); +            size_t l1s = count_entropy(least_entpy[least_entpy_sz-1]); + +            if(b1s == l1s) { +                if(least_entpy_sz >= TILEMAP_CAP) exit(69); +                least_entpy[least_entpy_sz++] = index; +            } else if(b1s < l1s) { +                least_entpy[0] = index; +                least_entpy_sz = 1; +            } +        } +    } + +    return least_entpy[rand() % least_entpy_sz]; + +} + +void collapse_this(int i) +{ +    if(count_entropy(i) == 0) { +        err("No possible tiles for this position: %d\n", i); +        exit(EXIT_FAILURE); +    } + +    small_t possibilities[TILES]; +    size_t psz = 0; + +    for(size_t n = 0; n < TILES; n++) +        if(is_set(i, n)) possibilities[psz++] = n; + +    size_t t = possibilities[rand() % psz]; +    collapse(i, t); // collapse a random tile + +    // apply a bitmask, on tiles around the newly collapsed tile +    if(i / SWIDTH != 0) // up +        if(!(has_collapsed(i-SWIDTH))) +            mask(i-SWIDTH, t, 0); + +    if(i % SWIDTH != (SWIDTH - 1)) // right +        if(!(has_collapsed(i+1))) +            mask(i+1, t, 1); + +    if(i % SWIDTH != 0) // left +        if(!(has_collapsed(i-1))) +            mask(i-1, t, 2); + +    if(i / SWIDTH != (SHEIGHT - 1)) // down +        if(!(has_collapsed(i+SWIDTH))) +            mask(i+SWIDTH, t, 3); +} + +void wfc() +{ +    for(int lei = get_least_entropy_index(); !has_collapsed(lei); lei = get_least_entropy_index()) +        collapse_this(lei); +} + +void save_wfc() +{ +    size_t  img_wdt = TILE_WIDTH  * SWIDTH; +    size_t  img_hgt = TILE_HEIGHT * SHEIGHT; +    small_t *image = malloc(img_wdt * img_hgt * 3); + +    for(size_t i = 0; i < SHEIGHT; i++) +    { +        for(size_t j = 0; j < SWIDTH; j++) +        { +            size_t t = get_collapsed_tile((i * SWIDTH) + j); + +            for(size_t y = 0; y < TILE_HEIGHT; y++) +                for(size_t x = 0; x < TILE_WIDTH; x++) +                    for(int k = 0; k < 3; k++) +                        image[((y+(i*TILE_HEIGHT))*img_wdt+ +                               (x+(j*TILE_WIDTH)))*3 + k] = +                            get_tile_pixel(t, x, y, k); +        } +    } + + + +    char file_name[128] = {0}; +    sprintf(file_name, "%s/file_%ld.ppm", PATH, SEED); + +    save_as_ppm(file_name, image, img_wdt, img_hgt, SCALE); +    info("Saved file with name: %s", file_name); + +    free(image); +} + +void init_wfc() +{ +    FILE *fp = fopen("files/tiles/tiles.dat", "rb"); +    if(!fp) { +        err("Could not open file: %s\n", "files/tiles/tiles.dat"); +        exit(EXIT_FAILURE); +    } + +    fread(&DIMENTIONS, sizeof(DIMENTIONS), 1, fp); + +    load_tiles(fp); +    info("Tiles Loaded"); + +    //load_rules(fp); +    //info("Tile Rules Loaded"); + +    fclose(fp); + +    init_tilemap(width, height); +    info("Tilemap Initialized"); +} + + +void deinit_wfc() +{ +    free_tiles(); +    destroy_tilemap(); +} diff --git a/src/wfc.h b/src/wfc.h new file mode 100644 index 0000000..529b0d5 --- /dev/null +++ b/src/wfc.h @@ -0,0 +1,18 @@ +#ifndef WFC_H +#define WFC_H + +extern size_t width; +extern size_t height; + +extern size_t SEED; +extern size_t SCALE; + +void default_values(); + +void init_wfc(); +void deinit_wfc(); + +void wfc(); +void save_wfc(); + +#endif | 
