BTR_tree BTR_Tree (int dim, leave leaves, double *weights) { int i; int height = (int) LOG2(dim); BTR_tree p = checkedMalloc (sizeof(*p)); if (height) { int j, size = DIV2(dim); p->nodes = checkedMalloc (height * sizeof(BTR_node*)); for (j = 0; j < height; j++) { p->nodes[j] = checkedMalloc (size * sizeof(struct BTR_node_)); size = DIV2(size); } p->height = height - 1; p->father = checkedMalloc (dim * sizeof(int)); } else { p->nodes = checkedMalloc (sizeof(BTR_node*)); p->nodes[0] = checkedMalloc (sizeof(struct BTR_node_)); p->height = 0; p->father = checkedMalloc (sizeof(int)); } p->size = dim; p->leaves = leaves; p->equals = (int*) malloc (dim * sizeof(int)); p->weights = (double*) malloc (dim * sizeof(double)); int totalWeights = 0; if (weights == NULL) { for (i = 0; i < dim; i++) { p->weights[i] = 1; totalWeights += p->weights[i]; } } else { for (i = 0; i < dim; i++) { p->weights[i] = weights[i]; totalWeights += p->weights[i]; } } p->weightedEquals = (int*) malloc (totalWeights * sizeof(int)); p->numEquals = 0; return (p); }
BT_info BT_Info (int mh, int mn) { int j; BT_info p = checkedMalloc (sizeof(*p)); p->fathers = checkedMalloc ((mh + 1) * sizeof(*p->fathers)); p->size = mh; mn = DIV2(mn); for (j = 0; j <= mh; j++) { p->fathers[j] = checkedMalloc (mn * sizeof(int)); mn = DIV2(mn); } return (p); }
VOID MapColors(short num, COLOR_MAP cm, short create) { int i; if (create) { for (i = 0; i < 256; i++) tempbuf[i] = i; } if (cm.FromRange == 0 || num <= 0 || num >= 256) { return; } // from 32 to 32 || 16 to 16 if (cm.ToRange == cm.FromRange) { for (i = 0; i < cm.FromRange; i++) tempbuf[i + cm.FromColor] = i + cm.ToColor; // Quick fix for grey if(cm.ToColor == LT_GREY) tempbuf[cm.FromColor+31] = 0; // Set to black } else // from 32 to 16 if (cm.ToRange == DIV2(cm.FromRange)) { for (i = 0; i < cm.FromRange; i++) tempbuf[cm.FromColor + i] = cm.ToColor + DIV2(i); } else // from 16 to 32 if (DIV2(cm.ToRange) == cm.FromRange) { for (i = 0; i < cm.FromRange; i++) tempbuf[cm.FromColor + DIV2(i)] = cm.ToColor; // Quick fix for grey if(cm.ToColor == LT_GREY) tempbuf[cm.FromColor+31] = 0; // Set to black } }
BT_tree BT_Tree (int dim, leave leaves, int leavesNumber, int *map) { BT_tree p = checkedMalloc (sizeof(*p)); if (dim == 0) { p->nodes = checkedMalloc (sizeof(BT_node*)); p->nodes[0] = checkedMalloc (sizeof(struct BT_node_)); p->height = 0; p->father = checkedMalloc (sizeof(int)); p->size = 1; p->leaves = leaves; p->map = map; return (p); } int height = (int) LOG2(dim); if (height) { int j, size = DIV2(dim); p->nodes = checkedMalloc (height * sizeof(BT_node*)); for (j = 0; j < height; j++) { p->nodes[j] = checkedMalloc (size * sizeof(struct BT_node_)); size = DIV2(size); } p->height = height - 1; p->father = checkedMalloc (leavesNumber * sizeof(int)); for (j = 0; j < leavesNumber; j++) { p->father[j] = NOT_ASSIGNED; } } else { p->nodes = checkedMalloc (sizeof(BT_node*)); p->nodes[0] = checkedMalloc (sizeof(struct BT_node_)); p->height = 0; p->father = checkedMalloc (sizeof(int)); } p->size = dim; p->leaves = leaves; p->map = map; return (p); }
int shDrawRadialGradientMesh(SHPaint *p, SHVector2 *min, SHVector2 *max, VGPaintMode mode, GLenum texUnit) { SHint i, j; float a, n; SHfloat cx = p->radialGradient[0]; SHfloat cy = p->radialGradient[1]; SHfloat fx = p->radialGradient[2]; SHfloat fy = p->radialGradient[3]; float r = p->radialGradient[4]; float fcx, fcy, rr, C; SHVector2 ux; SHVector2 uy; SHVector2 c, f; SHVector2 cf; SHMatrix3x3 *m; SHMatrix3x3 mi; SHint invertible; SHVector2 corners[4]; SHVector2 fcorners[4]; SHfloat minOffset=0.0f; SHfloat maxOffset=0.0f; SHint maxI=0, maxJ=0; SHfloat maxA=0.0f; SHfloat startA=0.0f; int numsteps = 100; float step = 2*PI/numsteps; SHVector2 tmin, tmax; SHVector2 min1, max1, min2, max2; /* Pick paint transform matrix */ SH_GETCONTEXT(0); if (mode == VG_FILL_PATH) m = &context->fillTransform; else if (mode == VG_STROKE_PATH) m = &context->strokeTransform; /* Move focus into circle if outside */ SET2(cf, fx,fy); SUB2(cf, cx,cy); n = NORM2(cf); if (n > r) { DIV2(cf, n); fx = cx + 0.995f * r * cf.x; fy = cy + 0.995f * r * cf.y; } /* Precalculations */ rr = r*r; fcx = fx - cx; fcy = fy - cy; C = fcx*fcx + fcy*fcy - rr; /* Apply paint-to-user transformation to focus and unit vectors */ SET2(f, fx, fy); SET2(c, cx, cy); SET2(ux, 1, 0); SET2(uy, 0, 1); ADD2(ux, cx, cy); ADD2(uy, cx, cy); TRANSFORM2(f, (*m)); TRANSFORM2(c, (*m)); TRANSFORM2(ux, (*m)); TRANSFORM2(uy, (*m)); SUB2V(ux, c); SUB2V(uy, c); /* Boundbox corners */ SET2(corners[0], min->x, min->y); SET2(corners[1], max->x, min->y); SET2(corners[2], max->x, max->y); SET2(corners[3], min->x, max->y); /* Find inverse transformation (back to paint space) */ invertible = shInvertMatrix(m, &mi); if (!invertible || r <= 0.0f) { /* Fill boundbox with color at offset 1 */ SHColor *c = &p->stops.items[p->stops.size-1].color; glColor4fv((GLfloat*)c); glBegin(GL_QUADS); for (i=0; i<4; ++i) glVertex2fv((GLfloat*)&corners[i]); glEnd(); return 1; } /*--------------------------------------------------------*/ /* Find min/max offset */ for (i=0; i<4; ++i) { /* Transform to paint space */ SHfloat ax,ay, A,B,D,t, off; TRANSFORM2TO(corners[i], mi, fcorners[i]); SUB2(fcorners[i], fx, fy); n = NORM2(fcorners[i]); if (n == 0.0f) { /* Avoid zero-length vectors */ off = 0.0f; }else{ /* Distance from focus to circle at corner angle */ DIV2(fcorners[i], n); ax = fcorners[i].x; ay = fcorners[i].y; A = ax*ax + ay*ay; B = 2 * (fcx*ax + fcy*ay); D = B*B - 4*A*C; t = (-B + SH_SQRT(D)) / (2*A); /* Relative offset of boundbox corner */ if (D <= 0.0f) off = 1.0f; else off = n / t; } /* Find smallest and largest offset */ if (off < minOffset || i==0) minOffset = off; if (off > maxOffset || i==0) maxOffset = off; } /* Is transformed focus inside original boundbox? */ if (f.x >= min->x && f.x <= max->x && f.y >= min->y && f.y <= max->y) { /* Draw whole circle */ minOffset = 0.0f; startA = 0.0f; maxA = 2*PI; }else{ /* Find most distant corner pair */ for (i=0; i<3; ++i) { if (ISZERO2(fcorners[i])) continue; for (j=i+1; j<4; ++j) { if (ISZERO2(fcorners[j])) continue; a = ANGLE2N(fcorners[i], fcorners[j]); if (a > maxA || maxA == 0.0f) {maxA=a; maxI=i; maxJ=j;} }} /* Pick starting angle */ if (CROSS2(fcorners[maxI],fcorners[maxJ]) > 0.0f) startA = shVectorOrientation(&fcorners[maxI]); else startA = shVectorOrientation(&fcorners[maxJ]); } /*---------------------------------------------------------*/ /* TODO: for minOffset we'd actually need to find minimum of the gradient function when X and Y are substitued with a line equation for each bound-box edge. As a workaround we use 0.0f for now. */ minOffset = 0.0f; step = PI/50; numsteps = (SHint)SH_CEIL(maxA / step) + 1; glActiveTexture(texUnit); shSetGradientTexGLState(p); glEnable(GL_TEXTURE_1D); glBegin(GL_QUADS); /* Walk the steps and draw gradient mesh */ for (i=0, a=startA; i<numsteps; ++i, a+=step) { /* Distance from focus to circle border at current angle (gradient space) */ float ax = SH_COS(a); float ay = SH_SIN(a); float A = ax*ax + ay*ay; float B = 2 * (fcx*ax + fcy*ay); float D = B*B - 4*A*C; float t = (-B + SH_SQRT(D)) / (2*A); if (D <= 0.0f) t = 0.0f; /* Vectors pointing towards minimum and maximum offset at current angle (gradient space) */ tmin.x = ax * t * minOffset; tmin.y = ay * t * minOffset; tmax.x = ax * t * maxOffset; tmax.y = ay * t * maxOffset; /* Transform back to user space */ min2.x = f.x + tmin.x * ux.x + tmin.y * uy.x; min2.y = f.y + tmin.x * ux.y + tmin.y * uy.y; max2.x = f.x + tmax.x * ux.x + tmax.y * uy.x; max2.y = f.y + tmax.x * ux.y + tmax.y * uy.y; /* Draw quad */ if (i!=0) { glMultiTexCoord1f(texUnit, minOffset); glVertex2fv((GLfloat*)&min1); glVertex2fv((GLfloat*)&min2); glMultiTexCoord1f(texUnit, maxOffset); glVertex2fv((GLfloat*)&max2); glVertex2fv((GLfloat*)&max1); } /* Save prev points */ min1 = min2; max1 = max2; } glEnd(); glDisable(GL_TEXTURE_1D); return 1; }
int shDrawLinearGradientMesh(SHPaint *p, SHVector2 *min, SHVector2 *max, VGPaintMode mode, GLenum texUnit) { SHint i; SHfloat n; SHfloat x1 = p->linearGradient[0]; SHfloat y1 = p->linearGradient[1]; SHfloat x2 = p->linearGradient[2]; SHfloat y2 = p->linearGradient[3]; SHVector2 c, ux, uy; SHVector2 cc, uux, uuy; SHMatrix3x3 *m; SHMatrix3x3 mi; SHint invertible; SHVector2 corners[4]; SHfloat minOffset = 0.0f; SHfloat maxOffset = 0.0f; SHfloat left = 0.0f; SHfloat right = 0.0f; SHVector2 l1,r1,l2,r2; /* Pick paint transform matrix */ SH_GETCONTEXT(0); if (mode == VG_FILL_PATH) m = &context->fillTransform; else if (mode == VG_STROKE_PATH) m = &context->strokeTransform; /* Gradient center and unit vectors */ SET2(c, x1, y1); SET2(ux, x2-x1, y2-y1); SET2(uy, -ux.y, ux.x); n = NORM2(ux); DIV2(ux, n); NORMALIZE2(uy); /* Apply paint-to-user transformation */ ADD2V(ux, c); ADD2V(uy, c); TRANSFORM2TO(c, (*m), cc); TRANSFORM2TO(ux, (*m), uux); TRANSFORM2TO(uy, (*m), uuy); SUB2V(ux,c); SUB2V(uy,c); SUB2V(uux,cc); SUB2V(uuy,cc); /* Boundbox corners */ SET2(corners[0], min->x, min->y); SET2(corners[1], max->x, min->y); SET2(corners[2], max->x, max->y); SET2(corners[3], min->x, max->y); /* Find inverse transformation (back to paint space) */ invertible = shInvertMatrix(m, &mi); if (!invertible || n==0.0f) { /* Fill boundbox with color at offset 1 */ SHColor *c = &p->stops.items[p->stops.size-1].color; glColor4fv((GLfloat*)c); glBegin(GL_QUADS); for (i=0; i<4; ++i) glVertex2fv((GLfloat*)&corners[i]); glEnd(); return 1; } /*--------------------------------------------------------*/ for (i=0; i<4; ++i) { /* Find min/max offset and perpendicular span */ SHfloat o, s; TRANSFORM2(corners[i], mi); SUB2V(corners[i], c); o = DOT2(corners[i], ux) / n; s = DOT2(corners[i], uy); if (o < minOffset || i==0) minOffset = o; if (o > maxOffset || i==0) maxOffset = o; if (s < left || i==0) left = s; if (s > right || i==0) right = s; } /*---------------------------------------------------------*/ /* Corners of boundbox in gradient system */ SET2V(l1, cc); SET2V(r1, cc); SET2V(l2, cc); SET2V(r2, cc); OFFSET2V(l1, uuy, left); OFFSET2V(l1, uux, minOffset * n); OFFSET2V(r1, uuy, right); OFFSET2V(r1, uux, minOffset * n); OFFSET2V(l2, uuy, left); OFFSET2V(l2, uux, maxOffset * n); OFFSET2V(r2, uuy, right); OFFSET2V(r2, uux, maxOffset * n); /* Draw quad using color-ramp texture */ glActiveTexture(texUnit); shSetGradientTexGLState(p); glEnable(GL_TEXTURE_1D); glBegin(GL_QUAD_STRIP); glMultiTexCoord1f(texUnit, minOffset); glVertex2fv((GLfloat*)&r1); glVertex2fv((GLfloat*)&l1); glMultiTexCoord1f(texUnit, maxOffset); glVertex2fv((GLfloat*)&r2); glVertex2fv((GLfloat*)&l2); glEnd(); glDisable(GL_TEXTURE_1D); return 1; }
int WallBreakPosition(short hitwall, short *sectnum, long *x, long *y, long *z, short *ang) { short w,nw; WALLp wp; long nx,ny; short wall_ang; long ret=0; w = hitwall; wp = &wall[w]; nw = wall[w].point2; wall_ang = NORM_ANGLE(getangle(wall[nw].x - wall[w].x, wall[nw].y - wall[w].y)+512); *sectnum = SectorOfWall(w); ASSERT(*sectnum >= 0); // midpoint of wall *x = DIV2(wall[w].x + wall[w].x); *y = DIV2(wall[w].y + wall[w].y); //getzsofsector(*sectnum, *x, *y, cz, fz); if (wp->nextwall < 0) { // white wall *z = DIV2(sector[*sectnum].floorz + sector[*sectnum].ceilingz); } else { short next_sectnum = wp->nextsector; // red wall ASSERT(wp->nextsector >= 0); // floor and ceiling meet if (sector[next_sectnum].floorz == sector[next_sectnum].ceilingz) *z = DIV2(sector[*sectnum].floorz + sector[*sectnum].ceilingz); else // floor is above other sector if (sector[next_sectnum].floorz < sector[*sectnum].floorz) *z = DIV2(sector[next_sectnum].floorz + sector[*sectnum].floorz); else // ceiling is below other sector if (sector[next_sectnum].ceilingz > sector[*sectnum].ceilingz) *z = DIV2(sector[next_sectnum].ceilingz + sector[*sectnum].ceilingz); } *ang = wall_ang; nx = MOVEx(128, wall_ang); ny = MOVEy(128, wall_ang); *x += nx; *y += ny; updatesectorz(*x,*y,*z,sectnum); if (*sectnum < 0) { *x = MAXLONG; // don't spawn shrap, just change wall return(FALSE); } return(TRUE); }
void BTR_initTree (SC_scheduler scheduler, BTR_tree tree) { if (tree->size == 1) { tree->nodes[0][0].value = 0; tree->nodes[0][0].father = 0; tree->nodes[0][0].size = 1; tree->nodes[0][0].visit[0] = NOT_EQUAL; tree->nodes[0][0].visit[1] = NOT_EQUAL; tree->nodes[0][0].visit[2] = NOT_EQUAL; tree->father[0] = 0; return; } unsigned int j, i, size, rightChild, leftChild; int k; int *numberOfNodes; if (tree->size == 2 || tree->size == 3) { numberOfNodes = checkedMalloc (sizeof(int)); numberOfNodes[0] = 0; } else { numberOfNodes = checkedMalloc ((tree->height + 1) * sizeof(int)); } size = DIV2(tree->size); for (j = 0; j < tree->size; j++) { tree->father[j] = DIV2(j); } if (tree->size & ODD) { tree->father[tree->size - 1]--; } if (tree->height) { for (j = 0; j <= tree->height; j++) { numberOfNodes[j] = size - 1; size = DIV2(size); } } for (j = 0; j <= numberOfNodes[0]; j++) { leftChild = MUL2(j); rightChild = MUL2(j) + 1; tree->nodes[0][j].size = 2; tree->nodes[0][j].father = DIV2(j); tree->nodes[0][j].value = MIN(tree->leaves[leftChild], leftChild, tree->leaves[rightChild], rightChild); tree->nodes[0][j].visit[0] = tree->nodes[0][j].value; if (tree->leaves[leftChild] == tree->leaves[rightChild]) { tree->nodes[0][j].visit[1] = rightChild; } else { tree->nodes[0][j].visit[1] = NOT_EQUAL; } } if ((numberOfNodes[0] + 1) & ODD) { tree->nodes[0][numberOfNodes[0]].father--; } if (tree->size & ODD) { j = numberOfNodes[0]; tree->nodes[0][numberOfNodes[0]].size++; rightChild = MUL2(numberOfNodes[0]) + 2; k = tree->nodes[0][numberOfNodes[0]].value; if (tree->leaves[k] == tree->leaves[rightChild]) { if (tree->nodes[0][j].visit[1] != NOT_EQUAL) { tree->nodes[0][j].visit[2] = rightChild; } else { tree->nodes[0][j].visit[1] = rightChild; tree->nodes[0][j].visit[2] = NOT_EQUAL; } } else { tree->nodes[0][j].visit[2] = NOT_EQUAL; tree->nodes[0][numberOfNodes[0]].value = MIN(tree->leaves[k], k, tree->leaves[rightChild], rightChild); if (tree->nodes[0][numberOfNodes[0]].value == rightChild) { tree->nodes[0][j].visit[0] = rightChild; tree->nodes[0][j].visit[1] = NOT_EQUAL; } } } if (tree->height) { for (i = 1; i <= tree->height; i++) { for (j = 0; j <= numberOfNodes[i]; j++) { leftChild = tree->nodes[i - 1][MUL2(j)].value; rightChild = tree->nodes[i - 1][MUL2(j) + 1].value; tree->nodes[i][j].size = 2; tree->nodes[i][j].father = DIV2(j); tree->nodes[i][j].value = MIN(tree->leaves[leftChild], leftChild, tree->leaves[rightChild], rightChild); tree->nodes[i][j].visit[0] = MIN(tree->leaves[leftChild], MUL2(j), tree->leaves[rightChild], MUL2(j)+1); if (tree->leaves[leftChild] == tree->leaves[rightChild]) { tree->nodes[i][j].visit[1] = MUL2(j) + 1; } else { tree->nodes[i][j].visit[1] = NOT_EQUAL; } } if ((numberOfNodes[i] + 1) & ODD) { tree->nodes[i][numberOfNodes[i]].father--; } if ((numberOfNodes[i - 1] + 1) & ODD) { j = numberOfNodes[i]; tree->nodes[i][numberOfNodes[i]].size++; rightChild = tree->nodes[i - 1][MUL2(numberOfNodes[i]) + 2].value; k = tree->nodes[i][numberOfNodes[i]].value; if (tree->leaves[k] == tree->leaves[rightChild]) { if (tree->nodes[i][j].visit[1] != NOT_EQUAL) { tree->nodes[i][j].visit[2] = MUL2(numberOfNodes[i]) + 2; } else { tree->nodes[i][j].visit[1] = MUL2(numberOfNodes[i]) + 2; tree->nodes[i][j].visit[2] = NOT_EQUAL; } } else { tree->nodes[i][j].visit[2] = NOT_EQUAL; tree->nodes[i][numberOfNodes[i]].value = MIN( tree->leaves[k], k, tree->leaves[rightChild], rightChild); if (tree->nodes[i][numberOfNodes[i]].value == rightChild) { tree->nodes[i][j].visit[0] = MUL2(numberOfNodes[i]) + 2; tree->nodes[i][j].visit[1] = NOT_EQUAL; } } } } tree->numEquals = 0; tree->randomRange = 0; scheduler->state->visit->fathers[tree->height][0] = 0; int visitNodes = 1; for (i = tree->height; i >= 1; i--) { int nNodes = visitNodes; visitNodes = 0; for (j = 0; j < nNodes; j++) { int upd = scheduler->state->visit->fathers[i][j]; int cChilds = tree->nodes[i][upd].size; for (k = 0; k < cChilds; k++) { int add = tree->nodes[i][upd].visit[k]; if (add != NOT_EQUAL) { scheduler->state->visit->fathers[i - 1][visitNodes++] = add; } else { break; } } } } for (i = 0; i < visitNodes; i++) { int upd = scheduler->state->visit->fathers[0][i]; int cChilds = tree->nodes[0][upd].size; for (j = 0; j < cChilds; j++) { int add = tree->nodes[0][upd].visit[j]; if (add != NOT_EQUAL) { tree->equals[add] = add; tree->numEquals++; int g, w = tree->randomRange + tree->weights[add]; for (g = tree->randomRange; g < w; g++) { tree->weightedEquals[g] = add; } tree->randomRange += tree->weights[add]; } } } if (tree->numEquals > 1) { shuffle (tree->weightedEquals, tree->randomRange); int selected = tree->weightedEquals[0]; tree->nodes[tree->height][0].value = selected; tree->equals[selected] = NOT_ASSIGNED; tree->num = 1; tree->numEquals--; } else { tree->numEquals = 0; } } free (numberOfNodes); }
/* routine computes the correctly rounded (to nearest) value of atan(x). */ double atan (double x) { double cor, s1, ss1, s2, ss2, t1, t2, t3, t7, t8, t9, t10, u, u2, u3, v, vv, w, ww, y, yy, z, zz; #ifndef DLA_FMS double t4, t5, t6; #endif int i, ux, dx; static const int pr[M] = { 6, 8, 10, 32 }; number num; num.d = x; ux = num.i[HIGH_HALF]; dx = num.i[LOW_HALF]; /* x=NaN */ if (((ux & 0x7ff00000) == 0x7ff00000) && (((ux & 0x000fffff) | dx) != 0x00000000)) return x + x; /* Regular values of x, including denormals +-0 and +-INF */ SET_RESTORE_ROUND (FE_TONEAREST); u = (x < 0) ? -x : x; if (u < C) { if (u < B) { if (u < A) { math_check_force_underflow_nonneg (u); return x; } else { /* A <= u < B */ v = x * x; yy = d11.d + v * d13.d; yy = d9.d + v * yy; yy = d7.d + v * yy; yy = d5.d + v * yy; yy = d3.d + v * yy; yy *= x * v; if ((y = x + (yy - U1 * x)) == x + (yy + U1 * x)) return y; EMULV (x, x, v, vv, t1, t2, t3, t4, t5); /* v+vv=x^2 */ s1 = f17.d + v * f19.d; s1 = f15.d + v * s1; s1 = f13.d + v * s1; s1 = f11.d + v * s1; s1 *= v; ADD2 (f9.d, ff9.d, s1, 0, s2, ss2, t1, t2); MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (f7.d, ff7.d, s1, ss1, s2, ss2, t1, t2); MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (f5.d, ff5.d, s1, ss1, s2, ss2, t1, t2); MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (f3.d, ff3.d, s1, ss1, s2, ss2, t1, t2); MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); MUL2 (x, 0, s1, ss1, s2, ss2, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (x, 0, s2, ss2, s1, ss1, t1, t2); if ((y = s1 + (ss1 - U5 * s1)) == s1 + (ss1 + U5 * s1)) return y; return atanMp (x, pr); } } else { /* B <= u < C */ i = (TWO52 + TWO8 * u) - TWO52; i -= 16; z = u - cij[i][0].d; yy = cij[i][5].d + z * cij[i][6].d; yy = cij[i][4].d + z * yy; yy = cij[i][3].d + z * yy; yy = cij[i][2].d + z * yy; yy *= z; t1 = cij[i][1].d; if (i < 112) { if (i < 48) u2 = U21; /* u < 1/4 */ else u2 = U22; } /* 1/4 <= u < 1/2 */ else { if (i < 176) u2 = U23; /* 1/2 <= u < 3/4 */ else u2 = U24; } /* 3/4 <= u <= 1 */ if ((y = t1 + (yy - u2 * t1)) == t1 + (yy + u2 * t1)) return __signArctan (x, y); z = u - hij[i][0].d; s1 = hij[i][14].d + z * hij[i][15].d; s1 = hij[i][13].d + z * s1; s1 = hij[i][12].d + z * s1; s1 = hij[i][11].d + z * s1; s1 *= z; ADD2 (hij[i][9].d, hij[i][10].d, s1, 0, s2, ss2, t1, t2); MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (hij[i][7].d, hij[i][8].d, s1, ss1, s2, ss2, t1, t2); MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (hij[i][5].d, hij[i][6].d, s1, ss1, s2, ss2, t1, t2); MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (hij[i][3].d, hij[i][4].d, s1, ss1, s2, ss2, t1, t2); MUL2 (z, 0, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (hij[i][1].d, hij[i][2].d, s1, ss1, s2, ss2, t1, t2); if ((y = s2 + (ss2 - U6 * s2)) == s2 + (ss2 + U6 * s2)) return __signArctan (x, y); return atanMp (x, pr); } } else { if (u < D) { /* C <= u < D */ w = 1 / u; EMULV (w, u, t1, t2, t3, t4, t5, t6, t7); ww = w * ((1 - t1) - t2); i = (TWO52 + TWO8 * w) - TWO52; i -= 16; z = (w - cij[i][0].d) + ww; yy = cij[i][5].d + z * cij[i][6].d; yy = cij[i][4].d + z * yy; yy = cij[i][3].d + z * yy; yy = cij[i][2].d + z * yy; yy = HPI1 - z * yy; t1 = HPI - cij[i][1].d; if (i < 112) u3 = U31; /* w < 1/2 */ else u3 = U32; /* w >= 1/2 */ if ((y = t1 + (yy - u3)) == t1 + (yy + u3)) return __signArctan (x, y); DIV2 (1, 0, u, 0, w, ww, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); t1 = w - hij[i][0].d; EADD (t1, ww, z, zz); s1 = hij[i][14].d + z * hij[i][15].d; s1 = hij[i][13].d + z * s1; s1 = hij[i][12].d + z * s1; s1 = hij[i][11].d + z * s1; s1 *= z; ADD2 (hij[i][9].d, hij[i][10].d, s1, 0, s2, ss2, t1, t2); MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (hij[i][7].d, hij[i][8].d, s1, ss1, s2, ss2, t1, t2); MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (hij[i][5].d, hij[i][6].d, s1, ss1, s2, ss2, t1, t2); MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (hij[i][3].d, hij[i][4].d, s1, ss1, s2, ss2, t1, t2); MUL2 (z, zz, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (hij[i][1].d, hij[i][2].d, s1, ss1, s2, ss2, t1, t2); SUB2 (HPI, HPI1, s2, ss2, s1, ss1, t1, t2); if ((y = s1 + (ss1 - U7)) == s1 + (ss1 + U7)) return __signArctan (x, y); return atanMp (x, pr); } else { if (u < E) { /* D <= u < E */ w = 1 / u; v = w * w; EMULV (w, u, t1, t2, t3, t4, t5, t6, t7); yy = d11.d + v * d13.d; yy = d9.d + v * yy; yy = d7.d + v * yy; yy = d5.d + v * yy; yy = d3.d + v * yy; yy *= w * v; ww = w * ((1 - t1) - t2); ESUB (HPI, w, t3, cor); yy = ((HPI1 + cor) - ww) - yy; if ((y = t3 + (yy - U4)) == t3 + (yy + U4)) return __signArctan (x, y); DIV2 (1, 0, u, 0, w, ww, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10); MUL2 (w, ww, w, ww, v, vv, t1, t2, t3, t4, t5, t6, t7, t8); s1 = f17.d + v * f19.d; s1 = f15.d + v * s1; s1 = f13.d + v * s1; s1 = f11.d + v * s1; s1 *= v; ADD2 (f9.d, ff9.d, s1, 0, s2, ss2, t1, t2); MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (f7.d, ff7.d, s1, ss1, s2, ss2, t1, t2); MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (f5.d, ff5.d, s1, ss1, s2, ss2, t1, t2); MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (f3.d, ff3.d, s1, ss1, s2, ss2, t1, t2); MUL2 (v, vv, s2, ss2, s1, ss1, t1, t2, t3, t4, t5, t6, t7, t8); MUL2 (w, ww, s1, ss1, s2, ss2, t1, t2, t3, t4, t5, t6, t7, t8); ADD2 (w, ww, s2, ss2, s1, ss1, t1, t2); SUB2 (HPI, HPI1, s1, ss1, s2, ss2, t1, t2); if ((y = s2 + (ss2 - U8)) == s2 + (ss2 + U8)) return __signArctan (x, y); return atanMp (x, pr); } else { /* u >= E */ if (x > 0) return HPI; else return MHPI; } } } }