diff options
-rw-r--r-- | src/graphics_c2.c | 15 | ||||
-rw-r--r-- | src/graphics_c3.c | 2 | ||||
-rw-r--r-- | src/graphics_cs_fb.c | 95 | ||||
-rw-r--r-- | src/graphics_cs_x11.c | 43 | ||||
-rw-r--r-- | src/math.c | 37 | ||||
-rw-r--r-- | src/math.h | 8 | ||||
-rw-r--r-- | src/mouse_die.c | 4 |
7 files changed, 86 insertions, 118 deletions
diff --git a/src/graphics_c2.c b/src/graphics_c2.c index d78f87b..65d139f 100644 --- a/src/graphics_c2.c +++ b/src/graphics_c2.c @@ -1,7 +1,11 @@ +#include "common.h" +#include "math.h" #include "graphics_cs.h" #include "graphics_c3.h" +#include "mouse.h" extern struct gra_global gra_global; +extern struct hvr_global global; int c2sX(real x) { return (gra_global.width/(gra_global.split_screen / (gra_global.red_and_blue ? gra_global.split_screen: 1))) * ((x + RIGHT) / (RIGHT *2)) + gra_global.xoff; } int s2cX(real x) { return (x/(gra_global.width/(gra_global.split_screen / (gra_global.red_and_blue?gra_global.split_screen :1))))*(RIGHT*2)-RIGHT; } @@ -29,6 +33,16 @@ void draw_c2_shape(c2_s_t s) { ss.p[i]=c2_to_cs(s.p[i]); } draw_cs_shape(ss); +// if(cn_PnPoly(gra_global.mouse,s.p,s.len+(s.len==1))) {//if the mouse is inside the shape, we're going to draw a different outline. + if(epoch_PnPoly(gra_global.mouse,s.p,s.len+(s.len==1))) {//if the mouse is inside the shape, we're going to draw a different outline. + set_ansi_color(7); + if(gra_global.mousemap[MOUSE_PRIMARY]==1) { + printf("%s action %s\n",global.user,s.id); + gra_global.mousemap[MOUSE_PRIMARY]=0; + } + //I need to debounce probably + draw_cs_shape(ss);//draw over. dunno. + } } void draw_c2_filled_shape(c2_s_t s) { @@ -40,6 +54,7 @@ void draw_c2_filled_shape(c2_s_t s) { ss.p[i]=c2_to_cs(s.p[i]); } draw_cs_filled_shape(ss); + draw_cs_shape(ss);//redraw outline last } void draw_c2_text(c2_t p,char *text) { diff --git a/src/graphics_c3.c b/src/graphics_c3.c index 72a03e3..e31233c 100644 --- a/src/graphics_c3.c +++ b/src/graphics_c3.c @@ -457,7 +457,7 @@ void draw_screen() { //} } //we check here to see if the mouse button is still down - if(gra_global.mousemap[MOUSE_PRIMARY]==-1) {//0 in x11 + if(gra_global.mousemap[MOUSE_PRIMARY]==-1) { printf("%s action %f %f\n",global.user,gra_global.mouse.x,gra_global.mouse.y); gra_global.mousemap[MOUSE_PRIMARY]=0; } diff --git a/src/graphics_cs_fb.c b/src/graphics_cs_fb.c index e32da74..0712bcd 100644 --- a/src/graphics_cs_fb.c +++ b/src/graphics_cs_fb.c @@ -63,8 +63,8 @@ void set_luminosity_color(int lum) {//need to come up with a good range for this void draw_cs_point(int x,int y) {//this should write to a backbuffer then I can memcopy it over. unsigned int i=y * fb_global.info.xres + x; - if(x > fb_global.info.xres) return; - if(y > fb_global.info.yres) return; + if(x >= fb_global.info.xres) return; + if(y >= fb_global.info.yres) return; if(i > fb_global.fblen) return; //hack to test it with. remove me later. //fb_global.current_color=-1; @@ -89,10 +89,33 @@ void draw_cs_point(int x,int y) {//this should write to a backbuffer then I can } } -void draw_cs_arc() {//now... how to draw an arc. +void draw_cs_arc(cs_t p1, cs_t p2) {//now... how to draw an arc. +// real r;//radius +// y=sin(); +// x=cos(); +} +int x_from_y(cs_t p1,cs_t p2,int y) {//get the value of x given a y within a line. + real m; + int b; + int x; +// y=mx+b MAGIC + if(p1.x == p2.x) return p1.x;//if this happens then we have a verticle line and can just shortcut this shit. + if(p1.y == p2.y) {//if this happens we have a horizontal line we're trying to find the X of based on a 'y' that probably isn't in the line... + return 0; + }//return p1.x;//WE SHOULD NOT GET HERE. fuck if I know. +// y=mx+b +// y-b=mx +// x=(y-b)/m +// b=y-mx + m=((real)(p1.y-p2.y))/((real)(p1.x-p2.x)); + b=(int)((real)p1.y - (m * (real)p1.x)); + x=(int)(((real)(y-b))/m); + if(!x) printf("x == %d y=%d m=%f b=%d\n",x,y,m,b); + return x; } +//does this actually work? seems to. void draw_cs_line(cs_t p1,cs_t p2) {//error somewhere in here. derp... int x,y; real m; @@ -110,13 +133,14 @@ void draw_cs_line(cs_t p1,cs_t p2) {//error somewhere in here. derp... } return; } + //this isn't working for some reason. xd=p1.x<p2.x?1:-1; yd=p1.y<p2.y?1:-1; - if(max(p1.x,p2.x)-min(p1.x,p2.x) >= max(p1.y,p2.y)-min(p1.y,p2.y)) { //loop over x. like normal math. :P y=mx+b stuff. + if(max(p1.x,p2.x)-min(p1.x,p2.x) > max(p1.y,p2.y)-min(p1.y,p2.y)) { //loop over x. like normal math. :P y=mx+b stuff. m=((real)(p1.y-p2.y))/((real)(p1.x-p2.x)); b=(int)((real)p1.y - (m * (real)p1.x)); for(x=p1.x;x!=p2.x;x+=xd) { - y=(int)(m * (real)x + (real)b); + y=(int)(m * (real)x + (real)b); draw_cs_point(x,y); } } else { //loop over y @@ -127,7 +151,7 @@ void draw_cs_line(cs_t p1,cs_t p2) {//error somewhere in here. derp... draw_cs_point(x,y); } } - //now for the fun part. + // ??? } void draw_cs_text(cs_t p,char *text) { @@ -141,13 +165,6 @@ void draw_cs_text(cs_t p,char *text) { } void draw_cs_shape(cs_s_t s) {//this is implemented as draw_cs_line... hrm. it could be moved up to graphics.c? probl no. - //test in here whether a mouse click is within this shape's... bounding box? sure. - cs_s_t bb;//bounding box - int minx=s.p[0].x; - int miny=s.p[0].y; - int maxx=s.p[0].x; - int maxy=s.p[0].y; - //int h; int i;//all cs shapes can have 1, 2, or 3+ points. guess I gotta do that logic here too. switch(s.len) { case 1: @@ -155,59 +172,16 @@ void draw_cs_shape(cs_s_t s) {//this is implemented as draw_cs_line... hrm. it c //h=max(s.p[0].x,s.p[1].x)-min(s.p[0].x,s.p[1].x); //XDrawArc(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,s.p[0].x-h,s.p[0].y-h,h*2,h*2,0,360*64); break; + case 2: + draw_cs_line(s.p[0],s.p[1]); default: - for(i=0;i<s.len+(s.len==1);i++) {//this shape is closed! - minx=(s.p[i].x<minx)?s.p[i].x:minx; - miny=(s.p[i].y<miny)?s.p[i].y:miny; - maxx=(s.p[i].x>maxx)?s.p[i].x:maxx; - maxy=(s.p[i].y>maxy)?s.p[i].y:maxy; - // draw_cs_line(s.p[i],s.p[(i+1)%(s.len+(s.len==1))]); - } - if(gra_global.mouse.x >= minx && - gra_global.mouse.y >= miny && - gra_global.mouse.x <= maxx && - gra_global.mouse.y <= maxy) { - if(gra_global.mousemap[0] == -1) {//if we're inside the bounding box let's make SOMETHING happen. - gra_global.mousemap[0]=0; - printf("%s action %s\n",global.user,s.id); - } - bb.id=strdup("boundingbox"); - bb.len=4; - bb.p[0].x=minx; - bb.p[0].y=miny; - bb.p[1].x=minx; - bb.p[1].y=maxy; - bb.p[2].x=maxx; - bb.p[2].y=maxy; - bb.p[3].x=maxx; - bb.p[3].y=miny; - draw_cs_filled_shape(bb); - free(bb.id); + for(i=0;i<s.len;i++) { + draw_cs_line(s.p[i],s.p[(i+1)%s.len]); } break; } } -int x_from_y(cs_t p1,cs_t p2,int y) {//get the value of x given a y within a line. - real m; - int b; - int x; -// y=mx+b MAGIC - if(p1.x == p2.x) return p1.x;//if this happens then we have a verticle line and can just shortcut this shit. - if(p1.y == p2.y) {//if this happens we have a horizontal line we're trying to find the X of based on a 'y' that probably isn't in the line... - return 0; - }//return p1.x;//WE SHOULD NOT GET HERE. fuck if I know. -// y=mx+b -// y-b=mx -// x=(y-b)/m -// b=y-mx - m=((real)(p1.y-p2.y))/((real)(p1.x-p2.x)); - b=(int)((real)p1.y - (m * (real)p1.x)); - x=(int)(((real)(y-b))/m); - if(!x) printf("x == %d y=%d m=%f b=%d\n",x,y,m,b); - return x; -} - void draw_cs_filled_shape(cs_s_t s) {//no circle handling atm. and only convex polygons. int maxmax=0; int minmin=0; @@ -232,6 +206,7 @@ void draw_cs_filled_shape(cs_s_t s) {//no circle handling atm. and only convex p draw_cs_line(p1,p2);//the two y values are always the same here. } } + /* void draw_cs_filled_shape(cs_s_t s) { int h; diff --git a/src/graphics_cs_x11.c b/src/graphics_cs_x11.c index 0395a38..1f9774a 100644 --- a/src/graphics_cs_x11.c +++ b/src/graphics_cs_x11.c @@ -85,13 +85,6 @@ void draw_cs_text(cs_t p,char *text) { } void draw_cs_shape(cs_s_t s) {//this is implemented as draw_cs_line... hrm. it could be moved up to graphics.c? probl no. - //test in here whether a mouse click is within this shape's... bounding box? sure. - //cs_s_t bb;//bounding box - cs_t smouse=c2_to_cs(gra_global.mouse); - int minx=s.p[0].x; - int miny=s.p[0].y; - int maxx=s.p[0].x; - int maxy=s.p[0].y; int h; int i;//all cs shapes can have 1, 2, or 3+ points. guess I gotta do that logic here too. switch(s.len) { @@ -99,47 +92,11 @@ void draw_cs_shape(cs_s_t s) {//this is implemented as draw_cs_line... hrm. it c //circle h=max(s.p[0].x,s.p[1].x)-min(s.p[0].x,s.p[1].x); XDrawArc(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,s.p[0].x-h,s.p[0].y-h,h*2,h*2,0,360*64); - if(distance2((c2_t){s.p[0].x,s.p[1].y},(c2_t){smouse.x,smouse.y} ) < h) { - if(gra_global.mousemap[0]==-1) { - gra_global.mousemap[0]=0; - printf("%s action %s\n",global.user,s.id); - } - XDrawArc(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,s.p[0].x-h-2,s.p[0].y-h-2,h*2+4,h*2+4,0,360*64); - } break; default: for(i=0;i<s.len+(s.len==1);i++) {//this shape is closed! - minx=(s.p[i].x<minx)?s.p[i].x:minx; - miny=(s.p[i].y<miny)?s.p[i].y:miny; - maxx=(s.p[i].x>maxx)?s.p[i].x:maxx; - maxy=(s.p[i].y>maxy)?s.p[i].y:maxy; draw_cs_line(s.p[i],s.p[(i+1)%(s.len+(s.len==1))]); } - //fix the comparison here and also fix the hilighting shape - if(smouse.x >= minx && //gra_global is a c2_t and these are in cs_t - smouse.y >= miny && - smouse.x <= maxx && - smouse.y <= maxy) { -// if(wn_PnPoly(smouse,s.p,s.len) != 0 && s.len > 2) { - if(gra_global.mousemap[0] == -1) {//if we're inside the bounding box let's make SOMETHING happen. - gra_global.mousemap[0]=0; - printf("%s action %s\n",global.user,s.id); -// } -/* bb.id=strdup("boundingbox"); - bb.len=4; - bb.p[0].x=minx; - bb.p[0].y=miny; - bb.p[1].x=minx; - bb.p[1].y=maxy; - bb.p[2].x=maxx; - bb.p[2].y=maxy; - bb.p[3].x=maxx; - bb.p[3].y=miny; - draw_cs_filled_shape(bb); - free(bb.id); -*/ - } - } break; } } @@ -19,7 +19,8 @@ c3_group_rel_t *get_group_relative(char *id) { if(gr) return gr; } //if we got here, we need to make a new one. - assert(gr=malloc(sizeof(c3_group_rel_t)));//just exit on malloc error? sure... + gr=malloc(sizeof(c3_group_rel_t));//just exit on malloc error? sure... + assert(gr && "failed to malloc something I don't want to figure out how to work around if it doesn't malloc."); memset(gr,0,sizeof(c3_group_rel_t)); gr->s=(c3_t){1,1,1};//scale needs to be all 1s, since it is multiplied against the coordinates. gr->id=strdup(id);//don't forget to free this when it gets deleted. @@ -245,7 +246,7 @@ real distance3(c3_t p1,c3_t p2) { // <0 for P2 right of the line // See: Algorithm 1 "Area of Triangles and Polygons" inline int -isLeft( cs_t P0, cs_t P1, cs_t P2 ) +isLeft( c2_t P0, c2_t P1, c2_t P2 ) { return ( (P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y) ); @@ -256,20 +257,23 @@ isLeft( cs_t P0, cs_t P1, cs_t P2 ) // cn_PnPoly(): crossing number test for a point in a polygon // Input: P = a point, // V[] = vertex points of a polygon V[n+1] with V[n]=V[0] +// hacked on by epoch to make the previous statement automatic. i+1 changed to i+1%n // Return: 0 = outside, 1 = inside // This code is patterned after [Franklin, 2000] + +//pretending like this will work fine with a real instead of an int... probably fine. int -cn_PnPoly( cs_t P, cs_t *V, int n ) +cn_PnPoly( c2_t P, c2_t *V, int n ) { int cn = 0; // the crossing number counter // loop through all edges of the polygon for (int i=0; i<n; i++) { // edge from V[i] to V[i+1] - if (((V[i].y <= P.y) && (V[i+1].y > P.y)) // an upward crossing - || ((V[i].y > P.y) && (V[i+1].y <= P.y))) { // a downward crossing + if (((V[i].y <= P.y) && (V[i+1%n].y > P.y)) // an upward crossing + || ((V[i].y > P.y) && (V[i+1%n].y <= P.y))) { // a downward crossing // compute the actual edge-ray intersect x-coordinate - float vt = (float)(P.y - V[i].y) / (V[i+1].y - V[i].y); - if (P.x < V[i].x + vt * (V[i+1].x - V[i].x)) // P.x < intersect + float vt = (float)(P.y - V[i].y) / (V[i+1%n].y - V[i].y); + if (P.x < V[i].x + vt * (V[i+1%n].x - V[i].x)) // P.x < intersect ++cn; // a valid crossing of y=P.y right of P.x } } @@ -283,8 +287,9 @@ cn_PnPoly( cs_t P, cs_t *V, int n ) // Input: P = a point, // V[] = vertex points of a polygon V[n+1] with V[n]=V[0] // Return: wn = the winding number (=0 only when P is outside) + int -wn_PnPoly( cs_t P, cs_t *V, int n ) +wn_PnPoly( c2_t P, c2_t *V, int n ) { int wn = 0; // the winding number counter @@ -304,3 +309,19 @@ wn_PnPoly( cs_t P, cs_t *V, int n ) return wn; } //=================================================================== + +int epoch_PnPoly( c2_t P, c2_t *V, int n ) { + cs_t min,max; + int i; + min.x=V[0].x; + min.y=V[0].y; + max.x=V[0].x; + max.y=V[0].y; + for(i=0;i<n;i++) { + min.x=min(min.x,V[i].x); + max.x=max(max.x,V[i].x); + min.y=min(min.y,V[i].y); + max.y=max(max.y,V[i].y); + } + return (P.x <= max.x && P.x >= min.x && P.y >= min.y && P.y <= max.y); +} @@ -25,8 +25,8 @@ c2_t c2_add(c2_t p1,c2_t p2); real distance3(c3_t p1,c3_t p2); void print_point(c3_t p); -int isLeft(cs_t, cs_t, cs_t); -int cn_PnPoly(cs_t, cs_t *, int); -int wn_PnPoly(cs_t, cs_t *, int); - +int isLeft(c2_t, c2_t, c2_t); +int cn_PnPoly(c2_t, c2_t *, int); +int wn_PnPoly(c2_t, c2_t *, int); +int epoch_PnPoly(c2_t, c2_t *,int); #endif diff --git a/src/mouse_die.c b/src/mouse_die.c index 2258a08..f24fbe1 100644 --- a/src/mouse_die.c +++ b/src/mouse_die.c @@ -40,8 +40,8 @@ int mouse_init() { //it doesn't care if you have X11 buttons swapped around ofc. char die2map(char d) {//edit this function if you want to change your primary and secondary mouse button. switch(d) { - case DIE_MOUSE_RIGHT: return MOUSE_PRIMARY; - case DIE_MOUSE_LEFT: return MOUSE_SECONDARY; + case DIE_MOUSE_LEFT: return MOUSE_PRIMARY; + case DIE_MOUSE_RIGHT: return MOUSE_SECONDARY; case DIE_MOUSE_CENTER: return MOUSE_TERTIARY; default: return -1; } |