/***************************************************************************** TEXTAIL2: Makes a piece of vector graphics text follow the mouse cursor wherever it goes. The characters rotate depending on their position relative to the next one towards the mouse pointer. Written by Neil, last update Dec 2003 *****************************************************************************/ #include #include #include #include #include #include #define SEP 13 #define DEGS_PER_RADIAN 57.29578 /*** Function prototypes ***/ void parse_command_line(int argc, char **argv); void init(); void mainloop(); void calc(int pos,double hyp); void draw(int pos, char ascii); /*** Global vars ***/ Display *display; Display *display2; Window rootwin; Window rootwin2; GC gc; GC gc2; char *disp; char *disp2; char *text; int delay; int scroll; int scale; int rotate; int lwidth; int local_draw; int ctrails; int follow; int curr; int next; /*** Co-ord and template structs ***/ struct xy { int x,y; }; struct char_template { int cnt; struct xy data[1]; } *trans[256]; /*** CHARACTER DATA ***/ struct { int cnt; } char_space = { 0 }; struct { int cnt; struct xy data[6]; } char_a = { 6, {{ 0,10 }, { 5,0 }, { 5,0 }, { 10,10 }, { 2,6 }, {8,6 }} }; struct { int cnt; struct xy data[20]; } char_b = { 20, {{ 0,0 }, { 8,0 }, { 8,0 }, { 10,1 }, { 10,1 }, { 10,4 }, { 10,4 }, { 5,5 }, { 5,5 }, { 10,6 }, { 10,6 }, { 10,9 }, { 10,9 }, { 8,10 }, { 8,10 }, { 0,10 }, { 0,10 }, { 0,0 }, { 0,5 }, { 5,5 }} }; struct { int cnt; struct xy data[14]; } char_c = { 14, {{10,1 } , { 9,0 }, { 9,0 } , { 2,0 }, { 2,0 }, { 0,2 }, { 0,2 }, { 0,8 }, { 0,8 }, { 2,10 }, { 2,10 }, { 9,10 }, { 9,10 }, { 10,9 }} }; struct { int cnt; struct xy data[12]; } char_d = { 12, {{ 0,0 }, { 7,0 }, { 7,0 }, { 10,2 }, { 10,2 }, { 10,8 }, { 10,8 }, { 7,10 }, { 7,10 }, { 0,10 }, { 0,10 }, { 0,0 }} }; struct { int cnt; struct xy data[8]; } char_e = { 8, {{ 0,0 }, { 10,0 }, { 0,0 } , { 0,10 }, { 0,5 }, { 7,5 }, { 0,10 }, { 10,10 }} }; struct { int cnt; struct xy data[6]; } char_f = { 6, {{ 0,0 } , { 10,0 }, { 0,0 }, { 0,10 }, { 0,5 }, { 7,5 }} }; struct { int cnt; struct xy data[18]; } char_g = { 18, {{ 10,2 } , { 7,0 }, { 7,0 }, { 2,0 }, { 2,0 }, { 0,2 }, { 0,2 }, { 0,8 }, { 0,8 }, { 2,10 }, { 2,10 }, { 7,10 }, { 7,10 }, { 10,7 }, { 10,7 }, { 10,5 }, { 10,5 }, { 5,5 }} }; struct { int cnt; struct xy data[6]; } char_h = { 6, {{ 0,0 }, { 0,10 }, { 0,5 }, { 10,5 }, { 10,0 }, { 10,10 }} }; struct { int cnt; struct xy data[6]; } char_i = { 6, {{ 0,0 }, { 10,0 }, { 5,0 }, { 5,10 }, { 0,10 }, { 10,10 }} }; struct { int cnt; struct xy data[12]; } char_j = { 12, {{ 0,0 }, { 10,0 }, { 7,0 }, { 7,7 }, { 7,7 }, { 5,10 }, { 5,10 }, { 2,10 }, { 2,10 }, { 1,8 }, { 1,8 }, { 1,6 }} }; struct { int cnt; struct xy data[6]; } char_k = { 6, {{ 0,0 }, { 0,10 }, { 0,7 }, { 10,0 }, { 3,5 }, { 10,10 }} }; struct { int cnt; struct xy data[4]; } char_l = { 4, {{ 0,0 }, { 0,10 }, { 0,10 }, { 10,10 }} }; struct { int cnt; struct xy data[8]; } char_m = { 8, {{ 0,0 } , { 0,10 }, { 0,0 }, { 5,5 }, { 5,5 }, { 10,0 }, { 10,0 }, { 10,10 }} }; struct { int cnt; struct xy data[6]; } char_n = { 6, {{ 0,0 }, { 0,10 }, { 0,0 }, { 10,10 }, { 10,10 }, { 10,0 }} }; struct { int cnt; struct xy data[16]; } char_o = { 16, {{ 3,0 }, { 7,0 }, { 7,0 }, { 10,3 }, { 10,3 }, { 10,7 }, { 10,7 }, { 7,10 }, { 7,10 }, { 3,10 }, { 3,10 }, { 0,7 }, { 0,7 }, { 0,3 }, { 0,3 }, { 3,0 }} }; struct { int cnt; struct xy data[12]; } char_p = { 12, {{ 0,0 }, { 7,0 }, { 7,0 }, { 10,2 }, { 10,2 }, { 10,4 }, { 10,4 }, { 7,6 }, { 7,6 }, { 0,6 }, { 0,0 }, { 0,10 }} }; struct { int cnt; struct xy data[18]; } char_q = { 18, {{ 3,0 }, { 7,0 }, { 7,0 }, { 10,3 }, { 10,3 }, { 10,7 }, { 10,7 }, { 7,10 }, { 7,10 }, { 3,10 }, { 3,10 }, { 0,7 }, { 0,7 }, { 0,3 }, { 0,3 }, { 3,0 }, { 0,10 }, { 4,6 }} }; struct { int cnt; struct xy data[14]; } char_r = { 14, {{ 0,0 }, { 7,0 }, { 7,0 }, { 10,2 }, { 10,2 }, { 10,4 }, { 10,4 }, { 7,6 }, { 7,6 }, { 0,6 }, { 0,0 }, { 0,10 }, { 3,6 }, { 9,10 }} }; struct { int cnt; struct xy data[22]; } char_s = { 22, {{ 10,1 }, { 9,0 }, { 9,0 }, { 1,0 }, { 1,0 }, { 0,1 }, { 0,1 }, { 0,4 }, { 0,4 }, { 1,5 }, { 1,5 }, { 9,5 }, { 9,5 }, { 10,6 }, { 10,6 }, { 10,9 }, { 10,9 }, { 9,10 }, { 9,10 }, { 1,10 }, { 1,10 }, { 0,9 }} }; struct { int cnt; struct xy data[4]; } char_t = { 4, {{ 0,0 }, { 10,0 }, { 5,0 }, { 5,10 }} }; struct { int cnt; struct xy data[10]; } char_u = { 10, {{ 0,0 } , { 0,8 }, { 0,8 }, { 2,10 }, { 2,10 }, { 8,10 }, { 8,10 }, { 10,8 }, { 10,8 }, { 10,0 }} }; struct { int cnt; struct xy data[4]; } char_v = { 4, {{ 0,0 }, { 5,10 }, { 5,10 }, { 10,0 }} }; struct { int cnt; struct xy data[8]; } char_w = { 8, {{ 0,0 }, { 2,10 }, { 2,10 }, { 5,4 }, { 5,4 }, { 8,10 }, { 8,10 }, { 10,0 }} }; struct { int cnt; struct xy data[4]; } char_x = { 4, {{ 0,0 }, { 10,10 }, { 10,0 }, { 0,10 }} }; struct { int cnt; struct xy data[4]; } char_y = { 4, {{ 0,0 }, { 6,4 }, { 10,0 }, { 2,10 }} }; struct { int cnt; struct xy data[6]; } char_z = { 6, {{ 0,0 }, { 10,0 }, { 10,0 }, { 0,10 }, { 0,10 }, { 10,10 }} }; struct { int cnt; struct xy data[6]; } char_1 = { 6, {{ 2,3 }, { 5,0 }, { 5,0 }, { 5,10 }, { 0,10 }, { 10,10 }} }; struct { int cnt; struct xy data[12]; } char_2 = { 12, {{ 0,2 }, { 2,0 }, { 2,0 }, { 8,0 }, { 8,0 }, { 10,2 }, { 10,2 }, { 10,4 }, { 10,4 }, { 0,10 }, { 0,10 }, { 10,10 }} }; struct { int cnt; struct xy data[16]; } char_3 = { 16, {{ 0,1 }, { 1,0 }, { 1,0 }, { 9,0 }, { 9,0 }, { 10,1 }, { 10,1 }, { 10,9 }, { 10,9 }, { 9,10 }, { 9,10 }, { 1,10 }, { 1,10 }, { 0,9 }, { 3,5 }, { 10,5 }} }; struct { int cnt; struct xy data[6]; } char_4 = { 6, {{ 10,5 }, { 0,5 }, { 0,5 }, { 5,0 }, { 5,0 }, { 5,10 }} }; struct { int cnt; struct xy data[14]; } char_5 = { 14, {{ 10,0 }, { 0,0 }, { 0,0 }, { 0,5 }, { 0,5 }, { 9,5 }, { 9,5 }, { 10,6 }, { 10,6 }, { 10,9 }, { 10,9 }, { 9,10 }, { 9,10 }, { 0,10 }} }; struct { int cnt; struct xy data[18]; } char_6 = { 18, {{ 10,0 }, { 1,0 }, { 1,0 }, { 0,1 }, { 0,1 }, { 0,9 }, { 0,9 }, { 1,10 }, { 1,10 }, { 9,10 }, { 9,10 }, { 10,9 }, { 10,9 }, { 10,6 }, { 10,6 }, { 9,5 }, { 9,5 }, { 0,5 }} }; struct { int cnt; struct xy data[4]; } char_7 = { 4, {{ 0,0 }, { 10,0 }, { 10,0 }, { 2,10 }} }; struct { int cnt; struct xy data[30]; } char_8 = { 30, {{ 1,0 }, { 9,0 }, { 9,0 }, { 10,1 }, { 10,1 }, { 10,4 }, { 10,4 }, { 9,5 }, { 9,5 }, { 10,6 }, { 10,6 }, { 10,9 }, { 10,9 }, { 9,10 }, { 9,10 }, { 1,10 }, { 1,10 }, { 0,9 }, { 0,9 }, { 0,6 }, { 0,6 }, { 1,5 }, { 1,5 }, { 0,4 }, { 0,4 }, { 0,1 }, { 0,1 }, { 1,0 }, { 1,5 }, { 9,5 }} }; struct { int cnt; struct xy data[18]; } char_9 = { 18, {{ 1,10 }, { 9,10 }, { 9,10 }, { 10,9 }, { 10,9 }, { 10,1 }, { 10,1 }, { 9,0 }, { 9,0 }, { 1,0 }, { 1,0 }, { 0,1 }, { 0,1 }, { 0,4 }, { 0,4 }, { 1,5 }, { 1,5 }, { 10,5 }} }; struct { int cnt; struct xy data[18]; } char_0 = { 18, {{ 3,0 }, { 7,0 }, { 7,0 }, { 10,3 }, { 10,3 }, { 10,7 }, { 10,7 }, { 7,10 }, { 7,10 }, { 3,10 }, { 3,10 }, { 0,7 }, { 0,7 }, { 0,3 }, { 0,3 }, { 3,0 }, { 3,10 }, { 7.0 }} }; struct { int cnt; struct xy data[16]; } char_qmark = { 16, {{ 0,2 }, { 2,0 }, { 2,0 }, { 9,0 }, { 9,0 }, { 10,1 }, { 10,1 }, { 10,4 }, { 10,4 }, { 9,5 }, { 9,5 }, { 5,5 }, { 5,5 }, { 5,7 }, { 5,9 }, { 5,10 }} }; struct { int cnt; struct xy data[8]; } char_exmark = { 8, {{ 4,0 }, { 6,0 }, { 6,0 }, { 5,7 }, { 5,7 }, { 4,0 }, { 5,9 }, { 5,10 }} }; struct { int cnt; struct xy data[4]; } char_plus = { 4, {{ 5,0 }, { 5,10 }, { 0,5 }, { 10,5 }} }; struct { int cnt; struct xy data[2]; } char_minus = { 2, {{ 0,5 }, { 10,5 }} }; struct { int cnt; struct xy data[8]; } char_star = { 8, {{ 0,5 }, { 10,5 }, { 5,0 }, { 5,10 }, { 1,1 }, { 9,9 }, { 1,9 }, { 9,1 }} }; struct { int cnt; struct xy data[4]; } char_equals = { 4, {{ 0,3 }, { 10,3 }, { 0,7 }, { 10,7 }} }; struct { int cnt; struct xy data[10]; } char_dot = { 8, {{ 4,8 }, { 6,8 }, { 6,8 }, { 6,10 }, { 6,10 }, { 4,10 }, { 4,10 }, { 4,8 }} }; struct { int cnt; struct xy data[4]; } char_comma = { 4, {{ 7,6 }, { 6,9 }, { 6,9 }, { 4,10 }} }; struct { int cnt; struct xy data[10]; } char_lrbracket = { 10, {{ 6,0 }, { 5,0 }, { 5,0 }, { 3,2 }, { 3,2 }, { 3,8 }, { 3,8 }, { 5,10 }, { 5,10 }, { 6,10 }} }; struct { int cnt; struct xy data[10]; } char_rrbracket = { 10, {{ 3,0 }, { 4,0 }, { 4,0 }, { 6,2 }, { 6,2 }, { 6,8 }, { 6,8 }, { 4,10 }, { 4,10 }, { 3,10 }} }; struct { int cnt; struct xy data[12]; } char_lcbracket = { 12, {{ 6,0 }, { 4,1 }, { 4,1 }, { 4,4 }, { 4,4 }, { 2,5 }, { 2,5 }, { 4,6 }, { 4,6 }, { 4,9 }, { 4,9 }, { 6,10 }} }; struct { int cnt; struct xy data[12]; } char_rcbracket = { 12, {{ 4,0 }, { 6,1 }, { 6,1 }, { 6,4 }, { 6,4 }, { 8,5 }, { 8,5 }, { 6,6 }, { 6,6 }, { 6,9 }, { 6,9 }, { 4,10 }} }; struct { int cnt; struct xy data[6]; } char_lsbracket = { 6, {{ 7,0 }, { 3,0 }, { 3,0 }, { 3,10 }, { 3,10 }, { 7,10 }} }; struct { int cnt; struct xy data[6]; } char_rsbracket = { 6, {{ 3,0 }, { 7,0 }, { 7,0 }, { 7,10 }, { 7,10 }, { 3,10 }} }; struct { int cnt; struct xy data[26]; } char_dollar = { 26, {{ 10,2 }, { 9,1 }, { 9,1 }, { 1,1 }, { 1,1 }, { 0,2 }, { 0,2 }, { 0,4 }, { 0,4 }, { 1,5 }, { 1,5 }, { 9,5 }, { 9,5 }, { 10,6 }, { 10,6 }, { 10,8 }, { 10,8 }, { 9,9 }, { 9,9 }, { 1,9 }, { 1,9 }, { 0,8 }, { 4,0 }, { 4,10 }, { 6,0 }, { 6,10 }} }; struct { int cnt; struct xy data[8]; } char_hash = { 8, {{ 0,3 }, { 10,3 }, { 0,7 }, { 10,7 }, { 3,0 }, { 3,10 }, { 7,0 }, { 7,10 }} }; struct { int cnt; struct xy data[4]; } char_fslash = { 4, {{ 10,0 }, { 0,10 }} }; struct { int cnt; struct xy data[4]; } char_bslash = { 4, {{ 0,0 }, { 10,10 }} }; struct { int cnt; struct xy data[4]; } char_greater = { 4, {{ 10,0 }, { 0,5 }, { 0,5 }, { 10,10 }} }; struct { int cnt; struct xy data[4]; } char_less = { 4, {{ 0,0 }, { 10,5 }, { 10,5 }, { 0,10 }} }; struct { int cnt; struct xy data[2]; } char_underscore = { 2, {{ 0,10 }, { 10,10 }} }; struct { int cnt; struct xy data[2]; } char_bar = { 2, {{ 5,0 }, { 5,10 }} }; struct { int cnt; struct xy data[2]; } char_squote = { 2, {{ 6,0 }, { 4,3 }} }; struct { int cnt; struct xy data[4]; } char_dquote = { 4, {{ 3,0 }, { 3,2 }, { 7,0 }, { 7,2 }} }; struct { int cnt; struct xy data[2]; } char_bquote = { 2, {{ 4,0 }, { 6,3 }} }; struct { int cnt; struct xy data[16]; } char_colon = { 16, {{ 4,1 }, { 6,1 }, { 6,1 }, { 6,3 }, { 6,3 }, { 4,3 }, { 4,3 }, { 4,1 }, { 4,7 }, { 6,7 }, { 6,7 }, { 6,9 }, { 6,9 }, { 4,9 }, { 4,9 }, { 4,7 }} }; struct { int cnt; struct xy data[12]; } char_semicolon = { 12, {{ 4,1 }, { 6,1 }, { 6,1 }, { 6,3 }, { 6,3 }, { 4,3 }, { 4,3 }, { 4,1 }, { 6,6 }, { 6,8 }, { 6,8 }, { 4,10 }} }; struct { int cnt; struct xy data[36]; } char_at = { 36, {{ 7,6 }, { 7,4 }, { 7,4 }, { 6,3 }, { 6,3 }, { 4,3 }, { 4,3 }, { 3,4 }, { 3,4 }, { 3,6 }, { 3,6 }, { 4,7 }, { 4,7 }, { 6,7 }, { 6,7 }, { 7,6 }, { 7,6 }, { 8,7 }, { 8,7 }, { 9,6 }, { 9,6 }, { 9,2 }, { 9,2 }, { 7,0 }, { 7,0 }, { 2,0 }, { 2,0 }, { 0,2 }, { 0,2 }, { 0,8 }, { 0,8 }, { 2,10 }, { 2,10 }, { 8,10 }, { 8,10 }, { 10,8 }} }; struct { int cnt; struct xy data[4]; } char_hat = { 4, {{ 5,0 }, { 1,5 }, { 5,0 }, { 9,5 }} }; struct { int cnt; struct xy data[6]; } char_tilda = { 6, {{ 1,2 }, { 3,0 }, { 3,0 }, { 5,2 }, { 5,2 }, { 7,0 }} }; struct { int cnt; struct xy data[26]; } char_ampersand = { 26, {{ 9,9 }, { 8,10 }, { 8,10 }, { 1,3 }, { 1,3 }, { 1,1 }, { 1,1 }, { 2,0 }, { 2,0 }, { 5,0 }, { 5,0 }, { 6,1 }, { 6,1 }, { 6,3 }, { 6,3 }, { 0,7 }, { 0,7 }, { 0,9 }, { 0,9 }, { 1,10 }, { 1,10 }, { 6,10 }, { 6,10 }, { 8,8 }, { 8,8 }, { 8,7 }} }; /*** Character drawing struct ***/ struct st_char { int x; int y; int pos; int rotang; int rotangadd; double ang; } **charobj; /*** Start here ***/ main(int argc, char **argv) { parse_command_line(argc,argv); init(); mainloop(); } /*** It all happens here ***/ void mainloop() { Window rw,cw; int len,i,j,mx,my,wx,wy,cnt,startcnt; int pmx,pmy; int scrpos,scrticker; u_int pmask; /* Init local vars */ scrticker = 0; scrpos = 0; curr = 0; next = (ctrails > 1); /* Set up character structures */ len = strlen(text); charobj = (struct st_char **)malloc(sizeof(struct st_char *) * ctrails); for(i=0;i < ctrails;++i) { charobj[i] = (struct st_char *)malloc(sizeof(struct st_char) * len); for(j=0;j < len;++j) { charobj[i][j].x = 0; charobj[i][j].y = 0; charobj[i][j].ang = 0; charobj[i][j].rotang = 0; charobj[i][j].pos = i; } } /* Main loop */ for(pmx=0,pmy=0,cnt=0,startcnt = len*ctrails;;pmx=mx,pmy=my) { /* Draw characters after we've hit point where all chars are in start positions */ if (cnt > startcnt) { for(i=len-1;i >= 0;--i) draw(i,text[(i+scrpos) % len]); /* Pause */ if (local_draw) XFlush(display); if (disp2) XFlush(display2); usleep(delay); /* Undraw */ for(i=len-1;i >= 0;--i) draw(i,text[(i+scrpos) % len]); } else ++cnt; /* Calculate new positions and rotations */ XQueryPointer(display,rootwin,&rw,&cw,&mx,&my,&wx,&wy,&pmask); if (scroll && ++scrticker == 3) { scrticker = 0; scrpos--; if (scrpos < 0) scrpos = len-1; } for(i=len-1;i > 0;--i) calc(i,follow ? hypot(mx - pmx,my - pmy) / scale : 0); charobj[next][0].x = mx + 10; charobj[next][0].y = my - 6 * scale; curr = next; next = (next + 1) % ctrails; } } /*** Parse command line args ***/ void parse_command_line(int argc, char **argv) { char *opt[] = { "t", "u", "d", "d2", "sc", "lw", "sr", "rot", "ct", "fol", "nld" }; enum { OPT_TEXT, OPT_DELAY, OPT_DISP, OPT_DISP2, OPT_SCALE, OPT_LWIDTH, OPT_SCROLL, OPT_ROTATE, OPT_CTRAILS, OPT_FOLLOW, OPT_NLD, OPT_END }; char *usage = "Usage: %s\n" " -t \"\"\n" " [-u ]\n" " [-d ] (your display)\n" " [-d2 ] (remote display)\n" " [-sc ] (size of characters)\n" " [-lw '] = (struct char_template *)&char_greater; trans['<'] = (struct char_template *)&char_less; trans['_'] = (struct char_template *)&char_underscore; trans['|'] = (struct char_template *)&char_bar; trans['\''] = (struct char_template *)&char_squote; trans['"'] = (struct char_template *)&char_dquote; trans['`'] = (struct char_template *)&char_bquote; trans[':'] = (struct char_template *)&char_colon; trans[';'] = (struct char_template *)&char_semicolon; trans['@'] = (struct char_template *)&char_at; trans['^'] = (struct char_template *)&char_hat; trans['~'] = (struct char_template *)&char_tilda; trans['&'] = (struct char_template *)&char_ampersand; } /*** Calculate new centre positions ***/ void calc(int pos,double hyp) { if (!follow || hyp < SEP) charobj[next][pos].x = charobj[curr][pos-1].x + (SEP - hyp) * scale; else charobj[next][pos].x = charobj[curr][pos-1].x; charobj[next][pos].y = charobj[curr][pos-1].y; if (rotate) charobj[next][pos].rotang = (charobj[curr][pos].rotang + 10) % 360; } /*** Draw the character at position pos including its trails ***/ void draw(int pos, char ascii) { struct char_template *td; double xb,x1,y1,x2,y2; double xd,yd,cpnt,ang; int i,j; /* Loop through trails for given character */ i = curr; do { if (i == curr) { /* Calculate new rotation angle if not position 0 */ if (pos) { xd = charobj[i][pos].x - charobj[i][pos-1].x; yd = charobj[i][pos].y - charobj[i][pos-1].y; if (!yd) ang = (xd > 0 ? 0 : 180); else if (!xd) ang = (yd > 0 ? 90 : 270); else { ang = atan(yd/xd) * DEGS_PER_RADIAN; if (xd < 0) ang += 180; else if (yd < 0) ang += 360; } ang += charobj[curr][pos].rotang; ang /= DEGS_PER_RADIAN; } else ang = charobj[i][1].ang; /* Cheat, but looks ok. */ } else ang = charobj[i][pos].ang; td = trans[ascii]; cpnt = 11 * scale / 2; /* Draw character */ for(j=0;j < td->cnt;j+=2) { x1 = td->data[j].x * scale; y1 = td->data[j].y * scale; x2 = td->data[j+1].x * scale; y2 = td->data[j+1].y * scale; xb = x1; x1 = ((x1 - cpnt) * cos(ang) - (y1 - cpnt) * sin(ang)) + cpnt; y1 = ((y1 - cpnt) * cos(ang) + (xb - cpnt) * sin(ang)) + cpnt; xb = x2; x2 = ((x2 - cpnt) * cos(ang) - (y2 - cpnt) * sin(ang)) + cpnt; y2 = ((y2 - cpnt) * cos(ang) + (xb - cpnt) * sin(ang)) + cpnt; if (local_draw) XDrawLine( display,rootwin,gc, (int)(charobj[i][pos].x + x1), (int)(charobj[i][pos].y + y1), (int)(charobj[i][pos].x + x2), (int)(charobj[i][pos].y + y2)); if (disp2) XDrawLine( display2,rootwin2,gc2, (int)(charobj[i][pos].x + x1), (int)(charobj[i][pos].y + y1), (int)(charobj[i][pos].x + x2), (int)(charobj[i][pos].y + y2)); } charobj[i][pos].ang = ang; i = (i+1) % ctrails; } while(i != curr); }