Exemple #1
0
void
resize(void)
{
	Rectangle old, r;
	int dxo, dyo, dxn, dyn;
	Win *w;
	
	old = screen->r;
	dxo = Dx(old);
	dyo = Dy(old);
	if(getwindow(display, Refnone) < 0)
		sysfatal("resize failed: %r");
	dxn = Dx(screen->r);
	dyn = Dy(screen->r);
	freescreen(scr);
	scr = allocscreen(screen, display->white, 0);
	if(scr == nil)
		sysfatal("allocscreen: %r");
	for(w = wlist.next; w != &wlist; w = w->next){
		r = rectsubpt(w->entire, old.min);
		r.min.x = muldiv(r.min.x, dxn, dxo);
		r.max.x = muldiv(r.max.x, dxn, dxo);
		r.min.y = muldiv(r.min.y, dyn, dyo);
		r.max.y = muldiv(r.max.y, dyn, dyo);
		w->entire = rectaddpt(r, screen->r.min);
		w->inner = insetrect(w->entire, BORDSIZ);
		freeimage(w->im);
		w->im = allocwindow(scr, w->entire, Refbackup, 0);
		if(w->im == nil)
			sysfatal("allocwindow: %r");
		draw(w->im, w->inner, w->tab->cols[BACK], nil, ZP);
		border(w->im, w->entire, BORDSIZ, w->tab->cols[w == actw ? BORD : DISB], ZP);
		w->tab->draw(w);
	}
}
Exemple #2
0
mr_small smul(mr_small x,mr_small y,mr_small n)
{ /* returns x*y mod n */
    mr_small r;

#ifdef MR_ITANIUM
    mr_small tm;
#endif
#ifdef MR_WIN64
    mr_small tm;
#endif
#ifdef MR_FP
    mr_small dres;
#endif
#ifndef MR_NOFULLWIDTH
    if (n==0)
    { /* Assume n=2^MIRACL */
        muldvd(x,y,(mr_small)0,&r);
        return r;
    }
#endif
    x=MR_REMAIN(x,n);
    y=MR_REMAIN(y,n);
    muldiv(x,y,(mr_small)0,n,&r);
    return r;
}
bool ZLTextView::PositionIndicator::onStylusPress(int x, int y) {
	x = myTextView.visualX(x);

	const long bottom = this->bottom();
	const long top = this->top();
	const long left = this->left();
	const long right = this->right();

	if ((x < left) || (x > right) || (y < top) || (y > bottom)) {
		return false;
	}

	const std::vector<size_t> &textSizeVector = myTextView.myTextSize;
	if (textSizeVector.size() <= 1) {
		return true;
	}

	if (myTextView.endCursor().isNull()) {
		return false;
	}
	size_t fullTextSize = sizeOfTextBeforeParagraph(endTextIndex());
	size_t textSize = muldiv(fullTextSize, x - left + 1, right - left + 1);

	myTextView.gotoCharIndex(textSize);

	return true;
}
Exemple #4
0
uint8_t CubeFace::GetFaceCoordinates(const VK::ivec3 &v, int &x, int &y)
{
	uint8_t nFace;
	int ax = VK::Math::Abs(v.x), ay = VK::Math::Abs(v.y), az = VK::Math::Abs(v.z);
	int sc, tc, ma;
	if(ax > ay && ax > az) {
		ma = ax;
		sc = v.z;
		tc = -v.y;
		if(v.x > 0) {
			nFace = RightFace;
			sc = -sc;
		} else {
			nFace = LeftFace;
		}
	} else if(ay > az) {
		ma = ay;
		sc = v.x;
		tc = v.z;
		if(v.y > 0) {
			nFace = TopFace;
		} else {
			nFace = BottomFace;
			tc = -tc;
		}
	} else {
		ma = az;
		sc = v.x;
		tc = -v.y;
		if(v.z > 0) {
			nFace = FrontFace;
		} else {
			nFace = BackFace;
			sc = -sc;
		}
	}

	// x and y should be approximately from MinCoord to MaxCoord
	x = (muldiv(sc, MaxCoord, ma) + MaxCoord) >> 1;
	y = (muldiv(tc, MaxCoord, ma) + MaxCoord) >> 1;
	return nFace;
}
Exemple #5
0
mr_small spmd(mr_small x,mr_small n,mr_small m) 
{ /*  returns x^n mod m  */
    mr_small r,sx;
#ifdef MR_FP
    mr_small dres;
#endif
    x=MR_REMAIN(x,m);
    r=0;
    if (x==0) return r;
    r=1;
    if (n==0) return r;
    sx=x;
    forever
    {
        if (MR_REMAIN(n,2)!=0) muldiv(r,sx,(mr_small)0,m,&r);
        n=MR_DIV(n,2);
        if (n==0) return r;
        muldiv(sx,sx,(mr_small)0,m,&sx);
    }
}
size_t ZLTextView::PositionIndicator::sizeOfTextBeforeCursor(const ZLTextWordCursor &cursor) const {
	const size_t paragraphIndex = cursor.paragraphCursor().index();
	const size_t paragraphLength = cursor.paragraphCursor().paragraphLength();

	if (paragraphLength == 0) {
		return sizeOfTextBeforeParagraph(paragraphIndex);
	} else {
		return
			sizeOfTextBeforeParagraph(paragraphIndex) +
			muldiv(sizeOfParagraph(paragraphIndex), cursor.elementIndex(), paragraphLength);
	}
}
Exemple #7
0
/*
 * Return the specified percentage of a off_t.
 */
off_t
percent_pos(off_t pos, int percent, long fraction)
{
	/*
	 * Change percent (parts per 100) to perden
	 * (parts per NUM_FRAC_DENOM).
	 */
	off_t perden = (percent * (NUM_FRAC_DENOM / 100)) + (fraction / 100);

	if (perden == 0)
		return (0);
	return (muldiv(pos, perden, (off_t)NUM_FRAC_DENOM));
}
void ZLTextView::PositionIndicator::draw() {
	ZLTextBaseStyle &baseStyle = ZLTextStyleCollection::instance().baseStyle();

	ZLPaintContext &context = this->context();

	ZLTextWordCursor endCursor = myTextView.endCursor();
	bool isEndOfText = false;
	if (endCursor.isEndOfParagraph()) {
		isEndOfText = !endCursor.nextParagraph();
	}

	myExtraWidth = 0;
	if (myInfo.isTimeShown()) {
		drawExtraText(timeString());
	}
	if (myInfo.isBatteryShown()) {
		drawExtraText(batteryString());
	}
	if (myInfo.isTextPositionShown()) {
		drawExtraText(textPositionString());
	}

	const long bottom = this->bottom();
	const long top = this->top();
	const long left = this->left();
	const long right = this->right();

	if (left >= right) {
		return;
	}

	size_t fillWidth = right - left - 1;

	if (!isEndOfText) {
		fillWidth =
			muldiv(fillWidth, sizeOfTextBeforeCursor(myTextView.endCursor()), sizeOfTextBeforeParagraph(endTextIndex()));
	}

	context.setColor(baseStyle.RegularTextColorOption.value());
	context.setFillColor(myInfo.color());
	context.fillRectangle(myTextView.visualX(left + 1), top + 1, myTextView.visualX(left + fillWidth + 1), bottom - 1);
	context.drawLine(myTextView.visualX(left), top, myTextView.visualX(right), top);
	context.drawLine(myTextView.visualX(left), bottom, myTextView.visualX(right), bottom);
	context.drawLine(myTextView.visualX(left), bottom, myTextView.visualX(left), top);
	context.drawLine(myTextView.visualX(right), bottom, myTextView.visualX(right), top);
}
void ZLTextView::PositionIndicator::draw() {
	ZLPaintContext &context = this->context();

	ZLTextWordCursor endCursor = myTextView.textArea().endCursor();
	bool isEndOfText = false;
	if (endCursor.isEndOfParagraph()) {
		isEndOfText = !endCursor.nextParagraph();
	}

	myExtraWidth = 0;
	if (myInfo.isTimeShown()) {
		drawExtraText(timeString());
	}
	if (myInfo.isTextPositionShown()) {
		drawExtraText(textPositionString());
	}

	const long bottom = this->bottom();
	const long top = this->top();
	const long left = this->left();
	const long right = this->right();

	if (left >= right) {
		return;
	}

	size_t fillWidth = right - left - 1;

	if (!isEndOfText) {
		fillWidth =
			muldiv(fillWidth, sizeOfTextBeforeCursor(myTextView.textArea().endCursor()), sizeOfTextBeforeParagraph(endTextIndex()));
	}

	context.setColor(myTextView.color());
	context.setFillColor(myInfo.color());
	context.fillRectangle(left + 1, top + 1, left + fillWidth + 1, bottom - 1);
	context.drawLine(left, top, right, top);
	context.drawLine(left, bottom, right, bottom);
	context.drawLine(left, bottom, left, top);
	context.drawLine(right, bottom, right, top);
}
Exemple #10
0
void
drawoverlay(void)
{
	int major, minor;
	int hi, lo, x, y;
	Point omaj, omin, p;

	y = muldiv(2000, UNITMAG, scrn.mag);
	for(x = 0; mmap[x] < y; x++);
	major = mmap[x];
	minor = major/5;
	omaj.x = ((scrn.br.origin.x+major-1)/major)*major;
	omaj.y = ((scrn.br.origin.y+major-1)/major)*major;
	omin.x = ((scrn.br.origin.x+minor-1)/minor)*minor;
	omin.y = ((scrn.br.origin.y+minor-1)/minor)*minor;

	lo = scrn.br.origin.y;
	hi = scrn.br.corner.y;
	for(x = omaj.x; x < scrn.br.corner.x; x += major){
		segment(&screen, pbtos(Pt(x, lo)), pbtos(Pt(x, hi)), 0xf, F_XOR);
		for(y = omin.y; y < hi; y += minor){
			if((y-omaj.y)%major == 0) continue;
			p = pbtos(Pt(x, y));
			segment(&screen, Pt(p.x-10, p.y), Pt(p.x+10, p.y), 0xf, F_XOR);
		}
	}
	lo = scrn.br.origin.x;
	hi = scrn.br.corner.x;
	for(y = omaj.y; y < scrn.br.corner.y; y += major){
		segment(&screen, pbtos(Pt(lo, y)), pbtos(Pt(hi, y)), 0xf, F_XOR);
		for(x = omin.x; x < hi; x += minor){
			if((x-omaj.x)%major == 0) continue;
			p = pbtos(Pt(x, y));
			segment(&screen, Pt(p.x, p.y-10), Pt(p.x, p.y+10), 0xf, F_XOR);
		}
	}
}
Exemple #11
0
mr_small sqrmp(mr_small x,mr_small m)
{ /* square root mod a small prime by Shanks method  *
   * returns 0 if root does not exist or m not prime */
    mr_small z,y,v,w,t,q;
#ifdef MR_FP
    mr_small dres;
#endif
    int i,e,n,r;
    BOOL pp;
    x=MR_REMAIN(x,m);
    if (x==0) return 0;
    if (x==1) return 1;
    if (spmd(x,(mr_small)((m-1)/2),m)!=1) return 0;    /* Legendre symbol not 1   */
    if (MR_REMAIN(m,4)==3) return spmd(x,(mr_small)((m+1)/4),m);  /* easy case for m=4.k+3   */
    if (MR_REMAIN(m,8)==5)
    { /* also relatively easy */
        t=spmd(x,(mr_small)((m-1)/4),m);
        if (t==1) return spmd(x,(mr_small)((m+3)/8),m);
        if (t==(mr_small)(m-1))
        {
            muldiv((mr_small)4,x,(mr_small)0,m,&t);
            t=spmd(t,(mr_small)((m+3)/8),m);
            muldiv(t,(mr_small)((m+1)/2),(mr_small)0,m,&t);
            return t;
        }
        return 0;
    }
    q=m-1;
    e=0;
    while (MR_REMAIN(q,2)==0) 
    {
        q=MR_DIV(q,2);
        e++;
    }
    if (e==0) return 0;      /* even m */
    for (r=2;;r++)
    { /* find suitable z */
        z=spmd((mr_small)r,q,m);
        if (z==1) continue;
        t=z;
        pp=FALSE;
        for (i=1;i<e;i++)
        { /* check for composite m */
            if (t==(m-1)) pp=TRUE;
            muldiv(t,t,(mr_small)0,m,&t);
            if (t==1 && !pp) return 0;
        }
        if (t==(m-1)) break;
        if (!pp) return 0;   /* m is not prime */
    }
    y=z;
    r=e;
    v=spmd(x,(mr_small)((q+1)/2),m);
    w=spmd(x,q,m);
    while (w!=1)
    {
        t=w;
        for (n=0;t!=1;n++) muldiv(t,t,(mr_small)0,m,&t);
        if (n>=r) return 0;
        y=spmd(y,mr_shiftbits(1,r-n-1),m);
        muldiv(v,y,(mr_small)0,m,&v);
        muldiv(y,y,(mr_small)0,m,&y);
        muldiv(w,y,(mr_small)0,m,&w);
        r=n;
    }
    return v;
}
Exemple #12
0
/*
 * Return the ratio of two off_t, as a percentage.
 * {{ Assumes a off_t is a long int. }}
 */
int
percentage(off_t num, off_t den)
{
	return ((int)muldiv(num, (off_t)100, den));
}
Exemple #13
0
int egcd(_MIPD_ big x,big y,big z)
{ /* greatest common divisor z=gcd(x,y) by Euclids  *
   * method using Lehmers algorithm for big numbers */
    int q,r,a,b,c,d,n;
    mr_small sr,m,sm;
    mr_small u,v,lq,lr;
#ifdef MR_FP
    mr_small dres;
#endif
    big t;
#ifndef MR_GENERIC_MT
    miracl *mr_mip=get_mip();
#endif
    if (mr_mip->ERNUM) return 0;

    MR_IN(12)

    copy(x,mr_mip->w1);
    copy(y,mr_mip->w2);
    insign(PLUS,mr_mip->w1);
    insign(PLUS,mr_mip->w2);
    a=b=c=d=0;
    while (size(mr_mip->w2)!=0)
    {
        if (b==0)
        { /* update w1 and w2 */
            divide(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w2);
            t=mr_mip->w1,mr_mip->w1=mr_mip->w2,mr_mip->w2=t;   /* swap(w1,w2) */
        }
        else
        {
            premult(_MIPP_ mr_mip->w1,c,z);
            premult(_MIPP_ mr_mip->w1,a,mr_mip->w1);
            premult(_MIPP_ mr_mip->w2,b,mr_mip->w0);
            premult(_MIPP_ mr_mip->w2,d,mr_mip->w2);
            add(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w1);
            add(_MIPP_ mr_mip->w2,z,mr_mip->w2);
        }
        if (mr_mip->ERNUM || size(mr_mip->w2)==0) break;
        n=(int)mr_mip->w1->len;
        if (mr_mip->w2->len==1)
        { /* special case if mr_mip->w2 is now small */
            sm=mr_mip->w2->w[0];    
#ifdef MR_FP_ROUNDING
            sr=mr_sdiv(_MIPP_ mr_mip->w1,sm,mr_invert(sm),mr_mip->w1);
#else
            sr=mr_sdiv(_MIPP_ mr_mip->w1,sm,mr_mip->w1);
#endif
            if (sr==0)
            {
                copy(mr_mip->w2,mr_mip->w1);
                break;
            }
            zero(mr_mip->w1);
            mr_mip->w1->len=1;
            mr_mip->w1->w[0]=sr;
            while ((sr=MR_REMAIN(mr_mip->w2->w[0],mr_mip->w1->w[0]))!=0)
                  mr_mip->w2->w[0]=mr_mip->w1->w[0],mr_mip->w1->w[0]=sr;
            break;
        }
        a=1;
        b=0;
        c=0;
        d=1;
        m=mr_mip->w1->w[n-1]+1;
        if (mr_mip->base==0)
        {
#ifndef MR_NOFULLWIDTH
            if (m==0)
            {
                u=mr_mip->w1->w[n-1];
                v=mr_mip->w2->w[n-1];
            }
            else
            {
                u=muldvm(mr_mip->w1->w[n-1],mr_mip->w1->w[n-2],m,&sr);
                v=muldvm(mr_mip->w2->w[n-1],mr_mip->w2->w[n-2],m,&sr);
            }
#endif
        }
        else
        {
            u=muldiv(mr_mip->w1->w[n-1],mr_mip->base,mr_mip->w1->w[n-2],m,&sr);
            v=muldiv(mr_mip->w2->w[n-1],mr_mip->base,mr_mip->w2->w[n-2],m,&sr);
        }
        forever
        { /* work only with most significant piece */
            if (((v+c)==0) || ((v+d)==0)) break;
            lq=MR_DIV((u+a),(v+c));
            if (lq!=MR_DIV((u+b),(v+d))) break;
            if (lq>=(mr_small)(MR_TOOBIG/mr_abs(d))) break;
            q=(int)lq;
            r=a-q*c;
            a=c;
            c=r;
            r=b-q*d;
            b=d;
            d=r;
            lr=u-lq*v;
            u=v;
            v=lr;
        }
    }
    copy(mr_mip->w1,z);
    MR_OUT
    return (size(mr_mip->w1));
}
Exemple #14
0
static int euclid(_MIPD_ big x,int num)
{ /* outputs next c.f. quotient from gcd(w5,w6) */
    mr_small sr,m;
#ifdef MR_FP
    mr_small dres;
#endif
    mr_small lr,lq;
    big t;
#ifndef MR_GENERIC_MT
    miracl *mr_mip=get_mip();
#endif
    if (num==0)
    {
        mr_mip->oldn=(-1);
        mr_mip->carryon=FALSE;
        mr_mip->last=FALSE;
        if (compare(mr_mip->w6,mr_mip->w5)>0)
        { /* ensure w5>w6 */
            t=mr_mip->w5,mr_mip->w5=mr_mip->w6,mr_mip->w6=t;
            return (mr_mip->q=0);
        }
    }
    else if (num==mr_mip->oldn || mr_mip->q<0) return mr_mip->q;
    mr_mip->oldn=num;
    if (mr_mip->carryon) goto middle;
start:
    if (size(mr_mip->w6)==0) return (mr_mip->q=(-1));
    mr_mip->ndig=(int)mr_mip->w5->len;
    mr_mip->carryon=TRUE;
    mr_mip->a=1;
    mr_mip->b=0;
    mr_mip->c=0;
    mr_mip->d=1;
    if (mr_mip->ndig==1)
    {
        mr_mip->last=TRUE;
        mr_mip->u=mr_mip->w5->w[0];
        mr_mip->v=mr_mip->w6->w[0];
    }
    else
    {
        m=mr_mip->w5->w[mr_mip->ndig-1]+1;
        if (mr_mip->base==0)
        {
#ifndef MR_NOFULLWIDTH
            if (m==0)
            {
                mr_mip->u=mr_mip->w5->w[mr_mip->ndig-1];
                mr_mip->v=mr_mip->w6->w[mr_mip->ndig-1];
            }
            else
            {
                mr_mip->u=muldvm(mr_mip->w5->w[mr_mip->ndig-1],mr_mip->w5->w[mr_mip->ndig-2],m,&sr);
                mr_mip->v=muldvm(mr_mip->w6->w[mr_mip->ndig-1],mr_mip->w6->w[mr_mip->ndig-2],m,&sr);
            }
#endif
        }
        else
        {
            mr_mip->u=muldiv(mr_mip->w5->w[mr_mip->ndig-1],mr_mip->base,mr_mip->w5->w[mr_mip->ndig-2],m,&sr);
            mr_mip->v=muldiv(mr_mip->w6->w[mr_mip->ndig-1],mr_mip->base,mr_mip->w6->w[mr_mip->ndig-2],m,&sr);
        }
    }
    mr_mip->ku=mr_mip->u;
    mr_mip->kv=mr_mip->v;
middle:
    forever
    { /* work only with most significant piece */
        if (mr_mip->last)
        {
            if (mr_mip->v==0) return (mr_mip->q=(-1));
            lq=MR_DIV(mr_mip->u,mr_mip->v);
        }
        else
        {
            if (((mr_mip->v+mr_mip->c)==0) || ((mr_mip->v+mr_mip->d)==0)) break;
            lq=MR_DIV((mr_mip->u+mr_mip->a),(mr_mip->v+mr_mip->c));
            if (lq!=MR_DIV((mr_mip->u+mr_mip->b),(mr_mip->v+mr_mip->d))) break;
        }
        if (lq>=(mr_small)(MR_TOOBIG/mr_abs(mr_mip->d))) break;

        mr_mip->q=(int)lq;
        mr_mip->r=mr_mip->a-mr_mip->q*mr_mip->c;
        mr_mip->a=mr_mip->c;
        mr_mip->c=mr_mip->r;
        mr_mip->r=mr_mip->b-mr_mip->q*mr_mip->d;
        mr_mip->b=mr_mip->d;
        mr_mip->d=mr_mip->r;
        lr=mr_mip->u-lq*mr_mip->v;
        mr_mip->u=mr_mip->v;
        mr_mip->v=lr;
        return mr_mip->q;
    }
    mr_mip->carryon=FALSE;
    if (mr_mip->b==0)
    { /* update w5 and w6 */
        mr_mip->check=OFF;
        divide(_MIPP_ mr_mip->w5,mr_mip->w6,mr_mip->w7);
        mr_mip->check=ON;
        if (mr_lent(mr_mip->w7)>mr_mip->nib) return (mr_mip->q=(-2));
        t=mr_mip->w5,mr_mip->w5=mr_mip->w6,mr_mip->w6=t;   /* swap(w5,w6) */
        copy(mr_mip->w7,x);
        return (mr_mip->q=size(x));
    }
    else
    {
        mr_mip->check=OFF;
        premult(_MIPP_ mr_mip->w5,mr_mip->c,mr_mip->w7);
        premult(_MIPP_ mr_mip->w5,mr_mip->a,mr_mip->w5);
        premult(_MIPP_ mr_mip->w6,mr_mip->b,mr_mip->w0);
        premult(_MIPP_ mr_mip->w6,mr_mip->d,mr_mip->w6);
        add(_MIPP_ mr_mip->w5,mr_mip->w0,mr_mip->w5);
        add(_MIPP_ mr_mip->w6,mr_mip->w7,mr_mip->w6);
        mr_mip->check=ON;
    }
    goto start;
}
/**
 * \brief Find maximum corner speed between two moves.
 * \details Find out how fast we can move around around a corner without
 * exceeding the expected jerk. Worst case this speed is zero, which means a
 * full stop between both moves. Best case it's the lower of the maximum speeds.
 *
 * This function is expected to be called from within dda_create().
 *
 * \param [in] prev is the DDA structure of the move previous to the current one.
 * \param [in] current is the DDA structure of the move currently created.
 *
 * \return dda->crossF
 */
void dda_find_crossing_speed(DDA *prev, DDA *current) {
  uint32_t F, dv, speed_factor, max_speed_factor;
  axes_int32_t prevF, currF;
  enum axis_e i;

  // Bail out if there's nothing to join (e.g. G1 F1500).
  if ( ! prev || prev->nullmove)
    return;

  // We always look at the smaller of both combined speeds,
  // else we'd interpret intended speed changes as jerk.
  F = prev->endpoint.F;
  if (current->endpoint.F < F)
    F = current->endpoint.F;

  if (DEBUG_DDA && (debug_flags & DEBUG_DDA))
    sersendf_P(PSTR("Distance: %lu, then %lu\n"),
               prev->distance, current->distance);

  // Find individual axis speeds.
  // TODO: this is eight expensive muldiv()s. It should be possible to store
  //       currF as prevF for the next calculation somehow, to save 4 of
  //       these 8 muldiv()s. This would also allow to get rid of
  //       dda->delta_um[] and using delta_um[] from dda_create() instead.
  //       Caveat: bail out condition above and some other non-continuous
  //               situations might need some extra code for handling.
  for (i = X; i < AXIS_COUNT; i++) {
    prevF[i] = muldiv(prev->delta_um[i], F, prev->distance);
    currF[i] = muldiv(current->delta_um[i], F, current->distance);
  }

  if (DEBUG_DDA && (debug_flags & DEBUG_DDA))
    sersendf_P(PSTR("prevF: %ld  %ld  %ld  %ld\ncurrF: %ld  %ld  %ld  %ld\n"),
               prevF[X], prevF[Y], prevF[Z], prevF[E],
               currF[X], currF[Y], currF[Z], currF[E]);

  /**
   * What we want is (for each axis):
   *
   *   delta velocity = dv = |v1 - v2| < max_jerk
   *
   * In case this isn't satisfied, we can slow down by some factor x until
   * the equitation is satisfied:
   *
   *   x * |v1 - v2| < max_jerk
   *
   * Now computation is pretty straightforward:
   *
   *        max_jerk
   *   x = -----------
   *        |v1 - v2|
   *
   *   if x > 1: continue full speed
   *   if x < 1: v = v_max * x
   *
   * See also: https://github.com/Traumflug/Teacup_Firmware/issues/45
   */
  max_speed_factor = (uint32_t)2 << 8;

  for (i = X; i < AXIS_COUNT; i++) {
    dv = currF[i] > prevF[i] ? currF[i] - prevF[i] : prevF[i] - currF[i];
    if (dv) {
      speed_factor = ((uint32_t)pgm_read_dword(&maximum_jerk_P[i]) << 8) / dv;
      if (speed_factor < max_speed_factor)
        max_speed_factor = speed_factor;
      if (DEBUG_DDA && (debug_flags & DEBUG_DDA))
        sersendf_P(PSTR("%c: dv %lu of %lu   factor %lu of %lu\n"),
                   'X' + i, dv, (uint32_t)pgm_read_dword(&maximum_jerk_P[i]),
                   speed_factor, (uint32_t)1 << 8);
    }
  }

  if (max_speed_factor >= ((uint32_t)1 << 8))
    current->crossF = F;
  else
    current->crossF = (F * max_speed_factor) >> 8;

  if (DEBUG_DDA && (debug_flags & DEBUG_DDA))
    sersendf_P(PSTR("Cross speed reduction from %lu to %lu\n"),
               F, current->crossF);

  return;
}
/**
 * \brief Join 2 moves by removing the full stop between them, where possible.
 * \details To join the moves, the deceleration ramp of the previous move and
 * the acceleration ramp of the current move are shortened, resulting in a
 * non-zero speed at that point. The target speed at the corner is already to
 * be found in dda->crossF. See dda_find_corner_speed().
 *
 * Ideally, both ramps can be reduced to actually have Fcorner at the corner,
 * but the surrounding movements might no be long enough to achieve this speed.
 * Analysing both moves to find the best result is done here.
 *
 * TODO: to achieve better results with short moves (move distance < both ramps),
 *       this function should be able to enhance the corner speed on repeated
 *       calls when reverse-stepping through the movement queue.
 *
 * \param [in] prev is the DDA structure of the move previous to the current one.
 * \param [in] current is the DDA structure of the move currently created.
 *
 * Premise: the 'current' move is not dispatched in the queue: it should remain
 * constant while this function is running.
 *
 * Note: the planner always makes sure the movement can be stopped within the
 * last move (= 'current'); as a result a lot of small moves will still limit the speed.
 */
void dda_join_moves(DDA *prev, DDA *current) {

  // Calculating the look-ahead settings can take a while; before modifying
  // the previous move, we need to locally store any values and write them
  // when we are done (and the previous move is not already active).
  uint32_t prev_F, prev_F_in_steps, prev_F_start_in_steps, prev_F_end_in_steps;
  uint32_t prev_rampup, prev_rampdown, prev_total_steps;
  uint32_t crossF, crossF_in_steps;
  uint8_t prev_id;
  // Similarly, we only want to modify the current move if we have the results of the calculations;
  // until then, we do not want to touch the current move settings.
  // Note: we assume 'current' will not be dispatched while this function runs, so we do not to
  // back up the move settings: they will remain constant.
  uint32_t this_F, this_F_in_steps, this_F_start_in_steps, this_rampup, this_rampdown, this_total_steps;
  uint8_t this_id;
  static uint32_t la_cnt = 0;     // Counter: how many moves did we join?
  #ifdef LOOKAHEAD_DEBUG
  static uint32_t moveno = 0;     // Debug counter to number the moves - helps while debugging
  moveno++;
  #endif

  // Bail out if there's nothing to join (e.g. G1 F1500).
  if ( ! prev || prev->nullmove || current->crossF == 0)
    return;

    // Show the proposed crossing speed - this might get adjusted below.
    if (DEBUG_DDA && (debug_flags & DEBUG_DDA))
      sersendf_P(PSTR("Initial crossing speed: %lu\n"), current->crossF);

  // Make sure we have 2 moves and the previous move is not already active
  if (prev->live == 0) {
    // Perform an atomic copy to preserve volatile parameters during the calculations
    ATOMIC_START
      prev_id = prev->id;
      prev_F = prev->endpoint.F;
      prev_F_start_in_steps = prev->start_steps;
      prev_F_end_in_steps = prev->end_steps;
      prev_rampup = prev->rampup_steps;
      prev_rampdown = prev->rampdown_steps;
      prev_total_steps = prev->total_steps;
      crossF = current->crossF;
      this_id = current->id;
      this_F = current->endpoint.F;
      this_total_steps = current->total_steps;
    ATOMIC_END

    // Here we have to distinguish between feedrate along the movement
    // direction and feedrate of the fast axis. They can differ by a factor
    // of 2.
    // Along direction: F, crossF.
    // Along fast axis already: start_steps, end_steps.
    //
    // All calculations here are done along the fast axis, so recalculate
    // F and crossF to match this, too.
    prev_F = muldiv(prev->fast_um, prev_F, prev->distance);
    this_F = muldiv(current->fast_um, current->endpoint.F, current->distance);
    crossF = muldiv(current->fast_um, crossF, current->distance);

    // TODO: calculate the steps from the fastest axis and not from X.
    prev_F_in_steps = ACCELERATE_RAMP_LEN(prev_F);
    this_F_in_steps = ACCELERATE_RAMP_LEN(this_F);
    crossF_in_steps = ACCELERATE_RAMP_LEN(crossF);

    // Show the proposed crossing speed - this might get adjusted below
    if (DEBUG_DDA && (debug_flags & DEBUG_DDA))
      sersendf_P(PSTR("Initial crossing speed: %lu\n"), crossF_in_steps);

    // Compute the maximum speed we can reach for crossing.
    crossF_in_steps = MIN(crossF_in_steps, this_total_steps);
    crossF_in_steps = MIN(crossF_in_steps, prev_total_steps + prev_F_start_in_steps);

    if (crossF_in_steps == 0)
      return;

    // Build ramps for previous move.
    if (crossF_in_steps == prev_F_in_steps) {
      prev_rampup = prev_F_in_steps - prev_F_start_in_steps;
      prev_rampdown = 0;
    }
    else if (crossF_in_steps < prev_F_start_in_steps) {
      uint32_t extra, limit;

      prev_rampup = 0;
      prev_rampdown = prev_F_start_in_steps - crossF_in_steps;
      extra = (prev_total_steps - prev_rampdown) >> 1;
      limit = prev_F_in_steps - prev_F_start_in_steps;
      extra = MIN(extra, limit);

      prev_rampup += extra;
      prev_rampdown += extra;
    }
Exemple #17
0
main()
{
	char buff[100];
	int cn, r, k, t, dt, lp, x, rx, ry;
	int oldx, oldy, newx, newy;
	int offx, offy;
	Point jstring();
	char *getstring();
	Point p;
	int nonstop = NONSTOP;

	local();
	request(MOUSE);
	/* random number seed is derived from position of dmd layer */
	srand(mouse.xy.x);
	request(KBD);
	for ( ;; ) {
		lp = dt = 0;
		if ( nonstop == 0 ) {
			/* ask for lp parameter */
			jmoveto(Pt(0,0));
			p = jstring("loops=");
			lp = getnum(p);
			jmoveto(Pt(0,0));
			jstring("loops=");
		}
		if ( lp < 0 )
			exit();
		if ( lp == 0 )
			lp = rand() % 31 + 1;

		if ( nonstop == 0 ) {
			/* ask for dt parameter */
			jmoveto(Pt(0,0));
			p = jstring("delta=");
			dt = getnum(p);
			jmoveto(Pt(0,0));
			jstring("delta=");
		}
		if ( dt <= 0 )
			dt = rand() % 358 + 1;

		/* clear screen */
		jrectf(Jrect,F_CLR);
		t=0; 
		oldx = offx = XMAX / 2;
		oldy = offy = YMAX / 2;
		cn = 1;
		/* draw rose */
		do {
			t=(t+dt)%360;
			x=(lp*t)%360;
			r = Isin(x);
			rx=muldiv(r,XMAX-1,1024);
			ry=muldiv(r,YMAX-1,1024);
			newx = offx + muldiv(rx,Icos(t),1024) / 2;
			newy = offy +  muldiv(ry,Isin(t),1024) / 2;
			jsegment(Pt(oldx,oldy),Pt(newx,newy),F_STORE);
			oldx=newx; 
			oldy=newy;
			/* give up the CPU every 10 times around */
			if ( cn++ > 10 ) {
				cn = 0;
				sleep(4);
			}
		} while ( t != 0 && (k=kbdchar()) != 'q' ) ;
		if ( nonstop == 1 ) {
			/* in nonstop mode, any key aborts */
			if ( k != -1 )
				exit();
			/* sleep 2 seconds between random patterns */
			sleep(120);
		}
	}
}
Exemple #18
0
void CubeFace::GetFaceCoordinates(unsigned char nFace, const VK::ivec3 &v, int &x, int &y)
{
	// The vector passed in may not be in the specified face.
	// If not, the coordinates within nFace closest to v are returned.
	// (This helps find the shortest distance from a point to a node in the quad-tree)
	switch(nFace) {
		case RightFace:
			if(v.x < 0) { // If v is in the left, force the coordinates to the nearest corner of this face.
				x = v.z > 0 ? -MaxCoord : MaxCoord;
				y = v.y > 0 ? -MaxCoord : MaxCoord;
			} else {
				x = v.x <= VK::Math::Abs(v.z) ? (v.z > 0 ? -MaxCoord : MaxCoord) : muldiv(-v.z, MaxCoord, v.x);
				y = v.x <= VK::Math::Abs(v.y) ? (v.y > 0 ? -MaxCoord : MaxCoord) : muldiv(-v.y, MaxCoord, v.x);
			}
			break;
		case LeftFace:
			if(v.x > 0) { // If v is in the right, force the coordinates to the nearest corner of this face.
				x = v.z > 0 ? MaxCoord : -MaxCoord;
				y = v.y > 0 ? -MaxCoord : MaxCoord;
			} else {
				x = -v.x <= VK::Math::Abs(v.z) ? (v.z > 0 ? MaxCoord : -MaxCoord) : muldiv(v.z, MaxCoord, -v.x);
				y = -v.x <= VK::Math::Abs(v.y) ? (v.y > 0 ? -MaxCoord : MaxCoord) : muldiv(-v.y, MaxCoord, -v.x);
			}
			break;
		case TopFace:
			if(v.y < 0) { // If v is in the bottom, force the coordinates to the nearest corner of this face.
				x = v.x > 0 ? MaxCoord : -MaxCoord;
				y = v.z > 0 ? MaxCoord : -MaxCoord;
			} else {
				x = v.y <= VK::Math::Abs(v.x) ? (v.x > 0 ? MaxCoord : -MaxCoord) : muldiv(v.x, MaxCoord, v.y);
				y = v.y <= VK::Math::Abs(v.z) ? (v.z > 0 ? MaxCoord : -MaxCoord) : muldiv(v.z, MaxCoord, v.y);
			}
			break;
		case BottomFace:
			if(v.y > 0) { // If v is in the top, force the coordinates to the nearest corner of this face.
				x = v.x > 0 ? MaxCoord : -MaxCoord;
				y = v.z > 0 ? -MaxCoord : MaxCoord;
			} else {
				x = -v.y <= VK::Math::Abs(v.x) ? (v.x > 0 ? MaxCoord : -MaxCoord) : muldiv(v.x, MaxCoord, -v.y);
				y = -v.y <= VK::Math::Abs(v.z) ? (v.z > 0 ? -MaxCoord : MaxCoord) : muldiv(-v.z, MaxCoord, -v.y);
			}
			break;
		case FrontFace:
			if(v.z < 0) { // If v is in the back, force the coordinates to the nearest corner of this face.
				x = v.x > 0 ? MaxCoord : -MaxCoord;
				y = v.y > 0 ? -MaxCoord : MaxCoord;
			} else {
				x = v.z <= VK::Math::Abs(v.x) ? (v.x > 0 ? MaxCoord : -MaxCoord) : muldiv(v.x, MaxCoord, v.z);
				y = v.z <= VK::Math::Abs(v.y) ? (v.y > 0 ? -MaxCoord : MaxCoord) : muldiv(-v.y, MaxCoord, v.z);
			}
			break;
		case BackFace:
			if(v.z > 0) { // If v is in the front, force the coordinates to the nearest corner of this face.
				x = v.x > 0 ? -MaxCoord : MaxCoord;
				y = v.y > 0 ? -MaxCoord : MaxCoord;
			} else {
				x = -v.z <= VK::Math::Abs(v.x) ? (v.x > 0 ? -MaxCoord : MaxCoord) : muldiv(-v.x, MaxCoord, -v.z);
				y = -v.z <= VK::Math::Abs(v.y) ? (v.y > 0 ? -MaxCoord : MaxCoord) : muldiv(-v.y, MaxCoord, -v.z);
			}
			break;
	}

	x = (x + MaxCoord) >> 1;
	y = (y + MaxCoord) >> 1;
}
Exemple #19
0
  { if(la&1) { q += qn;
               r += rn;
               if(r>=lc) { q++; r -= lc; }
            }
    la  >>= 1;
/*    la = la & 0x7FFFFFFF;*/
    qn <<= 1;
    rn <<= 1;
    if(rn>=lc) {qn++; rn -= lc; }
  }
  result2 = rneg ? -r : r;
  return qneg ? -q : q;
}

void try(INT32 a, INT32 b, INT32 c)
{ INT32 x = muldiv(a, b, c), y = muldiva(a, b, c);
  printf("muldiv (%8x, %8x, %8x) = %8x,  remainder %8x\n",
          a, b, c, x, result2);
  printf("muldiva(%8x, %8x, %8x) = %8x,  remainder %8x\n\n",
          a, b, c, y, result2a);
}

int main()
{ int i,j,k;
  INT32 w = 0x80000000;

  try(4,5,6);
  try(-5,6,7);
  try(-5,-6,7);
  try(-5,6,-7);
  try(5,-6,7);
Exemple #20
0
Fichier : clib.c Projet : 8l/bcpl
BCPLWORD dosys(register BCPLWORD *p, register BCPLWORD *g)
{ register BCPLWORD i;
  /*PRINTFD("dosys(%" FormD ", ", (BCPLWORD)p); */
  /*PRINTFD("%" FormD, g); */
  /*PINTFD(") P3=%" FormD " ", p[3]); */
  /*PRINTFD("P4=%" FormD "\n",  p[4]); */

  switch((int)(p[3]))
  { default: printf("\nBad sys %ld\n", (long)p[3]);  return p[3];
  
    /* case Sys_setcount: set count               -- done in cinterp
    ** case Sys_quit:     return from interpreter -- done in cinterp

    ** case Sys_rti:      sys(Sys_rti, regs)      -- done in cinterp  Cintpos
    ** case Sys_saveregs: sys(Sys_saveregs, regs) -- done in cinterp  Cintpos
    ** case Sys_setst:    sys(Sys_setst, st)      -- done in cinterp  Cintpos
    */
    case Sys_tracing:  /* sys(Sys_tracing, b)  */
      tracing = p[4];
      return 0;
    /* case Sys_watch:    sys(Sys_watch, addr)    -- done in cinterp
    */
    /*
    case  Sys_tally:         // sys(Sys_tally, flag) 
      if(p[4]) {
        tallylim = tallyupb;
        for(i=1; i<=tallylim; i++) tallyv[i] = 0;
      } else {
        tallylim = 0;
      }
      return 0;
     
    case Sys_interpret: // call interpreter (recursively)
    { BCPLWORD regsv = p[4];
      if(W[regsv+7]>=0 || slowflag) return interpret(regsv, W);
      return CINTASM  (regsv, W);
    }
    */

    case Sys_sardch:
    { BCPLWORD ch;
      /*printf("parmp=%d parms[0]=%d\n", parmp, parms[0]); */
      if(parmp<=parms[0]) {  /* Added MR 10/04/06 */
        /* Read the command arguments (without echo) first. */
        /*printf("sardch: parmp=%d parms[0]=%d\n", parmp, parms[0]); */
        /*printf("sardch: returning %d\n", parms[parmp]); */
        return parms[parmp++];
      }
      ch = Readch();
      if (ttyinp) {  /* echo tty input only */
        if (ch>=0) putchar((char)ch);
        if(ch==13) { ch = 10; putchar(10); }
        fflush(stdout);
      }
      return ch;
    }

    case Sys_sawrch:
      if(p[4] == 10) putchar(13);
      putchar((char)p[4]);
      fflush(stdout);
      return 0;

    case Sys_read:  /* bytesread := sys(Sys_read, fp, buf, bytecount) */
    { FILE *fp = findfp(p[4]);
      char *bbuf = (char *)(p[5]<<B2Wsh);
      BCPLWORD len   = p[6];
      len = fread(bbuf, (size_t)1, (size_t)len, fp);
      return len;
    }

    case Sys_write:
      { FILE *fp = findfp(p[4]);
        char *bbuf = (char *)(p[5]<<B2Wsh);
        BCPLWORD len = p[6];
        len = WD fwrite(bbuf, (size_t)1, (size_t)len, fp);
        fflush(fp);
        return len;
      }

    case Sys_openread:
      { char *name = b2c_str(p[4], chbuf1);
        FILEPT fp;
        fp = pathinput(name,                      /* Filename */
                       b2c_str(p[5], chbuf2));    /* Environment variable */
        if(fp==0) return 0L;
        return newfno(fp);
      }

    case Sys_openwrite:
      { char *name = b2c_str(p[4], chbuf1);
        FILEPT fp;
        fp = fopen(osfname(name, chbuf4), "wb");
        if(fp==0) return 0L;
        return newfno(fp);
      }

    case Sys_openappend:
      { char *name = b2c_str(p[4], chbuf1);
        FILEPT fp;
        fp = fopen(osfname(name, chbuf4), "ab");
        if(fp==0) return 0L;
        return newfno(fp);
      }

    case Sys_openreadwrite:
      { char *name = b2c_str(p[4], chbuf1);
	FILEPT fp;
        fp = fopen(osfname(name, chbuf4), "rb+");
        if(fp==0) fp = fopen(name, "wb+");
        if(fp==0) return 0L;
        return newfno(fp);
      }

    case Sys_close:
    { BCPLWORD res = fclose(findfp(p[4]));
      freefno(p[4]);
      return res==0 ? -1 : 0; /* res==0 means success */
    }

    case Sys_deletefile:
    { char *name = b2c_str(p[4], chbuf1);
      FILEPT fp;
      name = osfname(name, chbuf4);
#ifdef VMSNAMES
      { /* Append ';*' to name */
        int len = 0;
        while (name[len]) len++;
        name[len++] = ';';
        name[len++] = '*';
        name[len] = 0;
      }
#endif
      return ! REMOVE(name);
    }

    case Sys_renamefile:
    { char *name1 = b2c_str(p[4], chbuf1);
      char *name2 = b2c_str(p[5], chbuf2);
      int len = 0;
      name1 = osfname(name1, chbuf3);
      name2 = osfname(name2, chbuf4);
#ifdef VMSNAMES
      { /* Append ';*' to name2 */
        len = 0;
        while (name2[len]) len++;
        name2[len]   = ';';
        name2[len+1] = '*';
        name2[len+2] = 0;
      }
#endif
      REMOVE(name2);
#ifdef VMSNAMES
      name2[len] = 0;
#endif
      return ! rename(name1, name2);
    }

    case Sys_getvec:
      return ((BCPLWORD)(malloc((1+p[4])<<B2Wsh)))>>B2Wsh;

    case Sys_freevec:
      free((void *)(p[4]<<B2Wsh)); return -1;
/*
    case Sys_loadseg:
      return loadseg(b2c_str(p[4], chbuf1));

    case Sys_globin:
      return globin(p[4], g);

    case Sys_unloadseg:
      unloadseg(p[4]);                    return 0;
*/

    case Sys_muldiv:
      //printf("dosys: calling muldiv(%d, %d, %d)\n", p[4], p[5], p[6]);
    { BCPLWORD res =  muldiv(p[4], p[5], p[6]);
	//printf("res=%d   result2=%d\n", res, result2);
      globbase[Gn_result2] = result2;
      return res;
    }

    case Sys_intflag:
      return intflag() ? -1L : 0L;

/*
    case Sys_setraster:
      return setraster(p[4], p[5]);
*/

    case Sys_cputime: /* Return CPU time in milliseconds  */
      return muldiv(clock(), 1000, TICKS_PER_SEC);

#ifndef forWinCE
    case Sys_filemodtime:
    /* sys(Sys_filemodtime, filename, datv)
       Set the elements of datv to represent the date and time of
       the last modification of the given file, returning TRUE if
       successful and FALSE otherwise. datv!0 is the number of days
       since 1 January 1970, datv!1 is the number of milli-seconds
       since midnight and datv!2=-1 indicating that the new date and
       time format is being used.
       If the file does not exist or there is an error then
       FALSE is returned and the elements of datv are set to 0, 0 and
       -1, respectively.
    */
    { struct stat buf;
      BCPLWORD days, secs, msecs;
      char *name = b2c_str(p[4], chbuf1);
      BCPLWORD *datestamp = (BCPLWORD *)(p[5]<<B2Wsh);
      if (stat(osfname(name, chbuf4), &buf)) {
        datestamp[0] = 0;
        datestamp[1] = 0;
        datestamp[2] = -1;
        return 0;
      }
      secs = buf.st_mtime;
      // nsecs = buf.st_mtimensec; // nano second time, if poss
      days = secs / (24*60*60);
      msecs = (secs % (24*60*60)) * 1000;
      datestamp[0] = days;
      datestamp[1] = msecs;
      datestamp[2] = -1;  // New dat format
      //printf("filemodtime: name=%s days=%" FormD " msecs=%" FormD "\n",
      //        name, days, msecs);
      return -1;
    }
#endif

    case Sys_setprefix: /* Set the file name prefix string  */
    { BCPLWORD str = p[4];
      char *fp = (char*)(str<<B2Wsh);
      char *tp = prefixbp;
      int i, len=*fp;
      if(len>63) return 0;
      for (i=0; i<=len; i++) *tp++ = *fp++;
      return prefixstr;
    }

    case Sys_getprefix: /* Return the file name prefix string  */
      return prefixstr;

    case Sys_graphics: /* Perform an operation on the graphics window  */
      return sysGraphics(p);

    case 35: /* Return TRUE if no keyboard character is available */
#ifdef forWinCE
              return chBufEmpty() ? -1 : 0;
#else
              return -1;
#endif

    case 36:   return 0; /* Spare */

    case 37:   return 0; /* Spare  */

    case Sys_seek:  /* res := sys(Sys_seek, fd, pos)   */
    { FILEPT fp = findfp(p[4]);
      BCPLWORD pos = p[5];
      BCPLWORD res = fseek(fp, pos, SEEK_SET);
      /*printf("fseek => res=%d errno=%d\n", res, errno); */
      /*g[Gn_result2] = errno; */
      return res==0 ? -1 : 0; /* res=0 succ, res=-1 error  */
    }

    case Sys_tell: /* pos := sys(Sys_tell,fd)  */
    { FILE *fp = findfp(p[4]);
      BCPLWORD pos = ftell(fp);
      /*g[Gn_result2] = errno; */
      return pos; /* >=0 succ, -1=error */
    }

    case Sys_waitirq: /* Wait for irq */
      /*
      pthread_mutex_lock  (         &irq_mutex);
      pthread_cond_wait   (&irq_cv, &irq_mutex);
      pthread_mutex_unlock(         &irq_mutex);
      */
      return 0;

    case Sys_lockirq: /* Stop all devices from modifying */
                      /* packets or generating interrupts */
      /*
      pthread_mutex_lock(&irq_mutex);
      */
      return 0;

    case Sys_unlockirq: /* Allow devices to modify packets */
                        /* and generate interrupts */
      /*
      pthread_mutex_unlock(&irq_mutex);
      */
      return 0;

    case Sys_devcom: /* res := sys(Sys_devcom, dcb, com, arg) */
      return 0; /*devcommand(W[p+4], W[p+5], W[p+6]); */

    case Sys_datstamp: /* res := sys(Sys_datstamp, v)  */
    // Set v!0 = days  since 1 January 1970
    //     v!1 = msecs since midnight
    //     v!2 = ticks =-1 for new dat format
    // Return -1 if successful
      return timestamp((BCPLWORD*)(p[4]));

    case Sys_filesize:  /* res := sys(Sys_filesize, fd)   */
      { FILEPT fp   = findfp(p[4]);
        long pos  = ftell(fp);
        BCPLWORD rc   = fseek(fp, 0, SEEK_END);
        BCPLWORD size = ftell(fp);
        rc  = fseek(fp, pos, SEEK_SET);
        if (rc) size = -1;
        return size; /* >=0 succ, -1=error  */
      }

     case Sys_getsysval: /* res := sys(Sys_getsysval, addr) */
     { BCPLWORD *addr = (BCPLWORD*)p[4];
       return *addr;
     }

     case Sys_putsysval: /* res := sys(Sys_putsysval, addr, val) */
     { BCPLWORD *addr = (BCPLWORD*)p[4];
       *addr = p[5];
       return 0;
     }

     case Sys_shellcom: /* res := sys(Sys_shellcom, comstr) */
     { char *comstr = (char*)(p[4]<<2);
       int i;
       char com[256];
       int len = strlen(comstr);
       for(i=0; i<len; i++) com[i] = comstr[i+1];
       com[len] = 0;
       /*
       printf("\ndosys: calling shell command %s\n", com);
       */
       return system(com);
     }

     case Sys_getpid: /* res := sys(Sys_getpid) */
       return getpid();

     case Sys_dumpmem: /* sys(Sys_dumpmem, context) */
       printf("\nCintpos memory not dumped to DUMP.mem\n");
       return 0;

     case Sys_callnative:
     { /* Call native code. */
       int(*rasmfn)(void) = (int(*)(void))&p[4];
       return rasmfn();
     }              

    case Sys_platform:
              { /* Return platform code, 0 if unknown */
		BCPLWORD res = 0;
#ifdef forMAC
		res = 1;
#endif
#ifdef forMIPS
		res = 2;
#endif
#ifdef forSGI
		res = 3;
#endif
#ifdef forARM
		res = 4;
#endif
#ifdef forLINUX
		res = 5;
#endif
#ifdef forLINUXamd64
		res = 6;
#endif
#ifdef forCYGWIN32
		res = 7;
#endif
#ifdef forLINUXPPC
		res = 8;
#endif
#ifdef forSUN4
		res = 9;
#endif
#ifdef forSPARC
		res = 10;
#endif
#ifdef forALPHA
		res = 11;
#endif
#ifdef forMSDOS
		res = 12;
#endif
#ifdef forOS2
		res = 13;
#endif
#ifdef forSHwinCE
		res = 14;
#endif
#ifdef forMIPSwinCE
		res = 15;
#endif
                return res;
              }              

    case Sys_inc: /* newval := sys(Sys_inc, ptr, amount) */
              { /* !ptr := !ptr + amount; RESULTIS !ptr */
                return 0; /**p[4] += p[5];*/
              }

    case Sys_buttons: /* Return bit pattern of buttons currently
                          pressed on the GP2X */
#ifdef forGP2X
              { unsigned long buttons = 0;
	        int fd = open("/dev/GPIO", O_RDWR | O_NDELAY);
	        if (fd<0) return -1;
                if (read(fd, &buttons, 4) != 4) return -2;
                close(fd);
                return (BCPLWORD)buttons;
              }
#else
              return -3;

#endif

    case Sys_delay: /* sys(Sys_delay, msecs) */
              { unsigned int msecs = (unsigned int)p[4];
                msecdelay(msecs);
                return 0;
              }

    case Sys_sound: /* res := sys(Sys_sound, fno, a1, a2,...) */
#ifdef SOUND
                return soundfn(&p[4], &g[0]);
#else
                return 0;
#endif

    case Sys_sdl: /* res := sys(Sys_sdl, fno, a1, a2,...) */
#ifdef SDLavail
      return sdlfn(&((BCPLWORD*)p)[4], &((BCPLWORD*)g)[0], 0/*W*/);
#else
      return 0;
#endif

    case Sys_callc: /* res := sys(Sys_callc, fno, a1, a2,...) */
#ifdef CALLC
      /*
         printf("dosys: sys(Sys_callc, %" FormD ", %" FormD ", %" FormD", ...)\n",
                 W[p+4], W[p+5], W[p+6]);
      */
      return 0;//callc(&p[4], &g[0]);
#else
                return -1;
#endif

    case Sys_trpush: /* sys(Sys_trpush, val) */
                trpush(p[4]);
                return 0;

    case Sys_settrcount: /* res := sys(Sys_settrcount, count) */
                return settrcount(p[4]);

    case Sys_gettrval: /* res := sys(Sys_gettrval, count) */
                return gettrval(p[4]);

    case Sys_flt: /* res := sys(Sys_flt, op, a, b)) */
              { BCPLWORD res = doflt(p[4], p[5], p[6], p[7]);
                globbase[Gn_result2] = result2;
		//g[Gn_result2] = result2;
		//if(W[p+4]==35)
		//printf("sys_flt: op=%d res=%08" FormX " result2=%08" FormX "\n",
                //       W[p+4], (UBCPLWORD)res, (UBCPLWORD)result2);
                return res;
              }

    case Sys_pollsardch: /* res := sys(Sys_pollsardch) */
              {
                // Return a character if available otherwise pollch (=-3)
                return pollReadch();
              }

    case Sys_incdcount: /* res := sys(Sys_incdcount, n) */
                return incdcount(p[4]);


		//#ifndef forWinCE
    case 135:
    { /* Return system date and time in VEC 5 */
      time_t clk = time(0);
      struct tm *now = gmtime(&clk);
      BCPLWORD *arg = PT(p[4] << B2Wsh);
      arg[0] = now->tm_year+1900;
      arg[1] = now->tm_mon+1;
      arg[2] = now->tm_mday;
      arg[3] = now->tm_hour;
      arg[4] = now->tm_min;
      arg[5] = now->tm_sec;
      return 0;
    }

    case 136: /* Return current directory in VEC 1 + 256/bytesperword */
    { char *res = getcwd(chbuf1, 256);
      c2b_str(chbuf1, p[4]);
      return 0;
    }

    case 137:
      return (BCPLWORD)parms >> B2Wsh;
  }
  // This is unreadchable
  // return 0;
}
Exemple #21
0
int xgcd(_MIPD_ big x,big y,big xd,big yd,big z)
{ /* greatest common divisor by Euclids method  *
   * extended to also calculate xd and yd where *
   *      z = x.xd + y.yd = gcd(x,y)            *
   * if xd, yd not distinct, only xd calculated *
   * z only returned if distinct from xd and yd *
   * xd will always be positive, yd negative    */

    int s,n,iter;
    mr_small r,a,b,c,d;
    mr_small q,m,sr;
#ifdef MR_FP
    mr_small dres;
#endif

#ifdef mr_dltype
    union doubleword uu,vv;
    mr_large u,v,lr;
#else
    mr_small u,v,lr;
#endif

    BOOL last,dplus=TRUE;
    big t;
#ifdef MR_OS_THREADS
    miracl *mr_mip=get_mip();
#endif

    if (mr_mip->ERNUM) return 0;

    MR_IN(30)

#ifdef MR_COUNT_OPS
    fpx++; 
#endif
  
    copy(x,mr_mip->w1);
    copy(y,mr_mip->w2);
    s=exsign(mr_mip->w1);
    insign(PLUS,mr_mip->w1);
    insign(PLUS,mr_mip->w2);
    convert(_MIPP_ 1,mr_mip->w3);
    zero(mr_mip->w4);
    last=FALSE;
    a=b=c=d=0;
    iter=0;

    while (size(mr_mip->w2)!=0)
    {
        if (b==0)
        { /* update mr_mip->w1 and mr_mip->w2 */

            divide(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w5);
            t=mr_mip->w1,mr_mip->w1=mr_mip->w2,mr_mip->w2=t;    /* swap(mr_mip->w1,mr_mip->w2) */
            multiply(_MIPP_ mr_mip->w4,mr_mip->w5,mr_mip->w0);
            add(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3);
            t=mr_mip->w3,mr_mip->w3=mr_mip->w4,mr_mip->w4=t;    /* swap(xd,yd) */
            iter++;

        }
        else
        {

 /* printf("a= %I64u b= %I64u c= %I64u  d= %I64u \n",a,b,c,d);   */

            mr_pmul(_MIPP_ mr_mip->w1,c,mr_mip->w5);   /* c*w1 */
            mr_pmul(_MIPP_ mr_mip->w1,a,mr_mip->w1);   /* a*w1 */
            mr_pmul(_MIPP_ mr_mip->w2,b,mr_mip->w0);   /* b*w2 */
            mr_pmul(_MIPP_ mr_mip->w2,d,mr_mip->w2);   /* d*w2 */

            if (!dplus)
            {
                mr_psub(_MIPP_ mr_mip->w0,mr_mip->w1,mr_mip->w1); /* b*w2-a*w1 */
                mr_psub(_MIPP_ mr_mip->w5,mr_mip->w2,mr_mip->w2); /* c*w1-d*w2 */
            }
            else
            {
                mr_psub(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w1); /* a*w1-b*w2 */
                mr_psub(_MIPP_ mr_mip->w2,mr_mip->w5,mr_mip->w2); /* d*w2-c*w1 */
            }
            mr_pmul(_MIPP_ mr_mip->w3,c,mr_mip->w5);
            mr_pmul(_MIPP_ mr_mip->w3,a,mr_mip->w3);
            mr_pmul(_MIPP_ mr_mip->w4,b,mr_mip->w0);
            mr_pmul(_MIPP_ mr_mip->w4,d,mr_mip->w4);
    
            if (a==0) copy(mr_mip->w0,mr_mip->w3);
            else      mr_padd(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3);
            mr_padd(_MIPP_ mr_mip->w4,mr_mip->w5,mr_mip->w4);
        }
        if (mr_mip->ERNUM || size(mr_mip->w2)==0) break;


        n=(int)mr_mip->w1->len;
        if (n==1)
        {
            last=TRUE;
            u=mr_mip->w1->w[0];
            v=mr_mip->w2->w[0];
        }
        else
        {
            m=mr_mip->w1->w[n-1]+1;
#ifndef MR_SIMPLE_BASE
            if (mr_mip->base==0)
            {
#endif
#ifndef MR_NOFULLWIDTH
#ifdef mr_dltype
 /* use double length type if available */
                if (n>2 && m!=0)
                { /* squeeze out as much significance as possible */
                    uu.h[MR_TOP]=muldvm(mr_mip->w1->w[n-1],mr_mip->w1->w[n-2],m,&sr);
                    uu.h[MR_BOT]=muldvm(sr,mr_mip->w1->w[n-3],m,&sr);
                    vv.h[MR_TOP]=muldvm(mr_mip->w2->w[n-1],mr_mip->w2->w[n-2],m,&sr);
                    vv.h[MR_BOT]=muldvm(sr,mr_mip->w2->w[n-3],m,&sr);
                }
                else
                {
                    uu.h[MR_TOP]=mr_mip->w1->w[n-1];
                    uu.h[MR_BOT]=mr_mip->w1->w[n-2];
                    vv.h[MR_TOP]=mr_mip->w2->w[n-1];
                    vv.h[MR_BOT]=mr_mip->w2->w[n-2];
                    if (n==2) last=TRUE;
                }

                u=uu.d;
                v=vv.d;
#else
                if (m==0)
                {
                    u=mr_mip->w1->w[n-1];
                    v=mr_mip->w2->w[n-1];   
                }
                else
                {
                    u=muldvm(mr_mip->w1->w[n-1],mr_mip->w1->w[n-2],m,&sr);
                    v=muldvm(mr_mip->w2->w[n-1],mr_mip->w2->w[n-2],m,&sr);
                }
#endif
#endif
#ifndef MR_SIMPLE_BASE
            }
            else
            {
#ifdef mr_dltype
                if (n>2)
                { /* squeeze out as much significance as possible */
                    u=muldiv(mr_mip->w1->w[n-1],mr_mip->base,mr_mip->w1->w[n-2],m,&sr);
                    u=u*mr_mip->base+muldiv(sr,mr_mip->base,mr_mip->w1->w[n-3],m,&sr);
                    v=muldiv(mr_mip->w2->w[n-1],mr_mip->base,mr_mip->w2->w[n-2],m,&sr);
                    v=v*mr_mip->base+muldiv(sr,mr_mip->base,mr_mip->w2->w[n-3],m,&sr);
                }
                else
                {
                    u=(mr_large)mr_mip->base*mr_mip->w1->w[n-1]+mr_mip->w1->w[n-2];
                    v=(mr_large)mr_mip->base*mr_mip->w2->w[n-1]+mr_mip->w2->w[n-2];
                    last=TRUE;
                }
#else
                u=muldiv(mr_mip->w1->w[n-1],mr_mip->base,mr_mip->w1->w[n-2],m,&sr);
                v=muldiv(mr_mip->w2->w[n-1],mr_mip->base,mr_mip->w2->w[n-2],m,&sr);
#endif
            }
#endif
        }

        dplus=TRUE;
        a=1; b=0; c=0; d=1;

        forever
        { /* work only with most significant piece */
            if (last)
            {
                if (v==0) break;
                q=qdiv(u,v);
                if (q==0) break;
            }
            else
            {
                if (dplus)
                { 
                    if ((mr_small)(v-c)==0 || (mr_small)(v+d)==0) break;

                    q=qdiv(u+a,v-c);

                    if (q==0) break;

                    if (q!=qdiv(u-b,v+d)) break;
                }
                else 
                {
                    if ((mr_small)(v+c)==0 || (mr_small)(v-d)==0) break;
                    q=qdiv(u-a,v+c);
                    if (q==0) break;
                    if (q!=qdiv(u+b,v-d)) break;
                }
            }

            if (q==1)
            {
                if ((mr_small)(b+d) >= MAXBASE) break; 
                r=a+c;  a=c; c=r;
                r=b+d;  b=d; d=r;
                lr=u-v; u=v; v=lr;      
            }
            else
            { 
                if (q>=MR_DIV(MAXBASE-b,d)) break;
                r=a+q*c;  a=c; c=r;
                r=b+q*d;  b=d; d=r;
                lr=u-q*v; u=v; v=lr;
            }
            iter++;
            dplus=!dplus;
        }
        iter%=2;

    }

    if (s==MINUS) iter++;
    if (iter%2==1) subtract(_MIPP_ y,mr_mip->w3,mr_mip->w3);

    if (xd!=yd)
    {
        negify(x,mr_mip->w2);
        mad(_MIPP_ mr_mip->w2,mr_mip->w3,mr_mip->w1,y,mr_mip->w4,mr_mip->w4);
        copy(mr_mip->w4,yd);
    }
    copy(mr_mip->w3,xd);
    if (z!=xd && z!=yd) copy(mr_mip->w1,z);

    MR_OUT
    return (size(mr_mip->w1));
}
Exemple #22
0
int xgcd(_MIPD_ big x,big y,big xd,big yd,big z)
{ /* greatest common divisor by Euclids method  *
   * extended to also calculate xd and yd where *
   *      z = x.xd + y.yd = gcd(x,y)            *
   * if xd, yd not distinct, only xd calculated *
   * z only returned if distinct from xd and yd *
   * xd will always be positive, yd negative    */
    int q,r,a,b,c,d,s,n;
    mr_small m,sr;
#ifdef mr_dltype
    mr_large u,v,lq,lr;
#else
    mr_small u,v,lq,lr;
#endif

    BOOL last;
    big t;
#ifndef MR_GENERIC_MT
    miracl *mr_mip=get_mip();
#endif
    if (mr_mip->ERNUM) return 0;

    MR_IN(30)

    copy(x,mr_mip->w1);
    copy(y,mr_mip->w2);
    s=exsign(mr_mip->w1);
    insign(PLUS,mr_mip->w1);
    insign(PLUS,mr_mip->w2);
/*    copy(mr_mip->w1,mr_mip->w3);
    copy(mr_mip->w2,mr_mip->w4);  */
    convert(_MIPP_ 1,mr_mip->w3);
    zero(mr_mip->w4);
    last=FALSE;
    a=b=c=d=0;
    while (size(mr_mip->w2)!=0)
    {
        if (b==0)
        { /* update mr_mip->w1 and mr_mip->w2 */
            divide(_MIPP_ mr_mip->w1,mr_mip->w2,mr_mip->w5);
            t=mr_mip->w1,mr_mip->w1=mr_mip->w2,mr_mip->w2=t;    /* swap(mr_mip->w1,mr_mip->w2) */
            multiply(_MIPP_ mr_mip->w4,mr_mip->w5,mr_mip->w0);
            subtract(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3);
            t=mr_mip->w3,mr_mip->w3=mr_mip->w4,mr_mip->w4=t;    /* swap(xd,yd) */
        }
        else
        {
            premult(_MIPP_ mr_mip->w1,c,mr_mip->w5);
            premult(_MIPP_ mr_mip->w1,a,mr_mip->w1);
            premult(_MIPP_ mr_mip->w2,b,mr_mip->w0);
            premult(_MIPP_ mr_mip->w2,d,mr_mip->w2);
            add_r(_MIPP_ mr_mip->w1,mr_mip->w0,mr_mip->w1);
            add_r(_MIPP_ mr_mip->w2,mr_mip->w5,mr_mip->w2);
            premult(_MIPP_ mr_mip->w3,c,mr_mip->w5);
            premult(_MIPP_ mr_mip->w3,a,mr_mip->w3);
            premult(_MIPP_ mr_mip->w4,b,mr_mip->w0);
            premult(_MIPP_ mr_mip->w4,d,mr_mip->w4);
            add_r(_MIPP_ mr_mip->w3,mr_mip->w0,mr_mip->w3);
            add_r(_MIPP_ mr_mip->w4,mr_mip->w5,mr_mip->w4);
        }
        if (mr_mip->ERNUM || size(mr_mip->w2)==0) break;
        n=(int)mr_mip->w1[0];
        a=1;
        b=0;
        c=0;
        d=1;
        if (n==1)
        {
            last=TRUE;
            u=mr_mip->w1[1];
            v=mr_mip->w2[1];
        }
        else
        {
            m=mr_mip->w1[n]+1;
            if (mr_mip->base==0)
            {
#ifdef mr_dltype
 /* use double length type if available */
                if (n>2 && m!=0)
                { /* squeeze out as much significance as possible */
                    MR_TOP(u)=muldvm(mr_mip->w1[n],mr_mip->w1[n-1],m,&sr);
                    MR_BOT(u)=muldvm(sr,mr_mip->w1[n-2],m,&sr);
                    MR_TOP(v)=muldvm(mr_mip->w2[n],mr_mip->w2[n-1],m,&sr);
                    MR_BOT(v)=muldvm(sr,mr_mip->w2[n-2],m,&sr);
                }
                else
                {
                    MR_TOP(u)=mr_mip->w1[n];
                    MR_BOT(u)=mr_mip->w1[n-1];
                    MR_TOP(v)=mr_mip->w2[n];
                    MR_BOT(v)=mr_mip->w2[n-1];
                    if (n==2) last=TRUE;
                }
#else
                if (m==0)
                {
                    u=mr_mip->w1[n];
                    v=mr_mip->w2[n];
                }
                else
                {
                    u=muldvm(mr_mip->w1[n],mr_mip->w1[n-1],m,&sr);
                    v=muldvm(mr_mip->w2[n],mr_mip->w2[n-1],m,&sr);
                }
#endif
            }
            else
            {
#ifdef mr_dltype
 /* use double length type if available */
                if (n>2)
                { /* squeeze out as much significance as possible */
                    u=muldiv(mr_mip->w1[n],mr_mip->base,mr_mip->w1[n-1],m,&sr);
                    u=u*mr_mip->base+muldiv(sr,mr_mip->base,mr_mip->w1[n-2],m,&sr);
                    v=muldiv(mr_mip->w2[n],mr_mip->base,mr_mip->w2[n-1],m,&sr);
                    v=v*mr_mip->base+muldiv(sr,mr_mip->base,mr_mip->w2[n-2],m,&sr);
                }
                else
                {
                    u=(mr_large)mr_mip->base*mr_mip->w1[n]+mr_mip->w1[n-1];
                    v=(mr_large)mr_mip->base*mr_mip->w2[n]+mr_mip->w2[n-1];
                    last=TRUE;
                }
#else
                u=muldiv(mr_mip->w1[n],mr_mip->base,mr_mip->w1[n-1],m,&sr);
                v=muldiv(mr_mip->w2[n],mr_mip->base,mr_mip->w2[n-1],m,&sr);
#endif
            }
        }
        forever
        { /* work only with most significant piece */
            if (last)
            {
                if (v==0) break;
                lq=u/v;
            }
            else
            {
                if (((v+c)==0) || ((v+d)==0)) break;
                lq=(u+a)/(v+c);
                if (lq!=(u+b)/(v+d)) break;
            }
#ifdef mr_dltype
            if (lq>=(mr_large)(MR_TOOBIG/abs(d))) break;
#else
            if (lq>=(mr_small)(MR_TOOBIG/abs(d))) break;
#endif
            q=(int)lq;
            r=a-q*c;
            a=c;
            c=r;
            r=b-q*d;
            b=d;
            d=r;
            lr=u-lq*v;
            u=v;
            v=lr;
        }
    }
    if (s==MINUS) negate(mr_mip->w3,mr_mip->w3);
    if (size(mr_mip->w3)<=0) add_r(_MIPP_ mr_mip->w3,y,mr_mip->w3);
    if (xd!=yd)
    {
        negate(x,mr_mip->w2);
        mad(_MIPP_ mr_mip->w2,mr_mip->w3,mr_mip->w1,y,mr_mip->w4,mr_mip->w4);
        copy(mr_mip->w4,yd);
    }
    copy(mr_mip->w3,xd);
    if (z!=xd && z!=yd) copy(mr_mip->w1,z);
    MR_OUT
    return (size(mr_mip->w1));
}