+++ /dev/null
-/* $Id$
-
-This file is part of the MSP Märklin suite
-Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa
-Distributed under the GPL
-*/
-
-#include <msp/time/timer.h>
-#include <msp/time/units.h>
-#include "command.h"
-#include "constants.h"
-#include "control.h"
-#include "locomotive.h"
-#include "locotype.h"
-#include "reply.h"
-
-using namespace std;
-using namespace Msp;
-
-namespace Marklin {
-
-Locomotive::Locomotive(const LocoType &t, Control &c, unsigned a):
- type(t),
- control(c),
- addr(a),
- speed(0),
- reverse(false),
- funcs(0)
-{
- control.add_locomotive(*this);
-
- refresh_status();
-}
-
-void Locomotive::set_speed(unsigned spd)
-{
- spd = min(spd, 14U);
- if(spd==speed)
- return;
- signal_speed_changing.emit(spd);
-
- speed = spd;
- send_command(false);
-
- signal_speed_changed.emit(speed);
-}
-
-void Locomotive::set_reverse(bool rev)
-{
- if(rev==reverse)
- return;
-
- if(speed)
- {
- control.set_timer((500+speed*150)*Time::msec).signal_timeout.connect(sigc::mem_fun(this, &Locomotive::reverse_timeout));
- set_speed(0);
- }
- else
- {
- reverse = rev;
- send_command(false);
- signal_reverse_changed.emit(reverse);
- }
-}
-
-void Locomotive::set_function(unsigned func, bool state)
-{
- if(state)
- funcs |= 1<<func;
- else
- funcs &= ~(1<<func);
-
- send_command(true);
-
- signal_function_changed.emit(func, state);
-}
-
-void Locomotive::refresh_status()
-{
- unsigned char data[2];
- data[0] = addr&0xFF;
- data[1] = (addr>>8)&0xFF;
- control.command(CMD_LOK_STATUS, data, 2).signal_done.connect(sigc::mem_fun(this, &Locomotive::status_reply));
-}
-
-void Locomotive::send_command(bool setf)
-{
- unsigned char data[4];
- data[0] = addr&0xFF;
- data[1] = (addr>>8)&0xFF;
-
- if(speed==0)
- data[2] = 0;
- else if(speed==1)
- data[2] = 2;
- else
- data[2] = (speed*19-18)/2;
-
- data[3] = (reverse ? 0 : 0x20) | ((funcs&1) ? 0x10 : 0);
-
- if(setf)
- {
- data[3] |= 0x80;
- for(unsigned i=0; i<4; ++i)
- if((funcs>>i)&2)
- data[3] |= (1<<i);
- }
- control.command(CMD_LOK, data, 4);
-
- if(setf && type.get_max_function()>4)
- {
- if(!++data[0])
- ++data[1];
- data[2] = 0;
- data[3] = 0xA0;
- for(unsigned i=0; i<4; ++i)
- if((funcs>>i)&32)
- data[3] |= (1<<i);
- control.command(CMD_LOK, data, 4);
- }
-}
-
-void Locomotive::status_reply(const Reply &reply)
-{
- if(reply.get_error()==ERR_NO_ERROR)
- {
- const unsigned char *data = reply.get_data();
-
- if(data[0]<=1)
- speed = 0;
- else
- speed = data[0]*2/19+1;
-
- reverse = (data[1]&0x20) ? false : true;
- funcs = (data[1]&0xF)<<1;
- if(data[1]&0x10)
- funcs |= 1;
-
- for(unsigned i=0; i<5; ++i)
- signal_function_changed.emit(i, (funcs>>i)&1);
- }
-}
-
-bool Locomotive::reverse_timeout()
-{
- reverse = !reverse;
- send_command(true);
- signal_reverse_changed.emit(reverse);
- return false;
-}
-
-} // namespace Marklin