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:
M | pietp.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);
}