/* * drawpolyf * * draw some filled polygons */ void drawpolyf() { short val; color(YELLOW); polymode(PYM_FILL); /* * Draw a polygon using poly, parray is our array of * points and 4 is the number of points in it. */ polf(4L, parray); color(GREEN); /* * Draw a filled 5 sided figure by using pmv, pdr and pclos. */ pmv(0.0, 0.0, 0.0); pdr(3.0, 0.0, 0.0); pdr(3.0, 4.0, 0.0); pdr(-1.0, 5.0, 0.0); pdr(-2.0, 2.0, 0.0); pclos(); color(MAGENTA); /* * draw a filled sector representing a 1/4 circle */ arcf(1.5, -7.0, 3.0, 0, 900); qread(&val); }
void parse_bt_file(const std::string &infile, std::map<std::string, simple_shared_ptr<std::vector<DataSample<double> > > > &data, std::vector<ParseError> &errors, ParseInfo &info) { info.good_records = 0; info.bad_records = 0; double begintime = doubletime(); // Memory-map file FILE *in = fopen(infile.c_str(), "rb"); if (!in) throw std::runtime_error("fopen"); struct stat statbuf; if (-1 == fstat(fileno(in), &statbuf)) throw std::runtime_error("fopen"); long long len = statbuf.st_size; const unsigned char *in_mem = (unsigned char*) mmap(NULL, len, PROT_READ, MAP_SHARED/*|MAP_POPULATE*/, fileno(in), 0); const unsigned char *end = in_mem + len; if (in_mem == (unsigned char*)-1) throw std::runtime_error("mmap"); if (verbose) log_f("parse_bt_file: Mapped %s (%lld KB)", infile.c_str(), len/1024); Source source(in_mem); const unsigned char *ptr = in_mem; int nrecords[256]; memset(nrecords, 0, sizeof(nrecords)); long long nvalues=0; StartOfFileRecord sofr; TickToTime ttt; std::map<std::string, unsigned long long> last_tick; bool out_of_order = false; while (ptr < end) { const unsigned char *beginning_of_record = ptr; try { unsigned int magic = read_u32(ptr); if (magic != 0xb0de744c) throw ParseError("Incorrect magic # at byte %d", source.pos(ptr - 4)); unsigned int record_size = read_u32(ptr); if (verbose) { log_f("parse_bt_file: At location %d, magic=0x%x, record size %d", (int)(beginning_of_record - in_mem), magic, record_size); } if (record_size + beginning_of_record > end) throw ParseError("Record size too long at byte %d (size=%d, but only %d bytes left in file)", source.pos(ptr - 4), record_size, end-beginning_of_record); int record_type = read_u16(ptr); if (record_type != RTYPE_START_OF_FILE && record_type != RTYPE_RTC && record_type != RTYPE_PERIODIC_DATA) { throw ParseError("Unknown record type 0x%x at byte %d", record_type, source.pos(ptr - 2)); } const unsigned char *payload = ptr; unsigned int payload_len = record_size-14; ptr += payload_len; if (verbose) log_f("parse_bt_file: Got record type %d, payload len %d", record_type, payload_len); unsigned int crc = read_u32(ptr); unsigned int calculated_crc = crc32(beginning_of_record, record_size - 4, 0); if (crc != calculated_crc) { // Recoverable error; add to errors and try to continue errors.push_back(ParseError("Incorrect CRC32 byte %d. read 0x%x != calculated 0x%x", source.pos(ptr - 4), crc, calculated_crc)); if (record_type == RTYPE_PERIODIC_DATA) info.bad_records++; continue; } switch (record_type) { case RTYPE_START_OF_FILE: sofr = StartOfFileRecord(source, payload, payload_len); ttt.receive_binrec(sofr); info.channel_specs = sofr.channel_specs; break; case RTYPE_RTC: { RtcRecord rtcr(source, payload, payload_len); ttt.receive_binrec(rtcr); if (verbose) log_f("parse_bt_file: %s", rtcr.to_string().c_str()); } break; case RTYPE_PERIODIC_DATA: { PeriodicDataRecord pdr(source, payload, payload_len, &sofr); ttt.receive_binrec(pdr); pdr.set_time(ttt); for (unsigned i = 0; i < pdr.n_channels(); i++) { std::string channel_name = pdr.channel_name(i); nvalues += pdr.number_of_samples; log_f("parse_pt_file: %d samples, start tick 0x%x (%u)", pdr.number_of_samples, pdr.first_sample_short_tick, pdr.first_sample_short_tick); std::vector<DataSample<double> > data_samples; pdr.get_data_samples(i, data_samples); if (data_samples.size()) { if (data.find(channel_name) == data.end()) { data[channel_name].reset(new std::vector<DataSample<double> >()); } else { if (data[channel_name]->back().time > data_samples.front().time) { if (verbose) log_f("Warning: sample times in channel %s are out-of-order (%f > %f)", channel_name.c_str(), data[channel_name]->back().time, data_samples.front().time); out_of_order = true; } } data[channel_name]->insert(data[channel_name]->end(), data_samples.begin(), data_samples.end()); info.good_records++; } last_tick[channel_name] = pdr.first_sample_long_tick; } } break; default: assert(0); } nrecords[record_type]++; } catch (ParseError &e) { errors.push_back(ParseError("In record starting at byte %d in file %s: %s", source.pos(beginning_of_record), infile.c_str(), e.what())); info.bad_records++; } } if (-1 == munmap((void*)in_mem, len)) { perror("munmap"); exit(1); } fclose(in); if (out_of_order) { for (std::map<std::string, simple_shared_ptr<std::vector<DataSample<double> > > >::iterator i = data.begin(); i != data.end(); ++i) { simple_shared_ptr<std::vector<DataSample<double > > > samples = i->second; std::sort(samples->begin(), samples->end(), DataSample<double>::time_lessthan); } } // Check samples are in order for (std::map<std::string, simple_shared_ptr<std::vector<DataSample<double> > > >::iterator i = data.begin(); i != data.end(); ++i) { simple_shared_ptr<std::vector<DataSample<double > > > samples = i->second; for (unsigned i = 0; i < samples->size()-1; i++) { assert((*samples)[i].time <= ((*samples)[i+1].time)); } } double duration = doubletime() - begintime; log_f("parse_bt_file: Parsed %lld bytes in %g seconds (%dK/sec)", len, duration, (int)(len / duration / 1024)); if (verbose) { log_f("parse_bt_file: %d RTYPE_START_OF_FILE records", nrecords[RTYPE_START_OF_FILE]); log_f("parse_bt_file: %d RTYPE_RTC records", nrecords[RTYPE_RTC]); log_f("parse_bt_file: %d RTYPE_PERIODIC_DATA records", nrecords[RTYPE_PERIODIC_DATA]); log_f("parse_bt_file: %lld values", nvalues); } }
/* * pdr2 * * add another vertex to the polygon array */ void pdr2(float x, float y) { pdr(x, y, vdevice.cpW[V_Z]); }
/* * pdr2s * * The short argument version of pdr2. */ void pdr2s(Scoord x, Scoord y) { pdr((float)x, (float)y, vdevice.cpW[V_Z]); }
/* * pdr2i * * The integer argument version of pdr2. */ void pdr2i(Icoord x, Icoord y) { pdr((float)x, (float)y, vdevice.cpW[V_Z]); }
/* * pdri * * The integer argument version of pdr. */ void pdri(Icoord x, Icoord y, Icoord z) { pdr((float)x, (float)y, (float)z); }
/* * rpdr2s * * relative polygon draw - only (x, y). Scoord version. */ void rpdr2s(Scoord dx, Scoord dy) { pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), vdevice.cpW[V_Z]); }
/* * rpdrs * * relative polygon draw. Icoord version. */ void rpdrs(Scoord dx, Scoord dy, Scoord dz) { pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), (vdevice.cpW[V_Z] + dz)); }
/* * rpdr2i * * relative polygon draw - only (x, y). Icoord version. */ void rpdr2i(Icoord dx, Icoord dy) { pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), vdevice.cpW[V_Z]); }
/* * rpdri * * relative polygon draw. Icoord version. */ void rpdri(Icoord dx, Icoord dy, Icoord dz) { pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), (vdevice.cpW[V_Z] + dz)); }
/* * rpdr2 * * relative polygon draw - only (x, y). */ void rpdr2(Coord dx, Coord dy) { pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), vdevice.cpW[V_Z]); }
/* * rpdr * * relative polygon draw. */ void rpdr(Coord dx, Coord dy, Coord dz) { pdr((vdevice.cpW[V_X] + dx), (vdevice.cpW[V_Y] + dy), (vdevice.cpW[V_Z] + dz)); }