*/ void Sieve_Ports(REBSER *ports) /* ** Remove all ports not found in the WAKE list. ** ports could be NULL, in which case the WAKE list is cleared. ** ***********************************************************************/ { REBVAL *port; REBVAL *waked; REBVAL *val; REBCNT n; port = Get_System(SYS_PORTS, PORTS_SYSTEM); if (!IS_PORT(port)) return; waked = VAL_OBJ_VALUE(port, STD_PORT_DATA); if (!IS_BLOCK(waked)) return; for (n = 0; ports && n < SERIES_TAIL(ports);) { val = BLK_SKIP(ports, n); if (IS_PORT(val)) { assert(VAL_TAIL(waked) != 0); if (VAL_TAIL(waked) == Find_Block_Simple(VAL_SERIES(waked), 0, val)) {//not found Remove_Series(ports, n, 1); continue; } } n++; } //clear waked list RESET_SERIES(VAL_SERIES(waked)); }
*/ REBVAL *Find_Last_Event (REBINT model, REBINT type) /* ** Find the last event in the queue by the model ** Check its type, if it matches, then return the event or NULL ** ** ***********************************************************************/ { REBVAL *port; REBVAL *value; REBVAL *state; port = Get_System(SYS_PORTS, PORTS_SYSTEM); if (!IS_PORT(port)) return NULL; // verify it is a port object // Get queue block: state = VAL_OBJ_VALUE(port, STD_PORT_STATE); if (!IS_BLOCK(state)) return NULL; for (value = VAL_BLK_TAIL(state) - 1; value >= VAL_BLK(state); -- value) { if (VAL_EVENT_MODEL(value) == model) { if (VAL_EVENT_TYPE(value) == type) { return value; } else { return NULL; } } } return NULL; }
*/ REBVAL *Append_Event() /* ** Append an event to the end of the current event port queue. ** Return a pointer to the event value. ** ** Note: this function may be called from out of environment, ** so do NOT extend the event queue here. If it does not have ** space, return 0. (Should it overwrite or wrap???) ** ***********************************************************************/ { REBVAL *port; REBVAL *value; REBVAL *state; port = Get_System(SYS_PORTS, PORTS_SYSTEM); if (!IS_PORT(port)) return 0; // verify it is a port object // Get queue block: state = VAL_BLK_SKIP(port, STD_PORT_STATE); if (!IS_BLOCK(state)) return 0; // Append to tail if room: if (SERIES_FULL(VAL_SERIES(state))) Crash(RP_MAX_EVENTS); VAL_TAIL(state)++; value = VAL_BLK_TAIL(state); SET_END(value); value--; SET_NONE(value); //Dump_Series(VAL_SERIES(state), "state"); //Print("Tail: %d %d", VAL_TAIL(state), nn++); return value; }
*/ REBINT Awake_System(REBSER *ports, REBINT only) /* ** Returns: ** -1 for errors ** 0 for nothing to do ** 1 for wait is satisifed ** ***********************************************************************/ { REBVAL *port; REBVAL *state; REBVAL *waked; REBVAL *awake; REBVAL tmp; REBVAL ref_only; REBINT result; REBVAL out; // Get the system port object: port = Get_System(SYS_PORTS, PORTS_SYSTEM); if (!IS_PORT(port)) return -10; // verify it is a port object // Get wait queue block (the state field): state = VAL_OBJ_VALUE(port, STD_PORT_STATE); if (!IS_BLOCK(state)) return -10; //Debug_Num("S", VAL_TAIL(state)); // Get waked queue block: waked = VAL_OBJ_VALUE(port, STD_PORT_DATA); if (!IS_BLOCK(waked)) return -10; // If there is nothing new to do, return now: if (VAL_TAIL(state) == 0 && VAL_TAIL(waked) == 0) return -1; //Debug_Num("A", VAL_TAIL(waked)); // Get the system port AWAKE function: awake = VAL_OBJ_VALUE(port, STD_PORT_AWAKE); if (!ANY_FUNC(awake)) return -1; if (ports) Val_Init_Block(&tmp, ports); else SET_NONE(&tmp); if (only) SET_TRUE(&ref_only); else SET_NONE(&ref_only); // Call the system awake function: if (Apply_Func_Throws(&out, awake, port, &tmp, &ref_only, 0)) raise Error_No_Catch_For_Throw(&out); // Awake function returns 1 for end of WAIT: result = (IS_LOGIC(&out) && VAL_LOGIC(&out)) ? 1 : 0; return result; }
static void doRep (node_t* p, node_t* q, double xdelta, double ydelta, double dist2) { double force; double dist; while (dist2 == 0.0) { xdelta = 5 - rand()%10; ydelta = 5 - rand()%10; dist2 = xdelta*xdelta + ydelta*ydelta; } if (T_useNew) { dist = sqrt (dist2); force = K2/(dist*dist2); } else force = K2/dist2; if (IS_PORT(p) && IS_PORT(q)) force *= 10.0; DISP(q)[0] += xdelta * force; DISP(q)[1] += ydelta * force; DISP(p)[0] -= xdelta * force; DISP(p)[1] -= ydelta * force; }
static void updatePos (Agraph_t* g, double temp, bport_t* pp) { Agnode_t* n; double temp2; double len2; double x,y,d; double dx,dy; temp2 = temp * temp; for (n = agfstnode(g); n; n = agnxtnode(g,n)) { if (ND_pinned(n) & P_FIX) continue; dx = DISP(n)[0]; dy = DISP(n)[1]; len2 = dx*dx + dy*dy; /* limit by temperature */ if (len2 < temp2) { x = ND_pos(n)[0] + dx; y = ND_pos(n)[1] + dy; } else { double fact = temp/(sqrt(len2)); x = ND_pos(n)[0] + dx*fact; y = ND_pos(n)[1] + dy*fact; } /* if ports, limit by boundary */ if (pp) { d = sqrt((x*x)/Wd2 + (y*y)/Ht2); if (IS_PORT(n)) { ND_pos(n)[0] = x/d; ND_pos(n)[1] = y/d; } else if (d >= 1.0) { ND_pos(n)[0] = 0.95*x/d; ND_pos(n)[1] = 0.95*y/d; } else { ND_pos(n)[0] = x; ND_pos(n)[1] = y; } } else { ND_pos(n)[0] = x; ND_pos(n)[1] = y; } } }
*/ REBFLG Pending_Port(REBVAL *port) /* ** Return TRUE if port value is pending a signal. ** Not valid for all ports - requires request struct!!! ** ***********************************************************************/ { REBVAL *state; REBREQ *req; if (IS_PORT(port)) { state = BLK_SKIP(VAL_PORT(port), STD_PORT_STATE); if (IS_BINARY(state)) { req = (REBREQ*)VAL_BIN(state); if (!GET_FLAG(req->flags, RRF_PENDING)) return FALSE; } } return TRUE; }
// Only instructions addressing 16bits are replaced. // And this 16bit address must access an IO port or the backup ram, and not the joystick 1 register. int Crecompilateur::isreplaced(t_pinstr pinstr, Copcodes *popcode_list) { int addressing; int addr; addressing = popcode_list->addressing(pinstr->opcode); if (addressing < 0) { addressing = popcode_list->addressing(pinstr->opcode); fprintf(stderr, "Wrong address and opcode $%4X at $%4X!!!! FIXME rom code confusion?\n", pinstr->opcode, pinstr->addr); return 80; } //assert (addressing >= 0); switch (addressing) { case Ind: return replaceJumpIndirect; case Abs: case AbsX: case AbsY: case IndX: case IndY: addr = pinstr->operand; if (IS_PORT(addr) && addr != JOYSTICK1) { return replaceIOPort; } if (IS_PORT_RANGE(addr) && addr != JOYSTICK1) { snprintf(m_error_str, sizeof(m_error_str), "unknown Io port $%4X", addr); throw int(1); } if (IS_BACKUP_RAM_RANGE(pinstr->addr)) return replaceBackupRam; default: break; }; return noreplace; }
/* initPositions: * Create initial layout of nodes * TODO : * Position nodes near neighbors with positions. * Use bbox to reset K. */ static pointf initPositions (graph_t* g, bport_t* pp) { int nG = agnnodes (g) - NPORTS (g); double size; Agnode_t* np; int n_pos = 0; /* no. of nodes with position info */ box bb; pointf ctr; /* center of boundary ellipse */ long local_seed; double PItimes2 = M_PI * 2.0; for (np = agfstnode(g); np; np = agnxtnode(g,np)) { if (ND_pinned(np)) { if (n_pos) { bb.LL.x = MIN(ND_pos(np)[0],bb.LL.x); bb.LL.y = MIN(ND_pos(np)[1],bb.LL.y); bb.UR.x = MAX(ND_pos(np)[0],bb.UR.x); bb.UR.y = MAX(ND_pos(np)[1],bb.UR.y); } else { bb.UR.x = bb.LL.x = ND_pos(np)[0]; bb.UR.y = bb.LL.y = ND_pos(np)[1]; } n_pos++; } } size = T_K * (sqrt((double)nG) + 1.0); Wd = Ht = expFactor*(size/2.0); if (n_pos == 1) { ctr.x = bb.LL.x; ctr.y = bb.LL.y; } else if (n_pos > 1) { double alpha, area, width, height, quot; ctr.x = (bb.LL.x + bb.UR.x)/2.0; ctr.y = (bb.LL.y + bb.UR.y)/2.0; width = expFactor*(bb.UR.x - bb.LL.x); height = expFactor*(bb.UR.y - bb.LL.y); area = 4.0*Wd*Ht; quot = (width*height)/area; if (quot >= 1.0) { /* If bbox has large enough area, use it */ Wd = width/2.0; Ht = height/2.0; } else if (quot > 0.0) { /* else scale up to have enough area */ quot = 2.0*sqrt(quot); Wd = width/quot; Ht = height/quot; } else { /* either width or height is 0 */ if (width > 0) { height = area/width; Wd = width/2.0; Ht = height/2.0; } else if (height > 0) { width = area/height; Wd = width/2.0; Ht = height/2.0; } /* If width = height = 0, use Wd and Ht as defined above for * the case the n_pos == 0. */ } /* Construct enclosing ellipse */ alpha = atan2 (Ht, Wd); Wd = Wd/cos(alpha); Ht = Ht/sin(alpha); } else { ctr.x = ctr.y = 0; } Wd2 = Wd*Wd; Ht2 = Ht*Ht; /* Set seed value */ if (smode == seed_val) local_seed = T_seed; else { #ifdef MSWIN32 local_seed = time(NULL); #else local_seed = getpid() ^ time(NULL); #endif } srand48(local_seed); /* If ports, place ports on and nodes within an ellipse centered at origin * with halfwidth Wd and halfheight Ht. * If no ports, place nodes within a rectangle centered at origin * with halfwidth Wd and halfheight Ht. Nodes with a given position * are translated. Wd and Ht are set to contain all positioned points. * The reverse translation will be applied to all * nodes at the end of the layout. * TODO: place unfixed points using adjacent ports or fixed pts. */ if (pp) { while (pp->e) { /* position ports on ellipse */ np = pp->n; ND_pos(np)[0] = Wd * cos(pp->alpha); ND_pos(np)[1] = Ht * sin(pp->alpha); ND_pinned(np) = P_SET; pp++; } for (np = agfstnode(g); np; np = agnxtnode(g,np)) { if (IS_PORT(np)) continue; if (ND_pinned(np)) { ND_pos(np)[0] -= ctr.x; ND_pos(np)[1] -= ctr.y; } else { double angle = PItimes2 * drand48(); double radius = 0.9 * drand48(); ND_pos(np)[0] = radius * Wd * cos(angle); ND_pos(np)[1] = radius * Ht * sin(angle); } } } else { if (n_pos) { /* If positioned nodes */ for (np = agfstnode(g); np; np = agnxtnode(g,np)) { if (ND_pinned(np)) { ND_pos(np)[0] -= ctr.x; ND_pos(np)[1] -= ctr.y; } else { ND_pos(np)[0] = Wd * (2.0*drand48() - 1.0); ND_pos(np)[1] = Ht * (2.0*drand48() - 1.0); } } } else { /* No ports or positions; place randomly */ for (np = agfstnode(g); np; np = agnxtnode(g,np)) { ND_pos(np)[0] = Wd * (2.0*drand48() - 1.0); ND_pos(np)[1] = Ht * (2.0*drand48() - 1.0); } } } return ctr; }
*/ REBCNT Get_Part_Length(REBVAL *bval, REBVAL *eval) /* ** Determine the length of a /PART value. ** If /PART value is an integer just use it. ** If it is a series and it is the same series as the first, ** use the difference between the two indices. ** ** If the length ends up negative, back up the index as much ** as possible. If backed up over the head, adjust the length. ** ** Note: This one does not handle list datatypes. ** ***********************************************************************/ { REBINT len; REBCNT tail; if (IS_INTEGER(eval) || IS_DECIMAL(eval)) { len = Int32(eval); if (IS_SCALAR(bval) && VAL_TYPE(bval) != REB_PORT) Trap1(RE_INVALID_PART, bval); } else if ( ( // IF normal series and self referencing: VAL_TYPE(eval) >= REB_STRING && VAL_TYPE(eval) <= REB_BLOCK && VAL_TYPE(bval) == VAL_TYPE(eval) && VAL_SERIES(bval) == VAL_SERIES(eval) ) || ( // OR IF it is a port: IS_PORT(bval) && IS_PORT(eval) && VAL_OBJ_FRAME(bval) == VAL_OBJ_FRAME(eval) ) ) len = (REBINT)VAL_INDEX(eval) - (REBINT)VAL_INDEX(bval); else Trap1(RE_INVALID_PART, eval); /* !!!! if (IS_PORT(bval)) { PORT_STATE_OBJ *port; port = VAL_PORT(&VAL_PSP(bval)->state); if (PORT_FLAG(port) & PF_DIRECT) tail = 0x7fffffff; else tail = PORT_TAIL(VAL_PORT(&VAL_PSP(bval)->state)); } else */ tail = VAL_TAIL(bval); if (len < 0) { len = -len; if (len > (REBINT)VAL_INDEX(bval)) len = (REBINT)VAL_INDEX(bval); VAL_INDEX(bval) -= (REBCNT)len; } else if (!IS_INTEGER(eval) && (len + VAL_INDEX(bval)) > tail) len = (REBINT)(tail - VAL_INDEX(bval)); return (REBCNT)len; }
static void pswrite(Agraph_t * g, FILE * fp, int expMode) { Agnode_t *n; Agnode_t *h; Agedge_t *e; Agnodeinfo_t *data; Agnodeinfo_t *hdata; double minx, miny, maxx, maxy; double scale, width, height; int do_arrow; int angle; char *p; double theta; double arrow_w, arrow_l; int portColor; fprintf(fp, plog); /* if (agisdirected (g) && DoArrow) { do_arrow = 1; fprintf(fp,arrow); } else */ do_arrow = 0; n = agfstnode(g); data = &(n->u); minx = data->pos[0]; miny = data->pos[1]; maxx = data->pos[0]; maxy = data->pos[1]; n = agnxtnode(g, n); for (; n; n = agnxtnode(g, n)) { data = &(n->u); if (data->pos[0] < minx) minx = data->pos[0]; if (data->pos[1] < miny) miny = data->pos[1]; if (data->pos[0] > maxx) maxx = data->pos[0]; if (data->pos[1] > maxy) maxy = data->pos[1]; } /* Convert to points */ minx *= POINTS_PER_INCH; miny *= POINTS_PER_INCH; maxx *= POINTS_PER_INCH; maxy *= POINTS_PER_INCH; /* Check for rotation */ if ((p = agget(g, "rotate")) && (*p != '\0') && ((angle = atoi(p)) != 0)) { fprintf(fp, "306 396 translate\n"); fprintf(fp, "%d rotate\n", angle); fprintf(fp, "-306 -396 translate\n"); } /* If user gives scale factor, use it. * Else if figure too large for standard PS page, scale it to fit. */ if (Scale > 0.0) scale = Scale; else { width = maxx - minx + 20; height = maxy - miny + 20; if (width > PSWidth) { if (height > PSHeight) { scale = (PSWidth / width < PSHeight / height ? PSWidth / width : PSHeight / height); } else scale = PSWidth / width; } else if (height > PSHeight) { scale = PSHeight / height; } else scale = 1.0; } fprintf(fp, "%f %f translate\n", (PSWidth - scale * (minx + maxx)) / 2.0, (PSHeight - scale * (miny + maxy)) / 2.0); fprintf(fp, "%f %f scale\n", scale, scale); /* if (Verbose) fprintf (stderr, "Region (%f,%f) (%f,%f), scale %f\n", minx, miny, maxx, maxy, scale); */ if (do_arrow) { arrow_w = ArrowScale * ARROW_WIDTH / scale; arrow_l = ArrowScale * ARROW_LENGTH / scale; } fprintf(fp, "0.0 setlinewidth\n"); #ifdef SHOW_GRID if (UseGrid) { int i; fprintf(fp, "%f %f 5 fillCircle\n", 0.0, 0.0); for (i = 0; i < maxx; i += CellW) { fprintf(fp, "%f 0.0 moveto %f %f lineto stroke\n", (float) i, (float) i, maxy); } for (i = 0; i < maxy; i += CellH) { fprintf(fp, "0.0 %f moveto %f %f lineto stroke\n", (float) i, maxx, (float) i); } } #endif for (n = agfstnode(g); n; n = agnxtnode(g, n)) { if (IS_PORT(n)) { double r; data = &(n->u); r = sqrt(data->pos[0] * data->pos[0] + data->pos[1] * data->pos[1]); fprintf(fp, "0 0 %f inch drawCircle\n", r); break; } } for (n = agfstnode(g); n; n = agnxtnode(g, n)) { data = &(n->u); for (e = agfstout(g, n); e; e = agnxtout(g, e)) { h = e->head; hdata = &(h->u); fprintf(fp, "%f inch %f inch moveto %f inch %f inch lineto\n", data->pos[0], data->pos[1], hdata->pos[0], hdata->pos[1]); fprintf(fp, "stroke\n"); if (do_arrow) { theta = atan2(data->pos[1] - hdata->pos[1], data->pos[0] - hdata->pos[0]); fprintf(fp, "%f %f %.2f %.2f %.2f doArrow\n", hdata->pos[0], hdata->pos[1], DEGREES(theta), arrow_l, arrow_w); } } } #ifdef BOX for (n = agfstnode(g); n; n = agnxtnode(g, n)) { float wd, ht; data = getData(n); wd = data->wd; ht = data->ht; fprintf(fp, "%f %f %f %f doBox\n", wd, ht, data->pos.x - (wd / 2), data->pos.y - (ht / 2)); } #else for (n = agfstnode(g); n; n = agnxtnode(g, n)) { data = &(n->u); fprintf(fp, "%% %s\n", n->name); if (expMode) { double wd, ht; double r; wd = data->width; ht = data->height; r = sqrt((wd * wd / 4) + ht * ht / 4); fprintf(fp, "%f inch %f inch %f inch %f inch doBox\n", wd, ht, data->pos[0] - (wd / 2), data->pos[1] - (ht / 2)); fprintf(fp, "%f inch %f inch %f inch drawCircle\n", data->pos[0], data->pos[1], r); } else { if (IS_PORT(n)) { if (!portColor) { fprintf(fp, "0.667 1.000 1.000 sethsbcolor\n"); portColor = 1; } } else { if (portColor) { fprintf(fp, "0.0 0.000 0.000 sethsbcolor\n"); portColor = 0; } } } fprintf(fp, "%f inch %f inch %f fillCircle\n", data->pos[0], data->pos[1], 3 / scale); } #endif fprintf(fp, "0.667 1.000 1.000 sethsbcolor\n"); for (n = agfstnode(g); n; n = agnxtnode(g, n)) { data = &(n->u); for (e = agfstout(g, n); e; e = agnxtout(g, e)) { h = e->head; hdata = &(h->u); fprintf(fp, "%f inch %f inch moveto %f inch %f inch lineto\n", data->pos[0], data->pos[1], hdata->pos[0], hdata->pos[1]); fprintf(fp, "stroke\n"); if (do_arrow) { theta = atan2(data->pos[1] - hdata->pos[1], data->pos[0] - hdata->pos[0]); fprintf(fp, "%f %f %.2f %.2f %.2f doArrow\n", hdata->pos[0], hdata->pos[1], DEGREES(theta), arrow_l, arrow_w); } } } fprintf(fp, elog); }