void result_process_pair(const struct result *r1, const struct result *r2, u32 tx_ts, bool skip) { static struct result last_r1, last_r2; int d1, d2, min, res; if (tx_ts - last_r1.tx_ts < 0x2300 && tx_ts - last_r1.tx_ts > 0x1e00) { pinf("Fixup tx_ts"); tx_ts ^= 0x1000; } d1 = result_get_delta(r1->rx_ts, tx_ts); d2 = result_get_delta(r2->rx_ts, tx_ts); if (d1 > d2) { res = d1 - d2; min = d2; } else { res = d2 - d1; min = d1; } #define BAD_TRH 4500 #define bad_macro(d) \ ({ \ static unsigned long long bad_##d; \ if (d > BAD_TRH && !bad_##d) \ bad_##d = pair_no; \ if (d <= BAD_TRH && bad_##d) { \ msg(#d " was bad on pairs [%llu - %llu]\n", \ bad_##d, pair_no - bad_##d); \ bad_##d = 0; \ } \ }) // bad_macro(d1); bad_macro(d2); // bad_macro(min); if (d1 == g_search_val || d2 == g_search_val) msg("found %d at pair %llu\n", g_search_val, pair_no); if (pair_no >= g_pr_start && pair_no < g_pr_end) msg("%llu T %08x[%04x] R %08x[%04x]%c%08x[%04x]%c D %d.%03d %d.%03d us d %d.%03d\n", pair_no, tx_ts, tx_ts - last_r1.tx_ts, r1->rx_ts, r1->rx_ts - last_r1.rx_ts, r1->tx_ts ? ' ' : 'S', r2->rx_ts, r2->rx_ts - last_r2.rx_ts, r2->tx_ts ? ' ' : 'S', d1*8/1000, d1*8%1000, d2*8/1000, d2*8%1000, res*8/1000, res*8%1000); last_r1.rx_ts = r1->rx_ts; last_r2.rx_ts = r2->rx_ts; last_r1.tx_ts = last_r2.tx_ts = tx_ts; //msg("%llu %d %d %d\n", pair_no, d1*8, d2*8, min*8); if (skip) return; if (g_dump) { dist_record(dist1, d1); dist_record(dist2, d2); dist_record(dist_min, min); } if (g_hm) hm_record(d1, d2); }
void packet_cb(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { static int skip_frames; u8 src, other; struct result_frame *fr = (void *)packet, *dut1, *dut2; struct enqueued_frame *ofr; int i; if (header->len != sizeof(*fr)) { err("Wrong sized packet: %d!\n", header->len); return; } src = fr->key & 1; other = src ^ 1; /* If other DUT's result isn't in yet, enqueue packet and wait. */ if (list_empty(&g_pkt_queue[other])) { struct enqueued_frame *copy = malloc(sizeof(*copy)); memcpy(©->fr, packet, header->len); if (!list_empty(&g_pkt_queue[src])) msg("Multi enqueue %llu\n", pair_no/128); list_add_tail(&g_pkt_queue[src], ©->node); return; } ofr = list_pop(&g_pkt_queue[other], struct enqueued_frame, node); dut1 = src ? fr : &ofr->fr; dut2 = other ? fr : &ofr->fr; if (dut1->key != 0x55 || dut2->key != 0xaa) pinf("Keys wrong!"); for (i = 0; i < FR_N_RES; i++) { u32 tx_ts; const bool is_notif = !dut1->r[i].tx_ts || !dut2->r[i].tx_ts; result_ntoh(&dut1->r[i]); result_ntoh(&dut2->r[i]); tx_ts = dut1->r[i].tx_ts ?: dut2->r[i].tx_ts; if (is_notif) { if (skip_frames) pinf("Multiple skip frames!"); skip_frames = g_n_skip; if (!dut1->r[i].tx_ts && !dut2->r[i].tx_ts) { pinf("Double skip!"); skip_frames = skip_frames ?: 1; } /* msg("skip %d %d [pair %llu]\n", !!dut1->r[i].tx_ts, !!dut2->r[i].tx_ts, pair_no);*/ } if (dut1->r[i].tx_ts != dut2->r[i].tx_ts && !is_notif) { pinf("Frame tx ts mismatch"); goto cb_out; } /* if (is_time_backward(dut1->r[i].tx_ts, &last_tx_ts) || is_time_backward(dut1->r[i].rx_ts, &last_rx_ts1) || is_time_backward(dut2->r[i].rx_ts, &last_rx_ts2)) msg("Time runs backward [pair %llu]\n", pair_no); */ result_process_pair(&dut1->r[i], &dut2->r[i], tx_ts, !!skip_frames); if (skip_frames) skip_frames--; pair_no++; }
int PCS_Model::SaveToPOF(std::string filename, AsyncProgress* progress) { PCS_Model::BSP_MAX_DEPTH = 0; PCS_Model::BSP_NODE_POLYS = 1; PCS_Model::BSP_TREE_TIME = 0; PCS_Model::BSP_COMPILE_ERROR = false; POF poffile; unsigned int i,j,k,l; progress->setTarget(6 + light_arrays.size() + ai_paths.size() + insignia.size() + shield_mesh.size() + thrusters.size() + docking.size() + turrets.size() + weapons.size() + special.size() + eyes.size() + model_info.size() + subobjects.size() + textures.size()); char cstringtemp[256]; // Update Progress progress->incrementWithMessage("Writing Header Pt1"); // --------- convert cross sections --------- std::vector<cross_section> sections; sections.resize(header.cross_sections.size()); for (i = 0; i < header.cross_sections.size(); i++) { sections[i].depth = header.cross_sections[i].depth; sections[i].radius = header.cross_sections[i].radius; } poffile.HDR2_Set_CrossSections(header.cross_sections.size(), sections); // Update Progress progress->incrementWithMessage("Writing Header Pt2"); // --------- ACEN --------- poffile.ACEN_Set_acen(POFTranslate(autocentering)); // Update Progress progress->incrementWithMessage("Writing Acen"); // --------- TXTR --------- // Update Progress progress->incrementWithMessage("Writing Textures"); for (i = 0; i < textures.size(); i++) poffile.TXTR_AddTexture(textures[i]); // --------- Sub object Consversion --------- wxLongLong time = wxGetLocalTimeMillis(); bool bsp_compiled = false; header.max_radius = 0.0f; for (i = 0; i < subobjects.size(); i++) { // Update Progress //if (subobjects[i].name == "debris08") // sprintf(cstringtemp, "Submodel %d: %s SENTINAL!", i, subobjects[i].name.c_str()); //else sprintf(cstringtemp, "Submodel %d: %s", i, subobjects[i].name.c_str()); progress->incrementWithMessage(cstringtemp); //memset((char *)&obj, 0, sizeof(OBJ2)); this is NO LONGER ALLOWED - obj2 now contains an class w/ vtable boost::scoped_ptr<OBJ2> obj(new OBJ2); obj->submodel_number = i; if (!PMFObj_to_POFObj2(i, *obj, bsp_compiled, header.max_radius)) { return 2; // error occured in bsp splitting! } poffile.OBJ2_Add(*obj); // takes over object management - including pointers } time = wxGetLocalTimeMillis() - time; // we succeeded in compiling - let's cache the result can_bsp_cache = true; bsp_cache.resize(subobjects.size()); for (i = 0; i < subobjects.size(); i++) poffile.OBJ2_Get_BSPData(i, bsp_cache[i].bsp_data); // --------- ---------------------- --------- int idx = GetModelInfoCount(); char cstrtmp[256]; wxString strtmp = PCS2_VERSION; sprintf(cstrtmp, "PMFSaveToPOF: Compiled on %s with %s\nmax BSP depth was %d\nmost polys in a single node was %d\nTotal Compile time was %ldms, tree generation time was %ldms", std::string(strtmp.mb_str()).c_str(), std::string(PCS2_COMP_VERSION.mb_str()).c_str(), PCS_Model::BSP_MAX_DEPTH,PCS_Model::BSP_NODE_POLYS, time.ToLong(), PCS_Model::BSP_TREE_TIME.ToLong()); bool found = false; for (i = 0; i < model_info.size() && !found; i++) { if (strstr(model_info[i].c_str(), "PMFSaveToPOF") != NULL) { found = true; if (bsp_compiled) // update the string model_info[i] = cstrtmp; } } if (!found) AddModelInfo(cstrtmp); j = 0; for (i = 0; i < model_info.size(); i++) j += model_info[i].length() + 1; boost::scoped_ptr<char> pinf(new char[j]); memset(pinf.get(), 0, j); j = 0; for (i = 0; i < model_info.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing String %d", i); progress->incrementWithMessage(cstringtemp); strncpy(pinf.get()+j, model_info[i].c_str(), model_info[i].length()); j+= model_info[i].length() + 1; } poffile.PINF_Set(pinf.get(), j); if (found) model_info.resize(idx); // back down to size // --------- EYE --------- for (i = 0; i < eyes.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing Eye %d", i); progress->incrementWithMessage(cstringtemp); poffile.EYE_Add_Eye(eyes[i].sobj_number, POFTranslate(eyes[i].sobj_offset), POFTranslate(eyes[i].normal)); } // --------- SPCL --------- for (i = 0; i < special.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing Special %d", i); progress->incrementWithMessage(cstringtemp); poffile.SPCL_AddSpecial(special[i].name, special[i].properties, POFTranslate(special[i].point), special[i].radius); } k = l = 0; // --------- weapons (GPNT/MPNT) --------- for (i = 0; i < weapons.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing Weapon %d", i); progress->incrementWithMessage(cstringtemp); if (weapons[i].type == GUN) { poffile.GPNT_AddSlot(); for (j = 0; j < weapons[i].muzzles.size(); j++) { poffile.GPNT_AddPoint(k, POFTranslate(weapons[i].muzzles[j].point), POFTranslate(weapons[i].muzzles[j].norm)); } k++; } else { poffile.MPNT_AddSlot(); for (j = 0; j < weapons[i].muzzles.size(); j++) { poffile.MPNT_AddPoint(l, POFTranslate(weapons[i].muzzles[j].point), POFTranslate(weapons[i].muzzles[j].norm)); } l++; } } // --------- turrets TGUN/TMIS --------- k = l = 0; for (i = 0; i < turrets.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing Turret %d", i); progress->incrementWithMessage(cstringtemp); if (turrets[i].type == GUN) { poffile.TGUN_Add_Bank(turrets[i].sobj_parent, turrets[i].sobj_par_phys, POFTranslate(turrets[i].turret_normal)); for (j = 0; j < turrets[i].fire_points.size(); j++) { poffile.TGUN_Add_FirePoint(k, POFTranslate(turrets[i].fire_points[j])); } k++; } else { poffile.TMIS_Add_Bank(turrets[i].sobj_parent, turrets[i].sobj_par_phys, POFTranslate(turrets[i].turret_normal)); for (j = 0; j < turrets[i].fire_points.size(); j++) { poffile.TMIS_Add_FirePoint(l, POFTranslate(turrets[i].fire_points[j])); } l++; } } // --------- docking --------- for (i = 0; i < docking.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing Docking %d", i); progress->incrementWithMessage(cstringtemp); poffile.DOCK_Add_Dock(docking[i].properties); for (j = 0; j < docking[i].dockpoints.size(); j++) { poffile.DOCK_Add_Point(i, POFTranslate(docking[i].dockpoints[j].point), POFTranslate(docking[i].dockpoints[j].norm)); } for (j = 0; j < docking[i].paths.size(); j++) { poffile.DOCK_Add_SplinePath(i, docking[i].paths[j]); } } // --------- thrusters --------- for (i = 0; i < thrusters.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing Thruster %d", i); progress->incrementWithMessage(cstringtemp); poffile.FUEL_Add_Thruster(thrusters[i].properties); for (j = 0; j < thrusters[i].points.size(); j++) { poffile.FUEL_Add_GlowPoint(i, thrusters[i].points[j].radius, POFTranslate(thrusters[i].points[j].pos), POFTranslate(thrusters[i].points[j].norm)); } } // --------- shield_mesh --------- int fcs[3], nbs[3]; std::vector<vector3d> points(shield_mesh.size()*3); vector3d shldtvect; // make points list l = 0; for (i = 0; i < shield_mesh.size(); i++) { for (j = 0; j < 3; j++) { bool found_corner = false; for (auto& p : points) { if (p == POFTranslate(shield_mesh[i].corners[j])) { found_corner = true; break; } } if (!found_corner) { if (l >= points.size()) points.resize(points.size()*2); points[l] = POFTranslate(shield_mesh[i].corners[j]); l++; } } } points.resize(l); // translate shield mesh for (i = 0; i < shield_mesh.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing Shield Tri %d", i); progress->incrementWithMessage(cstringtemp); // adds points to list if need, determine fcs[] for (j = 0; j < 3; j++) { shldtvect = POFTranslate(shield_mesh[i].corners[j]); fcs[j] = FindInList(points, shldtvect); } // determine neighbors (nbs[]) j=0; for (k = 0; k < shield_mesh.size() && j < 3; k++) { if (Neighbor(shield_mesh[i], shield_mesh[k]) && i != k) { nbs[j] = k; j++; } } // add poffile.SHLD_Add_Face(POFTranslate(shield_mesh[i].face_normal), fcs, nbs); } // add points // Update Progress progress->incrementWithMessage("Writing Shield Points"); for (i = 0; i < points.size(); i++) poffile.SHLD_Add_Vertex(points[i]); progress->incrementWithMessage("Writing Shield Collision Tree"); // --------------- generate shield collision tree ---------------- if (poffile.SHLD_Count_Faces() > 0) { std::vector<pcs_polygon> shldmesh(poffile.SHLD_Count_Faces()); // make a pcs_polygon mesh from the shields for (i = 0; i < shldmesh.size(); i++) { shldmesh[i].verts.resize(3); poffile.SHLD_Get_Face(i, shldmesh[i].norm, fcs, nbs); for (j = 0; j < 3; j++) { poffile.SHLD_Get_Vertex(fcs[j], shldmesh[i].verts[j].point); shldmesh[i].verts[j].norm = shldmesh[i].norm; } shldmesh[i].centeroid = PolygonCenter(shldmesh[i]); } // make the tree vector3d smin, smax; std::unique_ptr<bsp_tree_node> shld_root = MakeTree(shldmesh, smax, smin); // pack the tree int sldc_size = CalcSLDCTreeSize(shld_root.get()); std::vector<char> sldc; sldc.resize(sldc_size); PackTreeInSLDC(shld_root.get(), 0, &sldc.front(), sldc_size); poffile.SLDC_SetTree(std::move(sldc)); // POFHandler will steal our copy of the buffer } // --------- insignia --------- vector3d uv, vv; float *u = (float *)&uv, *v = (float *)&vv; for (i = 0; i < insignia.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing Insignia %d", i); progress->incrementWithMessage(cstringtemp); poffile.INSG_Add_insignia(insignia[i].lod, POFTranslate(insignia[i].offset)); for (j = 0; j < insignia[i].faces.size(); j++) { for (k = 0; k < 3; k++) { while ((l = poffile.INST_Find_Vert(i, POFTranslate(insignia[i].faces[j].verts[k]))) == (unsigned)-1) { poffile.INSG_Add_Insig_Vertex(i, POFTranslate(insignia[i].faces[j].verts[k])); } fcs[k] = l; u[k] = insignia[i].faces[j].u[k]; v[k] = insignia[i].faces[j].v[k]; } poffile.INSG_Add_Insig_Face(i, fcs, uv, vv); } } // --------- ai_paths --------- for (i = 0; i < ai_paths.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing Path %d", i); progress->incrementWithMessage(cstringtemp); poffile.PATH_Add_Path(ai_paths[i].name, ai_paths[i].parent); for (j = 0; j < ai_paths[i].verts.size(); j++) { poffile.PATH_Add_Vert(i, POFTranslate(ai_paths[i].verts[j].pos), ai_paths[i].verts[j].radius); } } // --------- light arrays --------- pcs_glow_array *gla; for (i = 0; i < light_arrays.size(); i++) { // Update Progress sprintf(cstringtemp, "Writing Glow %d", i); progress->incrementWithMessage(cstringtemp); gla = &light_arrays[i]; poffile.GLOW_Add_LightGroup(gla->disp_time, gla->on_time, gla->off_time, gla->obj_parent, gla->LOD, gla->type, gla->properties); for (j = 0; j < gla->lights.size(); j++) { poffile.GLOW_Add_GlowPoint(i, gla->lights[j].radius, POFTranslate(gla->lights[j].pos), POFTranslate(gla->lights[j].norm)); } } // --------- HDR2 --------- // let's make new BBoxes based on the subobjects vector3d minbox, maxbox, tmpmin, tmpmax; poffile.OBJ2_Get_BoundingMax(0, maxbox); poffile.OBJ2_Get_BoundingMin(0, minbox); for (i = 1; i < poffile.OBJ2_Count(); i++) { vector3d sobj_offset(POFTranslate(OffsetFromParent(i))); poffile.OBJ2_Get_BoundingMax(i, tmpmax); poffile.OBJ2_Get_BoundingMin(i, tmpmin); ExpandBoundingBoxes(maxbox, minbox, tmpmax + sobj_offset); ExpandBoundingBoxes(maxbox, minbox, tmpmin + sobj_offset); } for (i = 0; i < poffile.SHLD_Count_Vertices(); i++) { poffile.SHLD_Get_Vertex(i, tmpmax); ExpandBoundingBoxes(maxbox, minbox, tmpmax); } // update our bounding boxes //axis doesn't matter on the bounding boxes - it's all negative/positive values! i'm a faqing moron poffile.HDR2_Set_MinBound(header.min_bounding_overridden ? header.min_bounding_override : minbox); poffile.HDR2_Set_MaxBound(header.max_bounding_overridden ? header.max_bounding_override : maxbox); this->header.max_bounding = minbox; this->header.min_bounding = maxbox; poffile.HDR2_Set_MaxRadius(header.max_radius_overridden ? header.max_radius_override : header.max_radius); poffile.HDR2_Set_Details(header.detail_levels.size(), header.detail_levels); poffile.HDR2_Set_Debris(header.debris_pieces.size(), header.debris_pieces); poffile.HDR2_Set_Mass(header.mass); poffile.HDR2_Set_MassCenter(POFTranslate(header.mass_center)); poffile.HDR2_Set_MomentInertia(header.MOI); poffile.HDR2_Set_SOBJCount(GetSOBJCount()); std::ofstream out(filename.c_str(), std::ios::out | std::ios::binary); if (!poffile.SavePOF(out)) return 1; return 0; }