pietp

Piet code painter
git clone https://git.sinitax.com/sinitax/pietp
Log | Files | Refs | LICENSE | sfeed.txt

commit 84c1e75aa8eaefbaaf853ca3c4edb48301989189
parent 60b74531aa329e626650a4e0ecdcfd99d984e037
Author: Louis Burda <quent.burda@gmail.com>
Date:   Sun, 25 Sep 2022 18:36:05 +0200

Add flags and improve debug output

Diffstat:
Mpietp.c | 156++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
1 file changed, 111 insertions(+), 45 deletions(-)

diff --git a/pietp.c b/pietp.c @@ -10,13 +10,6 @@ #define ARRLEN(x) (sizeof(x)/sizeof((x)[0])) -uint32_t colors[] = { - 0xffc0c0, 0xffffc0, 0xc0ffc0, 0xc0ffff, 0xc0c0ff, 0xffc0ff, - 0xff0000, 0xffff00, 0x00ff00, 0x00ffff, 0x0000ff, 0xff00ff, - 0xc00000, 0xc0c000, 0x00c000, 0x00c0c0, 0x0000c0, 0xc000c0, - 0xffffff -}; - enum { PUSH, POP, @@ -34,10 +27,39 @@ enum { INN, INC, OUTN, - OUTC + OUTC, + NONE +}; + +static const char *inst_names[] = { + "PUSH", + "POP", + "ADD", + "SUB", + "MUL", + "DIV", + "MOD", + "NOT", + "GTR", + "DPI", + "CCI", + "DUP", + "ROLL", + "INN", + "INC", + "OUTN", + "OUTC", + "" +}; + +static const uint32_t colors[] = { + 0xffc0c0, 0xffffc0, 0xc0ffc0, 0xc0ffff, 0xc0c0ff, 0xffc0ff, + 0xff0000, 0xffff00, 0x00ff00, 0x00ffff, 0x0000ff, 0xff00ff, + 0xc00000, 0xc0c000, 0x00c000, 0x00c0c0, 0x0000c0, 0xc000c0, + 0x000000, 0xffffff }; -int instiructions[][2] = { +static const int instructions[][2] = { [PUSH] = { 0, 1 }, [POP] = { 0, 2 }, [ADD] = { 1, 0 }, @@ -57,20 +79,40 @@ int instiructions[][2] = { [OUTC] = { 5, 2 }, }; -int piet_code[] = { +static const int piet_code[] = { PUSH, PUSH, ADD, DUP, DUP, MUL, DUP, DUP, MUL, MUL, MUL, // 128 PUSH, PUSH, ADD, DUP, MUL, DUP, MUL, SUB, // 112 PUSH, PUSH, ADD, PUSH, ADD, ADD, // 115 - OUTC + DUP, DUP, OUTC, + PUSH, PUSH, ADD, DUP, MUL, SUB, PUSH, SUB, // 110 + DUP, OUTC, + PUSH, PUSH, ADD, ADD, OUTC }; +static int debug = 0; + +const char * +dirstr(int dx, int dy) +{ + if (dx > 0) + return "+X"; + else if (dx < 0) + return "-X"; + else if (dy > 0) + return "+Y"; + else if (dy < 0) + return "-Y"; + else + return "O"; +} + int nextcolor(int prev, int insti) { int x, y; - x = ((prev % 6) + 6 + instiructions[insti][0]) % 6; - y = ((prev / 6) + 3 + instiructions[insti][1]) % 3; + x = ((prev % 6) + 6 + instructions[insti][0]) % 6; + y = ((prev / 6) + 3 + instructions[insti][1]) % 3; return y * 6 + x; } @@ -85,23 +127,39 @@ setrgb(uint8_t *pix, int stride, int x, int y, int color) int main(int argc, const char **argv) { - uint8_t *dir_map, *vis_map; + uint8_t *map, *vis; uint8_t *pix; + const char *mappath; int width, height; - int insti, x, y; - int dx, dy; + int insti, nexti; + int x, y, dx, dy; + int color, nextc; int rotonce; - int color; + int i; + + mappath = NULL; + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-d")) + debug = 1; + else if (!strcmp(argv[i], "-h")) + errx(0, "pietp [-h] [-d] [MAP-IMAGE]"); + else if (mappath) + errx(1, "More than one map specified\n"); + else + mappath = argv[i]; + } - if (argc != 2) { - fprintf(stderr, "Usage: pietp MAP-IMAGE"); - exit(1); + if (mappath) { + map = stbi_load(mappath, &width, &height, NULL, STBI_grey); + if (!map) errx(1, "Failed to read image"); + } else { + map = calloc(width * height, 1); + if (!map) err(1, "calloc"); } - dir_map = stbi_load(argv[1], &width, &height, NULL, STBI_grey); - vis_map = calloc(1, width * height); - pix = calloc(1, width * height * 3); - if (!pix || !vis_map) err(1, "malloc"); + vis = calloc(width * height, 1); + pix = calloc(width * height, 3); + if (!pix || !vis) err(1, "malloc"); dx = 1; dy = 0; @@ -112,37 +170,44 @@ main(int argc, const char **argv) insti = 0; while (1) { - if (vis_map[y * width + x]) { + if (vis[y * width + x]) { if (insti >= ARRLEN(piet_code)) break; - fprintf(stderr, "Overlapping code! %i/%li %i,%i\n", - insti, ARRLEN(piet_code), x, y); + fprintf(stderr, "Overlap! Code remaining: %i/%li\n", + insti, ARRLEN(piet_code)); exit(1); } /* write color to image */ - if (dir_map[y * width + x] == 0xC0) - color = nextcolor(color, PUSH); - else if (dir_map[y * width + x] == 0x80) - color = nextcolor(color, DPI); - else if (dir_map[y * width + x] == 0x40) - color = color; /* keep color */ - else if (insti < ARRLEN(piet_code)) - color = nextcolor(color, piet_code[insti++]); - else - color = color; /* keep color */ - setrgb(pix, width * 3, x, y, color); - vis_map[y * width + x] = 1; - printf("%i %i (%i %i) %i\n", x, y, dx, dy, color); + if (map[y * width + x] == 0xC0) { + nexti = PUSH; + nextc = nextcolor(color, nexti); + } else if (map[y * width + x] == 0x80) { + nexti = DPI; + nextc = nextcolor(color, nexti); + } else if (map[y * width + x] == 0x40) { + nexti = NONE; + nextc = color; + } else if (insti < ARRLEN(piet_code)) { + nexti = piet_code[insti++]; + nextc = nextcolor(color, nexti); + } else { + nexti = NONE; + nextc = color; + } + setrgb(pix, width * 3, x, y, nextc); + vis[y * width + x] = 1; + if (debug) printf("[%3i,%3i]: %06X -> %06X | %4s\n", x, y, + colors[color], colors[nextc], inst_names[nexti]); /* rotate until free */ rotonce = 0; while (x + dx < 0 || x + dx >= width || y + dy < 0 || y + dy >= height - || dir_map[y * width + x] == 0x80 && !rotonce - || dir_map[(y + dy) * width + x + dx] == 0) + || map[y * width + x] == 0x80 && !rotonce + || map[(y + dy) * width + x + dx] == 0) { - printf("ROT %i %i (%i %i) %i\n", x, y, dx, dy, color); + if (debug) printf("ROTATE %s ->", dirstr(dx, dy)); if (dx != 0) { dy = dx; dx = 0; @@ -150,6 +215,7 @@ main(int argc, const char **argv) dx = -dy; dy = 0; } + if (debug) printf(" %s\n", dirstr(dx, dy)); rotonce = 1; } @@ -160,6 +226,6 @@ main(int argc, const char **argv) stbi_write_png("piet.png", width, height, STBI_rgb, pix, 3 * width); free(pix); - free(vis_map); - STBI_FREE(dir_map); + free(vis); + STBI_FREE(map); }