]> git.tdb.fi Git - r2c2.git/commitdiff
Move double-address logic to drivers
authorMikko Rasa <tdb@tdb.fi>
Mon, 22 Nov 2010 20:42:23 +0000 (20:42 +0000)
committerMikko Rasa <tdb@tdb.fi>
Mon, 22 Nov 2010 20:42:23 +0000 (20:42 +0000)
13 files changed:
source/libr2c2/driver.h
source/libr2c2/dummy.cpp
source/libr2c2/dummy.h
source/libr2c2/intellibox.cpp
source/libr2c2/intellibox.h
source/libr2c2/layout.cpp
source/libr2c2/layout.h
source/libr2c2/track.cpp
source/libr2c2/track.h
source/libr2c2/tracktype.cpp
source/libr2c2/tracktype.h
source/libr2c2/train.cpp
tracks.dat

index d9d11270eb697c5d4155d6eb87026c535b1839b6..e8d27f0b5cc58864e781a880e42a9a3774ae093c 100644 (file)
@@ -13,6 +13,9 @@ Distributed under the GPL
 
 namespace R2C2 {
 
+class TrackType;
+class VehicleType;
+
 class Driver
 {
 public:
@@ -20,7 +23,7 @@ public:
        sigc::signal<void, bool> signal_halt;
        sigc::signal<void, unsigned, unsigned, bool> signal_loco_speed;
        sigc::signal<void, unsigned, unsigned, bool> signal_loco_function;
-       sigc::signal<void, unsigned, bool> signal_turnout;
+       sigc::signal<void, unsigned, unsigned> signal_turnout;
        sigc::signal<void, unsigned, bool> signal_sensor;
 
 protected:
@@ -35,14 +38,14 @@ public:
 
        virtual const char *enumerate_protocols(unsigned) const = 0;
        virtual unsigned get_protocol_speed_steps(const std::string &) const = 0;
-       virtual void add_loco(unsigned, const std::string &) = 0;
+       virtual void add_loco(unsigned, const std::string &, const VehicleType &) = 0;
        virtual void set_loco_speed(unsigned, unsigned) = 0;
        virtual void set_loco_reverse(unsigned, bool) = 0;
        virtual void set_loco_function(unsigned, unsigned, bool) = 0;
 
-       virtual void add_turnout(unsigned) = 0;
-       virtual void set_turnout(unsigned, bool) = 0;
-       virtual bool get_turnout(unsigned) const = 0;
+       virtual void add_turnout(unsigned, const TrackType &) = 0;
+       virtual void set_turnout(unsigned, unsigned) = 0;
+       virtual unsigned get_turnout(unsigned) const = 0;
 
        virtual void add_sensor(unsigned) = 0;
        virtual void set_sensor(unsigned, bool) = 0;
index 814dce44a99818f78de28f7aa4f4c5c836b2bc8d..9c78234f644b7fe3a897fbfeb11cfa9b49a07b1f 100644 (file)
@@ -33,12 +33,12 @@ unsigned Dummy::get_protocol_speed_steps(const string &) const
        return 0;
 }
 
-void Dummy::add_turnout(unsigned addr)
+void Dummy::add_turnout(unsigned addr, const TrackType &)
 {
        turnouts[addr];
 }
 
-void Dummy::set_turnout(unsigned addr, bool state)
+void Dummy::set_turnout(unsigned addr, unsigned state)
 {
        if(turnouts[addr]!=state)
        {
@@ -47,9 +47,9 @@ void Dummy::set_turnout(unsigned addr, bool state)
        }
 }
 
-bool Dummy::get_turnout(unsigned addr) const
+unsigned Dummy::get_turnout(unsigned addr) const
 {
-       map<unsigned, bool>::const_iterator i = turnouts.find(addr);
+       map<unsigned, unsigned>::const_iterator i = turnouts.find(addr);
        if(i!=turnouts.end())
                return i->second;
        return false;
index 5357bbd7bad9726bb1d11f89562a65074d531c3a..d388ca6ecc87eb9402af1f46197b5c50766e71f8 100644 (file)
@@ -23,7 +23,7 @@ private:
        };
 
        bool power;
-       std::map<unsigned, bool> turnouts;
+       std::map<unsigned, unsigned> turnouts;
        std::map<unsigned, LocoState> locos;
        std::map<unsigned, bool> sensors;
 
@@ -37,14 +37,14 @@ public:
 
        virtual const char *enumerate_protocols(unsigned) const;
        virtual unsigned get_protocol_speed_steps(const std::string &) const;
-       virtual void add_loco(unsigned, const std::string &) { }
+       virtual void add_loco(unsigned, const std::string &, const VehicleType &) { }
        virtual void set_loco_speed(unsigned, unsigned);
        virtual void set_loco_reverse(unsigned, bool);
        virtual void set_loco_function(unsigned, unsigned, bool);
 
-       virtual void add_turnout(unsigned);
-       virtual void set_turnout(unsigned, bool);
-       virtual bool get_turnout(unsigned) const;
+       virtual void add_turnout(unsigned, const TrackType &);
+       virtual void set_turnout(unsigned, unsigned);
+       virtual unsigned get_turnout(unsigned) const;
 
        virtual void add_sensor(unsigned) { }
        virtual void set_sensor(unsigned, bool);
index 9ac448e466108f3e964ffc6b6f6bbd9151566faf..64e785582dce0f8895deda28493af96cb5f7974c 100644 (file)
@@ -12,6 +12,8 @@ Distributed under the GPL
 #include <msp/time/units.h>
 #include <msp/time/utils.h>
 #include "intellibox.h"
+#include "tracktype.h"
+#include "vehicletype.h"
 
 using namespace std;
 using namespace Msp;
@@ -96,6 +98,7 @@ void Intellibox::halt(bool h)
 
 const char *Intellibox::enumerate_protocols(unsigned i) const
 {
+       ++i;
        if(i==MM)
                return "MM";
        else if(i==MM_27)
@@ -113,13 +116,19 @@ unsigned Intellibox::get_protocol_speed_steps(const string &proto_name) const
        return 0;
 }
 
-void Intellibox::add_loco(unsigned addr, const string &proto_name)
+void Intellibox::add_loco(unsigned addr, const string &proto_name, const VehicleType &type)
 {
        Protocol proto = map_protocol(proto_name);
 
        if(!locos.count(addr))
        {
-               locos[addr].protocol = proto;
+               Locomotive &loco = locos[addr];
+               loco.protocol = proto;
+               if(type.get_max_function()>4)
+               {
+                       loco.ext_func = true;
+                       locos[addr+1].protocol = NONE;
+               }
 
                unsigned char data[2];
                data[0] = addr&0xFF;
@@ -131,6 +140,9 @@ void Intellibox::add_loco(unsigned addr, const string &proto_name)
 void Intellibox::set_loco_speed(unsigned addr, unsigned speed)
 {
        Locomotive &loco = locos[addr];
+       if(loco.protocol==NONE)
+               return;
+
        if(speed==loco.speed)
        {
                if(loco.pending_half_step)
@@ -163,14 +175,14 @@ void Intellibox::set_loco_speed(unsigned addr, unsigned speed)
                        loco.pending_half_step = 0;
                loco.half_step_delay = Time::TimeStamp();
 
-               loco_command(addr, (speed+1)/2, loco.reverse, loco.funcs|0x100);
+               loco_command(addr, (speed+1)/2, loco.reverse, loco.funcs, false);
        }
-       else
+       else if(loco.protocol==MM)
        {
                if(speed>14)
                        speed = 14;
 
-               loco_command(addr, speed, loco.reverse, loco.funcs|0x100);
+               loco_command(addr, speed, loco.reverse, loco.funcs, false);
        }
        loco.speed = speed;
 }
@@ -178,56 +190,82 @@ void Intellibox::set_loco_speed(unsigned addr, unsigned speed)
 void Intellibox::set_loco_reverse(unsigned addr, bool rev)
 {
        Locomotive &loco = locos[addr];
-       if(rev==loco.reverse)
+       if(loco.protocol==NONE || rev==loco.reverse)
                return;
 
+       loco.speed = 0;
        loco.reverse = rev;
-       loco_command(addr, loco.speed, rev, loco.funcs|0x100);
+       loco_command(addr, 0, rev, loco.funcs, false);
 }
 
 void Intellibox::set_loco_function(unsigned addr, unsigned func, bool state)
 {
        Locomotive &loco = locos[addr];
+       if(loco.protocol==NONE)
+               return;
+
        if(state)
                loco.funcs |= 1<<func;
        else
                loco.funcs &= ~(1<<func);
-       loco_command(addr, loco.speed, loco.reverse, loco.funcs);
+       if(func<=4)
+               loco_command(addr, loco.speed, loco.reverse, loco.funcs, true);
+       else if(loco.ext_func && func<=8)
+               loco_command(addr+1, 0, false, (loco.funcs>>4)&0x1E, true);
        signal_loco_function.emit(addr, func, state);
 }
 
-void Intellibox::add_turnout(unsigned addr)
+void Intellibox::add_turnout(unsigned addr, const TrackType &type)
 {
        if(!turnouts.count(addr))
        {
-               turnouts[addr];
+               Turnout &turnout = turnouts[addr];
+               turnout.bits = type.get_state_bits();
 
                unsigned char data[2];
                data[0] = addr&0xFF;
                data[1] = (addr>>8)&0xFF;
                command(CMD_TURNOUT_STATUS, addr, data, 2);
+               for(unsigned i=1; i<turnout.bits; ++i)
+               {
+                       turnouts[addr+i].bits = 0;
+
+                       ++data[0];
+                       if(!data[0])
+                               ++data[1];
+                       command(CMD_TURNOUT_STATUS, addr+i, data, 2);
+               }
        }
 }
 
-void Intellibox::set_turnout(unsigned addr, bool state)
+void Intellibox::set_turnout(unsigned addr, unsigned state)
 {
        Turnout &turnout = turnouts[addr];
-       if(state==turnout.state || state==turnout.pending)
+       unsigned mask = (1<<turnout.bits)-1;
+       if(((state^turnout.state)&mask)==0 || ((state^turnout.pending)&mask)==0)
+       {
+               turnout.state = state;
+               turnout.pending = state;
+               signal_turnout.emit(addr, state);
                return;
+       }
 
+       turnout.state = (turnout.state&mask) | (state&~mask);
        turnout.pending = state;
        turnout.active = true;
        turnout.off_timeout = Time::TimeStamp();
 
-       turnout_command(addr, state, true);
+       for(unsigned i=0; i<turnout.bits; ++i)
+               if((state^turnout.state)&(1<<i))
+                       turnout_command(addr+i, state&(1<<i), true);
 }
 
-bool Intellibox::get_turnout(unsigned addr) const
+unsigned Intellibox::get_turnout(unsigned addr) const
 {
        map<unsigned, Turnout>::const_iterator i = turnouts.find(addr);
        if(i!=turnouts.end())
                return i->second.state;
-       return false;
+       return 0;
 }
 
 void Intellibox::add_sensor(unsigned addr)
@@ -263,7 +301,7 @@ void Intellibox::tick()
                        i->second.speed += i->second.pending_half_step;
                        i->second.pending_half_step = 0;
                        i->second.half_step_delay = Time::TimeStamp();
-                       loco_command(i->first, (i->second.speed+1)/2, i->second.reverse, i->second.funcs|0x100);
+                       loco_command(i->first, (i->second.speed+1)/2, i->second.reverse, i->second.funcs, false);
                }
 
        for(map<unsigned, Turnout>::iterator i=turnouts.begin(); i!=turnouts.end(); ++i)
@@ -365,7 +403,7 @@ void Intellibox::command(Command cmd, unsigned addr, const unsigned char *data,
        queue.push_back(slot);
 }
 
-void Intellibox::loco_command(unsigned addr, unsigned speed, bool rev, unsigned funcs)
+void Intellibox::loco_command(unsigned addr, unsigned speed, bool rev, unsigned funcs, bool setf)
 {
        unsigned char data[4];
        data[0] = addr&0xFF;
@@ -380,7 +418,7 @@ void Intellibox::loco_command(unsigned addr, unsigned speed, bool rev, unsigned
        
        data[3] = (rev ? 0 : 0x20) | ((funcs&1) ? 0x10 : 0);
 
-       if(!(funcs&0x100))
+       if(setf)
                data[3] |= 0x80 | ((funcs>>1)&0xF);
 
        command(CMD_LOK, addr, data, 4);
@@ -498,9 +536,12 @@ void Intellibox::process_reply(const Time::TimeStamp &t)
                {
                        unsigned addr = queue.front().addr;
                        Locomotive &loco = locos[addr];
-                       signal_loco_speed.emit(addr, loco.speed+loco.pending_half_step, loco.reverse);
-                       if(loco.pending_half_step)
-                               loco.half_step_delay = Time::now()+500*Time::msec;
+                       if(loco.protocol)
+                       {
+                               signal_loco_speed.emit(addr, loco.speed+loco.pending_half_step, loco.reverse);
+                               if(loco.pending_half_step)
+                                       loco.half_step_delay = Time::now()+500*Time::msec;
+                       }
                }
                else
                        error(cmd, err);
@@ -511,14 +552,21 @@ void Intellibox::process_reply(const Time::TimeStamp &t)
                read_status(&err);
 
                unsigned addr = queue.front().addr;
+               unsigned mask = 1;
+               while(!turnouts[addr].bits)
+               {
+                       --addr;
+                       mask <<= 1;
+               }
                Turnout &turnout = turnouts[addr];
 
                if(err==ERR_NO_ERROR)
                {
-                       turnout.state = turnout.pending;
+                       turnout.state = (turnout.state&~mask) | (turnout.pending&mask);
                        if(turnout.active)
                        {
-                               signal_turnout.emit(addr, turnout.state);
+                               if(turnout.state==turnout.pending)
+                                       signal_turnout.emit(addr, turnout.state);
                                turnout.off_timeout = t+500*Time::msec;
                        }
                }
@@ -526,7 +574,7 @@ void Intellibox::process_reply(const Time::TimeStamp &t)
                        queue.push_back(queue.front());
                else
                {
-                       turnout.pending = turnout.state;
+                       turnout.pending = (turnout.pending&~mask) | (turnout.state&mask);
                        error(cmd, err);
                }
        }
@@ -541,13 +589,19 @@ void Intellibox::process_reply(const Time::TimeStamp &t)
                        read_all(&data, 1);
 
                        unsigned addr = queue.front().addr;
-                       bool state = data&0x04;
-
+                       unsigned mask = 1;
+                       while(!turnouts[addr].bits)
+                       {
+                               --addr;
+                               mask <<= 1;
+                       }
                        Turnout &turnout = turnouts[addr];
-                       if(state!=turnout.state)
+
+                       bool state = data&0x04;
+                       if(state!=((turnout.state&mask)!=0))
                        {
-                               turnout.state = state;
-                               turnout.pending = state;
+                               turnout.state = (turnout.state&~mask) | (state ? mask : 0);
+                               turnout.pending = turnout.state;
                                signal_turnout.emit(addr, turnout.state);
                        }
                }
@@ -686,6 +740,7 @@ void Intellibox::error(Command cmd, Error err)
 
 
 Intellibox::Locomotive::Locomotive():
+       ext_func(false),
        speed(0),
        reverse(false),
        funcs(0)
@@ -693,7 +748,8 @@ Intellibox::Locomotive::Locomotive():
 
 
 Intellibox::Turnout::Turnout():
-       state(false),
+       bits(1),
+       state(0),
        active(false),
        pending(false)
 { }
index 8655bfc8ddc9509a472c0c091a6122ef02034004..a4eed30d4bcf0cda32e28c80ee2748c786d7872a 100644 (file)
@@ -73,6 +73,7 @@ private:
 
        enum Protocol
        {
+               NONE,
                MM,
                MM_27
        };
@@ -80,6 +81,7 @@ private:
        struct Locomotive
        {
                Protocol protocol;
+               bool ext_func;
                unsigned speed;
                bool reverse;
                unsigned funcs;
@@ -91,9 +93,10 @@ private:
 
        struct Turnout
        {
-               bool state;
+               unsigned bits;
+               unsigned state;
                bool active;
-               bool pending;
+               unsigned pending;
                Msp::Time::TimeStamp off_timeout;
 
                Turnout();
@@ -136,14 +139,14 @@ public:
 
        virtual const char *enumerate_protocols(unsigned) const;
        virtual unsigned get_protocol_speed_steps(const std::string &) const;
-       virtual void add_loco(unsigned, const std::string &);
+       virtual void add_loco(unsigned, const std::string &, const VehicleType &);
        virtual void set_loco_speed(unsigned, unsigned);
        virtual void set_loco_reverse(unsigned, bool);
        virtual void set_loco_function(unsigned, unsigned, bool);
 
-       virtual void add_turnout(unsigned);
-       virtual void set_turnout(unsigned, bool);
-       virtual bool get_turnout(unsigned) const;
+       virtual void add_turnout(unsigned, const TrackType &);
+       virtual void set_turnout(unsigned, unsigned);
+       virtual unsigned get_turnout(unsigned) const;
 
        virtual void add_sensor(unsigned);
        virtual void set_sensor(unsigned, bool) { }
@@ -157,7 +160,7 @@ private:
        void command(Command);
        void command(Command, const unsigned char *, unsigned);
        void command(Command, unsigned, const unsigned char *, unsigned);
-       void loco_command(unsigned, unsigned, bool, unsigned);
+       void loco_command(unsigned, unsigned, bool, unsigned, bool);
        void turnout_command(unsigned, bool, bool);
        void process_reply(const Msp::Time::TimeStamp &);
        unsigned read_all(unsigned char *, unsigned);
index 3e49f19b836fa56351f4b42439e9be6b00e588be..a55819bdb3db2763abc7825a8b6fc6121fbac426 100644 (file)
@@ -84,7 +84,7 @@ void Layout::remove_track(Track &t)
        }
 }
 
-unsigned Layout::allocate_turnout_id(bool dbl)
+unsigned Layout::allocate_turnout_id()
 {
        set<unsigned> used_ids;
        for(set<Track *>::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
@@ -92,9 +92,9 @@ unsigned Layout::allocate_turnout_id(bool dbl)
                        used_ids.insert((*i)->get_turnout_id());
 
        unsigned result = next_turnout_id;
-       while(used_ids.count(result) || (dbl && used_ids.count(result+1)))
+       while(used_ids.count(result))
                ++result;
-       next_turnout_id = result+1+dbl;
+       next_turnout_id = result+1;
 
        return result;
 }
index ecb801f0e07c5bc8d4c4af4f9edb300967fba6db..6ef7e0900b517e4015e58874de66be306d193b26 100644 (file)
@@ -87,7 +87,7 @@ public:
        void add_track(Track &);
        const std::set<Track *> &get_tracks() const { return tracks; }
        void remove_track(Track &);
-       unsigned allocate_turnout_id(bool);
+       unsigned allocate_turnout_id();
 
        void add_block(Block &);
        Block &get_block(unsigned) const;
index 0592731c6bb24aab7cae2b44cbca29437328502f..b157b331a12dc9a8106f1720aceeecaddc549e02 100644 (file)
@@ -25,11 +25,14 @@ Track::Track(Layout &l, const TrackType &t):
        rot(0),
        slope(0),
        flex(false),
-       turnout_id(type.is_turnout() ? layout.allocate_turnout_id(type.is_double_address()) : 0),
+       turnout_id(0),
        sensor_id(0),
        links(type.get_endpoints().size()),
        active_path(0)
 {
+       if(type.is_turnout())
+               turnout_id = layout.allocate_turnout_id();
+
        layout.add_track(*this);
 
        if(layout.has_driver())
@@ -126,11 +129,7 @@ void Track::set_turnout_id(unsigned i)
        layout.create_blocks(*this);
        layout.update_routes();
        if(layout.has_driver() && turnout_id)
-       {
-               layout.get_driver().add_turnout(turnout_id);
-               if(type.is_double_address())
-                       layout.get_driver().add_turnout(turnout_id+1);
-       }
+               layout.get_driver().add_turnout(turnout_id, type);
 }
 
 void Track::set_sensor_id(unsigned i)
@@ -151,11 +150,7 @@ void Track::set_active_path(unsigned p)
        if(!(type.get_paths()&(1<<p)))
                throw InvalidParameterValue("Invalid path");
 
-       layout.get_driver().set_turnout(turnout_id, p&1);
-       if(type.is_double_address())
-               layout.get_driver().set_turnout(turnout_id+1, p&2);
-       else if(type.get_n_paths()>2)
-               active_path = (active_path&1) | (p&2);
+       layout.get_driver().set_turnout(turnout_id, p);
 }
 
 int Track::get_endpoint_by_link(Track &other) const
@@ -347,19 +342,16 @@ void Track::save(list<DataFile::Statement> &st) const
                st.push_back((DataFile::Statement("flex"), true));
 }
 
-void Track::turnout_event(unsigned addr, bool state)
+void Track::turnout_event(unsigned addr, unsigned state)
 {
        if(!turnout_id)
                return;
 
        if(addr==turnout_id)
-               active_path = (active_path&2) | (state ? 1 : 0);
-       else if(type.is_double_address() && addr==turnout_id+1)
-               active_path = (active_path&1) | (state ? 2 : 0);
-       else
-               return;
-
-       signal_path_changed.emit(active_path);
+       {
+               active_path = state;
+               signal_path_changed.emit(active_path);
+       }
 }
 
 
index 95f902303a58f8a08d1118f0afd9c95782516702..6747ed7f082281865a2ac31551c3978b86d9b416 100644 (file)
@@ -90,7 +90,7 @@ public:
 
        void save(std::list<Msp::DataFile::Statement> &) const;
 private:
-       void turnout_event(unsigned, bool);
+       void turnout_event(unsigned, unsigned);
 };
 
 } // namespace R2C2
index 4ac096767bac5a1e5efa580f4c8da5c3c700a46b..1679dc3f93f8a736efa4f54718cb7a6040bb9db3 100644 (file)
@@ -15,7 +15,7 @@ namespace R2C2 {
 
 TrackType::TrackType(const ArticleNumber &an):
        art_nr(an),
-       double_address(false),
+       state_bits(0),
        autofit_preference(1)
 { }
 
@@ -171,11 +171,12 @@ TrackType::Endpoint::Endpoint(float x, float y, float d, unsigned p):
 
 
 TrackType::Loader::Loader(TrackType &t):
-       Msp::DataFile::BasicLoader<TrackType>(t)
+       Msp::DataFile::BasicLoader<TrackType>(t),
+       state_bits_set(false)
 {
        add("autofit_preference", &TrackType::autofit_preference);
        add("description", &TrackType::description);
-       add("double_address", &TrackType::double_address);
+       add("state_bits",  &Loader::state_bits);
        add("part",        &Loader::part);
 }
 
@@ -189,6 +190,15 @@ void TrackType::Loader::part()
        TrackPart p;
        load_sub(p);
        obj.parts.push_back(p);
+       if(!state_bits_set && p.get_path())
+               while(p.get_path()>=(1U<<obj.state_bits))
+                       ++obj.state_bits;
+}
+
+void TrackType::Loader::state_bits(unsigned b)
+{
+       obj.state_bits = b;
+       state_bits_set = true;
 }
 
 } // namespace R2C2
index d38f1b21b86d4f4fdac0f4e6f84d21804189c807..fb40ac9473708623c3560ac586f4b79a8557902b 100644 (file)
@@ -29,12 +29,16 @@ public:
 
        class Loader: public Msp::DataFile::BasicLoader<TrackType>
        {
+       private:
+               bool state_bits_set;
+
        public:
                Loader(TrackType &);
        private:
                virtual void finish();
                void part();
                void position(float, float, float);
+               void state_bits(unsigned);
        };
 
 private:
@@ -42,7 +46,7 @@ private:
        std::string description;
        std::vector<TrackPart> parts;
        std::vector<Endpoint> endpoints;
-       bool double_address;
+       unsigned state_bits;
        unsigned autofit_preference;
 
 public:
@@ -54,9 +58,9 @@ public:
        float get_path_length(int) const;
        unsigned get_paths() const;
        unsigned get_n_paths() const;
+       unsigned get_state_bits() const { return state_bits; }
        bool is_turnout() const;
        bool is_dead_end() const;
-       bool is_double_address() const { return double_address; }
        unsigned get_autofit_preference() const { return autofit_preference; }
        const std::vector<TrackPart> &get_parts() const { return parts; }
        const std::vector<Endpoint> &get_endpoints() const { return endpoints; }
index 0cbe306234c09b11a9535f1e21fe71673e4bed2e..28976838fcf7da9c699ed11b8b461cdab566fd41 100644 (file)
@@ -76,7 +76,7 @@ Train::Train(Layout &l, const VehicleType &t, unsigned a, const string &p):
 
        layout.add_train(*this);
 
-       layout.get_driver().add_loco(address, protocol);
+       layout.get_driver().add_loco(address, protocol, loco_type);
        layout.get_driver().signal_loco_speed.connect(sigc::mem_fun(this, &Train::loco_speed_event));
        layout.get_driver().signal_loco_function.connect(sigc::mem_fun(this, &Train::loco_func_event));
 
@@ -186,10 +186,7 @@ void Train::set_function(unsigned func, bool state)
 {
        if(!loco_type.get_functions().count(func))
                throw InvalidParameterValue("Invalid function");
-       if(func<5)
-               layout.get_driver().set_loco_function(address, func, state);
-       else
-               layout.get_driver().set_loco_function(address+1, func-4, state);
+       layout.get_driver().set_loco_function(address, func, state);
 }
 
 float Train::get_control(const string &ctrl) const
@@ -690,10 +687,8 @@ void Train::loco_speed_event(unsigned addr, unsigned speed, bool)
 
 void Train::loco_func_event(unsigned addr, unsigned func, bool state)
 {
-       if(addr==address || (addr==address+1 && loco_type.get_max_function()>4))
+       if(addr==address)
        {
-               if(addr==address+1)
-                       func += 4;
                if(state)
                        functions |= 1<<func;
                else
index 96d0772e2b65caf59698361e4a8b60ff7704d6c9..7a5eb8b9935f1b6cdf5742a0440dabe61a912569 100644 (file)
@@ -313,7 +313,6 @@ track 24612
 track 24630
 {
        description "Turnout, 3-way";
-       double_address true;
        part
        {
                length 188.3;
@@ -336,6 +335,7 @@ track 24630
 track 24624
 {
        description "Turnout, double slip";
+       state_bits 1;
        part
        {
                length 188.3;