diff --git a/src/openttd.cpp b/src/openttd.cpp index 91f1ff7558..119098cd3e 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1289,6 +1289,7 @@ static void CheckCaches() VehicleCache *veh_cache = CallocT(length); GroundVehicleCache *gro_cache = CallocT(length); TrainCache *tra_cache = CallocT(length); + Vehicle **veh_old = CallocT(length); length = 0; for (const Vehicle *u = v; u != NULL; u = u->Next()) { @@ -1299,11 +1300,17 @@ static void CheckCaches() case VEH_TRAIN: gro_cache[length] = Train::From(u)->gcache; tra_cache[length] = Train::From(u)->tcache; + veh_old[length] = CallocT(1); + MemCpyT((Train *) veh_old[length], Train::From(u)); break; case VEH_ROAD: gro_cache[length] = RoadVehicle::From(u)->gcache; + veh_old[length] = CallocT(1); + MemCpyT((RoadVehicle *) veh_old[length], RoadVehicle::From(u)); break; default: + veh_old[length] = CallocT(1); + MemCpyT(veh_old[length], u); break; } length++; @@ -1326,6 +1333,30 @@ static void CheckCaches() if (memcmp(&veh_cache[length], &u->vcache, sizeof(VehicleCache)) != 0) { DEBUG(desync, 2, "vehicle cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length); } + if (veh_old[length]->acceleration != u->acceleration) { + DEBUG(desync, 2, "acceleration mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } + if (veh_old[length]->breakdown_chance != u->breakdown_chance) { + DEBUG(desync, 2, "breakdown_chance mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } + if (veh_old[length]->breakdown_ctr != u->breakdown_ctr) { + DEBUG(desync, 2, "breakdown_ctr mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } + if (veh_old[length]->breakdown_delay != u->breakdown_delay) { + DEBUG(desync, 2, "breakdown_delay mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } + if (veh_old[length]->breakdowns_since_last_service != u->breakdowns_since_last_service) { + DEBUG(desync, 2, "breakdowns_since_last_service mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } + if (veh_old[length]->breakdown_severity != u->breakdown_severity) { + DEBUG(desync, 2, "breakdown_severity mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } + if (veh_old[length]->breakdown_type != u->breakdown_type) { + DEBUG(desync, 2, "breakdown_type mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } + if (veh_old[length]->vehicle_flags != u->vehicle_flags) { + DEBUG(desync, 2, "vehicle_flags mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } switch (u->type) { case VEH_TRAIN: if (memcmp(&gro_cache[length], &Train::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) { @@ -1334,6 +1365,15 @@ static void CheckCaches() if (memcmp(&tra_cache[length], &Train::From(u)->tcache, sizeof(TrainCache)) != 0) { DEBUG(desync, 2, "train cache mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); } + if (Train::From(veh_old[length])->railtype != Train::From(u)->railtype) { + DEBUG(desync, 2, "railtype mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } + if (Train::From(veh_old[length])->compatible_railtypes != Train::From(u)->compatible_railtypes) { + DEBUG(desync, 2, "compatible_railtypes mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } + if (Train::From(veh_old[length])->flags != Train::From(u)->flags) { + DEBUG(desync, 2, "flags mismatch: vehicle %i, company %i, unit number %i, wagon %i", v->index, (int)v->owner, v->unitnumber, length); + } break; case VEH_ROAD: if (memcmp(&gro_cache[length], &RoadVehicle::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) { @@ -1343,6 +1383,7 @@ static void CheckCaches() default: break; } + free(veh_old[length]); length++; } @@ -1350,6 +1391,7 @@ static void CheckCaches() free(veh_cache); free(gro_cache); free(tra_cache); + free(veh_old); } /* Check whether the caches are still valid */ diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp index 7b6834112b..7cd883847c 100644 --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -185,6 +185,41 @@ public: return true; } + + static void stDesyncCheck(Tpf &pf1, Tpf &pf2, const char *name, bool check_res) + { + Node *n1 = pf1.GetBestNode(); + Node *n2 = pf2.GetBestNode(); + uint depth = 0; + for (;;) { + if ((n1 != NULL) != (n2 != NULL)) { + DEBUG(desync, 2, "%s: node nonnull state at %u = [%d, %d]", name, depth, (n1 != NULL), (n2 != NULL)); + DumpState(pf1, pf2); + return; + } + if (n1 == NULL) break; + + if (n1->GetTile() != n2->GetTile()) { + DEBUG(desync, 2, "%s tile mismatch at %u = [0x%X, 0x%X]", name, depth, n1->GetTile(), n2->GetTile()); + DumpState(pf1, pf2); + return; + } + if (n1->GetTrackdir() != n2->GetTrackdir()) { + DEBUG(desync, 2, "%s trackdir mismatch at %u = [0x%X, 0x%X]", name, depth, n1->GetTrackdir(), n2->GetTrackdir()); + DumpState(pf1, pf2); + return; + } + n1 = n1->m_parent; + n2 = n2->m_parent; + depth++; + } + + if (check_res && (pf1.m_res_dest != pf2.m_res_dest || pf1.m_res_dest_td != pf2.m_res_dest_td)) { + DEBUG(desync, 2, "%s reservation target mismatch = [(0x%X, %d), (0x%X, %d)]", name, pf1.m_res_dest, pf1.m_res_dest_td, pf2.m_res_dest, pf2.m_res_dest_td); + DumpState(pf1, pf2); + return; + } + } }; template @@ -334,6 +369,8 @@ public: if (result1 != result2) { DEBUG(desync, 2, "CACHE ERROR: FindSafeTile() = [%s, %s]", result2 ? "T" : "F", result1 ? "T" : "F"); DumpState(pf1, pf2); + } else if (result1) { + CYapfFollowAnySafeTileRailT::stDesyncCheck(pf1, pf2, "CACHE ERROR: FindSafeTile()", true); } } @@ -418,6 +455,8 @@ public: if (result1 != result2) { DEBUG(desync, 2, "CACHE ERROR: ChooseRailTrack() = [%d, %d]", result1, result2); DumpState(pf1, pf2); + } else if (result1 != INVALID_TRACKDIR) { + CYapfFollowRailT::stDesyncCheck(pf1, pf2, "CACHE ERROR: ChooseRailTrack()", true); } } @@ -476,6 +515,8 @@ public: if (result1 != result2) { DEBUG(desync, 2, "CACHE ERROR: CheckReverseTrain() = [%s, %s]", result1 ? "T" : "F", result2 ? "T" : "F"); DumpState(pf1, pf2); + } else if (result1) { + CYapfFollowRailT::stDesyncCheck(pf1, pf2, "CACHE ERROR: CheckReverseTrain()", false); } }