| @@ -27,15 +27,36 @@ | |||
| #include "ee.h" | |||
| struct line | |||
| { | |||
| int x1, y1; | |||
| int x2, y2; | |||
| char c; | |||
| void (*draw) (struct line*); | |||
| }; | |||
| static void clip_line(struct line*); | |||
| static uint8_t clip_bits(int, int); | |||
| static void draw_solid_line(int, int, int, int, char); | |||
| static void draw_solid_line(struct line*); | |||
| void ee_draw_line(int x1, int y1, int x2, int y2, char c) | |||
| { | |||
| struct line s; | |||
| s.x1 = x1; | |||
| s.y1 = y1; | |||
| s.x2 = x2; | |||
| s.y2 = y2; | |||
| s.c = c; | |||
| s.draw = draw_solid_line; | |||
| clip_line(&s); | |||
| } | |||
| static void clip_line(struct line* s) | |||
| { | |||
| uint8_t bits1, bits2; | |||
| bits1 = clip_bits(x1, y1); | |||
| bits2 = clip_bits(x2, y2); | |||
| bits1 = clip_bits(s->x1, s->y1); | |||
| bits2 = clip_bits(s->x2, s->y2); | |||
| if(bits1 & bits2) | |||
| return; | |||
| @@ -43,41 +64,68 @@ void ee_draw_line(int x1, int y1, int x2, int y2, char c) | |||
| if(bits1 == 0) | |||
| { | |||
| if(bits2 == 0) | |||
| draw_solid_line(x1, y1, x2, y2, c); | |||
| s->draw(s); | |||
| else | |||
| ee_draw_line(x2, y2, x1, y1, c); | |||
| { | |||
| int tmp; | |||
| tmp = s->x1; s->x1 = s->x2; s->x2 = tmp; | |||
| tmp = s->y1; s->y1 = s->y2; s->y2 = tmp; | |||
| clip_line(s); | |||
| } | |||
| return; | |||
| } | |||
| if(bits1 & (1<<0)) | |||
| { | |||
| y1 = y2 - (x2-0) * (y2-y1) / (x2-x1); | |||
| x1 = 0; | |||
| s->y1 = s->y2 - (s->x2 - 0) * (s->y2 - s->y1) / (s->x2 - s->x1); | |||
| s->x1 = 0; | |||
| } | |||
| else if( bits1 & (1<<1) ) | |||
| { | |||
| int xmax = ee_get_width() - 1; | |||
| y1 = y2 - (x2-xmax) * (y2-y1) / (x2-x1); | |||
| x1 = xmax; | |||
| s->y1 = s->y2 - (s->x2 - xmax) * (s->y2 - s->y1) / (s->x2 - s->x1); | |||
| s->x1 = xmax; | |||
| } | |||
| else if( bits1 & (1<<2) ) | |||
| { | |||
| x1 = x2 - (y2-0) * (x2-x1) / (y2-y1); | |||
| y1 = 0; | |||
| s->x1 = s->x2 - (s->y2 - 0) * (s->x2 - s->x1) / (s->y2 - s->y1); | |||
| s->y1 = 0; | |||
| } | |||
| else if( bits1 & (1<<3) ) | |||
| { | |||
| int ymax = ee_get_height() - 1; | |||
| x1 = x2 - (y2-ymax) * (x2-x1) / (y2-y1); | |||
| y1 = ymax; | |||
| s->x1 = s->x2 - (s->y2 - ymax) * (s->x2 - s->x1) / (s->y2 - s->y1); | |||
| s->y1 = ymax; | |||
| } | |||
| ee_draw_line(x1, y1, x2, y2, c); | |||
| clip_line(s); | |||
| } | |||
| static uint8_t clip_bits(int x, int y) | |||
| { | |||
| uint8_t b = 0; | |||
| if(x < 0) | |||
| b |= (1<<0); | |||
| else if(x >= ee_get_width()) | |||
| b |= (1<<1); | |||
| if(y < 0) | |||
| b |= (1<<2); | |||
| else if(y >= ee_get_height()) | |||
| b |= (1<<3); | |||
| return b; | |||
| } | |||
| static void draw_solid_line(int x1, int y1, int x2, int y2, char c) | |||
| static void draw_solid_line(struct line* s) | |||
| { | |||
| int x1 = s->x1; | |||
| int y1 = s->y1; | |||
| int x2 = s->x2; | |||
| int y2 = s->y2; | |||
| int dx = abs(x2-x1); | |||
| int dy = abs(y2-y1); | |||
| @@ -95,7 +143,7 @@ static void draw_solid_line(int x1, int y1, int x2, int y2, char c) | |||
| for(; dx>=0; dx--) | |||
| { | |||
| ee_goto(x1, y1); | |||
| ee_putchar(c); | |||
| ee_putchar(s->c); | |||
| if(delta > 0) | |||
| { | |||
| x1 += xinc; | |||
| @@ -118,7 +166,7 @@ static void draw_solid_line(int x1, int y1, int x2, int y2, char c) | |||
| for(; dy >= 0; dy--) | |||
| { | |||
| ee_goto(x1, y1); | |||
| ee_putchar(c); | |||
| ee_putchar(s->c); | |||
| if(delta > 0) | |||
| { | |||
| x1 += xinc; | |||
| @@ -134,20 +182,3 @@ static void draw_solid_line(int x1, int y1, int x2, int y2, char c) | |||
| } | |||
| } | |||
| static uint8_t clip_bits(int x, int y) | |||
| { | |||
| uint8_t b = 0; | |||
| if(x < 0) | |||
| b |= (1<<0); | |||
| else if(x >= ee_get_width()) | |||
| b |= (1<<1); | |||
| if(y < 0) | |||
| b |= (1<<2); | |||
| else if(y >= ee_get_height()) | |||
| b |= (1<<3); | |||
| return b; | |||
| } | |||