| @@ -27,15 +27,36 @@ | |||||
| #include "ee.h" | #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 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) | 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; | 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) | if(bits1 & bits2) | ||||
| return; | return; | ||||
| @@ -43,41 +64,68 @@ void ee_draw_line(int x1, int y1, int x2, int y2, char c) | |||||
| if(bits1 == 0) | if(bits1 == 0) | ||||
| { | { | ||||
| if(bits2 == 0) | if(bits2 == 0) | ||||
| draw_solid_line(x1, y1, x2, y2, c); | |||||
| s->draw(s); | |||||
| else | 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; | return; | ||||
| } | } | ||||
| if(bits1 & (1<<0)) | 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) ) | else if( bits1 & (1<<1) ) | ||||
| { | { | ||||
| int xmax = ee_get_width() - 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) ) | 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) ) | else if( bits1 & (1<<3) ) | ||||
| { | { | ||||
| int ymax = ee_get_height() - 1; | 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 dx = abs(x2-x1); | ||||
| int dy = abs(y2-y1); | 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--) | for(; dx>=0; dx--) | ||||
| { | { | ||||
| ee_goto(x1, y1); | ee_goto(x1, y1); | ||||
| ee_putchar(c); | |||||
| ee_putchar(s->c); | |||||
| if(delta > 0) | if(delta > 0) | ||||
| { | { | ||||
| x1 += xinc; | 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--) | for(; dy >= 0; dy--) | ||||
| { | { | ||||
| ee_goto(x1, y1); | ee_goto(x1, y1); | ||||
| ee_putchar(c); | |||||
| ee_putchar(s->c); | |||||
| if(delta > 0) | if(delta > 0) | ||||
| { | { | ||||
| x1 += xinc; | 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; | |||||
| } | |||||