#include <GL/gl.h>
#include <msp/core/error.h>
#include <msp/core/getopt.h>
+#include <msp/gl/matrix.h>
+#include <msp/gl/transform.h>
+#include <msp/strings/formatter.h>
#include <msp/strings/lexicalcast.h>
#include <msp/strings/regex.h>
#include "engineer.h"
layout(catalogue),
layout_3d(layout),
no_lighting(false),
- placing_train(0)
+ placing_train(0),
+ placing_block(0),
+ placing_entry(0),
+ simulate(false)
{
string res;
bool debug=false;
getopt.add_option('g', "debug", debug, GetOpt::NO_ARG);
getopt.add_option('d', "device", device, GetOpt::REQUIRED_ARG);
getopt.add_option('q', "quality", quality, GetOpt::REQUIRED_ARG);
+ getopt.add_option('s', "simulate", simulate, GetOpt::NO_ARG);
getopt.add_option( "no-lighting", no_lighting, GetOpt::NO_ARG);
getopt(argc, argv);
throw UsageError("No layout given");
layout.load(args.front());
+ control.signal_sensor_event.connect(sigc::mem_fun(this, &Engineer::sensor_event));
+
trfc_mgr=new TrafficManager(control, layout);
+ trfc_mgr->signal_block_reserved.connect(sigc::mem_fun(this, &Engineer::block_reserved));
view_all();
-
- /*const TrackSeq &tracks=layout.get_tracks();
-
- for(TrackSeq::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
- {
- if(unsigned trnt_id=(*i)->get_turnout_id())
- {
- Turnout *trnt=new Turnout(control, trnt_id);
- trnt->signal_route_changed.connect(sigc::mem_fun(this, &Engineer::turnout_route_changed));
- }
- if(unsigned sens_id=(*i)->get_sensor_id())
- {
- Sensor *sens=new Sensor(control, sens_id);
- sens->signal_state_changed.connect(sigc::bind(sigc::mem_fun(this, &Engineer::sensor_state_changed), sens_id));
- }
- }*/
}
Engineer::~Engineer()
{
+ delete trfc_mgr;
}
void Engineer::add_train(unsigned addr)
Locomotive *loco=new Locomotive(control, addr);
Train *train=new Train(*trfc_mgr, *loco);
+ train->set_name(format("Train %d", trfc_mgr->get_trains().size()));
TrainPanel *tpanel=new TrainPanel(*this, ui_res, *train);
int y=main_panel->get_geometry().y;
train_panels.push_back(tpanel);
placing_train=train;
+ placing_block=0;
+ status_text="Select train location";
}
int Engineer::main()
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- font=new GL::Font();
- if(screen_w>=1024)
- {
- font_size=20;
- Parser::load(*font, "dejavu-20.font");
- }
- else
- {
- font_size=12;
- Parser::load(*font, "dejavu-12.font");
- }
-
Parser::load(ui_res, "engineer.res");
main_panel=new MainPanel(*this, ui_res);
main_panel->set_position(0, screen_h-main_panel->get_geometry().h);
Application::main();
- delete font;
delete main_panel;
+ for(TrainPanelSeq::iterator i=train_panels.begin(); i!=train_panels.end(); ++i)
+ delete *i;
SDL_Quit();
(*i)->render_route(-1);
}
+ if(placing_train && placing_block)
+ {
+ float rot=placing_entry->track->get_rotation()+placing_entry->track_ep->rot;
+ Point pos=placing_entry->track->get_endpoint_position(*placing_entry->track_ep);
+ GL::push_matrix();
+ GL::translate(pos.x, pos.y, pos.z+0.03);
+ GL::rotate(rot*180/M_PI+180, 0, 0, 1);
+ GL::Texture::unbind();
+ glColor4f(1, 1, 1, 1);
+ glBegin(GL_TRIANGLE_FAN);
+ glVertex2f(0.08, 0);
+ glVertex2f(0.05, 0.03);
+ glVertex2f(0.05, 0.01);
+ glVertex2f(0, 0.01);
+ glVertex2f(0, -0.01);
+ glVertex2f(0.05, -0.01);
+ glVertex2f(0.05, -0.03);
+ glEnd();
+ GL::pop_matrix();
+ }
+
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, screen_w, 0, screen_h, 0, 1);
for(TrainPanelSeq::iterator i=train_panels.begin(); i!=train_panels.end(); ++i)
(*i)->render();
- glLoadIdentity();
- glTranslatef(340, 10, 0);
- glScalef(20, 20, 20);
+ const GL::Font &font=ui_res.get_font("dejavu-12");
+ GL::load_identity();
+ GL::translate(340, 10, 0);
+ GL::scale_uniform(font.get_default_size());
glColor4f(1, 1, 1, 1);
- font->draw_string(status_text);
+ font.draw_string(status_text);
SDL_GL_SwapBuffers();
}
return;
}
- Track3D *track=pick_track(x, y);
- if(track)
+ if(placing_train)
{
- if(placing_train)
+ if(btn==1 && placing_block)
{
- Section *sect=trfc_man->get_section_by_track(track->get_track());
+ set_block_color(*placing_block, Color(1, 1, 1));
+
+ placing_train->place(placing_block, placing_entry);
+ placing_train=0;
}
- else
+ else if(btn==3)
+ {
+ const Block::EndpointSeq &endpoints=placing_block->get_endpoints();
+ Block::EndpointSeq::const_iterator i;
+ for(i=endpoints.begin(); i!=endpoints.end(); ++i)
+ if(&*i==placing_entry)
+ break;
+ ++i;
+ if(i==endpoints.end())
+ i=endpoints.begin();
+ placing_entry=&*i;
+ }
+ }
+ else
+ {
+ Track3D *track=pick_track(x, y);
+ if(track)
{
Turnout *turnout=control.get_turnout(track->get_track().get_turnout_id());
if(turnout)
turnout->set_route(1-turnout->get_route());
+ else if(simulate)
+ {
+ Sensor *sensor=control.get_sensor(track->get_track().get_sensor_id());
+ if(sensor)
+ control.signal_sensor_event.emit(track->get_track().get_sensor_id(), !sensor->get_state());
+ }
}
}
}
}
Track3D *track=pick_track(x, y);
- if(track && track->get_track().get_turnout_id())
+ if(track && placing_train)
+ {
+ Block *block=trfc_mgr->get_block_by_track(&track->get_track());
+ if(block!=placing_block)
+ {
+ if(placing_block)
+ set_block_color(*placing_block, Color(1, 1, 1));
+ placing_block=block;
+ placing_entry=&block->get_endpoints().front();
+ set_block_color(*placing_block, Color(0.5, 1, 0.7));
+ }
+ }
+ else if(track && track->get_track().get_turnout_id())
{
ostringstream ss;
ss<<"Turnout "<<track->get_track().get_turnout_id();
status_text=ss.str();
}
- else
+ else if(!placing_train)
status_text="";
}
cam_pos.z=max(best_height*1.05/0.82843, 0.15);
}
-void Engineer::turnout_route_changed(unsigned)
+void Engineer::set_block_color(const Block &block, const Color &color)
{
+ const TrackSet &tracks=block.get_tracks();
+ for(TrackSet::const_iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ layout_3d.get_track(*i)->set_color(color);
}
-void Engineer::sensor_state_changed(bool state, unsigned addr)
+void Engineer::sensor_event(unsigned addr, bool state)
{
+ cout<<"sensor_event "<<state<<" @ "<<addr<<'\n';
const Track3DSeq <racks=layout_3d.get_tracks();
for(Track3DSeq::const_iterator i=ltracks.begin(); i!=ltracks.end(); ++i)
if((*i)->get_track().get_sensor_id()==addr)
{
if(state)
- (*i)->set_color(Color(1, 0, 0));
+ (*i)->set_color(Color(1, 0.5, 0.3));
else
(*i)->set_color(Color(1, 1, 1));
}
}
+void Engineer::block_reserved(const Block &block, const Train *train)
+{
+ if(Sensor *sensor=control.get_sensor(block.get_sensor_id()))
+ if(sensor->get_state())
+ return;
+
+ if(train)
+ set_block_color(block, Color(1, 1, 0.3));
+ else
+ set_block_color(block, Color(1, 1, 1));
+}
+
void Engineer::project_3d()
{
glMatrixMode(GL_PROJECTION);
glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z);
return layout_3d.pick_track(xx, yy, size);
-
- /*unsigned select_buf[1024];
- glSelectBuffer(1024, select_buf);
- glRenderMode(GL_SELECT);
-
- //XXX Hardcoded values
- float xn=((float)(x-800)/960)*0.082843;
- float yn=((float)(y-480)/960)*0.082843;
- float size=(float)4/960*0.082843;
-
- project_3d();
- glLoadIdentity();
-
- double clip[4];
- clip[0]=0.1;
- clip[1]=0;
- clip[2]=xn-size;
- clip[3]=0;
- glClipPlane(GL_CLIP_PLANE0, clip);
- glEnable(GL_CLIP_PLANE0);
-
- clip[0]=-0.1;
- clip[2]=-(xn+size);
- glClipPlane(GL_CLIP_PLANE1, clip);
- glEnable(GL_CLIP_PLANE1);
-
- clip[0]=0;
- clip[1]=0.1;
- clip[2]=yn-size;
- glClipPlane(GL_CLIP_PLANE2, clip);
- glEnable(GL_CLIP_PLANE2);
-
- clip[1]=-0.1;
- clip[2]=-(yn+size);
- glClipPlane(GL_CLIP_PLANE3, clip);
- glEnable(GL_CLIP_PLANE3);
-
- glRotatef(-cam_rot*180/M_PI, 0, 0, 1);
- glTranslatef(-cam_pos.x, -cam_pos.y, -cam_pos.z);
-
- layout_3d.render();
-
- glDisable(GL_CLIP_PLANE0);
- glDisable(GL_CLIP_PLANE1);
- glDisable(GL_CLIP_PLANE2);
- glDisable(GL_CLIP_PLANE3);
-
- unsigned n_records=glRenderMode(GL_RENDER);
- if(n_records)
- {
- Track *track=0;
- unsigned i=0;
- unsigned track_depth=numeric_limits<unsigned>::max();
- for(unsigned j=0; j<n_records; ++j)
- {
- unsigned ns_size=select_buf[i++];
- unsigned min_depth=select_buf[i++];
- ++i; // Skip max_depth
- if(min_depth<track_depth)
- {
- track=(Track *)select_buf[i+ns_size-1];
- track_depth=min_depth;
- }
- i+=ns_size;
- }
-
- return track;
- }
-
- return 0;*/
}
Application::RegApp<Engineer> Engineer::reg;