#include #include #include #include #include "algo.h" #include "output.h" #define VIEWPORT_WIDTH 16 #define VIEWPORT_HEIGHT 16 #define FMT_BITMAP 1 #define FMT_TEXT 2 /* Format of the output */ static int fmt = FMT_BITMAP; static struct _viewport { int x; int y; int width; int height; } viewport = { 0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT }; typedef struct _viewport Viewport; typedef char pixel; static pixel **pixarray; /***************************************************************** * * Pixel allocation * *****************************************************************/ void *my_calloc(size_t n, size_t size) { void *ptr = calloc(n, size); assert(ptr); return ptr; } void allocate_pixels() { int i; pixarray = my_calloc(viewport.height + 1, sizeof(pixel *)); for(i = 0; i < viewport.height + 1; i++) pixarray[i] = my_calloc(viewport.width + 1, sizeof(pixel)); } /***************************************************************** * * Output functions * *****************************************************************/ void output(int x, int y) { x -= viewport.x; y -= viewport.y; /* Clip */ if(x>= 0 && y >= 0 && x <= viewport.width && y <= viewport.height) pixarray[x][y] = 1u; } void output4(int x, int y) { output(x, y); output(x, -y); output(-x, y); output(-x, -y); } void output8(int x, int y) { output4(x, y); output4(y, x); } /***************************************************************** * * Rendering functions * *****************************************************************/ void render_bitmap() { int x, y; for(y = viewport.width; y >= 0; y--) { for(x = 0; x < viewport.height; x++) { if(pixarray[x][y] != 0u) { printf("#"); } else { printf("-"); } } puts(""); } fflush(stdout); } void render_text() { int x, y; for(x = 0; x < viewport.height; x++) for(y = 0; y < viewport.width; y++) if(pixarray[x][y] != 0u) printf("%d %d\n", x + viewport.x, y + viewport.y); fflush(stdout); } /***************************************************************** * * Wrappers for raw algorithms * *****************************************************************/ void d_line(int argc, char *argv[]) { int x0 = 3, y0 = 2, x1 = 10, y1 =7; if(argc >= 1) x0 = atoi(argv[0]); if(argc >= 2) y0 = atoi(argv[1]); if(argc >= 3) x1 = atoi(argv[2]); if(argc >= 4) y1 = atoi(argv[3]); line(x0, y0, x1, y1); } void d_circle(void (*circle)(int), int argc, char *argv[]) { int radius = 7; if(argc >= 1) radius = atoi(argv[0]); (*circle)(radius); } /***************************************************************** * * Driver info * *****************************************************************/ static char* shapes[] = {"line", "circle"}; void list_shapes(FILE *f) { int i; for(i = 0; i < sizeof(shapes)/sizeof(char *); i++) fprintf(f, "-%s, \n", shapes[i]); } void usage(char *progname) { fprintf(stderr, "Usage: %s -name arg1 arg2 ...\n", progname); list_shapes(stderr); } /***************************************************************** * * main * *****************************************************************/ int main(int argc, char*argv[]) { char *progname = argv[0]; argv++; argc--; /* Skip progname */ /* Parse input line */ while(argc >= 1) { if(!strncmp(*argv, "-text", 5)) { fmt = FMT_TEXT; argc--; argv++; } else if(!strncmp(*argv, "-bitmap", 5)) { fmt = FMT_BITMAP; argc--; argv++; } else if(!strncmp(*argv, "-w", 2)) { argc--; argv++; if(argc >= 1) { viewport.width = atoi(*argv); argc--; argv++; } else continue; } else if(!strncmp(*argv, "-h", 2)){ argc--; argv++; if(argc >= 1) { viewport.height = atoi(*argv); argc--; argv++; } else continue; } else if(!strncmp(*argv, "-x", 2)) { argc--; argv++; if(argc >= 1) { viewport.x = atoi(*argv); argc--; argv++; } else continue; } else if(!strncmp(*argv, "-y", 2)) { argc--; argv++; if(argc >= 1) { viewport.y = atoi(*argv); argc--; argv++; } else continue; } else break; } allocate_pixels(); /* Set the shape to be scan-converted */ if(argc >= 1) { if(!strncmp(*argv, "-line", 6)) d_line(--argc, ++argv); else if(!strncmp(*argv, "-circle", 7)) d_circle(circle, --argc, ++argv); else if(!strncmp(*argv, "-circle2", 7)) d_circle(circle2, --argc, ++argv); else { usage(progname); return 1; } } switch(fmt){ case FMT_TEXT: render_text(); break; case FMT_BITMAP: render_bitmap(); break; default: } return 0; }