]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/vehicle.cpp
Make LCD output selectable at runtime through an extra I/O pin
[r2c2.git] / source / libmarklin / vehicle.cpp
index d81848076c5984a26928873a49b13023785817d1..b54b531e0de2964e9fe1fb87590d4d3835ed4da7 100644 (file)
@@ -10,6 +10,7 @@ Distributed under the GPL
 #include "driver.h"
 #include "layout.h"
 #include "track.h"
+#include "trackiter.h"
 #include "tracktype.h"
 #include "vehicle.h"
 #include "vehicletype.h"
@@ -48,6 +49,9 @@ void Vehicle::attach_back(Vehicle &veh)
 
        next = &veh;
        veh.prev = this;
+
+       if(track_pos.track)
+               propagate_backward();
 }
 
 void Vehicle::attach_front(Vehicle &veh)
@@ -55,8 +59,11 @@ void Vehicle::attach_front(Vehicle &veh)
        if(prev || veh.next)
                throw InvalidState("Already attached");
 
-       next = &veh;
-       veh.prev = this;
+       prev = &veh;
+       veh.next = this;
+
+       if(prev->get_track())
+               prev->propagate_backward();
 }
 
 void Vehicle::detach_back()
@@ -77,9 +84,9 @@ void Vehicle::detach_front()
        prev = 0;
 }
 
-void Vehicle::place(Track *t, unsigned e, float o, PlaceMode m)
+void Vehicle::place(Track &t, unsigned e, float o, PlaceMode m)
 {
-       track_pos = TrackPosition(t, e, o);
+       track_pos = TrackPosition(&t, e, o);
 
        if(m==FRONT_AXLE)
                track_pos.advance(-type.get_front_axle_offset());
@@ -94,6 +101,19 @@ void Vehicle::place(Track *t, unsigned e, float o, PlaceMode m)
        propagate_position();
 }
 
+void Vehicle::unplace()
+{
+       if(!track_pos.track)
+               return;
+
+       track_pos = TrackPosition();
+
+       if(prev)
+               prev->unplace();
+       if(next)
+               next->unplace();
+}
+
 void Vehicle::advance(float d)
 {
        track_pos.advance(d);
@@ -150,6 +170,7 @@ void Vehicle::update_position()
                check_sensor(type.get_back_axle_offset(), back_sensor);
 
        position = tp.pos;
+       position.z += layout.get_catalogue().get_rail_elevation();
        direction = tp.dir;
 }
 
@@ -207,6 +228,8 @@ void Vehicle::check_sensor(float offset, unsigned &sensor)
        {
                /* Sensor ID under axle has changed.  Deduce movement direction by using
                the sensor ID under the midpoint of the vehicle. */
+               /* XXX This depends on the simulation running fast enough.  Something
+               more robust would be preferable. */
                unsigned old = sensor;
                sensor = s;
                unsigned mid = track_pos.track->get_sensor_id();
@@ -214,7 +237,6 @@ void Vehicle::check_sensor(float offset, unsigned &sensor)
                if(s && s!=mid)
                        /* There's a sensor and it's different from mid.  We've just entered
                        that sensor. */
-                       // XXX The Train will reset the vehicles to the start of the sensor, which is somewhat undesirable
                        layout.get_driver().set_sensor(sensor, true);
                if(old && old!=mid)
                        /* A sensor was under the axle and it was different from mid.  We've
@@ -299,51 +321,36 @@ void Vehicle::TrackPosition::advance(float d)
        if(!track)
                return;
 
-       unsigned path = track->get_active_path();
-
        offs += d;
-       float path_len = track->get_type().get_path_length(path);
-       while(track && offs>=path_len)
+       TrackIter iter(track, ep);
+       while(iter)
        {
-               unsigned out = track->traverse(ep, path);
-               Track *next = track->get_link(out);
+               float path_len = iter->get_type().get_path_length(iter->get_active_path());
 
-               if(next)
+               if(offs>path_len)
                {
-                       ep = next->get_endpoint_by_link(*track);
-                       track = next;
-
                        offs -= path_len;
-                       path = track->get_active_path();
-                       path_len = track->get_type().get_path_length(path);
+                       iter = iter.next();
                }
                else
-                       track = 0;
+                       break;
        }
 
-       while(track && offs<0)
+       while(iter && offs<0)
        {
-               Track *prev = track->get_link(ep);
-               if(prev)
-               {
-                       unsigned in = prev->get_endpoint_by_link(*track);
-                       track = prev;
+               iter = iter.flip().reverse();
 
-                       path = track->get_active_path();
-                       ep = track->traverse(in, path);
-
-                       path_len = track->get_type().get_path_length(path);
+               if(iter)
+               {
+                       float path_len = iter->get_type().get_path_length(iter->get_active_path());
                        offs += path_len;
                }
-               else
-                       track = 0;
        }
 
+       track = iter.track();
+       ep = iter.entry();
        if(!track)
-       {
-               ep = 0;
                offs = 0;
-       }
 }
 
 TrackPoint Vehicle::TrackPosition::get_point() const