#include <stdio.h>
#include <math.h>
#include <stdint.h>

#define XRES 20     //width of a quadrant
#define YRES 32     //height of a quadrant
//#define PAR  2.0f   //pixel aspect ratio
#define DIVS 8      //number of times to divide 60 degrees

typedef struct {
    int32_t pixels[YRES];
} Quadrant;

int clamp(int a, int b, int c) {
    if (a < b) return b;
    if (a > c) return c;
    return a;
}

void render(Quadrant *q, float angle) {
    //render Q2
    float angle2 = angle + M_PI/3;
    float x0, x1, d0, d1;
    int y;

    if (angle) {
        x0 = XRES / tan(angle);
        d0 = -x0 / YRES;
    } else {
        x0 = XRES;
        d0 = 0;
    }

    x1 = XRES / tan(angle2);
    d1 = -x1 / YRES;

    //printf("%f: %f %f %f %f\n", angle, x0, d0, x1, d1);

    for (y = 0; y < YRES; y++) {
        q->pixels[y] = ((1 << (clamp(x0, 0, XRES))) - 1) ^ ((1 << (clamp(x1, 0, XRES))) - 1);
        //printf("%2i: %08X\n", y, q->pixels[y]);
        x0 += d0;
        x1 += d1;
    }
}

void printbin(FILE *f, int x, int flip) {
    if (flip) {
        fprintf(f, "%i%i%i%i%i%i%i%i",
            x & 1,
            (x >> 1) & 1,
            (x >> 2) & 1,
            (x >> 3) & 1,
            (x >> 4) & 1,
            (x >> 5) & 1,
            (x >> 6) & 1,
            (x >> 7) & 1);
    } else {
        fprintf(f, "%i%i%i%i%i%i%i%i",
                (x >> 7) & 1,
                (x >> 6) & 1,
                (x >> 5) & 1,
                (x >> 4) & 1,
                (x >> 3) & 1,
                (x >> 2) & 1,
                (x >> 1) & 1,
                x & 1);
    }
}

int main() {
    int x, y, p;
    Quadrant q[DIVS];
    int freq[256] = {0}, num = 0;

    for (x = 0; x < DIVS; x++)
        render(&q[x], x * M_PI/3 / DIVS);

    printf(";%i bytes\n", 3*DIVS*YRES);
    for (p = 0; p <= 2; p++) {
        printf("PinwheelQ2PF%i\n", p);
        for (x = 0; x < DIVS; x++) {
            for (y = YRES - 1; y >= 0; y--) {
                int masks[3] = {0xFF, 0xFF, 0xFF};
                int shifts[3] = {16, 8, 0};
                int byte = (q[x].pixels[y] >> shifts[p]) & masks[p];
                
                if (!freq[byte]++)
                    num++;

                printf("\t.byte %%");
                printbin(stdout, byte, p != 1);
                printf("\n");
            }
            printf("\n");
        }
    }

    fprintf(stderr, "%i unique bytes\n", num);
    
    for (x = 0; x < 256; x++) {
        if (!freq[x])
            continue;

        printbin(stderr, x, 0);
        fprintf(stderr, "\n");
    }
    
    return 0;
}
