diff -Nru opentracks-0.1/CAudioManager.cpp opentracks-0.0.7/CAudioManager.cpp --- opentracks-0.1/CAudioManager.cpp 2010-11-28 06:32:44.000000000 +0000 +++ opentracks-0.0.7/CAudioManager.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -#include "CAudioManager.h" diff -Nru opentracks-0.1/CAudioManager.h opentracks-0.0.7/CAudioManager.h --- opentracks-0.1/CAudioManager.h 2010-12-01 04:03:02.000000000 +0000 +++ opentracks-0.0.7/CAudioManager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -#ifndef CAUDIOMANAGER_H -#define CAUDIOMANAGER_H - -class CAudioManager -{ - //... -}; - -#endif diff -Nru opentracks-0.1/CEventManager.cpp opentracks-0.0.7/CEventManager.cpp --- opentracks-0.1/CEventManager.cpp 2010-12-01 04:37:01.000000000 +0000 +++ opentracks-0.0.7/CEventManager.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,394 +0,0 @@ -#include "CEventManager.h" - -#include - -#define PI2 (PI / 2.0f) - -// GUI ID values -#define ID_ADD_STRAIGHT 1 -#define ID_ADD_CURVED 2 -#define ID_ADD_TRAIN 3 - -CEventManager::CEventManager() - : m_device(NULL), m_camera(NULL), fRot(0.0f), m_previous_time(0), m_up(false), m_down(false), m_left(false), m_right(false), - m_r_down(false), m_x_prev(0), m_y_prev(0), m_x_cur(0), m_y_cur(0), m_x_diff(0), m_y_diff(0), m_radius(3.0f), m_mode(CM_SELECT) -{ -} - -CEventManager::~CEventManager() -{ - if(m_device) - m_device->drop(); -} - -void CEventManager::SetDevice(IrrlichtDevice * pDevice, CTrackManager * track, CTrainManager * train, CGround * ground) -{ - // When this function is called, we set up the camera - // and the GUI environment - - m_camera = pDevice->getSceneManager()->addCameraSceneNode(); - - // Set the camera's rotation - m_camera->bindTargetAndRotation(true); - m_camera->setPosition(vector3df(30,4,2)); - m_camera->setTarget(vector3df(30,2,5)); - m_camera->setFOV(PI / 3.5f); - m_camera->setAspectRatio(1.66f); - - m_device = pDevice; - m_device->grab(); - - // Grab a copy of the track manager - // and the ground - m_ground = ground; - m_track = track; - m_train = train; - - // Now start creating the GUI environment - IGUIEnvironment* pGUI = m_device->getGUIEnvironment(); - - pGUI->addButton(rect(10,12,90,32), NULL, ID_ADD_STRAIGHT, L"Add straight piece"); - pGUI->addButton(rect(100,12,190,32), NULL, ID_ADD_CURVED, L"Add curved piece"); - pGUI->addButton(rect(200,12,290,32), NULL, ID_ADD_TRAIN, L"Add train"); - - //================== - - m_straight_ghost = m_device->getSceneManager()->getMesh(DATA_DIR "/models/track_straight.b3d"); - m_straight_ghost_node = m_device->getSceneManager()->addMeshSceneNode(m_straight_ghost); - - m_curve_ghost = m_device->getSceneManager()->getMesh(DATA_DIR "/models/track_small_curve.b3d"); - m_curve_ghost_node = m_device->getSceneManager()->addMeshSceneNode(m_curve_ghost); - - m_engine_ghost = m_device->getSceneManager()->getMesh(DATA_DIR "/models/simple_engine_ghost.b3d"); - m_engine_ghost_node = m_device->getSceneManager()->addMeshSceneNode(m_engine_ghost); - - // Make them all invisible - m_straight_ghost_node->setVisible(false); - m_curve_ghost_node->setVisible(false); - m_engine_ghost_node->setVisible(false); -} - -bool CEventManager::OnEvent(const SEvent& event) -{ - // Switch on the event type - switch(event.EventType) - { - case EET_KEY_INPUT_EVENT: - - // We do two seperate things here. - // If the key was held down, we process - // it in the following switch block - - // See which key was pushed. - switch(event.KeyInput.Key) - { - case KEY_UP: - m_up = event.KeyInput.PressedDown; - break; - - case KEY_DOWN: - m_down = event.KeyInput.PressedDown; - break; - - case KEY_LEFT: - m_left = event.KeyInput.PressedDown; - break; - - case KEY_RIGHT: - m_right = event.KeyInput.PressedDown; - break; - - default: - break; - } - - // Otherwise, react to a key-up event - if(!event.KeyInput.PressedDown) - { - if(event.KeyInput.Key == KEY_RETURN) - { - if(m_mode == CM_PLACE_STRAIGHT_TRACK) - { - if(cur == TT_VERTICAL_STRAIGHT) cur = TT_HORIZONTAL_STRAIGHT; - else if(cur == TT_HORIZONTAL_STRAIGHT) cur = TT_VERTICAL_STRAIGHT; - } - if(m_mode == CM_PLACE_CURVE_TRACK) - { - if(cur == TT_CURVE_NE) cur = TT_CURVE_SE; - else if(cur == TT_CURVE_SE) cur = TT_CURVE_SW; - else if(cur == TT_CURVE_SW) cur = TT_CURVE_NW; - else if(cur == TT_CURVE_NW) cur = TT_CURVE_NE; - } - } - else if(event.KeyInput.Key == KEY_ESCAPE) - { - m_device->drop(); - m_device->drop(); - } - } - - break; - - case EET_MOUSE_INPUT_EVENT: - - // First, make sure that the coords - // do not confilct with the GUI - // Get the current values - m_x_cur = event.MouseInput.X; - m_y_cur = event.MouseInput.Y; - - { - IGUIElement * root = m_device->getGUIEnvironment()->getRootGUIElement(); - - if(root != root->getElementFromPoint(position2d(m_x_cur,m_y_cur))) - { - m_device->getGUIEnvironment()->postEventFromUser(event); - - break; - } - } - - // See which event was generated - switch(event.MouseInput.Event) - { - case EMIE_RMOUSE_PRESSED_DOWN: - m_r_down = true; - - // Also reset mousemove values - m_x_diff = m_y_diff = 0; - - break; - - case EMIE_RMOUSE_LEFT_UP: - m_r_down = false; - - case EMIE_MOUSE_MOVED: - - // Add the new offsets to the existing ones - m_x_diff += m_x_cur - m_x_prev; - m_y_diff += m_y_cur - m_y_prev; - - // Now set the previous values - m_x_prev = m_x_cur; - m_y_prev = m_y_cur; - - // Given the cursor position, calculate a ray - // that projects from the camera. - m_cursor_ray = m_device->getSceneManager()-> - getSceneCollisionManager()-> - getRayFromScreenCoordinates(position2d(m_x_cur,m_y_cur), - NULL); - - break; - - case EMIE_LMOUSE_LEFT_UP: - - // Now we need to place the piece of track - // at the current place. - if(m_mode == CM_PLACE_STRAIGHT_TRACK || m_mode == CM_PLACE_CURVE_TRACK) - { - int x = 0, z = 0; - - // Now place this piece - if(m_ground->Intersection(m_device,m_cursor_ray,x,z)) - m_track->SetPiece(cur,x,z); - } - else if(m_mode == CM_PLACE_TRAIN) - { - int x = 0, z = 0; - - // Now place this train - if(m_ground->Intersection(m_device,m_cursor_ray,x,z)) - { - m_train->AddTrain(m_device, m_device->getTimer()->getTime(), x, z); - m_mode = CM_SELECT; - m_engine_ghost_node->setVisible(false); - } - } - - break; - - case EMIE_MOUSE_WHEEL: - - { - float fChange = event.MouseInput.Wheel * 0.1f; - - // Now calculate the amount to move the camera - // along the vector defined by the camera to target - vector3df v_target = m_camera->getTarget(); - vector3df v_position = m_camera->getPosition(); - - float x_total = v_position.X - v_target.X; - float y_total = v_position.Y - v_target.Y; - float z_total = v_position.Z - v_target.Z; - - // Calculate the amount to move along the vector - v_position.X -= x_total * fChange; - v_position.Y -= y_total * fChange; - v_position.Z -= z_total * fChange; - - m_radius -= m_radius * fChange; - - m_camera->setPosition(v_position); - } - - break; - - default: - - break; - } - - break; - - case EET_GUI_EVENT: - - switch(event.GUIEvent.EventType) - { - case EGET_BUTTON_CLICKED: - - if(event.GUIEvent.Caller->getID() == ID_ADD_STRAIGHT && m_mode != CM_PLACE_STRAIGHT_TRACK) - { - m_mode = CM_PLACE_STRAIGHT_TRACK; - - cur = TT_VERTICAL_STRAIGHT; - m_straight_ghost_node->setVisible(true); - m_curve_ghost_node->setVisible(false); - m_engine_ghost_node->setVisible(false); - } - else if(event.GUIEvent.Caller->getID() == ID_ADD_CURVED && m_mode != CM_PLACE_CURVE_TRACK) - { - m_mode = CM_PLACE_CURVE_TRACK; - - cur = TT_CURVE_NE; - m_straight_ghost_node->setVisible(false); - m_curve_ghost_node->setVisible(true); - m_engine_ghost_node->setVisible(false); - } - else if(event.GUIEvent.Caller->getID() == ID_ADD_TRAIN && m_mode != CM_PLACE_TRAIN) - { - // Make sure that the track ghosts are hidden - m_straight_ghost_node->setVisible(false); - m_curve_ghost_node->setVisible(false); - - m_engine_ghost_node->setVisible(true); - - m_mode = CM_PLACE_TRAIN; - } - else - { - m_mode = CM_SELECT; - - m_straight_ghost_node->setVisible(false); - m_curve_ghost_node->setVisible(false); - m_engine_ghost_node->setVisible(false); - } - - break; - - default: - break; - } - - break; - - default: - - break; - } - - return true; -} - -void CEventManager::Process(u32 cur_time) -{ - // Get the difference from the previous time - u32 diff = cur_time - m_previous_time; - - // Now get the current position of everything - vector3df cur_pos = m_camera->getPosition(); - vector3df cur_tar = m_camera->getTarget(); - - // Our rotation is increased everytime - // the left / right arrow keys are used - float fBefore = fRot; - - if(m_left) - fRot += (diff * 0.003f); - if(m_right) - fRot -= (diff * 0.003f); - - // Calculate the cos/sin of the before values - float bx = cosf(fBefore - PI2) * m_radius; - float bz = sinf(fBefore - PI2) * m_radius; - - // Now for the new values - float ax = cosf(fRot - PI2) * m_radius; - float az = sinf(fRot - PI2) * m_radius; - - // Now get the difference - cur_tar.X += bx - ax; - cur_tar.Z += bz - az; - - if(m_r_down) - { - // When the mouse is moved, we track - // the amount and move the target and - // camera accordingly. - - // We need to make sure that the angle - // of rotation (about the Y-Axis) is - // taken into account here. - - // Precalculated numbers - float xdiff = (m_x_diff * 0.01f * (m_radius / 3.0f)); - float zdiff = (m_y_diff * 0.02f * (m_radius / 3.0f)); - - float xtrans = xdiff * cosf(fRot) + zdiff * sinf(fRot); - float ztrans = zdiff * cosf(fRot) + xdiff * sinf(fRot - PI); - - cur_pos.X -= xtrans; - cur_tar.X -= xtrans; - cur_pos.Z += ztrans; - cur_tar.Z += ztrans; - - m_x_diff = m_y_diff = 0; - } - - m_camera->setPosition(cur_pos); - m_camera->setTarget(cur_tar); - - // Deal with the track piece - if(m_mode == CM_PLACE_STRAIGHT_TRACK || m_mode == CM_PLACE_CURVE_TRACK) - { - int x = 0, z = 0; - if(m_ground->Intersection(m_device,m_cursor_ray,x,z)) - { - // Depending on what the current piece is... - float x_off = g_trackOrientationInfo[cur].fTrans_x; - float z_off = g_trackOrientationInfo[cur].fTrans_z; - - float y_rot = g_trackOrientationInfo[cur].fRot_y; - - if(cur <= TT_HORIZONTAL_STRAIGHT) - { - m_straight_ghost_node->setPosition(vector3df(x * 2.0f + x_off, 0.05, z * 2.0f + z_off)); - m_straight_ghost_node->setRotation(vector3df(0,y_rot,0)); - } - else - { - m_curve_ghost_node->setPosition(vector3df(x * 2.0f + x_off, 0.05, z * 2.0f + z_off)); - m_curve_ghost_node->setRotation(vector3df(0,y_rot,0)); - } - } - } - else if(m_mode == CM_PLACE_TRAIN) - { - int x = 0, z = 0; - - if(m_ground->Intersection(m_device,m_cursor_ray,x,z)) - m_engine_ghost_node->setPosition(vector3df(x * 2.0f + 1.0f, 0.05, z * 2.0f + 1.0f)); - } - - m_previous_time = cur_time; -} diff -Nru opentracks-0.1/CEventManager.h opentracks-0.0.7/CEventManager.h --- opentracks-0.1/CEventManager.h 2010-12-01 00:53:53.000000000 +0000 +++ opentracks-0.0.7/CEventManager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -#ifndef CEVENTMANAGER_H -#define CEVENTMANAGER_H - -// Irrlicht includes -#include - -using namespace irr; - -using namespace core; -using namespace scene; -using namespace video; -using namespace io; -using namespace gui; - -// OpenTracks includes -#include "CGround.h" -#include "CTrackManager.h" -#include "CTrainManager.h" - -// Enumerations -enum CURRENT_MODE { CM_SELECT=0, // the default - CM_PLACE_STRAIGHT_TRACK, - CM_PLACE_CURVE_TRACK, - CM_PLACE_TRAIN }; - -class CEventManager : public IEventReceiver -{ - public: - - CEventManager(); - ~CEventManager(); - - void SetDevice(IrrlichtDevice *, CTrackManager *, CTrainManager *, CGround *); - virtual bool OnEvent(const SEvent&); - - void Process(u32); - - private: - - // A reference to the device - // and other necessary things - IrrlichtDevice * m_device; - CTrackManager * m_track; - CTrainManager * m_train; - CGround * m_ground; - - // Camera - ICameraSceneNode * m_camera; - float fRot; - - // Timing info - u32 m_previous_time; - - // Key information - bool m_up, m_down, m_left, m_right; - - // Mouse information - bool m_r_down; - s32 m_x_prev, m_y_prev; - s32 m_x_cur, m_y_cur; - s32 m_x_diff, m_y_diff; - float m_radius; - CURRENT_MODE m_mode; - - // For ray-picking - line3df m_cursor_ray; - - // Ghost meshes for placing objects - IMesh * m_straight_ghost; - IMeshSceneNode * m_straight_ghost_node; - IMesh * m_curve_ghost; - IMeshSceneNode * m_curve_ghost_node; - - IMesh * m_engine_ghost; - IMeshSceneNode * m_engine_ghost_node; - - // Placement information - TRACK_TYPE cur; -}; - -#endif diff -Nru opentracks-0.1/CGround.cpp opentracks-0.0.7/CGround.cpp --- opentracks-0.1/CGround.cpp 2010-12-01 04:37:01.000000000 +0000 +++ opentracks-0.0.7/CGround.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,137 +0,0 @@ -#include "CGround.h" - -CGround::CGround(IrrlichtDevice * pDevice,int width,int height) - : m_width(width), m_height(height), m_node(NULL), m_selector(NULL) -{ - // Our first step is to determine how many vertices - // we will need to create a mesh that is width x height - // - // *----*----*----* As you can see, we will need exactly - // | | | | (width + 1) * (height + 1) vertices - // *----*----*----* and (6 * width * height) indices for - // | | | | our index buffer - // *----*----*----* - - int iNumVertices = (width + 1) * (height + 1); - S3DVertex * vertices = new S3DVertex[iNumVertices]; - memset(vertices,0,sizeof(S3DVertex) * iNumVertices); // Set everything to 0 - - // Now loop through the vertices and fill them with the appropriate - // values - - for(int i=0;i<=height;++i) - { - for(int j=0;j<=width;++j) - { - int iIndex = (i*(width + 1)) + j; - - // Store this vertex's coords and color - vertices[iIndex].Pos.X = j * 2.0f; - vertices[iIndex].Pos.Y = 0.0f; - vertices[iIndex].Pos.Z = i * 2.0f; - vertices[iIndex].Color.color = 0xFFFFFFFF; - - // Also store the texture UV values - vertices[iIndex].TCoords.X = i; - vertices[iIndex].TCoords.Y = j; - } - } - - // Now we need to create the index buffer - int iNumIndices = 6 * width * height; - u16 * indices = new u16[iNumIndices]; - - for(int i=0;iappend(vertices,iNumVertices,indices,iNumIndices); - - // Load the grass texture - SMaterial mat; - mat.setTexture(0,pDevice->getVideoDriver()->getTexture(DATA_DIR "/textures/grass.jpg")); - buffer->Material = mat; - - // Create the SMesh - SMesh * mesh = new SMesh(); - mesh->addMeshBuffer(buffer); - - mesh->recalculateBoundingBox(); - - // Drop the ref. count of the buffer - buffer->drop(); - - // ...and free the memory held by the data - delete [] indices; - delete [] vertices; - - // Add this to the scene - m_node = pDevice->getSceneManager()->addMeshSceneNode(mesh); - - // In order to make the ground look good at a - // distance, we need to enable anisotropic filtering - m_node->setMaterialFlag(EMF_ANISOTROPIC_FILTER,true); - - // Lastly, we create a triangle selector for this - // mesh so that when we want to place things, we can - // determine where the user is pointing the cursor - m_selector = pDevice->getSceneManager()->createTriangleSelector(mesh, m_node); - m_node->setTriangleSelector(m_selector); - - // Drop the ref. count of the mesh - mesh->drop(); -} - -CGround::~CGround() -{ - m_selector->drop(); - m_node->drop(); -} - -bool CGround::Intersection(IrrlichtDevice * device, line3df ray, int & x_inter, int & z_inter) -{ - vector3df out_p; - triangle3df out_t; - const ISceneNode * out_s; - - bool bCollision = device->getSceneManager()->getSceneCollisionManager()-> - getCollisionPoint(ray, m_selector, out_p, out_t, out_s); - - if(bCollision) // one was found - { - // See if we can figure out which one - // by looping through the points on the - // triangle and getting the minimum value - // for each dimension. - float min_x = (out_t.pointA.X < out_t.pointB.X)?out_t.pointA.X:out_t.pointB.X; - min_x = (out_t.pointC.X < min_x)?out_t.pointC.X:min_x; - - float min_z = (out_t.pointA.Z < out_t.pointB.Z)?out_t.pointA.Z:out_t.pointB.Z; - min_z = (out_t.pointC.Z < min_z)?out_t.pointC.Z:min_z; - - // The track coords for this piece can be found by dividing the - // min_x and min_z values by 2 - x_inter = min_x / 2.0f; - z_inter = min_z / 2.0f; - - return true; - } - else - return false; -} diff -Nru opentracks-0.1/CGround.h opentracks-0.0.7/CGround.h --- opentracks-0.1/CGround.h 2010-12-01 00:53:53.000000000 +0000 +++ opentracks-0.0.7/CGround.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -#ifndef CGROUND_H -#define CGROUND_H - -// Irrlicht includes -#include - -using namespace irr; - -using namespace core; -using namespace scene; -using namespace video; -using namespace io; -using namespace gui; - -class CGround -{ - public: - - CGround(IrrlichtDevice *,int,int); - ~CGround(); - - // This is the ray-picking function - // that determines what triangles the given - // line intersects. - bool Intersection(IrrlichtDevice *,line3df,int&,int&); - - private: - - int m_width; - int m_height; - - IMeshSceneNode * m_node; - ITriangleSelector * m_selector; -}; - -#endif diff -Nru opentracks-0.1/CSkybox.cpp opentracks-0.0.7/CSkybox.cpp --- opentracks-0.1/CSkybox.cpp 2010-12-01 04:37:01.000000000 +0000 +++ opentracks-0.0.7/CSkybox.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -#include "CSkybox.h" - -CSkybox::CSkybox(IrrlichtDevice * pDevice, int width, int height) -{ - // Load the mesh for this piece - IMesh * mesh = pDevice->getSceneManager()->getMesh(DATA_DIR "/models/skybox.b3d"); - - // Now add the mesh to the scene manager - IMeshSceneNode * node = pDevice->getSceneManager()->addMeshSceneNode(mesh); - - // Set the position of the object based - // on the center of the ground - node->setPosition(vector3df(width,0,height)); - - // Disable lighting on it for now - node->setMaterialFlag(EMF_LIGHTING, false); - node->setMaterialTexture(0, pDevice->getVideoDriver()->getTexture(DATA_DIR "/textures/sky.jpg")); -} - -CSkybox::~CSkybox() -{ -} diff -Nru opentracks-0.1/CSkybox.h opentracks-0.0.7/CSkybox.h --- opentracks-0.1/CSkybox.h 2010-12-01 00:53:53.000000000 +0000 +++ opentracks-0.0.7/CSkybox.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -#ifndef CSKYBOX_H -#define CSKYBOX_H - -// Irrlicht includes -#include - -using namespace irr; - -using namespace core; -using namespace scene; -using namespace video; -using namespace io; -using namespace gui; - -// Standard includes -#include - -class CSkybox -{ - public: - - CSkybox(IrrlichtDevice *,int,int); - ~CSkybox(); -}; - -#endif diff -Nru opentracks-0.1/CTrack.cpp opentracks-0.0.7/CTrack.cpp --- opentracks-0.1/CTrack.cpp 2010-11-30 00:13:07.000000000 +0000 +++ opentracks-0.0.7/CTrack.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -#include "CTrack.h" - -// This is a global mapping of rotation values for each piece -CTrackOrientationInfo g_trackOrientationInfo[TT_NUM_PIECES] = - { - { 2, 1, 0, 1, 0, 0, 0, 0, 0 }, // TT_VERTICAL_STRAIGHT - { 2, 1, 0, 1, 0, 90, 0, 0, 0 }, // TT_HORIZONTAL_STRAIGHT - { 4.712, 0, 0, 2, 0, 0, 0, -2, 1 }, // TT_CURVE_NE - { 4.712, 0, 0, 0, 0, 90, 0, -2, -1 }, // TT_CURVE_SE - { 4.712, 2, 0, 0, 0, 180, 0, 2, -1 }, // TT_CURVE_SW - { 4.712, 2, 0, 2, 0, 270, 0, 2, 1 }, // TT_CURVE_NW - - { 4.712, 0, 0, 0, 0, 0, 0, 1, -2 }, // TT_CURVE_NE_OTHER - { 4.712, 0, 0, 0, 0, 0, 0, 1, 2 }, // TT_CURVE_SE_OTHER - { 4.712, 0, 0, 0, 0, 0, 0, -1, 2 }, // TT_CURVE_SW_OTHER - { 4.712, 0, 0, 0, 0, 0, 0, -1, -2 } // TT_CURVE_NW_OTHER - }; - -CTrack::CTrack(IrrlichtDevice * pDevice,float x, float y, float z, int ix, int iz) - : m_type(TT_NUM_PIECES), m_x(x), m_y(y), m_z(z), m_offset_x(ix), m_offset_z(iz) -{ - // Create the node - m_node = pDevice->getSceneManager()->addMeshSceneNode(NULL,0,-1, - core::vector3df(0, 0, 0), - core::vector3df(0, 0, 0), - core::vector3df(1, 1, 1), - true); - - // Now set the position - m_node->setPosition(vector3df(m_x,m_y,m_z)); -} - -CTrack::~CTrack() -{ -} - -void CTrack::SetPiece(TRACK_TYPE type,IMesh * pMesh) -{ - if(pMesh) - m_node->setVisible(true); - else - m_node->setVisible(false); - - m_type = type; - - // We need to update the mesh - m_node->setMesh(pMesh); - - if(m_type != TT_NUM_PIECES) - { - // The rotation info needs updating too - m_node->setRotation(vector3df(g_trackOrientationInfo[type].fRot_x, - g_trackOrientationInfo[type].fRot_y, - g_trackOrientationInfo[type].fRot_z)); - - m_node->setPosition(vector3df(g_trackOrientationInfo[type].fTrans_x + m_x, - g_trackOrientationInfo[type].fTrans_y + m_y, - g_trackOrientationInfo[type].fTrans_z + m_z)); - - m_node->setMaterialFlag(EMF_LIGHTING, false); - } -} diff -Nru opentracks-0.1/CTrack.h opentracks-0.0.7/CTrack.h --- opentracks-0.1/CTrack.h 2010-12-01 00:53:53.000000000 +0000 +++ opentracks-0.0.7/CTrack.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ -#ifndef CTRACK_H -#define CTRACK_H - -// Irrlicht includes -#include - -using namespace irr; - -using namespace core; -using namespace scene; -using namespace video; -using namespace io; -using namespace gui; - -// Standard includes -#include - -// Track types -enum TRACK_TYPE { TT_VERTICAL_STRAIGHT=0, - TT_HORIZONTAL_STRAIGHT, - TT_CURVE_NE, - TT_CURVE_SE, - TT_CURVE_SW, - TT_CURVE_NW, - - TT_CURVE_NE_OTHER, // these represent the other - TT_CURVE_SE_OTHER, // end of the track piece - TT_CURVE_SW_OTHER, - TT_CURVE_NW_OTHER, - - TT_NUM_PIECES }; // this last entry is used - // to determine the number of pieces - -// Directions -enum DIRECTION { D_NORTH=0, - D_EAST, - D_SOUTH, - D_WEST }; - -class CTrackOrientationInfo -{ - public: - - // Track length in units - float length; - - // Translation - float fTrans_x; - float fTrans_y; - float fTrans_z; - - // Rotation - float fRot_x; - float fRot_y; - float fRot_z; - - int iOffsetX; // The next piece of track - int iOffsetZ; // from the current offset -}; - -// This class represents an actual physical -// piece of track on the grid -class CTrack -{ - public: - - CTrack(IrrlichtDevice *,float,float,float,int,int); - ~CTrack(); - - void SetPiece(TRACK_TYPE,IMesh *); - TRACK_TYPE GetPiece() { return m_type; } - - float GetXPos() { return m_x; } - float GetZPos() { return m_z; } - - int GetXOffset() { return m_offset_x; } - int GetZOffset() { return m_offset_z; } - - private: - - TRACK_TYPE m_type; - - IMeshSceneNode * m_node; // the scene node - - float m_x, m_y, m_z; // the location of this piece - int m_offset_x, m_offset_z; // The offset of this piece -}; - -// Track information -extern CTrackOrientationInfo g_trackOrientationInfo[]; - -#endif diff -Nru opentracks-0.1/CTrackManager.cpp opentracks-0.0.7/CTrackManager.cpp --- opentracks-0.1/CTrackManager.cpp 2010-12-01 04:37:01.000000000 +0000 +++ opentracks-0.0.7/CTrackManager.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,343 +0,0 @@ -#include "CTrackManager.h" - -// Definitions -const float PI2 = PI / 2; - -CTrackManager::CTrackManager(IrrlichtDevice * pDevice, int width, int height) - : m_width(width), m_height(height), - m_straight(NULL), m_curved(NULL) -{ - // Temporarily set the current directory to the textures - path cur_dir = pDevice->getFileSystem()->getWorkingDirectory(); - pDevice->getFileSystem()->changeWorkingDirectoryTo(DATA_DIR "/textures"); - - // Start by loading all of the meshes - m_straight = pDevice->getSceneManager()->getMesh("../models/track_straight.b3d"); - m_curved = pDevice->getSceneManager()->getMesh("../models/track_small_curve.b3d"); - - // Now change it back - pDevice->getFileSystem()->changeWorkingDirectoryTo(cur_dir); - - // Grab a reference to these - m_straight->grab(); - m_curved->grab(); - - // Fill in the array of all the pieces - for(int i=0;iSetPiece(TT_NUM_PIECES,NULL); - - m_grid.push_back(pNew); - } - } -} - -CTrackManager::~CTrackManager() -{ - // Free the meshes - m_straight->drop(); - m_curved->drop(); - - // Free all of the track pieces - for(unsigned int i=0;iGetPiece(); - - if(current_type >= TT_CURVE_NE && current_type <= TT_CURVE_NW) - { - int iOtherOffset = iOffset; - - if(current_type == TT_CURVE_NE) { iOtherOffset -= 1; iOtherOffset += m_width; } - if(current_type == TT_CURVE_SE) { iOtherOffset -= 1; iOtherOffset -= m_width; } - if(current_type == TT_CURVE_SW) { iOtherOffset += 1; iOtherOffset -= m_width; } - if(current_type == TT_CURVE_NW) { iOtherOffset += 1; iOtherOffset += m_width; } - - CTrack * other_piece = m_grid.at(iOtherOffset); - other_piece->SetPiece(TT_NUM_PIECES, NULL); - } - - // AND make sure that if this is the other - // end of a curved piece that we set the other end - // to nothing - if(current_type >= TT_CURVE_NE_OTHER && current_type <= TT_CURVE_NW_OTHER) - { - int iOtherOffset = iOffset; - - if(current_type == TT_CURVE_NE_OTHER) { iOtherOffset += 1; iOtherOffset -= m_width; } - if(current_type == TT_CURVE_SE_OTHER) { iOtherOffset += 1; iOtherOffset += m_width; } - if(current_type == TT_CURVE_SW_OTHER) { iOtherOffset -= 1; iOtherOffset += m_width; } - if(current_type == TT_CURVE_NW_OTHER) { iOtherOffset -= 1; iOtherOffset -= m_width; } - - CTrack * other_piece = m_grid.at(iOtherOffset); - other_piece->SetPiece(TT_NUM_PIECES, NULL); - } - - // Now set that piece - if(type < TT_CURVE_NE) - piece->SetPiece(type,m_straight); - else - { - piece->SetPiece(type, m_curved); - // For the curved pieces, we need to - // also set the tile at the other end to - // the _OTHER track piece - int iOtherOffset = iOffset; - TRACK_TYPE other_type; - - if(type == TT_CURVE_NE) { iOtherOffset -= 1; iOtherOffset += m_width; other_type = TT_CURVE_NE_OTHER; } - if(type == TT_CURVE_SE) { iOtherOffset -= 1; iOtherOffset -= m_width; other_type = TT_CURVE_SE_OTHER; } - if(type == TT_CURVE_SW) { iOtherOffset += 1; iOtherOffset -= m_width; other_type = TT_CURVE_SW_OTHER; } - if(type == TT_CURVE_NW) { iOtherOffset += 1; iOtherOffset += m_width; other_type = TT_CURVE_NW_OTHER; } - - CTrack * other_piece = m_grid.at(iOtherOffset); - other_piece->SetPiece(other_type, NULL); - } -} - -CTrack * CTrackManager::GetPiece(int x, int z) -{ - // Calculate this item's offset - int iOffset = (z * m_width) + x; - - // Get that piece - CTrack * piece = m_grid.at(iOffset); - - // Return the type - return piece; -} - -void CTrackManager::CalculateTrainPosition(CTrack * pTrack, DIRECTION dir, float fPos, float & fx, float & fz, float & fy) -{ - // Determine what type of track - // we are dealing with - - switch(pTrack->GetPiece()) - { - case TT_VERTICAL_STRAIGHT: - - // The translation and rotation for the track piece - fx = 1.0f; - if(dir == D_NORTH) { fy = 0.0; fz = fPos * 2.0f; } - else { fy = 180.0; fz = 2.0f - (fPos * 2.0f); } - - break; - - case TT_HORIZONTAL_STRAIGHT: - - // The translation and rotation for the track piece - fz = 1.0f; - if(dir == D_EAST) { fy = 90.0; fx = fPos * 2.0f; } - else { fy = 270.0; fx = 2.0 - (fPos * 2.0f); } - - break; - - case TT_CURVE_NE: - - // The translation for the track - fx = (cosf(fPos * PI2) * 3.0f) - 2.0f; - fz = (sinf(fPos * PI2) * 3.0f); - - // The rotation - fy = -(90.0 * fPos); - - break; - - case TT_CURVE_SE: - - // The translation for the track - fx = (cosf(fPos * PI2) * 3.0f) - 2.0f; - fz = (-sinf(fPos * PI2) * 3.0f) + 2.0f; - - // The rotation - fy = (90.0 * fPos) - 180.0f; - - break; - - case TT_CURVE_SW: - - // The translation for the track - fx = (-cosf(fPos * PI2) * 3.0f) + 4.0f; - fz = (-sinf(fPos * PI2) * 3.0f) + 2.0f; - - // The rotation - fy = 180.0f - (90.0f * fPos); - - break; - - case TT_CURVE_NW: - - // The translation for the track - fx = (-cosf(fPos * PI2) * 3.0f) + 4.0f; - fz = (sinf(fPos * PI2) * 3.0f); - - // The rotation - fy = (90.0 * fPos); - - break; - - case TT_CURVE_NE_OTHER: - - // The translation for the track - fx = (-cosf(fPos * PI2 + PI2) * 3.0f); - fz = (sinf(fPos * PI2 + PI2) * 3.0f) - 2.0f; - - // The rotation - fy = (90.0 * fPos) + 90.0f; - - break; - - case TT_CURVE_SE_OTHER: - - // The translation for the track - fx = (-cosf(fPos * PI2 + PI2) * 3.0f); - fz = (sinf(fPos * PI2 - PI2) * 3.0f) + 4.0f; - - // The rotation - fy = 90.0f - (90.0 * fPos); - - break; - - case TT_CURVE_SW_OTHER: - - // The translation for the track - fx = (cosf(fPos * PI2 + PI2) * 3.0f) + 2.0f; - fz = (sinf(fPos * PI2 - PI2) * 3.0f) + 4.0f; - - // The rotation - fy = (90.0 * fPos) - 90; - - break; - - case TT_CURVE_NW_OTHER: - - // The translation for the track - fx = (cosf(fPos * PI2 + PI2) * 3.0f) + 2.0f; - fz = (sinf(fPos * PI2 + PI2) * 3.0f) - 2.0f; - - // The rotation - fy = -(90.0 * fPos) - 90.0f; - - break; - - default: - break; - } -} - -CTrack * CTrackManager::GetNextTrack(CTrack * pCurrent, DIRECTION d_current, DIRECTION & d_new) -{ - // Calculate the index into the current piece - int iOffset = (pCurrent->GetZOffset() * m_width) + pCurrent->GetXOffset(); - - // Determine the next piece of track - TRACK_TYPE cur_type = pCurrent->GetPiece(); - - switch(cur_type) - { - case TT_VERTICAL_STRAIGHT: - - if(d_current == D_NORTH) iOffset += m_width; - else iOffset -= m_width; - - // Direction is unchanged - d_new = d_current; - - break; - - case TT_HORIZONTAL_STRAIGHT: - - if(d_current == D_EAST) iOffset += 1; - else iOffset -= 1; - - // Direction is unchanged - d_new = d_current; - - break; - - // The curved pieces - case TT_CURVE_NE: - - iOffset += g_trackOrientationInfo[cur_type].iOffsetX; - iOffset += g_trackOrientationInfo[cur_type].iOffsetZ * m_width; - d_new = D_WEST; - break; - - case TT_CURVE_SE: - - iOffset += g_trackOrientationInfo[cur_type].iOffsetX; - iOffset += g_trackOrientationInfo[cur_type].iOffsetZ * m_width; - d_new = D_WEST; - break; - - case TT_CURVE_SW: - - iOffset += g_trackOrientationInfo[cur_type].iOffsetX; - iOffset += g_trackOrientationInfo[cur_type].iOffsetZ * m_width; - d_new = D_EAST; - break; - - case TT_CURVE_NW: - - iOffset += g_trackOrientationInfo[cur_type].iOffsetX; - iOffset += g_trackOrientationInfo[cur_type].iOffsetZ * m_width; - d_new = D_EAST; - break; - - // The other end of the curved pieces - case TT_CURVE_NE_OTHER: - - iOffset += g_trackOrientationInfo[cur_type].iOffsetX; - iOffset += g_trackOrientationInfo[cur_type].iOffsetZ * m_width; - d_new = D_SOUTH; - break; - - case TT_CURVE_SE_OTHER: - - iOffset += g_trackOrientationInfo[cur_type].iOffsetX; - iOffset += g_trackOrientationInfo[cur_type].iOffsetZ * m_width; - d_new = D_NORTH; - break; - - case TT_CURVE_SW_OTHER: - - iOffset += g_trackOrientationInfo[cur_type].iOffsetX; - iOffset += g_trackOrientationInfo[cur_type].iOffsetZ * m_width; - d_new = D_NORTH; - break; - - case TT_CURVE_NW_OTHER: - - iOffset += g_trackOrientationInfo[cur_type].iOffsetX; - iOffset += g_trackOrientationInfo[cur_type].iOffsetZ * m_width; - d_new = D_SOUTH; - break; - - default: - break; - } - - return m_grid.at(iOffset); -} diff -Nru opentracks-0.1/CTrackManager.h opentracks-0.0.7/CTrackManager.h --- opentracks-0.1/CTrackManager.h 2010-12-01 00:53:54.000000000 +0000 +++ opentracks-0.0.7/CTrackManager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -#ifndef CTRACKMANAGER_H -#define CTRACKMANAGER_H - -// Irrlicht includes -#include - -using namespace irr; - -using namespace core; -using namespace scene; -using namespace video; -using namespace io; -using namespace gui; - -// Standard includes -#include -#include - -// OpenTracks includes -#include "CTrack.h" - -// The class that manages the track -// being displayed. -class CTrackManager -{ - public: - - CTrackManager(IrrlichtDevice *,int,int); - ~CTrackManager(); - - void SetPiece(TRACK_TYPE,int,int); - CTrack * GetPiece(int,int); - - // This function returns the offset - // for a train given a track piece - // and its offset into that piece - void CalculateTrainPosition(CTrack *,DIRECTION,float,float &,float &,float &); - - // This function determines, given a piece - // of track and a direction, the next piece - // of track and direction - CTrack * GetNextTrack(CTrack *, DIRECTION, DIRECTION &); - - private: - - // The width and height of the grid - int m_width, m_height; - - // The actual track piece meshes - IMesh * m_straight; - IMesh * m_curved; - - // The grid of track pieces - std::vector m_grid; -}; - -#endif diff -Nru opentracks-0.1/CTrain.cpp opentracks-0.0.7/CTrain.cpp --- opentracks-0.1/CTrain.cpp 2010-12-01 04:37:01.000000000 +0000 +++ opentracks-0.0.7/CTrain.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -#include "CTrain.h" - -CTrain::CTrain(IrrlichtDevice * pDevice, u32 t_time, CTrack * pTrack, std::string mesh_filename) - : m_mesh(NULL), m_node(NULL), m_speed(0.0f), m_direction(D_NORTH), m_start_time(t_time), m_current_track(pTrack) -{ - // Try to open the train's mesh - m_mesh = pDevice->getSceneManager()->getMesh(DATA_DIR "/models/simple_engine.b3d"); - - // Grab a copy of it - m_mesh->grab(); - - // Now add the mesh to the scene manager - m_node = pDevice->getSceneManager()->addMeshSceneNode(m_mesh); - - // Disable lighting on it for now - //if(m_node) - // m_node->setMaterialFlag(EMF_LIGHTING, false); - - // TODO: add lookup for textures -} - -CTrain::~CTrain() -{ - // Free the mesh - m_mesh->drop(); - - // Now remove this train -} - -void CTrain::Process(CTrackManager * pManager,u32 t_time) -{ - // Calculate the percentage of the current piece of track - // that the train has travelled. - - // Elapsed time - int iElapsedMS = t_time - m_start_time; - - float fPerc = ((float)iElapsedMS / 1000.0f) * m_speed; - - // But wait! We might be at the end of the piece of track. - // If so, get the next piece of track and set the percentage accordingly. - TRACK_TYPE cur_type = m_current_track->GetPiece(); - - if(fPerc > g_trackOrientationInfo[cur_type].length) - { - fPerc -= g_trackOrientationInfo[cur_type].length; - - m_start_time = t_time - (fPerc * 1000.0f); - - DIRECTION new_dir; - m_current_track = pManager->GetNextTrack(m_current_track,m_direction,new_dir); - m_direction = new_dir; - } - - fPerc /= g_trackOrientationInfo[cur_type].length; - - float train_trans_x, train_trans_z; - float train_rotate_y; - - // Get the offset for the piece of track - pManager->CalculateTrainPosition(m_current_track,m_direction,fPerc,train_trans_x,train_trans_z,train_rotate_y); - - // Add the track's offset to this number - train_trans_x += m_current_track->GetXPos(); - train_trans_z += m_current_track->GetZPos(); - - // Now set this as the position - m_node->setPosition(vector3df(train_trans_x,0,train_trans_z)); - m_node->setRotation(vector3df(0,train_rotate_y,0)); -} diff -Nru opentracks-0.1/CTrain.h opentracks-0.0.7/CTrain.h --- opentracks-0.1/CTrain.h 2010-12-01 00:53:54.000000000 +0000 +++ opentracks-0.0.7/CTrain.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -#ifndef CTRAIN_H -#define CTRAIN_H - -// Irrlicht includes -#include - -using namespace irr; - -using namespace core; -using namespace scene; -using namespace video; -using namespace io; -using namespace gui; - -// Standard includes -#include - -// OpenTracks includes -#include "CTrackManager.h" - -class CTrain -{ - public: - - CTrain(IrrlichtDevice *,u32,CTrack *,std::string); - ~CTrain(); - - void SetSpeed(float speed) { m_speed = speed; } - - // Get information - float GetPosX() { return m_node->getPosition().X; } - float GetPosZ() { return m_node->getPosition().Z; } - float GetRotY() { return m_node->getRotation().Y; } - - // Processes the train - void Process(CTrackManager *,u32); - - private: - - IMesh * m_mesh; // the train's mesh - IMeshSceneNode * m_node; // the scene node - - // Information about where the train is - float m_speed; // blocks per second - DIRECTION m_direction; // direction - u32 m_start_time; // the time when the train entered the current piece of track - CTrack * m_current_track; -}; - -#endif diff -Nru opentracks-0.1/CTrainManager.cpp opentracks-0.0.7/CTrainManager.cpp --- opentracks-0.1/CTrainManager.cpp 2010-12-01 04:37:01.000000000 +0000 +++ opentracks-0.0.7/CTrainManager.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -#include "CTrainManager.h" - -CTrainManager::CTrainManager(CTrackManager * pManager) - : m_manager(pManager) -{ - //... -} - -CTrainManager::~CTrainManager() -{ - //... -} - -void CTrainManager::AddTrain(IrrlichtDevice * pDevice, u32 t_time, int x, int y) -{ - // We need to find the piece of track - // that corresponds to the given coords - - CTrack * pTrack = m_manager->GetPiece(x,y); - TRACK_TYPE tt = pTrack->GetPiece(); - - if(tt != TT_NUM_PIECES) - { - // Create the train and give it a small speed - CTrain * pTrain = new CTrain(pDevice,t_time,pTrack,DATA_DIR "/models/simple_train.b3d"); - pTrain->SetSpeed(1.5f); - - m_trains.push_back(pTrain); - } -} - -void CTrainManager::Process(u32 t_time) -{ - for(unsigned int i=0; iProcess(m_manager,t_time); - } -} diff -Nru opentracks-0.1/CTrainManager.h opentracks-0.0.7/CTrainManager.h --- opentracks-0.1/CTrainManager.h 2010-11-26 20:05:08.000000000 +0000 +++ opentracks-0.0.7/CTrainManager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -#ifndef CTRAINMANAGER_H -#define CTRAINMANAGER_H - -// Standard includes -#include - -// OpenTracks includes -#include "CTrain.h" -#include "CTrackManager.h" - -class CTrainManager -{ - public: - - CTrainManager(CTrackManager *); - ~CTrainManager(); - - void AddTrain(IrrlichtDevice *,u32,int,int); - CTrain * GetTrain(int i) { return m_trains.at(i); } - - // Loops through all of the trains, - // updating them. - void Process(u32); - - private: - - // A pointer to the track manager - CTrackManager * m_manager; - - // The list of trains - std::vector m_trains; -}; - -#endif Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/engines/standard_diesel/standard_diesel.b3d and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/engines/standard_diesel/standard_diesel.b3d differ diff -Nru opentracks-0.1/data/engines/standard_diesel/standard_diesel.xml opentracks-0.0.7/data/engines/standard_diesel/standard_diesel.xml --- opentracks-0.1/data/engines/standard_diesel/standard_diesel.xml 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/data/engines/standard_diesel/standard_diesel.xml 2010-12-14 06:19:23.000000000 +0000 @@ -0,0 +1,4 @@ + + + Standard Diesel + Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/fonts/arial/arial0.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/fonts/arial/arial0.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/fonts/arial/arial1.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/fonts/arial/arial1.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/fonts/arial/arial2.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/fonts/arial/arial2.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/fonts/arial/arial.xml and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/fonts/arial/arial.xml differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/fonts/arialmini/arialmini0.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/fonts/arialmini/arialmini0.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/fonts/arialmini/arialmini1.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/fonts/arialmini/arialmini1.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/fonts/arialmini/arialmini.xml and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/fonts/arialmini/arialmini.xml differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/icons/add_train.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/icons/add_train.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/icons/curved_track.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/icons/curved_track.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/icons/edit_track.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/icons/edit_track.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/icons/exit.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/icons/exit.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/icons/remove_track.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/icons/remove_track.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/icons/straight_track.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/icons/straight_track.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/icons/switch_track_inverted.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/icons/switch_track_inverted.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/icons/switch_track.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/icons/switch_track.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/icons/trains.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/icons/trains.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/models/bulldozer.b3d and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/models/bulldozer.b3d differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/models/simple_engine.b3d and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/models/simple_engine.b3d differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/models/simple_engine_ghost.b3d and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/models/simple_engine_ghost.b3d differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/models/track_switch_curve.b3d and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/models/track_switch_curve.b3d differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/models/track_switch_straight.b3d and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/models/track_switch_straight.b3d differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/textures/gui.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/textures/gui.png differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/data/textures/loading.jpg and /tmp/cwk4pSIoIs/opentracks-0.0.7/data/textures/loading.jpg differ diff -Nru opentracks-0.1/debian/changelog opentracks-0.0.7/debian/changelog --- opentracks-0.1/debian/changelog 2010-12-01 06:32:25.000000000 +0000 +++ opentracks-0.0.7/debian/changelog 2010-12-18 23:08:30.000000000 +0000 @@ -1,4 +1,4 @@ -opentracks (0.1-1) maverick; urgency=low +opentracks (0.0.7-1) maverick; urgency=low * Initial release (Closes: #nnnn) diff -Nru opentracks-0.1/debian/control opentracks-0.0.7/debian/control --- opentracks-0.1/debian/control 2010-12-01 06:31:26.000000000 +0000 +++ opentracks-0.0.7/debian/control 2010-12-16 07:37:56.000000000 +0000 @@ -4,10 +4,20 @@ Maintainer: Nathan Osman Build-Depends: debhelper (>= 7.0.50~), libirrlicht-dev (>= 1.7), libopenal-dev, libvorbis-dev Standards-Version: 3.8.4 -Homepage: https://launchpad.net/opentracks +Homepage: http://quickmediasolutions.com/software/opentracks/ Package: opentracks Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, libirrlicht1.7, libopenal1, libvorbisfile3 +Depends: ${shlibs:Depends}, ${misc:Depends}, libirrlicht1.7, libopenal1, libvorbisfile3, opentracks-data (= ${source:Version}) Description: A small railway simulation game. OpenTracks is a small railway simulation game. + . + This package contains the binary files for the game. + +Package: opentracks-data +Architecture: all +Depends: ${misc:Depends} +Description: A small railway simulation game. + OpenTracks is a small railway simulation game. + . + This package contains the textures and models needed for the game to run. diff -Nru opentracks-0.1/debian/opentracks-data.install opentracks-0.0.7/debian/opentracks-data.install --- opentracks-0.1/debian/opentracks-data.install 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/debian/opentracks-data.install 2010-12-15 05:36:12.000000000 +0000 @@ -0,0 +1,2 @@ +/usr/share/pixmaps +/usr/share/opentracks diff -Nru opentracks-0.1/debian/opentracks.install opentracks-0.0.7/debian/opentracks.install --- opentracks-0.1/debian/opentracks.install 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/debian/opentracks.install 2010-12-15 05:36:13.000000000 +0000 @@ -0,0 +1,2 @@ +/usr/bin/ +/usr/share/applications/opentracks.desktop diff -Nru opentracks-0.1/debian/patches/debian-changes-0.1-1 opentracks-0.0.7/debian/patches/debian-changes-0.1-1 --- opentracks-0.1/debian/patches/debian-changes-0.1-1 2010-12-01 06:37:47.000000000 +0000 +++ opentracks-0.0.7/debian/patches/debian-changes-0.1-1 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +0,0 @@ -Description: Upstream changes introduced in version 0.1-1 - This patch has been created by dpkg-source during the package build. - Here's the last changelog entry, hopefully it gives details on why - those changes were made: - . - opentracks (0.1-1) maverick; urgency=low - . - * Initial release (Closes: #nnnn) - . - The person named in the Author field signed this changelog entry. -Author: Nathan Osman - ---- -The information above should follow the Patch Tagging Guidelines, please -checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here -are templates for supplementary fields that you might want to add: - -Origin: , -Bug: -Bug-Debian: http://bugs.debian.org/ -Bug-Ubuntu: https://launchpad.net/bugs/ -Forwarded: -Reviewed-By: -Last-Update: - ---- opentracks-0.1.orig/Makefile -+++ opentracks-0.1/Makefile -@@ -33,5 +33,6 @@ clean: - install: - mkdir -p $(DESTDIR)$(BIN_DIR) - cp $(EXEC) $(DESTDIR)$(BIN_DIR) -+ mkdir -p $(DESTDIR)$(DATA_DIR) - cp -r data/* $(DESTDIR)$(DATA_DIR) - diff -Nru opentracks-0.1/debian/patches/series opentracks-0.0.7/debian/patches/series --- opentracks-0.1/debian/patches/series 2010-12-01 06:37:02.000000000 +0000 +++ opentracks-0.0.7/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -debian-changes-0.1-1 Binary files /tmp/2xBESq2lXr/opentracks-0.1/images/opentracks.png and /tmp/cwk4pSIoIs/opentracks-0.0.7/images/opentracks.png differ diff -Nru opentracks-0.1/include/CAudioManager.h opentracks-0.0.7/include/CAudioManager.h --- opentracks-0.1/include/CAudioManager.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CAudioManager.h 2010-12-15 01:59:29.000000000 +0000 @@ -0,0 +1,31 @@ +#ifndef CAUDIOMANAGER_H +#define CAUDIOMANAGER_H + +// We need to include OpenAL headers +#include +#include + +// Standard includes +#include + +// Ogg file headers +#include "COggFile.h" + +class CAudioManager +{ + public: + + // Constructor / destructor + CAudioManager(); + ~CAudioManager(); + + COggFile * LoadOggFile(std::string); + + private: + + // OpenAL variables + ALCdevice * m_device; + ALCcontext * m_context; +}; + +#endif diff -Nru opentracks-0.1/include/CGameState.h opentracks-0.0.7/include/CGameState.h --- opentracks-0.1/include/CGameState.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CGameState.h 2010-12-13 22:54:40.000000000 +0000 @@ -0,0 +1,69 @@ +#ifndef CGAMESTATE_H +#define CGAMESTATE_H + +// Irrlicht includes +#include + +using namespace irr; + +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +// Forward declaration of game state manager +class CStateManager; + +// All of the game states available +enum GAME_STATE { GS_NONE, + GS_LOADING, + GS_MENU, + GS_PLAYING }; + +// Abstract base class for all other game states +// Notice that this class derives from the event receiver +// class - that's because each game state needs to have +// its own event management code +class CGameState : public IEventReceiver +{ + public: + + // Constructor + CGameState(CStateManager * pManager); + virtual ~CGameState() {} + + //------------------- + // Utility functions + //------------------- + + // Indicates to the manager that we want to + // switch the current game state to something else + IrrlichtDevice * GetDevice(); + void SwitchState(GAME_STATE); + void Exit(); + + void ClearScreen(); + void Done(); + + //--------------------------------- + // Each of these MAY be overridden + // in the derived class + //--------------------------------- + virtual bool OnEvent(const SEvent& event) { return false; } + + //----------------------------------- + // Each of these MUST be implemented + // in the derived classes + //----------------------------------- + + // Renders the current frame + virtual void RenderFrame(u32)=0; + + protected: + + // The device + CStateManager * m_manager; +}; + +#endif diff -Nru opentracks-0.1/include/CGround.h opentracks-0.0.7/include/CGround.h --- opentracks-0.1/include/CGround.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CGround.h 2010-12-01 00:53:53.000000000 +0000 @@ -0,0 +1,36 @@ +#ifndef CGROUND_H +#define CGROUND_H + +// Irrlicht includes +#include + +using namespace irr; + +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +class CGround +{ + public: + + CGround(IrrlichtDevice *,int,int); + ~CGround(); + + // This is the ray-picking function + // that determines what triangles the given + // line intersects. + bool Intersection(IrrlichtDevice *,line3df,int&,int&); + + private: + + int m_width; + int m_height; + + IMeshSceneNode * m_node; + ITriangleSelector * m_selector; +}; + +#endif diff -Nru opentracks-0.1/include/CLoadingState.h opentracks-0.0.7/include/CLoadingState.h --- opentracks-0.1/include/CLoadingState.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CLoadingState.h 2010-12-13 02:07:26.000000000 +0000 @@ -0,0 +1,24 @@ +#ifndef CLOADINGSTATE_H +#define CLOADINGSTATE_H + +#include "CGameState.h" + +class CLoadingState : public CGameState +{ + public: + + CLoadingState(CStateManager *); + ~CLoadingState(); + + void RenderFrame(u32); + + private: + + // Textures, etc. + ITexture * m_loading_texture; + + // This is temporary + static bool bTemp; +}; + +#endif diff -Nru opentracks-0.1/include/CMenuState.h opentracks-0.0.7/include/CMenuState.h --- opentracks-0.1/include/CMenuState.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CMenuState.h 2010-12-12 22:33:25.000000000 +0000 @@ -0,0 +1,21 @@ +#ifndef CMENUSTATE_H +#define CMENUSTATE_H + +#include "CGameState.h" + +class CMenuState : public CGameState +{ + public: + + CMenuState(CStateManager *); + ~CMenuState(); + + bool OnEvent(const SEvent&); + void RenderFrame(u32); + + private: + + // Other stuff +}; + +#endif diff -Nru opentracks-0.1/include/COggFile.h opentracks-0.0.7/include/COggFile.h --- opentracks-0.1/include/COggFile.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/COggFile.h 2010-12-15 01:46:11.000000000 +0000 @@ -0,0 +1,23 @@ +#ifndef COGGFILE_H +#define COGGFILE_H + +// Standard includes +#include + +// vorbisfile includes +#include + +class COggFile +{ + public: + + COggFile(std::string); + ~COggFile(); + + private: + + // Audio data + char * m_data; +}; + +#endif diff -Nru opentracks-0.1/include/CPlayingState.h opentracks-0.0.7/include/CPlayingState.h --- opentracks-0.1/include/CPlayingState.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CPlayingState.h 2010-12-17 23:39:40.000000000 +0000 @@ -0,0 +1,100 @@ +#ifndef CPLAYINGSTATE_H +#define CPLAYINGSTATE_H + +#include "CGameState.h" + +// OpenTracks includes +#include "CGround.h" +#include "CSkybox.h" +#include "CTrackManager.h" +#include "CTrainManager.h" + +// Enumerations +enum INPUT_MODE { IM_SELECT=0, + IM_PLACE_TRACK, + IM_PLACE_TRAIN, + IM_REMOVE_TRACK }; + +enum TRACK_CLASS { TC_STRAIGHT, + TC_CURVE, + TC_SWITCH }; + +class CPlayingState : public CGameState +{ + public: + + CPlayingState(CStateManager *); + ~CPlayingState(); + + bool OnEvent(const SEvent&); + void RenderFrame(u32); + + private: + + // Utility functions + bool KeyEvent(const SEvent&); + bool MouseEvent(const SEvent&); + bool GUIEvent(const SEvent&); + + // GUI creation / management functions + void CreateToolbar(); + void CreateEditTrackWindow(); + void CreateAddTrainWindow(); + void CreateTrainWindow(CTrain *); + + // Input type functions + void SwitchInputMode(INPUT_MODE); + void CloseAllDialogs(); + + // Input manager + void ProcessInput(u32); + + // We have a few things to keep track of here... + + // Screen objects and pointers + ICameraSceneNode * m_camera; + IGUIToolBar * m_toolbar; + + // State information + INPUT_MODE m_mode; + + // Physical geometry + CGround m_ground; + CSkybox m_sky; + + // Track and train managers + CTrackManager m_track_manager; + CTrainManager m_train_manager; + + // Ghost objects + IMeshSceneNode * m_straight_ghost_node; + IMeshSceneNode * m_curve_ghost_node; + IMeshSceneNode * m_switch_ghost_node; + IMeshSceneNode * m_engine_ghost_node; + IMeshSceneNode * m_bulldozer_ghost_node; + + // GUI dialogs + IGUIWindow * m_dialog_edittrack; + IGUIWindow * m_dialog_addtrain; + + // Camera manipulation information + u32 m_previous_time; + float m_rotation; + float m_radius; + + // Key information + bool m_up, m_down, m_left, m_right; + + // Mouse information + bool m_r_down; + float m_x_diff, m_y_diff; + s32 m_x_cur, m_y_cur; + s32 m_x_prev, m_y_prev; + line3df m_cursor_ray; // for ray-picking + + // Track placement information + TRACK_CLASS m_current_class; + TRACK_TYPE m_current_track; +}; + +#endif diff -Nru opentracks-0.1/include/CSkin.h opentracks-0.0.7/include/CSkin.h --- opentracks-0.1/include/CSkin.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CSkin.h 2010-12-08 22:31:04.000000000 +0000 @@ -0,0 +1,87 @@ +#ifndef CSKIN_H +#define CSKIN_H + +#include + +using namespace irr; + +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +class CSkin : public IGUISkin +{ + public: + + // Constructor and destructor + CSkin(IrrlichtDevice *); + ~CSkin(); + + // We need to override a few functions here + virtual SColor getColor(EGUI_DEFAULT_COLOR color) const; + virtual void setColor(EGUI_DEFAULT_COLOR which, SColor newColor); + virtual s32 getSize(EGUI_DEFAULT_SIZE size) const; + virtual const wchar_t* getDefaultText(EGUI_DEFAULT_TEXT text) const ; + virtual void setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText); + virtual void setSize(EGUI_DEFAULT_SIZE which, s32 size); + virtual IGUIFont* getFont(EGUI_DEFAULT_FONT which=EGDF_DEFAULT) const; + virtual void setFont(IGUIFont* font, EGUI_DEFAULT_FONT which=EGDF_DEFAULT); + virtual IGUISpriteBank* getSpriteBank() const; + virtual void setSpriteBank(IGUISpriteBank* bank); + virtual u32 getIcon(EGUI_DEFAULT_ICON icon) const; + virtual void setIcon(EGUI_DEFAULT_ICON icon, u32 index); + virtual void draw3DButtonPaneStandard(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + virtual void draw3DButtonPanePressed(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + virtual void draw3DSunkenPane(IGUIElement* element, + SColor bgcolor, bool flat, bool fillBackGround, + const core::rect& rect, + const core::rect* clip=0); + virtual core::rect draw3DWindowBackground(IGUIElement* element, + bool drawTitleBar, SColor titleBarColor, + const core::rect& rect, + const core::rect* clip=0, + core::rect* checkClientArea=0); + virtual void draw3DMenuPane(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + virtual void draw3DToolBar(IGUIElement* element, + const core::rect& rect, + const core::rect* clip=0); + virtual void draw3DTabButton(IGUIElement* element, bool active, + const core::rect& rect, const core::rect* clip=0, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT); + virtual void draw3DTabBody(IGUIElement* element, bool border, bool background, + const core::rect& rect, const core::rect* clip=0, s32 tabHeight=-1, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT ); + virtual void drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const position2di position, u32 starttime=0, u32 currenttime=0, + bool loop=false, const core::rect* clip=0); + virtual void draw2DRectangle(IGUIElement* element, const SColor &color, + const core::rect& pos, const core::rect* clip ); + + virtual EGUI_SKIN_TYPE getType() const { return EGST_UNKNOWN; } + + private: + + // Internal utility functions + void DrawRoundedBox(const core::rect& rect, const SColor& color) const; + + // Pointer to the video driver + IrrlichtDevice * m_device; + + // The normal sized font + IGUIFont * m_normal_font; + + // The miniature font + IGUIFont * m_mini_font; + + // Our GUI texture and stuff + ITexture * m_tex; + IGUISpriteBank * m_sprites; +}; + +#endif diff -Nru opentracks-0.1/include/CSkybox.h opentracks-0.0.7/include/CSkybox.h --- opentracks-0.1/include/CSkybox.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CSkybox.h 2010-12-11 07:02:17.000000000 +0000 @@ -0,0 +1,31 @@ +#ifndef CSKYBOX_H +#define CSKYBOX_H + +// Irrlicht includes +#include + +using namespace irr; + +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +// Standard includes +#include + +class CSkybox +{ + public: + + CSkybox(IrrlichtDevice *,int,int); + ~CSkybox(); + + private: + + // Keep a copy of the scene node + IMeshSceneNode * m_node; +}; + +#endif diff -Nru opentracks-0.1/include/CStateManager.h opentracks-0.0.7/include/CStateManager.h --- opentracks-0.1/include/CStateManager.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CStateManager.h 2010-12-13 22:51:21.000000000 +0000 @@ -0,0 +1,56 @@ +#ifndef CSTATEMANAGER_H +#define CSTATEMANAGER_H + +// Irrlicht includes +#include + +using namespace irr; + +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +// OpenTracks inclues +#include "CGameState.h" + +// This is the global state manager that is responsible +// for swapping out game states as needed and delegating +// input to the appropriate function. +class CStateManager +{ + public: + + // Constructor + CStateManager(IrrlichtDevice *); + ~CStateManager(); + + // The 'main' function that + // runs the application + void Go(); + + // The function to call when we're done + void Exit(); + + // We have two functions here: + // - one queues the state change + // - the other actually does it + void QueueStateChange(GAME_STATE); + void SwitchState(GAME_STATE); + + // Accessor functions + IrrlichtDevice * GetDevice() { return m_device; } + + private: + + // Device + IrrlichtDevice * m_device; + + // Current game state + GAME_STATE m_state; + CGameState * m_state_pointer; + bool m_state_changing; // a small flag so that we know when the state needs to be changed +}; + +#endif diff -Nru opentracks-0.1/include/CTrack.h opentracks-0.0.7/include/CTrack.h --- opentracks-0.1/include/CTrack.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CTrack.h 2010-12-18 01:35:00.000000000 +0000 @@ -0,0 +1,139 @@ +#ifndef CTRACK_H +#define CTRACK_H + +// Irrlicht includes +#include + +using namespace irr; + +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +// Standard includes +#include + +// Track types +enum TRACK_TYPE { TT_VERTICAL_STRAIGHT=0, + TT_HORIZONTAL_STRAIGHT, + + // The curved pieces + TT_CURVE_NE, + TT_CURVE_SE, + TT_CURVE_SW, + TT_CURVE_NW, + + TT_CURVE_NE_OTHER, // these represent the other + TT_CURVE_SE_OTHER, // end of the track piece + TT_CURVE_SW_OTHER, + TT_CURVE_NW_OTHER, + + TT_SWITCH_VERTICAL_NE, // The innumerable switch + TT_SWITCH_VERTICAL_SE, // pieces... which are many + TT_SWITCH_VERTICAL_SW, + TT_SWITCH_VERTICAL_NW, + TT_SWITCH_HORIZONTAL_NE, // The horizontal version + TT_SWITCH_HORIZONTAL_SE, // of the switches + TT_SWITCH_HORIZONTAL_SW, + TT_SWITCH_HORIZONTAL_NW, + + TT_SWITCH_VERTICAL_NE_OTHER_CURVE, // The other end of the + TT_SWITCH_VERTICAL_SE_OTHER_CURVE, // curved part of the switches + TT_SWITCH_VERTICAL_SW_OTHER_CURVE, + TT_SWITCH_VERTICAL_NW_OTHER_CURVE, + TT_SWITCH_HORIZONTAL_NE_OTHER_CURVE, + TT_SWITCH_HORIZONTAL_SE_OTHER_CURVE, + TT_SWITCH_HORIZONTAL_SW_OTHER_CURVE, + TT_SWITCH_HORIZONTAL_NW_OTHER_CURVE, + + TT_SWITCH_VERTICAL_NE_OTHER_STRAIGHT, // The other end of the + TT_SWITCH_VERTICAL_SE_OTHER_STRAIGHT, // curved part of the switches + TT_SWITCH_VERTICAL_SW_OTHER_STRAIGHT, + TT_SWITCH_VERTICAL_NW_OTHER_STRAIGHT, + TT_SWITCH_HORIZONTAL_NE_OTHER_STRAIGHT, + TT_SWITCH_HORIZONTAL_SE_OTHER_STRAIGHT, + TT_SWITCH_HORIZONTAL_SW_OTHER_STRAIGHT, + TT_SWITCH_HORIZONTAL_NW_OTHER_STRAIGHT, + + TT_NUM_PIECES }; // this last entry is used + // to determine the number of pieces + +// Directions +enum DIRECTION { D_NORTH=0, + D_EAST, + D_SOUTH, + D_WEST }; + +enum SWITCH_STATE { SS_STRAIGHT, + SS_CURVED }; + +class CTrackOrientationInfo +{ + public: + + // Track length in units + float length; + + // Translation + float fTrans_x; + float fTrans_y; + float fTrans_z; + + // Rotation + float fRot_x; + float fRot_y; + float fRot_z; + + int iOffsetX; // The next piece of track + int iOffsetZ; // from the current offset + + // THIS ONLY USED FOR SWITCHES + float fScaleX; + float fScaleZ; + + float switch_length; + + int switch_iOffsetX; + int switch_iOffsetZ; +}; + +// This class represents an actual physical +// piece of track on the grid +class CTrack +{ + public: + + CTrack(IrrlichtDevice *,float,float,float,int,int); + ~CTrack(); + + void SetPiece(TRACK_TYPE,IAnimatedMesh *); + TRACK_TYPE GetPiece() { return m_type; } + + float GetXPos() { return m_x; } + float GetZPos() { return m_z; } + + int GetXOffset() { return m_offset_x; } + int GetZOffset() { return m_offset_z; } + + SWITCH_STATE GetState() { return m_state; } + void SetState(SWITCH_STATE); + + private: + + TRACK_TYPE m_type; + + IAnimatedMeshSceneNode * m_node; // the scene node + + float m_x, m_y, m_z; // the location of this piece + int m_offset_x, m_offset_z; // The offset of this piece + + // The state of the switch (if any) + SWITCH_STATE m_state; +}; + +// Track information +extern CTrackOrientationInfo g_trackOrientationInfo[]; + +#endif diff -Nru opentracks-0.1/include/CTrackManager.h opentracks-0.0.7/include/CTrackManager.h --- opentracks-0.1/include/CTrackManager.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CTrackManager.h 2010-12-18 19:09:26.000000000 +0000 @@ -0,0 +1,82 @@ +#ifndef CTRACKMANAGER_H +#define CTRACKMANAGER_H + +// Irrlicht includes +#include + +using namespace irr; + +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +// Standard includes +#include +#include + +// OpenTracks includes +#include "CTrack.h" + +// The class that manages the track +// being displayed. +class CTrackManager +{ + public: + + CTrackManager(IrrlichtDevice *,int,int); + ~CTrackManager(); + + void SetPiece(TRACK_TYPE,int,int); + CTrack * GetPiece(int,int); + + // Switch utility functions + void SetSwitchState(int,int,SWITCH_STATE); + + // This function returns the offset + // for a train given a track piece + // and its offset into that piece + void CalculateTrainPosition(CTrack *,DIRECTION,float,float &,float &,float &); + + // This function determines, given a piece + // of track and a direction, the next piece + // of track and direction + CTrack * GetNextTrack(CTrack *, DIRECTION, DIRECTION &); + + private: + + // These functions return the offset + // and rotation for the train at a + // given position. + + // The straight peices + inline void PositionStraightVertical(float,DIRECTION,float &,float &,float &,float=1.0f,float=0.0f); + inline void PositionStraightHorizontal(float,DIRECTION,float &,float &,float &,float=1.0f,float=0.0f); + + // The curves + inline void PositionCurveNE(float,float &,float &,float &); + inline void PositionCurveSE(float,float &,float &,float &); + inline void PositionCurveSW(float,float &,float &,float &); + inline void PositionCurveNW(float,float &,float &,float &); + + // And of course, for the other direction + inline void PositionCurveNEOther(float,float &,float &,float &); + inline void PositionCurveSEOther(float,float &,float &,float &); + inline void PositionCurveSWOther(float,float &,float &,float &); + inline void PositionCurveNWOther(float,float &,float &,float &); + + // The width and height of the grid + int m_width, m_height; + + // The actual track piece meshes + IAnimatedMesh * m_straight; + IAnimatedMesh * m_curved; + IAnimatedMesh * m_switch_curve; + IAnimatedMesh * m_switch_straight; + + // The grid of track pieces + std::vector m_grid; +}; + +#endif diff -Nru opentracks-0.1/include/CTrain.h opentracks-0.0.7/include/CTrain.h --- opentracks-0.1/include/CTrain.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CTrain.h 2010-12-13 21:59:57.000000000 +0000 @@ -0,0 +1,53 @@ +#ifndef CTRAIN_H +#define CTRAIN_H + +// Irrlicht includes +#include + +using namespace irr; + +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +// Standard includes +#include + +// OpenTracks includes +#include "CTrackManager.h" + +class CTrain +{ + public: + + CTrain(IrrlichtDevice *,ISceneNode *,u32,CTrack *,std::string); + ~CTrain(); + + float GetSpeed() { return m_speed; } + void SetSpeed(float speed) { m_speed = speed; } + + // Get information + float GetPosX() { return m_node->getPosition().X; } + float GetPosZ() { return m_node->getPosition().Z; } + float GetRotY() { return m_node->getRotation().Y; } + + ISceneNode * GetSceneNode() { return m_node; } + + // Processes the train + void Process(CTrackManager *,u32); + + private: + + IMeshSceneNode * m_node; // the scene node + + // Information about where the train is + float m_speed; // blocks per second + DIRECTION m_direction; // direction + u32 m_last_time; // the time when the train entered the current piece of track + float m_percent; // the pseudo-percentage of the current piece that the train has travelled + CTrack * m_current_track; // The current piece of track +}; + +#endif diff -Nru opentracks-0.1/include/CTrainManager.h opentracks-0.0.7/include/CTrainManager.h --- opentracks-0.1/include/CTrainManager.h 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/include/CTrainManager.h 2010-12-18 00:53:18.000000000 +0000 @@ -0,0 +1,56 @@ +#ifndef CTRAINMANAGER_H +#define CTRAINMANAGER_H + +// Standard includes +#include +#include + +// OpenTracks includes +#include "CTrain.h" +#include "CTrackManager.h" + +class CTrainManager +{ + public: + + CTrainManager(IrrlichtDevice *, CTrackManager *); + ~CTrainManager(); + + void AddTrain(u32,int,int); + CTrain * GetTrain(int i) { return m_trains.at(i); } + + // Loops through all of the trains, + // updating them. + void Process(u32); + + // This function will see if there are any trains + // that intersect the given ray. + CTrain * Intersection(line3df); + + // Add a window / train mapping + void AddWindowMapping(IGUIElement *, CTrain *); + void RemoveWindowMapping(IGUIElement *); + CTrain * GetTrainFromWindow(IGUIElement *); + + private: + + // A pointer to the device + IrrlichtDevice * m_device; + + // A pointer to the track manager + CTrackManager * m_manager; + + // The list of trains and the map that correlates + // the CTrain * to the scene node + std::vector m_trains; + std::map m_node_map; + + // Now we need a map for the train dialog + // to the window of its properties + std::map m_window_map; + + // The parent scene node + ISceneNode * m_parent_node; +}; + +#endif diff -Nru opentracks-0.1/LICENSE opentracks-0.0.7/LICENSE --- opentracks-0.1/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/LICENSE 2010-12-18 00:49:23.000000000 +0000 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff -Nru opentracks-0.1/main.cpp opentracks-0.0.7/main.cpp --- opentracks-0.1/main.cpp 2010-12-01 00:53:54.000000000 +0000 +++ opentracks-0.0.7/main.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -#include - -using namespace irr; - -using namespace core; -using namespace scene; -using namespace video; -using namespace io; -using namespace gui; - -#include "CEventManager.h" -#include "CTrainManager.h" -#include "CTrackManager.h" -#include "CGround.h" -#include "CSkybox.h" - -int main(int argc, char** argv) -{ - CEventManager em; - - // Begin by creating the device - IrrlichtDevice *device = - createDevice(EDT_OPENGL, dimension2d(960, 600), 16, - false, false, true, &em); - - device->setWindowCaption(L"OpenTracks"); - - IVideoDriver* driver = device->getVideoDriver(); - ISceneManager* smgr = device->getSceneManager(); - IGUIEnvironment* guienv = device->getGUIEnvironment(); - - // Create the ground and skybox - CGround gr(device,30,30); - CSkybox sb(device,30,30); - - // Create the track - CTrackManager tm(device,30,30); - - /* - // Set a few pieces to form a nice grid - tm.SetPiece(TT_CURVE_SW,0,2); - tm.SetPiece(TT_HORIZONTAL_STRAIGHT,2,1); - tm.SetPiece(TT_HORIZONTAL_STRAIGHT,3,1); - tm.SetPiece(TT_CURVE_SE,5,2); - tm.SetPiece(TT_VERTICAL_STRAIGHT,0,3); - tm.SetPiece(TT_VERTICAL_STRAIGHT,5,3); - tm.SetPiece(TT_VERTICAL_STRAIGHT,0,4); - tm.SetPiece(TT_CURVE_NW,5,4); - tm.SetPiece(TT_CURVE_NW,0,5); - tm.SetPiece(TT_CURVE_SE,3,7); - tm.SetPiece(TT_CURVE_NE,3,8); - tm.SetPiece(TT_CURVE_SW,0,10); - tm.SetPiece(TT_VERTICAL_STRAIGHT,0,11); - tm.SetPiece(TT_VERTICAL_STRAIGHT,0,12); - tm.SetPiece(TT_CURVE_NW,0,13); - tm.SetPiece(TT_HORIZONTAL_STRAIGHT,2,14); - tm.SetPiece(TT_CURVE_NE,4,13); - tm.SetPiece(TT_VERTICAL_STRAIGHT,4,12); - tm.SetPiece(TT_CURVE_SW,4,11); - tm.SetPiece(TT_HORIZONTAL_STRAIGHT,6,10); - tm.SetPiece(TT_CURVE_SE,8,6); - tm.SetPiece(TT_VERTICAL_STRAIGHT,8,7); - tm.SetPiece(TT_VERTICAL_STRAIGHT,8,8); - tm.SetPiece(TT_CURVE_NE,8,9); - */ - - // Create the train manager - CTrainManager trains(&tm); - - // ...and add a train - //trains.AddTrain(device,device->getTimer()->getTime(),5,3); - //trains.AddTrain(device,device->getTimer()->getTime(),8,8); - - // Add the camera - //ICameraSceneNode * pCamera = smgr->addCameraSceneNode(0, vector3df(0,0,0)); - //pCamera->bindTargetAndRotation(true); - //pCamera->setFarValue(100.0f); - - // Set the ambient light - smgr->setAmbientLight(SColorf(0.7,0.7,0.7,1)); - ILightSceneNode * light = smgr->addLightSceneNode(); - - light->setPosition(vector3df(0,4,0)); - light->setRotation(vector3df(90,0,0)); - light->setRadius(2.0f); - - SLight l_info; - l_info.Type = ELT_DIRECTIONAL; - - light->setLightData(l_info); - - // Set the event manager's data - em.SetDevice(device,&tm,&trains,&gr); - - while(device->run()) - { - u32 cur_time = device->getTimer()->getTime(); - - // Process the event manager - em.Process(cur_time); - - driver->beginScene(true, true, SColor(0,0,0,0)); - - // Process the trains - trains.Process(cur_time); - - smgr->drawAll(); - guienv->drawAll(); - - driver->endScene(); - } - - device->drop(); - - return 0; -} - diff -Nru opentracks-0.1/Makefile opentracks-0.0.7/Makefile --- opentracks-0.1/Makefile 2010-12-01 04:50:25.000000000 +0000 +++ opentracks-0.0.7/Makefile 2010-12-15 01:35:24.000000000 +0000 @@ -12,15 +12,15 @@ LFLAGS = -l Irrlicht -l vorbisfile -l openal # C++ files to compile -CXX_FILES = $(wildcard *.cpp) # All .cpp files in the directory -OBJ_FILES = $(CXX_FILES:%.cpp=$(OBJ_DIR)/%.o) +CXX_FILES = $(wildcard src/*.cpp) # All .cpp files in the directory +OBJ_FILES = $(CXX_FILES:src/%.cpp=$(OBJ_DIR)/%.o) # Rules all: object_directory $(OBJ_FILES) $(CXX) $(OBJ_FILES) -o $(EXEC) $(LFLAGS) -$(OBJ_DIR)/%.o: %.cpp - $(CXX) -c $< -o $@ $(CFLAGS) +$(OBJ_DIR)/%.o: src/%.cpp + $(CXX) -c $< -o $@ $(CFLAGS) -Iinclude object_directory: test -d $(OBJ_DIR) || mkdir $(OBJ_DIR) @@ -33,5 +33,10 @@ install: mkdir -p $(DESTDIR)$(BIN_DIR) cp $(EXEC) $(DESTDIR)$(BIN_DIR) + mkdir -p $(DESTDIR)$(DATA_DIR) cp -r data/* $(DESTDIR)$(DATA_DIR) + mkdir -p $(DESTDIR)/usr/share/pixmaps + mkdir -p $(DESTDIR)/usr/share/applications + cp -r images/* $(DESTDIR)/usr/share/pixmaps + cp other/opentracks.desktop $(DESTDIR)/usr/share/applications Binary files /tmp/2xBESq2lXr/opentracks-0.1/media/bulldozer.blend and /tmp/cwk4pSIoIs/opentracks-0.0.7/media/bulldozer.blend differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/media/simple_engine.blend and /tmp/cwk4pSIoIs/opentracks-0.0.7/media/simple_engine.blend differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/media/simple_engine_ghost.blend and /tmp/cwk4pSIoIs/opentracks-0.0.7/media/simple_engine_ghost.blend differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/media/skybox.blend and /tmp/cwk4pSIoIs/opentracks-0.0.7/media/skybox.blend differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/media/track_small_curve.blend and /tmp/cwk4pSIoIs/opentracks-0.0.7/media/track_small_curve.blend differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/media/track_straight.blend and /tmp/cwk4pSIoIs/opentracks-0.0.7/media/track_straight.blend differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/media/track_switch_base.blend and /tmp/cwk4pSIoIs/opentracks-0.0.7/media/track_switch_base.blend differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/media/track_switch_curve.blend and /tmp/cwk4pSIoIs/opentracks-0.0.7/media/track_switch_curve.blend differ Binary files /tmp/2xBESq2lXr/opentracks-0.1/media/track_switch_straight.blend and /tmp/cwk4pSIoIs/opentracks-0.0.7/media/track_switch_straight.blend differ diff -Nru opentracks-0.1/opentracks.cbp opentracks-0.0.7/opentracks.cbp --- opentracks-0.1/opentracks.cbp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/opentracks.cbp 2010-12-15 05:02:12.000000000 +0000 @@ -0,0 +1,84 @@ + + + + + + diff -Nru opentracks-0.1/other/opentracks.desktop opentracks-0.0.7/other/opentracks.desktop --- opentracks-0.1/other/opentracks.desktop 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/other/opentracks.desktop 2010-12-11 23:45:51.000000000 +0000 @@ -0,0 +1,8 @@ +[Desktop Entry] +Name=OpenTracks +Comment=An Open Source Railway Simulation Game +Exec=opentracks +Icon=opentracks +Type=Application +Categories=Game;ArcadeGame +Name[en_CA]=OpenTracks diff -Nru opentracks-0.1/src/CAudioManager.cpp opentracks-0.0.7/src/CAudioManager.cpp --- opentracks-0.1/src/CAudioManager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CAudioManager.cpp 2010-12-15 06:45:29.000000000 +0000 @@ -0,0 +1,22 @@ +#include "CAudioManager.h" + +CAudioManager::CAudioManager() +{ + // Open the default audio device + // and create the context + m_device = alcOpenDevice(NULL); + m_context = alcCreateContext(m_device, NULL); +} + +CAudioManager::~CAudioManager() +{ + // Free the context and close + // the device + alcDestroyContext(m_context); + alcCloseDevice(m_device); +} + +COggFile * CAudioManager::LoadOggFile(std::string filename) +{ + return new COggFile(filename); +} diff -Nru opentracks-0.1/src/CGameState.cpp opentracks-0.0.7/src/CGameState.cpp --- opentracks-0.1/src/CGameState.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CGameState.cpp 2010-12-13 22:50:57.000000000 +0000 @@ -0,0 +1,40 @@ +#include "CStateManager.h" +#include "CGameState.h" + +CGameState::CGameState(CStateManager * pManager) + : m_manager(pManager) +{ + // Set this item as the current event + // receiver + m_manager->GetDevice()->setEventReceiver(this); + + // Clear the GUI + GetDevice()->getGUIEnvironment()->clear(); +} + +IrrlichtDevice * CGameState::GetDevice() + { + return m_manager->GetDevice(); + } + +void CGameState::SwitchState(GAME_STATE new_state) +{ + // We will queue the state change + m_manager->QueueStateChange(new_state); +} + +void CGameState::Exit() +{ + // Quit the game + m_manager->Exit(); +} + +void CGameState::ClearScreen() +{ + m_manager->GetDevice()->getVideoDriver()->beginScene(true, true, SColor(0,0,0,0)); +} + +void CGameState::Done() +{ + m_manager->GetDevice()->getVideoDriver()->endScene(); +} diff -Nru opentracks-0.1/src/CGround.cpp opentracks-0.0.7/src/CGround.cpp --- opentracks-0.1/src/CGround.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CGround.cpp 2010-12-11 19:07:46.000000000 +0000 @@ -0,0 +1,140 @@ +#include "CGround.h" + +CGround::CGround(IrrlichtDevice * pDevice,int width,int height) + : m_width(width), m_height(height), m_node(NULL), m_selector(NULL) +{ + // Our first step is to determine how many vertices + // we will need to create a mesh that is width x height + // + // *----*----*----* As you can see, we will need exactly + // | | | | (width + 1) * (height + 1) vertices + // *----*----*----* and (6 * width * height) indices for + // | | | | our index buffer + // *----*----*----* + + int iNumVertices = (width + 1) * (height + 1); + S3DVertex * vertices = new S3DVertex[iNumVertices]; + memset(vertices,0,sizeof(S3DVertex) * iNumVertices); // Set everything to 0 + + // Now loop through the vertices and fill them with the appropriate + // values + + for(int i=0;i<=height;++i) + { + for(int j=0;j<=width;++j) + { + int iIndex = (i*(width + 1)) + j; + + // Store this vertex's coords and color + vertices[iIndex].Pos.X = j * 2.0f; + vertices[iIndex].Pos.Y = 0.0f; + vertices[iIndex].Pos.Z = i * 2.0f; + vertices[iIndex].Color.color = 0xFFFFFFFF; + + // Also store the texture UV values + vertices[iIndex].TCoords.X = i; + vertices[iIndex].TCoords.Y = j; + } + } + + // Now we need to create the index buffer + int iNumIndices = 6 * width * height; + u16 * indices = new u16[iNumIndices]; + + for(int i=0;iappend(vertices,iNumVertices,indices,iNumIndices); + + // Load the grass texture + SMaterial mat; + mat.setTexture(0,pDevice->getVideoDriver()->getTexture(DATA_DIR "/textures/grass.jpg")); + buffer->Material = mat; + + // Create the SMesh + SMesh * mesh = new SMesh(); + mesh->addMeshBuffer(buffer); + + mesh->recalculateBoundingBox(); + + // Drop the ref. count of the buffer + buffer->drop(); + + // ...and free the memory held by the data + delete [] indices; + delete [] vertices; + + // Add this to the scene + m_node = pDevice->getSceneManager()->addMeshSceneNode(mesh); + + // In order to make the ground look good at a + // distance, we need to enable anisotropic filtering + m_node->setMaterialFlag(EMF_ANISOTROPIC_FILTER,true); + + // Lastly, we create a triangle selector for this + // mesh so that when we want to place things, we can + // determine where the user is pointing the cursor + m_selector = pDevice->getSceneManager()->createTriangleSelector(mesh, m_node); + m_node->setTriangleSelector(m_selector); + + // Drop the ref. count of the mesh + mesh->drop(); +} + +CGround::~CGround() +{ + m_selector->drop(); + + // Do NOT drop the scene node pointer + // instead remove it + m_node->remove(); +} + +bool CGround::Intersection(IrrlichtDevice * device, line3df ray, int & x_inter, int & z_inter) +{ + vector3df out_p; + triangle3df out_t; + const ISceneNode * out_s; + + bool bCollision = device->getSceneManager()->getSceneCollisionManager()-> + getCollisionPoint(ray, m_selector, out_p, out_t, out_s); + + if(bCollision) // one was found + { + // See if we can figure out which one + // by looping through the points on the + // triangle and getting the minimum value + // for each dimension. + float min_x = (out_t.pointA.X < out_t.pointB.X)?out_t.pointA.X:out_t.pointB.X; + min_x = (out_t.pointC.X < min_x)?out_t.pointC.X:min_x; + + float min_z = (out_t.pointA.Z < out_t.pointB.Z)?out_t.pointA.Z:out_t.pointB.Z; + min_z = (out_t.pointC.Z < min_z)?out_t.pointC.Z:min_z; + + // The track coords for this piece can be found by dividing the + // min_x and min_z values by 2 + x_inter = min_x / 2.0f; + z_inter = min_z / 2.0f; + + return true; + } + else + return false; +} diff -Nru opentracks-0.1/src/CLoadingState.cpp opentracks-0.0.7/src/CLoadingState.cpp --- opentracks-0.1/src/CLoadingState.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CLoadingState.cpp 2010-12-13 02:10:32.000000000 +0000 @@ -0,0 +1,51 @@ +#include + +#include "CStateManager.h" +#include "CLoadingState.h" + +bool CLoadingState::bTemp = false; + +CLoadingState::CLoadingState(CStateManager * pManager) + : CGameState(pManager), m_loading_texture(NULL) +{ + // Load the loading texture + m_loading_texture = m_manager->GetDevice()->getVideoDriver()->getTexture(DATA_DIR "/textures/loading.jpg"); + + // Add some static text to the display + IGUIEnvironment* pGUI = GetDevice()->getGUIEnvironment(); + + if(!bTemp) + pGUI->addStaticText(L"Loading OpenTracks...", rect(25,570,300,600)); + else + pGUI->addStaticText(L"Loading Game Data...", rect(25,570,300,600)); +} + +CLoadingState::~CLoadingState() +{ + // NOTE: we do NOT free the texture +} + +void CLoadingState::RenderFrame(u32 cur_time) +{ + // Clear the screen + ClearScreen(); + + // We need to display the loading texture + m_manager->GetDevice()->getVideoDriver()->draw2DImage(m_loading_texture, position2d(80,50)); + GetDevice()->getGUIEnvironment()->drawAll(); + + // End the scene + Done(); + + // Sleep for 2 seconds + sleep(2); + + // Switch game states to playing + if(bTemp) + SwitchState(GS_PLAYING); + else + { + SwitchState(GS_MENU); + bTemp = true; + } +} diff -Nru opentracks-0.1/src/CMenuState.cpp opentracks-0.0.7/src/CMenuState.cpp --- opentracks-0.1/src/CMenuState.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CMenuState.cpp 2010-12-13 22:50:07.000000000 +0000 @@ -0,0 +1,53 @@ +#include "CMenuState.h" + +enum MENU_BUTTON_ID { BI_START, + BI_EXIT }; + +CMenuState::CMenuState(CStateManager * pManager) + : CGameState(pManager) +{ + // Start by creating the GUI components we will need + IGUIEnvironment* pGUI = GetDevice()->getGUIEnvironment(); + + pGUI->addStaticText(L"OpenTracks Menu:", rect(420,220,600,250)); + pGUI->addButton(rect(410,260,550,290), NULL, BI_START, L"Start the game!"); + pGUI->addButton(rect(410,300,550,330), NULL, BI_EXIT, L"Exit"); +} + +CMenuState::~CMenuState() +{ +} + +bool CMenuState::OnEvent(const SEvent& event) +{ + if(event.EventType == EET_GUI_EVENT && event.GUIEvent.EventType == EGET_BUTTON_CLICKED) + { + switch(event.GUIEvent.Caller->getID()) + { + case BI_START: + SwitchState(GS_LOADING); + break; + + case BI_EXIT: + Exit(); + break; + + default: + return false; + } + + return true; + } + + return false; +} + +void CMenuState::RenderFrame(u32 cur_time) +{ + ClearScreen(); + + // Display the GUI + GetDevice()->getGUIEnvironment()->drawAll(); + + Done(); +} diff -Nru opentracks-0.1/src/COggFile.cpp opentracks-0.0.7/src/COggFile.cpp --- opentracks-0.1/src/COggFile.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/COggFile.cpp 2010-12-15 01:48:25.000000000 +0000 @@ -0,0 +1,45 @@ +#include "COggFile.h" + +// Standard includes +#include + +COggFile::COggFile(std::string filename) + : m_data(NULL) +{ + // Our file pointer + OggVorbis_File ovf; + + // Attempt to open the file + ov_fopen(const_cast(filename.c_str()), &ovf); + + // Now get the number of samples + // in this file + ogg_int64_t num_samples = ov_pcm_total(&ovf, 0); + + // Read the file + m_data = new char[num_samples * 4]; + char buffer[4096]; + + // Variables used for reading the file + int iTotalRead = 0; + int iAmountRead; + int nm = 0; + + // Loop through the file's contents + while(iAmountRead = ov_read(&ovf, buffer, 4096, 0, 2, 1, &nm)) + { + // Now take these bytes and put them in our internal buffer + memcpy(m_data + iTotalRead, buffer, iAmountRead); + + iTotalRead += iAmountRead; + } + + // Now we have the buffer, close the file + ov_clear(&ovf); +} + +COggFile::~COggFile() +{ + // Free the buffer + if(m_data) delete [] m_data; +} diff -Nru opentracks-0.1/src/CPlayingState.cpp opentracks-0.0.7/src/CPlayingState.cpp --- opentracks-0.1/src/CPlayingState.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CPlayingState.cpp 2010-12-18 07:42:32.000000000 +0000 @@ -0,0 +1,722 @@ +#include "CPlayingState.h" + +// Definitions +#define PI2 (PI/2.0f) + +// Global ID enum +enum GUI_WINDOW_ID { // Toolbar buttons + TOOLBAR_EDIT_TRACK, + TOOLBAR_ADD_TRAIN, + TOOLBAR_REMOVE_TRACK, + TOOLBAR_EXIT, + + // Edit track dialog + EDITTRACK_STRAIGHT, + EDITTRACK_CURVED, + EDITTRACK_SWITCH, + EDITTRACK_SWITCH_INVERTED, + + // Add train dialog + ADDTRAIN_ADD, + + // Train properties dialog + TRAINPROP_WINDOW, + TRAINPROP_SPIN }; + + +CPlayingState::CPlayingState(CStateManager * pManager) + : CGameState(pManager), m_camera(NULL), m_toolbar(NULL), m_mode(IM_SELECT), m_ground(GetDevice(),25,25), + m_sky(GetDevice(),25,25), m_track_manager(GetDevice(),25,25), m_train_manager(GetDevice(), &m_track_manager), + m_straight_ghost_node(NULL), m_curve_ghost_node(NULL), m_switch_ghost_node(NULL), m_engine_ghost_node(NULL), + m_bulldozer_ghost_node(NULL), m_dialog_edittrack(NULL), m_dialog_addtrain(NULL), + m_previous_time(0), m_rotation(0.0f), m_radius(3.0f), m_up(false), m_down(false), m_left(false), m_right(false), + m_r_down(false), m_x_diff(0.0f), m_y_diff(0.0f), m_x_cur(0), m_y_cur(0), m_x_prev(0), m_y_prev(0), + m_current_class(TC_STRAIGHT), m_current_track(TT_VERTICAL_STRAIGHT) +{ + // Start by setting the ambient lighting + // and initializing the camera + GetDevice()->getSceneManager()->setAmbientLight(SColorf(0.6,0.6,0.6,1)); + m_camera = GetDevice()->getSceneManager()->addCameraSceneNode(); + + // TODO: Add some lighting to the scene + + // Set the camera's rotation, target, FOV, etc. + m_camera->bindTargetAndRotation(true); + m_camera->setPosition(vector3df(30,4,2)); + m_camera->setTarget(vector3df(30,2,5)); + m_camera->setFOV(PI / 3.5f); + m_camera->setAspectRatio(1.66f); + + // We need to set m_previous_time to a proper value + m_previous_time = GetDevice()->getTimer()->getTime(); + + // Create the toolbar + CreateToolbar(); + + // Load the ghost nodes + IMesh * straight_ghost = GetDevice()->getSceneManager()->getMesh(DATA_DIR "/models/track_straight.b3d"); + m_straight_ghost_node = GetDevice()->getSceneManager()->addMeshSceneNode(straight_ghost); + + IMesh * curve_ghost = GetDevice()->getSceneManager()->getMesh(DATA_DIR "/models/track_small_curve.b3d"); + m_curve_ghost_node = GetDevice()->getSceneManager()->addMeshSceneNode(curve_ghost); + + IMesh * switch_ghost = GetDevice()->getSceneManager()->getMesh(DATA_DIR "/models/track_switch_curve.b3d"); + m_switch_ghost_node = GetDevice()->getSceneManager()->addMeshSceneNode(switch_ghost); + + IMesh * engine_ghost = GetDevice()->getSceneManager()->getMesh(DATA_DIR "/engines/standard_diesel/standard_diesel.b3d"); + m_engine_ghost_node = GetDevice()->getSceneManager()->addMeshSceneNode(engine_ghost); + + IMesh * bulldozer_ghost = GetDevice()->getSceneManager()->getMesh(DATA_DIR "/models/bulldozer.b3d"); + m_bulldozer_ghost_node = GetDevice()->getSceneManager()->addMeshSceneNode(bulldozer_ghost); + + // Make them all invisible + m_straight_ghost_node->setVisible(false); + m_curve_ghost_node->setVisible(false); + m_engine_ghost_node->setVisible(false); + m_bulldozer_ghost_node->setVisible(false); + + m_switch_ghost_node->setMaterialFlag(EMF_BACK_FACE_CULLING, false); +} + +CPlayingState::~CPlayingState() +{ + // Remove the camera + m_camera->remove(); + + // Remove the ghost nodes + m_straight_ghost_node->remove(); + m_curve_ghost_node->remove(); + m_switch_ghost_node->remove(); + m_engine_ghost_node->remove(); + m_bulldozer_ghost_node->remove(); +} + +bool CPlayingState::OnEvent(const SEvent & event) +{ + // Switch on the event type + switch(event.EventType) + { + case EET_KEY_INPUT_EVENT: + return KeyEvent(event); + + case EET_MOUSE_INPUT_EVENT: + return MouseEvent(event); + + case EET_GUI_EVENT: + return GUIEvent(event); + + default: + break; + } + + return false; +} + +void CPlayingState::RenderFrame(u32 cur_time) +{ + // Start by processing any input + ProcessInput(cur_time); + + // Then process the trains + m_train_manager.Process(cur_time); + + // Clear the screen + ClearScreen(); + + // Make sure that the scene manager draws its things + GetDevice()->getSceneManager()->drawAll(); + GetDevice()->getGUIEnvironment()->drawAll(); + + // End the scene + Done(); +} + +bool CPlayingState::KeyEvent(const SEvent & event) +{ + // See which key was pushed. + switch(event.KeyInput.Key) + { + case KEY_UP: + m_up = event.KeyInput.PressedDown; + break; + + case KEY_DOWN: + m_down = event.KeyInput.PressedDown; + break; + + case KEY_LEFT: + m_left = event.KeyInput.PressedDown; + break; + + case KEY_RIGHT: + m_right = event.KeyInput.PressedDown; + break; + + default: + break; + } + + // Now see if a key was let up + if(!event.KeyInput.PressedDown) + { + if(event.KeyInput.Key == KEY_RETURN && m_mode == IM_PLACE_TRACK) + { + if(m_current_class == TC_STRAIGHT) + { + if(m_current_track == TT_VERTICAL_STRAIGHT) m_current_track = TT_HORIZONTAL_STRAIGHT; + else if(m_current_track == TT_HORIZONTAL_STRAIGHT) m_current_track = TT_VERTICAL_STRAIGHT; + } + else if(m_current_class == TC_CURVE) + { + if(m_current_track == TT_CURVE_NE) m_current_track = TT_CURVE_SE; + else if(m_current_track == TT_CURVE_SE) m_current_track = TT_CURVE_SW; + else if(m_current_track == TT_CURVE_SW) m_current_track = TT_CURVE_NW; + else if(m_current_track == TT_CURVE_NW) m_current_track = TT_CURVE_NE; + } + else + { + // The first set + if(m_current_track == TT_SWITCH_VERTICAL_NE) m_current_track = TT_SWITCH_HORIZONTAL_NW; + else if(m_current_track == TT_SWITCH_HORIZONTAL_NW) m_current_track = TT_SWITCH_VERTICAL_SW; + else if(m_current_track == TT_SWITCH_VERTICAL_SW) m_current_track = TT_SWITCH_HORIZONTAL_SE; + else if(m_current_track == TT_SWITCH_HORIZONTAL_SE) m_current_track = TT_SWITCH_VERTICAL_NE; + + // The second set + else if(m_current_track == TT_SWITCH_VERTICAL_NW) m_current_track = TT_SWITCH_HORIZONTAL_SW; + else if(m_current_track == TT_SWITCH_HORIZONTAL_SW) m_current_track = TT_SWITCH_VERTICAL_SE; + else if(m_current_track == TT_SWITCH_VERTICAL_SE) m_current_track = TT_SWITCH_HORIZONTAL_NE; + else if(m_current_track == TT_SWITCH_HORIZONTAL_NE) m_current_track = TT_SWITCH_VERTICAL_NW; + + } + + return true; + } + } + + return false; +} + +bool CPlayingState::MouseEvent(const SEvent & event) +{ + // First, make sure that the coords + // do not confilct with the GUI + // Get the current values + m_x_cur = event.MouseInput.X; + m_y_cur = event.MouseInput.Y; + + IGUIElement * root = GetDevice()->getGUIEnvironment()->getRootGUIElement(); + + if(root != root->getElementFromPoint(position2d(m_x_cur,m_y_cur))) + { + GetDevice()->getGUIEnvironment()->postEventFromUser(event); + return true; + } + + // Now see if any buttons were pressed + // See which event was generated + switch(event.MouseInput.Event) + { + case EMIE_LMOUSE_LEFT_UP: + + // Now we need to place the piece of track + // at the current place. + if(m_mode == IM_PLACE_TRACK) + { + int x = 0, z = 0; + + // Now place this piece + if(m_ground.Intersection(GetDevice(), m_cursor_ray, x, z)) + m_track_manager.SetPiece(m_current_track, x, z); + } + else if(m_mode == IM_PLACE_TRAIN) + { + int x = 0, z = 0; + + // Now place this train + if(m_ground.Intersection(GetDevice(), m_cursor_ray, x, z)) + { + m_train_manager.AddTrain(GetDevice()->getTimer()->getTime(), x, z); + + SwitchInputMode(IM_SELECT); + } + } + else if(m_mode == IM_REMOVE_TRACK) + { + int x = 0, z = 0; + + // Now place this piece + if(m_ground.Intersection(GetDevice(), m_cursor_ray, x, z)) + m_track_manager.SetPiece(TT_NUM_PIECES, x, z); + } + else + { + // We're in select mode, so see if we clicked on a train + // or some other scenery object. + CTrain * pTrain = m_train_manager.Intersection(m_cursor_ray); + + if(pTrain) + { + // Train selected! + // Display the train dialog + CreateTrainWindow(pTrain); + } + else + { + // Check to see if we clicked on a + // switch. + int x, z; + + if(m_ground.Intersection(GetDevice(), m_cursor_ray, x, z)) + { + + CTrack * pTrack = m_track_manager.GetPiece(x, z); + + if(pTrack->GetPiece() >= TT_SWITCH_VERTICAL_NE && pTrack->GetPiece() <= TT_SWITCH_HORIZONTAL_NW) + { + // Trip the switch + SWITCH_STATE ss = (pTrack->GetState() == SS_CURVED) ? SS_STRAIGHT : SS_CURVED; + + // Now set the state of this switch + m_track_manager.SetSwitchState(x, z, ss); + } + } + } + } + + break; + + case EMIE_RMOUSE_PRESSED_DOWN: + + // The button is down + m_r_down = true; + + // Also reset mousemove values + m_x_diff = m_y_diff = 0; + break; + + case EMIE_RMOUSE_LEFT_UP: + + // Button is up now + m_r_down = false; + break; + + case EMIE_MOUSE_MOVED: + + // Add the new offsets to the existing ones + m_x_diff += m_x_cur - m_x_prev; + m_y_diff += m_y_cur - m_y_prev; + + // Now set the previous values + m_x_prev = m_x_cur; + m_y_prev = m_y_cur; + + // Given the cursor position, calculate a ray + // that projects from the camera. + m_cursor_ray = GetDevice()->getSceneManager()-> + getSceneCollisionManager()-> + getRayFromScreenCoordinates(position2d(m_x_cur,m_y_cur), + NULL); + + break; + + case EMIE_MOUSE_WHEEL: + + { + float fChange = event.MouseInput.Wheel * 0.1f; + + // Now calculate the amount to move the camera + // along the vector defined by the camera to target + vector3df v_target = m_camera->getTarget(); + vector3df v_position = m_camera->getPosition(); + + float x_total = v_position.X - v_target.X; + float y_total = v_position.Y - v_target.Y; + float z_total = v_position.Z - v_target.Z; + + // Calculate the amount to move along the vector + v_position.X -= x_total * fChange; + v_position.Y -= y_total * fChange; + v_position.Z -= z_total * fChange; + + m_radius -= m_radius * fChange; + + m_camera->setPosition(v_position); + } + + break; + + default: + return false; + } + + return true; +} + +bool CPlayingState::GUIEvent(const SEvent & event) +{ + switch(event.GUIEvent.EventType) + { + // This will be the case for the toolbar buttons + case EGET_BUTTON_CLICKED: + + if(event.GUIEvent.Caller->getID() == TOOLBAR_EDIT_TRACK) + { + if(!m_dialog_edittrack) + { + CloseAllDialogs(); + CreateEditTrackWindow(); + } + else + { + // Close the track window + m_dialog_edittrack->remove(); + m_dialog_edittrack = NULL; + } + } + else if(event.GUIEvent.Caller->getID() == TOOLBAR_ADD_TRAIN) + { + if(!m_dialog_addtrain) + { + CloseAllDialogs(); + CreateAddTrainWindow(); + } + else + { + m_dialog_addtrain->remove(); + m_dialog_addtrain = NULL; + } + } + else if(event.GUIEvent.Caller->getID() == TOOLBAR_REMOVE_TRACK) + { + // Enter track removal mode + if(m_mode == IM_REMOVE_TRACK) + SwitchInputMode(IM_SELECT); + else + SwitchInputMode(IM_REMOVE_TRACK); + } + else if(event.GUIEvent.Caller->getID() == TOOLBAR_EXIT) + { + SwitchState(GS_MENU); + } + else if(event.GUIEvent.Caller->getID() == EDITTRACK_STRAIGHT) + { + m_current_class = TC_STRAIGHT; + m_current_track = TT_VERTICAL_STRAIGHT; + + SwitchInputMode(IM_PLACE_TRACK); + } + else if(event.GUIEvent.Caller->getID() == EDITTRACK_CURVED) + { + m_current_class = TC_CURVE; + m_current_track = TT_CURVE_NE; + + SwitchInputMode(IM_PLACE_TRACK); + } + else if(event.GUIEvent.Caller->getID() == EDITTRACK_SWITCH) + { + m_current_class = TC_SWITCH; + m_current_track = TT_SWITCH_VERTICAL_NE; + + SwitchInputMode(IM_PLACE_TRACK); + } + else if(event.GUIEvent.Caller->getID() == EDITTRACK_SWITCH_INVERTED) + { + m_current_class = TC_SWITCH; + m_current_track = TT_SWITCH_VERTICAL_NW; + + SwitchInputMode(IM_PLACE_TRACK); + } + else if(event.GUIEvent.Caller->getID() == ADDTRAIN_ADD) + { + SwitchInputMode(IM_PLACE_TRAIN); + + // Close the dialog + m_dialog_addtrain->remove(); + m_dialog_addtrain = NULL; + + // Switch off the train dialog + IGUIButton * pButton = dynamic_cast(m_toolbar->getElementFromId(TOOLBAR_ADD_TRAIN)); + pButton->setPressed(false); + } + + break; + + case EGET_ELEMENT_CLOSED: + + // Set the mode and update the ghost items + SwitchInputMode(IM_SELECT); + + // Depending on which dialog was closed, we + // may need to unhighlight a button + if(event.GUIEvent.Caller == m_dialog_edittrack) + { + IGUIButton * pButton = dynamic_cast(m_toolbar->getElementFromId(TOOLBAR_EDIT_TRACK)); + pButton->setPressed(false); + + m_dialog_edittrack = NULL; + } + else if(event.GUIEvent.Caller == m_dialog_addtrain) + { + IGUIButton * pButton = dynamic_cast(m_toolbar->getElementFromId(TOOLBAR_ADD_TRAIN)); + pButton->setPressed(false); + + m_dialog_addtrain = NULL; + } + // Now check if it was a train properties dialog + else if(event.GUIEvent.Caller->getID() == TRAINPROP_WINDOW) + { + // Remove the mapping + m_train_manager.RemoveWindowMapping(event.GUIEvent.Caller); + } + + return false; + + case EGET_SPINBOX_CHANGED: + + if(event.GUIEvent.Caller->getID() == TRAINPROP_SPIN) + { + // Get the value of the spinbox + IGUISpinBox * pBox = dynamic_cast(event.GUIEvent.Caller); + float fVal = pBox->getValue(); + + // Get the parent + IGUIElement * pParent = pBox->getParent(); + + // Now get the train + CTrain * pTrain = m_train_manager.GetTrainFromWindow(pParent); + + // Now determine the train that's affected + pTrain->SetSpeed(fVal); + } + + return false; + + default: + return false; + } + + return true; +} + +void CPlayingState::CreateToolbar() +{ + IGUIEnvironment* pGUI = GetDevice()->getGUIEnvironment(); + + // Begin by creating the toolbar + m_toolbar = pGUI->addToolBar(); + + IGUIButton * pEditTrack = m_toolbar->addButton(TOOLBAR_EDIT_TRACK, NULL, NULL, GetDevice()->getVideoDriver()->getTexture(DATA_DIR "/icons/edit_track.png"), NULL, false, true); + IGUIButton * pAddTrain = m_toolbar->addButton(TOOLBAR_ADD_TRAIN, NULL, NULL, GetDevice()->getVideoDriver()->getTexture(DATA_DIR "/icons/add_train.png"), NULL, false, true); + IGUIButton * pRemoveTrain = m_toolbar->addButton(TOOLBAR_REMOVE_TRACK, NULL, NULL, GetDevice()->getVideoDriver()->getTexture(DATA_DIR "/icons/remove_track.png"), NULL, false, true); + + m_toolbar->addButton(TOOLBAR_EXIT, NULL, NULL, GetDevice()->getVideoDriver()->getTexture(DATA_DIR "/icons/exit.png"), NULL, false, true); + + pEditTrack->setIsPushButton(true); + pAddTrain->setIsPushButton(true); + pRemoveTrain->setIsPushButton(true); +} + +void CPlayingState::CreateEditTrackWindow() +{ + // Create the track edit dialog + m_dialog_edittrack = GetDevice()->getGUIEnvironment()->addWindow(rect(12,50,180,255), false, L"Edit Track"); + + // Put the buttons in the window + GetDevice()->getGUIEnvironment()->addStaticText(L"Track type:", rect(10,35,100,52), false, false, m_dialog_edittrack); + IGUIButton * pStraight = GetDevice()->getGUIEnvironment()->addButton(rect(10,55,74,119), m_dialog_edittrack, EDITTRACK_STRAIGHT); + IGUIButton * pCurved = GetDevice()->getGUIEnvironment()->addButton(rect(80,55,144,119), m_dialog_edittrack, EDITTRACK_CURVED); + IGUIButton * pSwitch = GetDevice()->getGUIEnvironment()->addButton(rect(10,122,74,188), m_dialog_edittrack, EDITTRACK_SWITCH); + IGUIButton * pSwitchInverted = GetDevice()->getGUIEnvironment()->addButton(rect(80,122,144,188), m_dialog_edittrack, EDITTRACK_SWITCH_INVERTED); + + pStraight->setImage(GetDevice()->getVideoDriver()->getTexture(DATA_DIR "/icons/straight_track.png")); + pCurved->setImage(GetDevice()->getVideoDriver()->getTexture(DATA_DIR "/icons/curved_track.png")); + pSwitch->setImage(GetDevice()->getVideoDriver()->getTexture(DATA_DIR "/icons/switch_track.png")); + pSwitchInverted->setImage(GetDevice()->getVideoDriver()->getTexture(DATA_DIR "/icons/switch_track_inverted.png")); + + pStraight->setUseAlphaChannel(true); + pCurved->setUseAlphaChannel(true); + pSwitch->setUseAlphaChannel(true); + pSwitchInverted->setUseAlphaChannel(true); +} + +void CPlayingState::CreateAddTrainWindow() +{ + // Show the add train dialog + m_dialog_addtrain = GetDevice()->getGUIEnvironment()->addWindow(rect(12,50,230,195), false, L"Add Train"); + + GetDevice()->getGUIEnvironment()->addStaticText(L"Engine:", rect(10,35,100,60), false, false, m_dialog_addtrain); + + // At this point, we only have one engine + // so we only really need one entry in the + // drop down box + IGUIComboBox * pBox = GetDevice()->getGUIEnvironment()->addComboBox(rect(8,58,210,83), m_dialog_addtrain); + + pBox->addItem(L"Standard Diesel"); + + // And add a button + GetDevice()->getGUIEnvironment()->addButton(rect(8,100,210,126), m_dialog_addtrain, ADDTRAIN_ADD, L"Add train..."); +} + +void CPlayingState::CreateTrainWindow(CTrain * pTrain) +{ + // Create the dialog for the particular train. + IGUIWindow * pParent = GetDevice()->getGUIEnvironment()->addWindow(rect(12,50,260,165), false, L"Standard Diesel Properties", NULL, TRAINPROP_WINDOW); + + // Get the train's current speed + float fSpeed = pTrain->GetSpeed(); + + GetDevice()->getGUIEnvironment()->addStaticText(L"Speed:", rect(10,35,100,60), false, false, pParent); + + // Put the speed into the control + IGUISpinBox * pBox = GetDevice()->getGUIEnvironment()->addSpinBox(L"0", rect(10,60,100,100),true,pParent,TRAINPROP_SPIN); + + pBox->setRange(0.0f,3.0f); + pBox->setStepSize(0.2f); + pBox->setValue(fSpeed); + + m_train_manager.AddWindowMapping(pParent, pTrain); +} + +void CPlayingState::SwitchInputMode(INPUT_MODE new_mode) +{ + m_mode = new_mode; + + m_straight_ghost_node->setVisible(m_mode == IM_PLACE_TRACK && m_current_class == TC_STRAIGHT); + m_curve_ghost_node->setVisible(m_mode == IM_PLACE_TRACK && m_current_class == TC_CURVE); + m_switch_ghost_node->setVisible(m_mode == IM_PLACE_TRACK && m_current_class == TC_SWITCH); + m_engine_ghost_node->setVisible(m_mode == IM_PLACE_TRAIN); + m_bulldozer_ghost_node->setVisible(m_mode == IM_REMOVE_TRACK); +} + +void CPlayingState::CloseAllDialogs() +{ + // Close any dialogs + if(m_dialog_edittrack) + { + IGUIButton * pButton = dynamic_cast(m_toolbar->getElementFromId(TOOLBAR_EDIT_TRACK)); + pButton->setPressed(false); + + m_dialog_edittrack->remove(); + m_dialog_edittrack = NULL; + } + else if(m_dialog_addtrain) + { + IGUIButton * pButton = dynamic_cast(m_toolbar->getElementFromId(TOOLBAR_ADD_TRAIN)); + pButton->setPressed(false); + + m_dialog_edittrack->remove(); + m_dialog_edittrack = NULL; + } + + // Also reset the input mode + SwitchInputMode(IM_SELECT); +} + +void CPlayingState::ProcessInput(u32 cur_time) +{ + // Get the difference from the previous time + u32 diff = cur_time - m_previous_time; + + // Now get the current position of everything + vector3df cur_pos = m_camera->getPosition(); + vector3df cur_tar = m_camera->getTarget(); + + // Our rotation is increased everytime + // the left / right arrow keys are used + float fBefore = m_rotation; + + if(m_left) + m_rotation += (diff * 0.002f); + if(m_right) + m_rotation -= (diff * 0.002f); + + // Calculate the cos/sin of the before values + float bx = cosf(fBefore - PI2) * m_radius; + float bz = sinf(fBefore - PI2) * m_radius; + + // Now for the new values + float ax = cosf(m_rotation - PI2) * m_radius; + float az = sinf(m_rotation - PI2) * m_radius; + + // Now get the difference + cur_tar.X += bx - ax; + cur_tar.Z += bz - az; + + if(m_r_down) + { + // When the mouse is moved, we track + // the amount and move the target and + // camera accordingly. + + // We need to make sure that the angle + // of rotation (about the Y-Axis) is + // taken into account here. + + // Precalculated numbers + float xdiff = (m_x_diff * 0.01f * (m_radius / 3.0f)); + float zdiff = (m_y_diff * 0.02f * (m_radius / 3.0f)); + + float xtrans = xdiff * cosf(m_rotation) + zdiff * sinf(m_rotation); + float ztrans = zdiff * cosf(m_rotation) + xdiff * sinf(m_rotation - PI); + + cur_pos.X -= xtrans; + cur_tar.X -= xtrans; + cur_pos.Z += ztrans; + cur_tar.Z += ztrans; + + m_x_diff = m_y_diff = 0; + } + + m_camera->setPosition(cur_pos); + m_camera->setTarget(cur_tar); + + // Deal with the track piece + if(m_mode == IM_PLACE_TRACK) + { + int x = 0, z = 0; + + if(m_ground.Intersection(GetDevice(), m_cursor_ray, x, z)) + { + // Depending on what the current piece is... + float x_off = g_trackOrientationInfo[m_current_track].fTrans_x; + float z_off = g_trackOrientationInfo[m_current_track].fTrans_z; + + float y_rot = g_trackOrientationInfo[m_current_track].fRot_y; + + if(m_current_track <= TT_HORIZONTAL_STRAIGHT) + { + m_straight_ghost_node->setPosition(vector3df(x * 2.0f + x_off, 0.05, z * 2.0f + z_off)); + m_straight_ghost_node->setRotation(vector3df(0,y_rot,0)); + } + else if(m_current_track >= TT_CURVE_NE && m_current_track <= TT_CURVE_NW) + { + m_curve_ghost_node->setPosition(vector3df(x * 2.0f + x_off, 0.05, z * 2.0f + z_off)); + m_curve_ghost_node->setRotation(vector3df(0,y_rot,0)); + } + else + { + m_switch_ghost_node->setPosition(vector3df(x * 2.0f + x_off, 0.05, z * 2.0f + z_off)); + m_switch_ghost_node->setRotation(vector3df(0,y_rot,0)); + m_switch_ghost_node->setScale(vector3df(g_trackOrientationInfo[m_current_track].fScaleX, + 1, + g_trackOrientationInfo[m_current_track].fScaleZ)); + } + } + } + else if(m_mode == IM_PLACE_TRAIN) + { + int x = 0, z = 0; + + if(m_ground.Intersection(GetDevice(), m_cursor_ray, x, z)) + m_engine_ghost_node->setPosition(vector3df(x * 2.0f + 1.0f, 0.05, z * 2.0f + 1.0f)); + } + else if(m_mode == IM_REMOVE_TRACK) + { + int x = 0, z = 0; + + if(m_ground.Intersection(GetDevice(), m_cursor_ray, x, z)) + m_bulldozer_ghost_node->setPosition(vector3df(x * 2.0f + 1.0f, 0.05, z * 2.0f + 1.0f)); + } + + m_previous_time = cur_time; +} diff -Nru opentracks-0.1/src/CSkin.cpp opentracks-0.0.7/src/CSkin.cpp --- opentracks-0.1/src/CSkin.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CSkin.cpp 2010-12-13 22:38:58.000000000 +0000 @@ -0,0 +1,310 @@ +#include "CSkin.h" + +CSkin::CSkin(IrrlichtDevice * pDevice) +{ + m_device = pDevice; + m_device->grab(); + + IGUIEnvironment * pGUI = m_device->getGUIEnvironment(); + + m_normal_font = pGUI->getFont(DATA_DIR "/fonts/arial/arial.xml"); + m_mini_font = pGUI->getFont(DATA_DIR "/fonts/arialmini/arialmini.xml"); + + // Now load our texture + m_tex = pDevice->getVideoDriver()->getTexture(DATA_DIR "/textures/gui.png"); + + // Create and set up the sprite bank + m_sprites = pGUI->addEmptySpriteBank("Bob"); + m_sprites->addTexture(m_tex); + + // Now create the rectangles + core::array > & rectangles = m_sprites->getPositions(); + rectangles.push_back(core::rect(16,0,32,16)); // 0 - close button + rectangles.push_back(core::rect(32,0,48,16)); // 1 - drop-down button + rectangles.push_back(core::rect(48,0,56,8)); // 2 - Down arrow + rectangles.push_back(core::rect(56,0,64,8)); // 3 - Up arrow + + // Now create the sprites + core::array& sprite_array = m_sprites->getSprites(); + + for(int i=0;i<4;++i) + { + SGUISpriteFrame new_frame; + new_frame.rectNumber = i; + new_frame.textureNumber = 0; + + SGUISprite new_sprite; + new_sprite.Frames.push_back(new_frame); + new_sprite.frameTime = 0; + + sprite_array.push_back(new_sprite); + } +} + +CSkin::~CSkin() +{ + if(m_sprites) m_sprites->drop(); + if(m_normal_font) m_normal_font->drop(); + if(m_mini_font) m_mini_font->drop(); + if(m_tex) m_tex->drop(); +} + +SColor CSkin::getColor(EGUI_DEFAULT_COLOR color) const +{ + switch(color) + { + case EGDC_3D_DARK_SHADOW: return 0x77000000; + case EGDC_3D_SHADOW: return 0x77333333; + case EGDC_3D_FACE: + case EGDC_3D_HIGH_LIGHT: + case EGDC_3D_LIGHT: + case EGDC_ACTIVE_BORDER: + case EGDC_ACTIVE_CAPTION: + case EGDC_APP_WORKSPACE: + case EGDC_BUTTON_TEXT: return 0xffffffff; + case EGDC_GRAY_TEXT: + case EGDC_HIGH_LIGHT: + case EGDC_HIGH_LIGHT_TEXT: + case EGDC_INACTIVE_BORDER: + case EGDC_INACTIVE_CAPTION: + case EGDC_TOOLTIP: return 0xffffffff; + case EGDC_TOOLTIP_BACKGROUND: return 0x77000000; + case EGDC_SCROLLBAR: + case EGDC_WINDOW: + case EGDC_WINDOW_SYMBOL: + case EGDC_ICON: + case EGDC_ICON_HIGH_LIGHT: return 0xffffffff; + default: return 0; + } +} + +void CSkin::setColor(EGUI_DEFAULT_COLOR which, SColor newColor) +{ + //... +} + +s32 CSkin::getSize(EGUI_DEFAULT_SIZE size) const +{ + switch(size) + { + case EGDS_SCROLLBAR_SIZE: return 16; + case EGDS_MENU_HEIGHT: return 42; + case EGDS_WINDOW_BUTTON_WIDTH: return 20; + case EGDS_CHECK_BOX_WIDTH: return 10; + case EGDS_MESSAGE_BOX_WIDTH: return 0; + case EGDS_MESSAGE_BOX_HEIGHT: return 0; + case EGDS_BUTTON_WIDTH: return 32; + case EGDS_BUTTON_HEIGHT: return 32; + case EGDS_TEXT_DISTANCE_X: return 4; + case EGDS_TEXT_DISTANCE_Y: return 4; + case EGDS_TITLEBARTEXT_DISTANCE_X: return 8; + case EGDS_TITLEBARTEXT_DISTANCE_Y: return 2; + case EGDS_MESSAGE_BOX_GAP_SPACE: return 10; + case EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH: return 4; + case EGDS_MESSAGE_BOX_MAX_TEST_WIDTH: return 10; + case EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT: return 4; + case EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT: return 10; + default: return 0; + } +} + +const wchar_t* CSkin::getDefaultText(EGUI_DEFAULT_TEXT text) const +{ + switch(text) + { + case EGDT_MSG_BOX_OK: return L"OK"; + case EGDT_MSG_BOX_CANCEL: return L"Cancel"; + case EGDT_MSG_BOX_YES: return L"Yes"; + case EGDT_MSG_BOX_NO: return L"No"; + case EGDT_WINDOW_CLOSE: return L"Close this window"; + case EGDT_WINDOW_MAXIMIZE: return L"Maximize this window"; + case EGDT_WINDOW_MINIMIZE: return L"Minimize this window"; + case EGDT_WINDOW_RESTORE: return L"Restore this window"; + default: return L""; + } +} + +void CSkin::setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText) +{ + //... +} + +void CSkin::setSize(EGUI_DEFAULT_SIZE which, s32 size) +{ + //... +} + +IGUIFont* CSkin::getFont(EGUI_DEFAULT_FONT which) const +{ + switch(which) + { + case EGDF_DEFAULT: + case EGDF_BUTTON: + case EGDF_WINDOW: + case EGDF_MENU: return m_normal_font; + case EGDF_TOOLTIP: return m_mini_font; + default: return NULL; + } +} + +void CSkin::setFont(IGUIFont* font, EGUI_DEFAULT_FONT which) +{ + //... +} + +IGUISpriteBank* CSkin::getSpriteBank() const +{ + return m_sprites; +} + +void CSkin::setSpriteBank(IGUISpriteBank* bank) +{ + //... +} + +u32 CSkin::getIcon(EGUI_DEFAULT_ICON icon) const +{ + switch(icon) + { + case EGDI_WINDOW_MAXIMIZE: + case EGDI_WINDOW_RESTORE: + case EGDI_WINDOW_CLOSE: return 0; + case EGDI_WINDOW_MINIMIZE: + case EGDI_WINDOW_RESIZE: + case EGDI_CURSOR_UP: + case EGDI_CURSOR_DOWN: + case EGDI_CURSOR_LEFT: + case EGDI_CURSOR_RIGHT: + case EGDI_MENU_MORE: + case EGDI_CHECK_BOX_CHECKED: + case EGDI_DROP_DOWN: + case EGDI_SMALL_CURSOR_UP: return 3; + case EGDI_SMALL_CURSOR_DOWN: return 2; + case EGDI_RADIO_BUTTON_CHECKED: + case EGDI_MORE_LEFT: + case EGDI_MORE_RIGHT: + case EGDI_MORE_UP: + case EGDI_MORE_DOWN: return 1; + case EGDI_EXPAND: + case EGDI_COLLAPSE: + case EGDI_FILE: + case EGDI_DIRECTORY: + default: return 0; + } +} + +void CSkin::setIcon(EGUI_DEFAULT_ICON icon, u32 index) +{ + //... +} + +void CSkin::draw3DButtonPaneStandard(IGUIElement* element, + const core::rect& rect, + const core::rect* clip) +{ + DrawRoundedBox(rect, 0x7f333333); +} + +void CSkin::draw3DButtonPanePressed(IGUIElement* element, + const core::rect& rect, + const core::rect* clip) +{ + DrawRoundedBox(rect, 0x7f555555); +} + +void CSkin::draw3DSunkenPane(IGUIElement* element, + SColor bgcolor, bool flat, bool fillBackGround, + const core::rect& rect, + const core::rect* clip) +{ + DrawRoundedBox(rect, 0x7f000000); +} + +core::rect CSkin::draw3DWindowBackground(IGUIElement* element, + bool drawTitleBar, SColor titleBarColor, + const core::rect& rect, + const core::rect* clip, + core::rect* checkClientArea) +{ + DrawRoundedBox(rect, 0x7f111111); + + core::rect titlebar(rect.UpperLeftCorner.X + 4, rect.UpperLeftCorner.Y + 2, + rect.LowerRightCorner.X - 4, rect.UpperLeftCorner.Y + 24); + + if(drawTitleBar) + DrawRoundedBox(titlebar, + 0x7f222222); + + return titlebar; +} + +void CSkin::draw3DMenuPane(IGUIElement* element, + const core::rect& rect, + const core::rect* clip) +{ + //... +} + +void CSkin::draw3DToolBar(IGUIElement* element, + const core::rect& rect, + const core::rect* clip) +{ + m_device->getVideoDriver()->draw2DRectangle(0x7f000000, rect); +} + +void CSkin::draw3DTabButton(IGUIElement* element, bool active, + const core::rect& rect, const core::rect* clip, EGUI_ALIGNMENT alignment) +{ + //... +} + +void CSkin::draw3DTabBody(IGUIElement* element, bool border, bool background, + const core::rect& rect, const core::rect* clip, s32 tabHeight, EGUI_ALIGNMENT alignment ) +{ + //... +} + +void CSkin::drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon, + const position2di position, u32 starttime, u32 currenttime, + bool loop, const core::rect* clip) +{ + //... +} + +void CSkin::draw2DRectangle(IGUIElement* element, const SColor &color, + const core::rect& pos, const core::rect* clip ) +{ + //... +} + +void CSkin::DrawRoundedBox(const core::rect& rect, const SColor& color) const +{ + // Make things easier by defining a few simple variables + s32 x1 = rect.UpperLeftCorner.X; + s32 y1 = rect.UpperLeftCorner.Y; + s32 x2 = rect.LowerRightCorner.X; + s32 y2 = rect.LowerRightCorner.Y; + + // Draw the four corners of the image + m_device->getVideoDriver()->draw2DImage(m_tex, + position2d(x1, y1), + core::rect(0,0,8,8), 0, color, true); + m_device->getVideoDriver()->draw2DImage(m_tex, + position2d(x2 - 8, y1), + core::rect(8,0,16,8), 0, color, true); + m_device->getVideoDriver()->draw2DImage(m_tex, + position2d(x1, y2 - 8), + core::rect(0,8,8,16), 0, color, true); + m_device->getVideoDriver()->draw2DImage(m_tex, + position2d(x2 - 8, y2 - 8), + core::rect(8,8,16,16), 0, color, true); + // Now for the center + m_device->getVideoDriver()->draw2DRectangle(color, core::rect(x1 + 8, y1 + 8, x2 - 8, y2 - 8)); + + // Now the edges + m_device->getVideoDriver()->draw2DRectangle(color, core::rect(x1 + 8, y1, x2 - 8, y1 + 8)); + m_device->getVideoDriver()->draw2DRectangle(color, core::rect(x1 + 8, y2 - 8, x2 - 8, y2)); + m_device->getVideoDriver()->draw2DRectangle(color, core::rect(x1, y1 + 8, x1 + 8, y2 - 8)); + m_device->getVideoDriver()->draw2DRectangle(color, core::rect(x2 - 8, y1 + 8, x2, y2 - 8)); +} + diff -Nru opentracks-0.1/src/CSkybox.cpp opentracks-0.0.7/src/CSkybox.cpp --- opentracks-0.1/src/CSkybox.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CSkybox.cpp 2010-12-11 19:07:59.000000000 +0000 @@ -0,0 +1,24 @@ +#include "CSkybox.h" + +CSkybox::CSkybox(IrrlichtDevice * pDevice, int width, int height) + : m_node(NULL) +{ + // Load the mesh for this piece + IMesh * mesh = pDevice->getSceneManager()->getMesh(DATA_DIR "/models/skybox.b3d"); + + // Now add the mesh to the scene manager + m_node = pDevice->getSceneManager()->addMeshSceneNode(mesh); + + // Set the position of the object based + // on the center of the ground + m_node->setPosition(vector3df(width,0,height)); + + // Disable lighting on it for now + m_node->setMaterialFlag(EMF_LIGHTING, false); + m_node->setMaterialTexture(0, pDevice->getVideoDriver()->getTexture(DATA_DIR "/textures/sky.jpg")); +} + +CSkybox::~CSkybox() +{ + m_node->remove(); +} diff -Nru opentracks-0.1/src/CStateManager.cpp opentracks-0.0.7/src/CStateManager.cpp --- opentracks-0.1/src/CStateManager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CStateManager.cpp 2010-12-13 22:57:04.000000000 +0000 @@ -0,0 +1,101 @@ +#include "CStateManager.h" + +// State includes +#include "CLoadingState.h" +#include "CMenuState.h" +#include "CPlayingState.h" + +CStateManager::CStateManager(IrrlichtDevice * pDevice) + : m_device(pDevice), m_state(GS_LOADING), m_state_pointer(NULL), m_state_changing(false) +{ + // Grab a copy of the device + m_device->grab(); + + // At first, we will begin by showing the loading screen. + SwitchState(GS_LOADING); +} + +CStateManager::~CStateManager() +{ + // Make sure that the current state gets cleared + if(m_state_pointer) delete m_state_pointer; + + // We're done with our copy of the device + m_device->drop(); +} + +void CStateManager::Go() +{ + // This is the game's 'main loop' + // Basically just continue as long as + // run() is successful + + while(m_device->run()) + { + u32 cur_time = m_device->getTimer()->getTime(); + + // Delegate the rendering of the scene to + // the current state + m_state_pointer->RenderFrame(cur_time); + + // Now check to see if there are any pending tasks + if(m_state_changing) + { + if(m_state == GS_NONE) + break; + + // Perform the state change + SwitchState(m_state); + + m_state_changing = false; + } + } +} + +void CStateManager::Exit() +{ + // Switch to the exit state. + QueueStateChange(GS_NONE); +} + +void CStateManager::QueueStateChange(GAME_STATE new_state) +{ + m_state = new_state; + + // Note that we don't actually change the state + // here, because this function may get called from + // within the main loop and it would have the rug pulled + // from right under it. + + // Instead, we set a flag that the main loop will recognize + // and will then take action. + m_state_changing = true; +} + +void CStateManager::SwitchState(GAME_STATE new_state) +{ + m_state = new_state; + + // Free the old state + if(m_state_pointer) delete m_state_pointer; + + // Now create the new state + switch(m_state) + { + case GS_LOADING: + m_state_pointer = new CLoadingState(this); + break; + + case GS_MENU: + m_state_pointer = new CMenuState(this); + break; + + case GS_PLAYING: + m_state_pointer = new CPlayingState(this); + break; + + default: + m_state_pointer = NULL; + break; + } +} diff -Nru opentracks-0.1/src/CTrack.cpp opentracks-0.0.7/src/CTrack.cpp --- opentracks-0.1/src/CTrack.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CTrack.cpp 2010-12-18 01:48:08.000000000 +0000 @@ -0,0 +1,109 @@ +#include "CTrack.h" + +// This is a global mapping of rotation values for each piece +CTrackOrientationInfo g_trackOrientationInfo[TT_NUM_PIECES] = + { + { 2, 1, 0, 1, 0, 0, 0, 0, 0 }, // TT_VERTICAL_STRAIGHT + { 2, 1, 0, 1, 0, 90, 0, 0, 0 }, // TT_HORIZONTAL_STRAIGHT + + { 4.712, 0, 0, 2, 0, 0, 0, -2, 1 }, // TT_CURVE_NE + { 4.712, 0, 0, 0, 0, 90, 0, -2, -1 }, // TT_CURVE_SE + { 4.712, 2, 0, 0, 0, 180, 0, 2, -1 }, // TT_CURVE_SW + { 4.712, 2, 0, 2, 0, 270, 0, 2, 1 }, // TT_CURVE_NW + + { 4.712, 0, 0, 0, 0, 0, 0, 1, -2 }, // TT_CURVE_NE_OTHER + { 4.712, 0, 0, 0, 0, 0, 0, 1, 2 }, // TT_CURVE_SE_OTHER + { 4.712, 0, 0, 0, 0, 0, 0, -1, 2 }, // TT_CURVE_SW_OTHER + { 4.712, 0, 0, 0, 0, 0, 0, -1, -2 }, // TT_CURVE_NW_OTHER + + // Note that since these are switches, there are a few extra members + { 4.712, 0, 0, 2, 0, 0, 0, -2, 1, 1, 1, 4, 0, 2 }, // TT_SWITCH_VERTICAL_NE + { 4.712, 0, 0, 0, 0, 0, 0, -2, -1, 1, -1, 4, 0, -2 }, // TT_SWITCH_VERTICAL_SE + { 4.712, 2, 0, 0, 0, 0, 0, 2, -1, -1, -1, 4, 0, -2 }, // TT_SWITCH_VERTICAL_SW + { 4.712, 2, 0, 2, 0, 0, 0, 2, 1, -1, 1, 4, 0, 2 }, // TT_SWITCH_VERTICAL_NW + { 4.712, 2, 0, 0, 0, 90, 0, 1, -2, -1, 1, 4, 2, 0 }, // TT_SWITCH_HORIZONTAL_NE + { 4.712, 2, 0, 2, 0, 90, 0, 1, 2, 1, 1, 4, 2, 0 }, // TT_SWITCH_HORIZONTAL_SE + { 4.712, 0, 0, 2, 0, 90, 0, -1, 2, 1, -1, 4, -2, 0 }, // TT_SWITCH_HORIZONTAL_SW + { 4.712, 0, 0, 0, 0, 90, 0, -1, -2, -1, -1, 4, -2, 0 }, // TT_SWITCH_HORIZONTAL_NW + + { 4.712, 0, 0, 0, 0, 0, 0, 1, -2 }, // TT_SWITCH_VERTICAL_NE_OTHER_CURVE + { 4.712, 0, 0, 0, 0, 0, 0, 1, 2 }, // TT_SWITCH_VERTICAL_SE_OTHER_CURVE + { 4.712, 0, 0, 0, 0, 0, 0, -1, 2 }, // TT_SWITCH_VERTICAL_SW_OTHER_CURVE + { 4.712, 0, 0, 0, 0, 0, 0, -1, -2 }, // TT_SWITCH_VERTICAL_NW_OTHER_CURVE + { 4.712, 0, 0, 0, 0, 0, 0, -2, 1 }, // TT_SWITCH_HORIZONTAL_NE_OTHER_CURVE + { 4.712, 0, 0, 0, 0, 0, 0, -2, -1 }, // TT_SWITCH_HORIZONTAL_SE_OTHER_CURVE + { 4.712, 0, 0, 0, 0, 0, 0, 2, -1 }, // TT_SWITCH_HORIZONTAL_SW_OTHER_CURVE + { 4.712, 0, 0, 0, 0, 0, 0, 2, 1 }, // TT_SWITCH_HORIZONTAL_NW_OTHER_CURVE + + { 4, 0, 0, 0, 0, 0, 0, 0, -2 }, // TT_SWITCH_VERTICAL_NE_OTHER_STRAIGHT + { 4, 0, 0, 0, 0, 0, 0, 0, 2 }, // TT_SWITCH_VERTICAL_SE_OTHER_STRAIGHT + { 4, 0, 0, 0, 0, 0, 0, 0, 2 }, // TT_SWITCH_VERTICAL_SW_OTHER_STRAIGHT + { 4, 0, 0, 0, 0, 0, 0, 0, -2 }, // TT_SWITCH_VERTICAL_NW_OTHER_STRAIGHT + { 4, 0, 0, 0, 0, 0, 0, -2, 0 }, // TT_SWITCH_HORIZONTAL_NE_OTHER_STRAIGHT + { 4, 0, 0, 0, 0, 0, 0, -2, 0 }, // TT_SWITCH_HORIZONTAL_SE_OTHER_STRAIGHT + { 4, 0, 0, 0, 0, 0, 0, 2, 0 }, // TT_SWITCH_HORIZONTAL_SW_OTHER_STRAIGHT + { 4, 0, 0, 0, 0, 0, 0, 2, 0 } // TT_SWITCH_HORIZONTAL_NW_OTHER_STRAIGHT + }; + +CTrack::CTrack(IrrlichtDevice * pDevice,float x, float y, float z, int ix, int iz) + : m_type(TT_NUM_PIECES), m_x(x), m_y(y), m_z(z), m_offset_x(ix), m_offset_z(iz), m_state(SS_CURVED) +{ + // Create the node + m_node = pDevice->getSceneManager()->addAnimatedMeshSceneNode(NULL,0,-1, + core::vector3df(0, 0, 0), + core::vector3df(0, 0, 0), + core::vector3df(1, 1, 1), + true); + + // Now set the position + m_node->setPosition(vector3df(m_x,m_y,m_z)); +} + +CTrack::~CTrack() +{ + m_node->remove(); +} + +void CTrack::SetPiece(TRACK_TYPE type, IAnimatedMesh * pMesh) +{ + if(pMesh) + m_node->setVisible(true); + else + m_node->setVisible(false); + + m_type = type; + + // We need to update the mesh + m_node->setMesh(pMesh); + + if(m_type != TT_NUM_PIECES) + { + // The rotation info needs updating too + m_node->setRotation(vector3df(g_trackOrientationInfo[type].fRot_x, + g_trackOrientationInfo[type].fRot_y, + g_trackOrientationInfo[type].fRot_z)); + + m_node->setPosition(vector3df(g_trackOrientationInfo[type].fTrans_x + m_x, + g_trackOrientationInfo[type].fTrans_y + m_y, + g_trackOrientationInfo[type].fTrans_z + m_z)); + + if(m_type > TT_CURVE_NW_OTHER) + m_node->setScale(vector3df(g_trackOrientationInfo[type].fScaleX, + 1, + g_trackOrientationInfo[type].fScaleZ)); + + m_node->setMaterialFlag(EMF_LIGHTING, false); + m_node->setMaterialFlag(EMF_BACK_FACE_CULLING, false); + + m_node->setCurrentFrame(2.0f); + } +} + +void CTrack::SetState(SWITCH_STATE state) +{ + m_state = state; + + // Set the frame + if(state == SS_CURVED) m_node->setCurrentFrame(1.0f); + else m_node->setCurrentFrame(2.0f); +} diff -Nru opentracks-0.1/src/CTrackManager.cpp opentracks-0.0.7/src/CTrackManager.cpp --- opentracks-0.1/src/CTrackManager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CTrackManager.cpp 2010-12-18 20:31:17.000000000 +0000 @@ -0,0 +1,657 @@ +#include "CTrackManager.h" + +// Definitions +const float PI2 = PI / 2; + +CTrackManager::CTrackManager(IrrlichtDevice * pDevice, int width, int height) + : m_width(width), m_height(height), + m_straight(NULL), m_curved(NULL), m_switch_curve(NULL), m_switch_straight(NULL) +{ + // Temporarily set the current directory to the textures + path cur_dir = pDevice->getFileSystem()->getWorkingDirectory(); + pDevice->getFileSystem()->changeWorkingDirectoryTo(DATA_DIR "/textures"); + + // Start by loading all of the meshes + m_straight = pDevice->getSceneManager()->getMesh("../models/track_straight.b3d"); + m_curved = pDevice->getSceneManager()->getMesh("../models/track_small_curve.b3d"); + m_switch_curve = pDevice->getSceneManager()->getMesh("../models/track_switch_curve.b3d"); + m_switch_straight = pDevice->getSceneManager()->getMesh("../models/track_switch_straight.b3d"); + + // Now change it back + pDevice->getFileSystem()->changeWorkingDirectoryTo(cur_dir); + + // Grab a reference to these + m_straight->grab(); + m_curved->grab(); + + // Fill in the array of all the pieces + for(int i=0;iSetPiece(TT_NUM_PIECES,NULL); + + m_grid.push_back(pNew); + } + } +} + +CTrackManager::~CTrackManager() +{ + // Free the meshes + m_straight->drop(); + m_curved->drop(); + + // Free all of the track pieces + for(unsigned int i=0;i= m_width); + if(z < 0 || z >= m_height); + + // Calculate this item's offset into + // the track grid vector + int iOffset = (z * m_width) + x; + + // Get the piece with that offset + CTrack * piece = m_grid.at(iOffset); + + // Before we overwrite the current piece, we need + // to make sure that the tile at the other end + // of curved pieces is removed properly. + TRACK_TYPE current_type = piece->GetPiece(); + + if(current_type >= TT_CURVE_NE && current_type <= TT_CURVE_NW) + { + int iOtherOffset = iOffset; + + if(current_type == TT_CURVE_NE) { iOtherOffset -= 1; iOtherOffset += m_width; } + else if(current_type == TT_CURVE_SE) { iOtherOffset -= 1; iOtherOffset -= m_width; } + else if(current_type == TT_CURVE_SW) { iOtherOffset += 1; iOtherOffset -= m_width; } + else if(current_type == TT_CURVE_NW) { iOtherOffset += 1; iOtherOffset += m_width; } + + CTrack * other_piece = m_grid.at(iOtherOffset); + other_piece->SetPiece(TT_NUM_PIECES, NULL); + } + // And do the same for switches + else if(current_type >= TT_SWITCH_VERTICAL_NE && current_type <= TT_SWITCH_HORIZONTAL_NW) + { + // For switches, there are _TWO_ other ends + // that the train can enter on + int iOtherCurveOffset = iOffset; + int iOtherStraightOffset = iOffset; + + // The vertical switches + if(current_type == TT_SWITCH_VERTICAL_NE) { iOtherCurveOffset -= 1; iOtherCurveOffset += m_width; + iOtherStraightOffset += m_width; } + else if(current_type == TT_SWITCH_VERTICAL_SE) { iOtherCurveOffset -= 1; iOtherCurveOffset -= m_width; + iOtherStraightOffset -= m_width; } + else if(current_type == TT_SWITCH_VERTICAL_SW) { iOtherCurveOffset += 1; iOtherCurveOffset -= m_width; + iOtherStraightOffset -= m_width; } + else if(current_type == TT_SWITCH_VERTICAL_NW) { iOtherCurveOffset += 1; iOtherCurveOffset += m_width; + iOtherStraightOffset += m_width; } + + // The horizontal switches + else if(current_type == TT_SWITCH_HORIZONTAL_NE) { iOtherCurveOffset += 1; iOtherCurveOffset -= m_width; + iOtherStraightOffset += 1; } + else if(current_type == TT_SWITCH_HORIZONTAL_SE) { iOtherCurveOffset += 1; iOtherCurveOffset += m_width; + iOtherStraightOffset += 1; } + else if(current_type == TT_SWITCH_HORIZONTAL_SW) { iOtherCurveOffset -= 1; iOtherCurveOffset += m_width; + iOtherStraightOffset -= 1; } + else if(current_type == TT_SWITCH_HORIZONTAL_NW) { iOtherCurveOffset -= 1; iOtherCurveOffset -= m_width; + iOtherStraightOffset -= 1; } + + // Set those pieces to NULL + CTrack * other_curve_piece = m_grid.at(iOtherCurveOffset); + CTrack * other_straight_piece = m_grid.at(iOtherStraightOffset); + other_curve_piece->SetPiece(TT_NUM_PIECES, NULL); + other_straight_piece->SetPiece(TT_NUM_PIECES, NULL); + } + + // AND make sure that if this is the other + // end of a curved piece that we set the other end + // to nothing + if(current_type >= TT_CURVE_NE_OTHER && current_type <= TT_CURVE_NW_OTHER) + { + int iOtherOffset = iOffset; + + if(current_type == TT_CURVE_NE_OTHER) { iOtherOffset += 1; iOtherOffset -= m_width; } + if(current_type == TT_CURVE_SE_OTHER) { iOtherOffset += 1; iOtherOffset += m_width; } + if(current_type == TT_CURVE_SW_OTHER) { iOtherOffset -= 1; iOtherOffset += m_width; } + if(current_type == TT_CURVE_NW_OTHER) { iOtherOffset -= 1; iOtherOffset -= m_width; } + + CTrack * other_piece = m_grid.at(iOtherOffset); + other_piece->SetPiece(TT_NUM_PIECES, NULL); + } + // And again, we need to check to see if this is one of + // the other two ends of a switch. + else if(current_type >= TT_SWITCH_VERTICAL_NE_OTHER_CURVE && current_type <= TT_SWITCH_HORIZONTAL_NW_OTHER_CURVE) + { + // Set the other two ends to NULL + // By the way, this took a LOT of work to write :) + int iOriginalEnd = iOffset; + int iOtherStraightOffset = iOffset; + + // The vertical switches + if(current_type == TT_SWITCH_VERTICAL_NE) { iOriginalEnd += 1; iOriginalEnd -= m_width; + iOtherStraightOffset += 1; } + else if(current_type == TT_SWITCH_VERTICAL_SE) { iOriginalEnd += 1; iOriginalEnd += m_width; + iOtherStraightOffset += 1; } + else if(current_type == TT_SWITCH_VERTICAL_SW) { iOriginalEnd -= 1; iOriginalEnd += m_width; + iOtherStraightOffset -= 1; } + else if(current_type == TT_SWITCH_VERTICAL_NW) { iOriginalEnd -= 1; iOriginalEnd -= m_width; + iOtherStraightOffset -= 1; } + + // The horizontal switches + else if(current_type == TT_SWITCH_HORIZONTAL_NE) { iOriginalEnd -= 1; iOriginalEnd += m_width; + iOtherStraightOffset += m_width; } + else if(current_type == TT_SWITCH_HORIZONTAL_SE) { iOriginalEnd -= 1; iOriginalEnd -= m_width; + iOtherStraightOffset -= m_width; } + else if(current_type == TT_SWITCH_HORIZONTAL_SW) { iOriginalEnd += 1; iOriginalEnd -= m_width; + iOtherStraightOffset -= m_width; } + else if(current_type == TT_SWITCH_HORIZONTAL_NW) { iOriginalEnd += 1; iOriginalEnd += m_width; + iOtherStraightOffset += m_width; } + + // Set those pieces to NULL + CTrack * original_piece = m_grid.at(iOriginalEnd); + CTrack * other_straight_piece = m_grid.at(iOtherStraightOffset); + original_piece->SetPiece(TT_NUM_PIECES, NULL); + other_straight_piece->SetPiece(TT_NUM_PIECES, NULL); + } + // LASTLY the final straight part of the switch + else if(current_type >= TT_SWITCH_VERTICAL_NE_OTHER_STRAIGHT && current_type <= TT_SWITCH_HORIZONTAL_NW_OTHER_STRAIGHT) + { + int iOtherCurveOffset = iOffset; + int iOriginalEnd = iOffset; + + // The vertical switches + if(current_type == TT_SWITCH_VERTICAL_NE) { iOtherCurveOffset -= 1; iOriginalEnd -= m_width; } + else if(current_type == TT_SWITCH_VERTICAL_SE) { iOtherCurveOffset -= 1; iOriginalEnd += m_width; } + else if(current_type == TT_SWITCH_VERTICAL_SW) { iOtherCurveOffset += 1; iOriginalEnd += m_width; } + else if(current_type == TT_SWITCH_VERTICAL_NW) { iOtherCurveOffset += 1; iOriginalEnd -= m_width; } + + // The horizontal switches + else if(current_type == TT_SWITCH_HORIZONTAL_NE) { iOtherCurveOffset -= m_width; iOriginalEnd -= 1; } + else if(current_type == TT_SWITCH_HORIZONTAL_SE) { iOtherCurveOffset += m_width; iOriginalEnd -= 1; } + else if(current_type == TT_SWITCH_HORIZONTAL_SW) { iOtherCurveOffset += m_width; iOriginalEnd += 1; } + else if(current_type == TT_SWITCH_HORIZONTAL_NW) { iOtherCurveOffset -= m_width; iOriginalEnd += 1; } + + // Set those pieces to NULL + CTrack * other_curve_piece = m_grid.at(iOtherCurveOffset); + CTrack * original_piece = m_grid.at(iOriginalEnd); + other_curve_piece->SetPiece(TT_NUM_PIECES, NULL); + original_piece->SetPiece(TT_NUM_PIECES, NULL); + } + + // Now set that piece + if(type == TT_NUM_PIECES) + piece->SetPiece(TT_NUM_PIECES,NULL); + else if(type < TT_CURVE_NE) + piece->SetPiece(type,m_straight); + else if(type < TT_SWITCH_VERTICAL_NE) + { + piece->SetPiece(type, m_curved); + // For the curved pieces, we need to + // also set the tile at the other end to + // the _OTHER track piece + int iOtherOffset = iOffset; + TRACK_TYPE other_type = TT_NUM_PIECES; + + if(type == TT_CURVE_NE) { iOtherOffset -= 1; iOtherOffset += m_width; other_type = TT_CURVE_NE_OTHER; } + if(type == TT_CURVE_SE) { iOtherOffset -= 1; iOtherOffset -= m_width; other_type = TT_CURVE_SE_OTHER; } + if(type == TT_CURVE_SW) { iOtherOffset += 1; iOtherOffset -= m_width; other_type = TT_CURVE_SW_OTHER; } + if(type == TT_CURVE_NW) { iOtherOffset += 1; iOtherOffset += m_width; other_type = TT_CURVE_NW_OTHER; } + + CTrack * other_piece = m_grid.at(iOtherOffset); + other_piece->SetPiece(other_type, NULL); + } + else + { + // Set the piece + piece->SetPiece(type, m_switch_curve); + + // This is really going to be a MASSIVE chunk of + // barely readable code... hang on! + + // When we place a switch, we need to also place the + // other curved end and the straight end. + + // Here is where the relative offsets for those pieces go + int iOtherCurveOffset = iOffset; + int iOtherStraightOffset = iOffset; + + // ...and here's where their types go + TRACK_TYPE other_curve_type = TT_NUM_PIECES; + TRACK_TYPE other_straight_type = TT_NUM_PIECES; + + // Now fill 'em in + if(type == TT_SWITCH_VERTICAL_NE) { iOtherCurveOffset -= 1; iOtherCurveOffset += m_width; iOtherStraightOffset += m_width; + other_curve_type = TT_SWITCH_VERTICAL_NE_OTHER_CURVE; + other_straight_type = TT_SWITCH_VERTICAL_NE_OTHER_STRAIGHT; } + else if(type == TT_SWITCH_VERTICAL_SE) { iOtherCurveOffset -= 1; iOtherCurveOffset -= m_width; iOtherStraightOffset -= m_width; + other_curve_type = TT_SWITCH_VERTICAL_SE_OTHER_CURVE; + other_straight_type = TT_SWITCH_VERTICAL_SE_OTHER_STRAIGHT; } + else if(type == TT_SWITCH_VERTICAL_SW) { iOtherCurveOffset += 1; iOtherCurveOffset -= m_width; iOtherStraightOffset -= m_width; + other_curve_type = TT_SWITCH_VERTICAL_SW_OTHER_CURVE; + other_straight_type = TT_SWITCH_VERTICAL_SW_OTHER_STRAIGHT; } + else if(type == TT_SWITCH_VERTICAL_NW) { iOtherCurveOffset += 1; iOtherCurveOffset += m_width; iOtherStraightOffset += m_width; + other_curve_type = TT_SWITCH_VERTICAL_NW_OTHER_CURVE; + other_straight_type = TT_SWITCH_VERTICAL_NW_OTHER_STRAIGHT; } + + // The horizontal switches + else if(type == TT_SWITCH_HORIZONTAL_NE) { iOtherCurveOffset += 1; iOtherCurveOffset -= m_width; iOtherStraightOffset += 1; + other_curve_type = TT_SWITCH_HORIZONTAL_NE_OTHER_CURVE; + other_straight_type = TT_SWITCH_HORIZONTAL_NE_OTHER_STRAIGHT; } + else if(type == TT_SWITCH_HORIZONTAL_SE) { iOtherCurveOffset += 1; iOtherCurveOffset += m_width; iOtherStraightOffset += 1; + other_curve_type = TT_SWITCH_HORIZONTAL_SE_OTHER_CURVE; + other_straight_type = TT_SWITCH_HORIZONTAL_SE_OTHER_STRAIGHT; } + else if(type == TT_SWITCH_HORIZONTAL_SW) { iOtherCurveOffset -= 1; iOtherCurveOffset += m_width; iOtherStraightOffset -= 1; + other_curve_type = TT_SWITCH_HORIZONTAL_SW_OTHER_CURVE; + other_straight_type = TT_SWITCH_HORIZONTAL_SW_OTHER_STRAIGHT; } + else if(type == TT_SWITCH_HORIZONTAL_NW) { iOtherCurveOffset -= 1; iOtherCurveOffset -= m_width; iOtherStraightOffset -= 1; + other_curve_type = TT_SWITCH_HORIZONTAL_NW_OTHER_CURVE; + other_straight_type = TT_SWITCH_HORIZONTAL_NW_OTHER_STRAIGHT; } + + // Set those pieces to their appropriate types + CTrack * other_curve_piece = m_grid.at(iOtherCurveOffset); + CTrack * other_straight_piece = m_grid.at(iOtherStraightOffset); + other_curve_piece->SetPiece(other_curve_type, NULL); + other_straight_piece->SetPiece(other_straight_type, NULL); + } +} + +CTrack * CTrackManager::GetPiece(int x, int z) +{ + // Make sure that the x and z coords that are + // provided are within the proper bounds of the + // grid + if(x < 0 || x >= m_width) return NULL; + if(z < 0 || z >= m_height) return NULL; + + // Calculate this item's offset + int iOffset = (z * m_width) + x; + + // Get that piece + CTrack * piece = m_grid.at(iOffset); + + // Return the type + return piece; +} + +void CTrackManager::SetSwitchState(int x, int z, SWITCH_STATE state) +{ + CTrack * pPiece = GetPiece(x,z); + pPiece->SetState(state); + + // Set the mesh too! + if(state == SS_CURVED) + pPiece->SetPiece(pPiece->GetPiece(), m_switch_curve); + else + pPiece->SetPiece(pPiece->GetPiece(), m_switch_straight); +} + +void CTrackManager::CalculateTrainPosition(CTrack * pTrack, DIRECTION dir, float fPos, float & fx, float & fz, float & fy) +{ + // Wether this piece of track is switched + // or not + SWITCH_STATE state = pTrack->GetState(); + + // Determine what type of track + // we are dealing with so we + // know which of our functions to + // invoke. + switch(pTrack->GetPiece()) + { + case TT_VERTICAL_STRAIGHT: + PositionStraightVertical(fPos,dir,fx,fz,fy); + break; + + case TT_HORIZONTAL_STRAIGHT: + PositionStraightHorizontal(fPos,dir,fx,fz,fy); + break; + + case TT_CURVE_NE: + PositionCurveNE(fPos,fx,fz,fy); + break; + + case TT_CURVE_SE: + PositionCurveSE(fPos,fx,fz,fy); + break; + + case TT_CURVE_SW: + PositionCurveSW(fPos,fx,fz,fy); + break; + + case TT_CURVE_NW: + PositionCurveNW(fPos,fx,fz,fy); + break; + + case TT_CURVE_NE_OTHER: + PositionCurveNEOther(fPos,fx,fz,fy); + break; + + case TT_CURVE_SE_OTHER: + PositionCurveSEOther(fPos,fx,fz,fy); + break; + + case TT_CURVE_SW_OTHER: + PositionCurveSWOther(fPos,fx,fz,fy); + break; + + case TT_CURVE_NW_OTHER: + PositionCurveNWOther(fPos,fx,fz,fy); + break; + + // The switches + case TT_SWITCH_VERTICAL_NE: + if(state == SS_CURVED) PositionCurveNE(fPos,fx,fz,fy); + else PositionStraightVertical(fPos,dir,fx,fz,fy,2.0f); + break; + + case TT_SWITCH_VERTICAL_SE: + if(state == SS_CURVED) PositionCurveSE(fPos,fx,fz,fy); + else PositionStraightVertical(fPos,dir,fx,fz,fy,2.0f,-2.0f); + break; + + case TT_SWITCH_VERTICAL_SW: + if(state == SS_CURVED) PositionCurveSW(fPos,fx,fz,fy); + else PositionStraightVertical(fPos,dir,fx,fz,fy,2.0f,-2.0f); + break; + + case TT_SWITCH_VERTICAL_NW: + if(state == SS_CURVED) PositionCurveNW(fPos,fx,fz,fy); + else PositionStraightVertical(fPos,dir,fx,fz,fy,2.0f); + break; + + case TT_SWITCH_HORIZONTAL_NE: + if(state == SS_CURVED) PositionCurveNEOther(fPos,fx,fz,fy); + else PositionStraightHorizontal(fPos,dir,fx,fz,fy,2.0f); + break; + + case TT_SWITCH_HORIZONTAL_SE: + if(state == SS_CURVED) PositionCurveSEOther(fPos,fx,fz,fy); + else PositionStraightHorizontal(fPos,dir,fx,fz,fy,2.0f); + break; + + case TT_SWITCH_HORIZONTAL_SW: + if(state == SS_CURVED) PositionCurveSWOther(fPos,fx,fz,fy); + else PositionStraightHorizontal(fPos,dir,fx,fz,fy,2.0f,-2.0f); + break; + + case TT_SWITCH_HORIZONTAL_NW: + if(state == SS_CURVED) PositionCurveNWOther(fPos,fx,fz,fy); + else PositionStraightHorizontal(fPos,dir,fx,fz,fy,2.0f,-2.0f); + break; + + // The other curved end of the switches + case TT_SWITCH_VERTICAL_NE_OTHER_CURVE: + PositionCurveNEOther(fPos,fx,fz,fy); + break; + + case TT_SWITCH_VERTICAL_SE_OTHER_CURVE: + PositionCurveSEOther(fPos,fx,fz,fy); + break; + + case TT_SWITCH_VERTICAL_SW_OTHER_CURVE: + PositionCurveSWOther(fPos,fx,fz,fy); + break; + + case TT_SWITCH_VERTICAL_NW_OTHER_CURVE: + PositionCurveNWOther(fPos,fx,fz,fy); + break; + + case TT_SWITCH_HORIZONTAL_NE_OTHER_CURVE: + PositionCurveNE(fPos,fx,fz,fy); + break; + + case TT_SWITCH_HORIZONTAL_SE_OTHER_CURVE: + PositionCurveSE(fPos,fx,fz,fy); + break; + + case TT_SWITCH_HORIZONTAL_SW_OTHER_CURVE: + PositionCurveSW(fPos,fx,fz,fy); + break; + + case TT_SWITCH_HORIZONTAL_NW_OTHER_CURVE: + PositionCurveNW(fPos,fx,fz,fy); + break; + + // The other straight part of the switches + case TT_SWITCH_VERTICAL_NE_OTHER_STRAIGHT: + PositionStraightVertical(fPos,dir,fx,fz,fy,2.0f,-2.0f); + break; + + case TT_SWITCH_VERTICAL_SE_OTHER_STRAIGHT: + PositionStraightVertical(fPos,dir,fx,fz,fy,2.0f); + break; + + case TT_SWITCH_VERTICAL_SW_OTHER_STRAIGHT: + PositionStraightVertical(fPos,dir,fx,fz,fy,2.0f); + break; + + case TT_SWITCH_VERTICAL_NW_OTHER_STRAIGHT: + PositionStraightVertical(fPos,dir,fx,fz,fy,2.0f,-2.0f); + break; + + + case TT_SWITCH_HORIZONTAL_NE_OTHER_STRAIGHT: + PositionStraightHorizontal(fPos,dir,fx,fz,fy,2.0f,-2.0f); + break; + + case TT_SWITCH_HORIZONTAL_SE_OTHER_STRAIGHT: + PositionStraightHorizontal(fPos,dir,fx,fz,fy,2.0f,-2.0f); + break; + + case TT_SWITCH_HORIZONTAL_SW_OTHER_STRAIGHT: + PositionStraightHorizontal(fPos,dir,fx,fz,fy,2.0f); + break; + + case TT_SWITCH_HORIZONTAL_NW_OTHER_STRAIGHT: + PositionStraightHorizontal(fPos,dir,fx,fz,fy,2.0f); + break; + + + default: + break; + } +} + +CTrack * CTrackManager::GetNextTrack(CTrack * pCurrent, DIRECTION d_current, DIRECTION & d_new) +{ + // This function serves a couple of purposes + // - to determine if the next piece in the expected + // location is valid + // - if so, to then fetch that piece and return it + + // First make sure that we're not about to travel + // off the end of the ground! + if(d_current == D_EAST && pCurrent->GetXOffset() == m_width - 1) return NULL; + if(d_current == D_WEST && pCurrent->GetXOffset() == 0) return NULL; + if(d_current == D_NORTH && pCurrent->GetZOffset() == m_height - 1) return NULL; + if(d_current == D_SOUTH && pCurrent->GetZOffset() == 0) return NULL; + + // Calculate the index into the current piece + int iOffset = (pCurrent->GetZOffset() * m_width) + pCurrent->GetXOffset(); + + // Determine the next piece of track + TRACK_TYPE cur_type = pCurrent->GetPiece(); + + if(cur_type == TT_VERTICAL_STRAIGHT) + { + if(d_current == D_NORTH) iOffset += m_width; + else iOffset -= m_width; + + // Direction is unchanged + d_new = d_current; + } + else if(cur_type == TT_HORIZONTAL_STRAIGHT) + { + if(d_current == D_EAST) iOffset += 1; + else iOffset -= 1; + + // Direction is unchanged + d_new = d_current; + } + else if(cur_type >= TT_CURVE_NE && cur_type <= TT_CURVE_NW_OTHER) + { + iOffset += g_trackOrientationInfo[cur_type].iOffsetX; + iOffset += g_trackOrientationInfo[cur_type].iOffsetZ * m_width; + + // Now determine the direction + switch(cur_type) + { + // The curved pieces + case TT_CURVE_NE: d_new = D_WEST; break; + case TT_CURVE_SE: d_new = D_WEST; break; + case TT_CURVE_SW: d_new = D_EAST; break; + case TT_CURVE_NW: d_new = D_EAST; break; + + // The other end of the curved pieces + case TT_CURVE_NE_OTHER: d_new = D_SOUTH; break; + case TT_CURVE_SE_OTHER: d_new = D_NORTH; break; + case TT_CURVE_SW_OTHER: d_new = D_NORTH; break; + case TT_CURVE_NW_OTHER: d_new = D_SOUTH; break; + + default: return NULL; + } + } + else + { + bool bCurve = (pCurrent->GetState() == SS_CURVED); + + if(bCurve) + { + iOffset += g_trackOrientationInfo[cur_type].iOffsetX; + iOffset += g_trackOrientationInfo[cur_type].iOffsetZ * m_width; + } + else + { + iOffset += g_trackOrientationInfo[cur_type].switch_iOffsetX; + iOffset += g_trackOrientationInfo[cur_type].switch_iOffsetZ * m_width; + } + + // Now determine the direction + switch(cur_type) + { + // The curved pieces + case TT_SWITCH_VERTICAL_NE: d_new = (bCurve)?D_WEST:D_NORTH; break; + case TT_SWITCH_VERTICAL_SE: d_new = (bCurve)?D_WEST:D_SOUTH; break; + case TT_SWITCH_VERTICAL_SW: d_new = (bCurve)?D_EAST:D_SOUTH; break; + case TT_SWITCH_VERTICAL_NW: d_new = (bCurve)?D_EAST:D_NORTH; break; + case TT_SWITCH_HORIZONTAL_NE: d_new = (bCurve)?D_SOUTH:D_EAST; break; + case TT_SWITCH_HORIZONTAL_SE: d_new = (bCurve)?D_NORTH:D_EAST; break; + case TT_SWITCH_HORIZONTAL_SW: d_new = (bCurve)?D_NORTH:D_WEST; break; + case TT_SWITCH_HORIZONTAL_NW: d_new = (bCurve)?D_SOUTH:D_WEST; break; + + case TT_SWITCH_VERTICAL_NE_OTHER_CURVE: d_new = D_SOUTH; break; + case TT_SWITCH_VERTICAL_SE_OTHER_CURVE: d_new = D_NORTH; break; + case TT_SWITCH_VERTICAL_SW_OTHER_CURVE: d_new = D_NORTH; break; + case TT_SWITCH_VERTICAL_NW_OTHER_CURVE: d_new = D_SOUTH; break; + case TT_SWITCH_HORIZONTAL_NE_OTHER_CURVE: d_new = D_WEST; break; + case TT_SWITCH_HORIZONTAL_SE_OTHER_CURVE: d_new = D_WEST; break; + case TT_SWITCH_HORIZONTAL_SW_OTHER_CURVE: d_new = D_EAST; break; + case TT_SWITCH_HORIZONTAL_NW_OTHER_CURVE: d_new = D_EAST; break; + + case TT_SWITCH_VERTICAL_NE_OTHER_STRAIGHT: + case TT_SWITCH_VERTICAL_SE_OTHER_STRAIGHT: + case TT_SWITCH_VERTICAL_SW_OTHER_STRAIGHT: + case TT_SWITCH_VERTICAL_NW_OTHER_STRAIGHT: + case TT_SWITCH_HORIZONTAL_NE_OTHER_STRAIGHT: + case TT_SWITCH_HORIZONTAL_SE_OTHER_STRAIGHT: + case TT_SWITCH_HORIZONTAL_SW_OTHER_STRAIGHT: + case TT_SWITCH_HORIZONTAL_NW_OTHER_STRAIGHT: + d_new = d_current; + break; + + default: return NULL; + } + } + + return m_grid.at(iOffset); +} + +void CTrackManager::PositionStraightVertical(float fPercent, DIRECTION dir, float & fXPos, float & fZPos, float & fAngle, float fScale, float fOffset) +{ + fXPos = 1.0f; + float fFactor = 2.0f * fScale; + + if(dir == D_NORTH) { fAngle = 0.0; fZPos = fPercent * fFactor + fOffset; } + else { fAngle = 180.0; fZPos = fFactor - (fPercent * fFactor) + fOffset; } +} + +void CTrackManager::PositionStraightHorizontal(float fPercent, DIRECTION dir, float & fXPos, float & fZPos, float & fAngle, float fScale, float fOffset) +{ + fZPos = 1.0f; + float fFactor = 2.0f * fScale; + + if(dir == D_EAST) { fAngle = 90.0; fXPos = fPercent * fFactor + fOffset; } + else { fAngle = 270.0; fXPos = fFactor - (fPercent * fFactor) + fOffset; } +} + +void CTrackManager::PositionCurveNE(float fPercent, float & fXPos, float & fZPos, float & fAngle) +{ + fXPos = (cosf(fPercent * PI2) * 3.0f) - 2.0f; + fZPos = (sinf(fPercent * PI2) * 3.0f); + fAngle = -(90.0 * fPercent); +} + +void CTrackManager::PositionCurveSE(float fPercent, float & fXPos, float & fZPos, float & fAngle) +{ + fXPos = (cosf(fPercent * PI2) * 3.0f) - 2.0f; + fZPos = (-sinf(fPercent * PI2) * 3.0f) + 2.0f; + fAngle = (90.0 * fPercent) - 180.0f; +} + +void CTrackManager::PositionCurveSW(float fPercent, float & fXPos, float & fZPos, float & fAngle) +{ + fXPos = (-cosf(fPercent * PI2) * 3.0f) + 4.0f; + fZPos = (-sinf(fPercent * PI2) * 3.0f) + 2.0f; + fAngle = 180.0f - (90.0f * fPercent); +} + +void CTrackManager::PositionCurveNW(float fPercent, float & fXPos, float & fZPos, float & fAngle) +{ + fXPos = (-cosf(fPercent * PI2) * 3.0f) + 4.0f; + fZPos = (sinf(fPercent * PI2) * 3.0f); + fAngle = (90.0 * fPercent); +} + +void CTrackManager::PositionCurveNEOther(float fPercent, float & fXPos, float & fZPos, float & fAngle) +{ + fXPos = (-cosf(fPercent * PI2 + PI2) * 3.0f); + fZPos = (sinf(fPercent * PI2 + PI2) * 3.0f) - 2.0f; + fAngle = (90.0 * fPercent) + 90.0f; +} + +void CTrackManager::PositionCurveSEOther(float fPercent, float & fXPos, float & fZPos, float & fAngle) +{ + fXPos = (-cosf(fPercent * PI2 + PI2) * 3.0f); + fZPos = (sinf(fPercent * PI2 - PI2) * 3.0f) + 4.0f; + fAngle = 90.0f - (90.0 * fPercent); +} + +void CTrackManager::PositionCurveSWOther(float fPercent, float & fXPos, float & fZPos, float & fAngle) +{ + fXPos = (cosf(fPercent * PI2 + PI2) * 3.0f) + 2.0f; + fZPos = (sinf(fPercent * PI2 - PI2) * 3.0f) + 4.0f; + fAngle = (90.0 * fPercent) - 90; +} + +void CTrackManager::PositionCurveNWOther(float fPercent, float & fXPos, float & fZPos, float & fAngle) +{ + fXPos = (cosf(fPercent * PI2 + PI2) * 3.0f) + 2.0f; + fZPos = (sinf(fPercent * PI2 + PI2) * 3.0f) - 2.0f; + fAngle = -(90.0 * fPercent) - 90.0f; +} diff -Nru opentracks-0.1/src/CTrain.cpp opentracks-0.0.7/src/CTrain.cpp --- opentracks-0.1/src/CTrain.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CTrain.cpp 2010-12-17 19:30:55.000000000 +0000 @@ -0,0 +1,88 @@ +#include "CTrain.h" + +CTrain::CTrain(IrrlichtDevice * pDevice, ISceneNode * pParent, u32 t_time, CTrack * pTrack, std::string mesh_filename) + : m_node(NULL), m_speed(0.0f), m_direction(D_NORTH), m_last_time(t_time), m_percent(1.0f), m_current_track(pTrack) +{ + // Try to open the train's mesh + IMesh * mesh = pDevice->getSceneManager()->getMesh(mesh_filename.c_str()); + + // Now add the mesh to the scene manager + m_node = pDevice->getSceneManager()->addMeshSceneNode(mesh, pParent); + + // Disable lighting on it for now + //if(m_node) + // m_node->setMaterialFlag(EMF_LIGHTING, false); + + // TODO: add lookup for textures +} + +CTrain::~CTrain() +{ + // remove the node + m_node->remove(); +} + +void CTrain::Process(CTrackManager * pManager,u32 t_time) +{ + // Do nothing if the current piece is invalid + if(!m_current_track) return; + + // Start by calculating the amount of time that has elapsed + // since the last run through this function + int iElapsedMS = t_time - m_last_time; + + m_percent += ((float)iElapsedMS / 1000.0f) * m_speed; + + // But wait! We might be at the end of the piece of track. + // If so, get the next piece of track and set the percentage accordingly. + TRACK_TYPE cur_type = m_current_track->GetPiece(); + + // Determine the length of the current piece of track + float fLength = (m_current_track->GetState() == SS_CURVED)? + g_trackOrientationInfo[cur_type].length: + g_trackOrientationInfo[cur_type].switch_length; + + if(m_percent > fLength) + { + // See what the next piece is + DIRECTION new_dir; + m_current_track = pManager->GetNextTrack(m_current_track, m_direction, new_dir); + + if(!m_current_track || m_current_track->GetPiece() == TT_NUM_PIECES) + { + // Stop the train and reset the percentage + m_speed = 0.0f; + m_percent = 0.0f; + + m_current_track = NULL; + } + else + { + m_percent -= fLength; + + m_direction = new_dir; + } + } + + if(m_current_track) + { + float fPerc = m_percent / fLength; + + float train_trans_x, train_trans_z; + float train_rotate_y; + + // Get the offset for the piece of track + pManager->CalculateTrainPosition(m_current_track,m_direction,fPerc,train_trans_x,train_trans_z,train_rotate_y); + + // Add the track's offset to this number + train_trans_x += m_current_track->GetXPos(); + train_trans_z += m_current_track->GetZPos(); + + // Now set this as the position + m_node->setPosition(vector3df(train_trans_x,0,train_trans_z)); + m_node->setRotation(vector3df(0,train_rotate_y,0)); + + // Don't forget to store the last time + m_last_time = t_time; + } +} diff -Nru opentracks-0.1/src/CTrainManager.cpp opentracks-0.0.7/src/CTrainManager.cpp --- opentracks-0.1/src/CTrainManager.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/CTrainManager.cpp 2010-12-18 00:53:18.000000000 +0000 @@ -0,0 +1,84 @@ +#include "CTrainManager.h" + +CTrainManager::CTrainManager(IrrlichtDevice * pDevice, CTrackManager * pManager) + : m_device(pDevice), m_manager(pManager), m_parent_node(NULL) +{ + // Create the parent node + m_parent_node = m_device->getSceneManager()->addEmptySceneNode(); +} + +CTrainManager::~CTrainManager() +{ + // Free all of the trains + for(unsigned int i=0;iremove(); +} + +void CTrainManager::AddTrain(u32 t_time, int x, int y) +{ + // We need to find the piece of track + // that corresponds to the given coords + + CTrack * pTrack = m_manager->GetPiece(x,y); + + // Make sure that the piece is valid + if(!pTrack) return; + + TRACK_TYPE tt = pTrack->GetPiece(); + + if(tt != TT_NUM_PIECES) + { + // Create the train and give it a small speed + CTrain * pTrain = new CTrain(m_device,m_parent_node,t_time,pTrack,DATA_DIR "/engines/standard_diesel/standard_diesel.b3d"); + pTrain->SetSpeed(0.0f); + + // Push the train into the vector + m_trains.push_back(pTrain); + + // Create the map + m_node_map.insert(std::pair(pTrain->GetSceneNode(), pTrain)); + } +} + +void CTrainManager::Process(u32 t_time) +{ + for(unsigned int i=0; iProcess(m_manager,t_time); + } +} + +CTrain * CTrainManager::Intersection(line3df ray) +{ + // We need to see if the ray intersects any trains + + // We get a scene node here + ISceneNode * pNode = m_device->getSceneManager()->getSceneCollisionManager()->getSceneNodeFromRayBB(ray,0,true,m_parent_node); + + if(pNode) + { + // Now determine which train that is + // by looking it up in the map + return m_node_map[pNode]; + } + else + return NULL; +} + +void CTrainManager::AddWindowMapping(IGUIElement * pElement, CTrain * pTrain) +{ + m_window_map.insert(std::pair(pElement, pTrain)); +} + +void CTrainManager::RemoveWindowMapping(IGUIElement * pElement) +{ + m_window_map.erase(pElement); +} + +CTrain * CTrainManager::GetTrainFromWindow(IGUIElement * pElement) +{ + return m_window_map[pElement]; +} diff -Nru opentracks-0.1/src/main.cpp opentracks-0.0.7/src/main.cpp --- opentracks-0.1/src/main.cpp 1970-01-01 00:00:00.000000000 +0000 +++ opentracks-0.0.7/src/main.cpp 2010-12-11 23:11:11.000000000 +0000 @@ -0,0 +1,61 @@ +// Standard includes +#include + +// Irrlicht includes +#include + +using namespace irr; + +using namespace core; +using namespace scene; +using namespace video; +using namespace io; +using namespace gui; + +// OpenTracks includes +#include "CStateManager.h" +#include "CSkin.h" + +int main(int argc, char** argv) +{ + // The first thing we need to do is attempt + // to create the device. If we fail to do that, + // then just report an immediate error and abort. + + // Determine what device we're to use + E_DRIVER_TYPE driver_type = EDT_OPENGL; + + // TODO: Also determine what resolution and whether we're + // to go fullscreen or not. + IrrlichtDevice * pDevice = + createDevice(driver_type, dimension2d(960, 600), 16, + false, false, true, NULL); + + // Check for failure + if(!pDevice) + { + std::cerr << "There was an error initializing the Irrlicht " + << "video driver." << std::endl; + return 1; + } + + // Set the window title + pDevice->setWindowCaption(L"OpenTracks - The Open Source Railway Simulator"); + + // And activate our GUI skin + pDevice->getGUIEnvironment()->setSkin(new CSkin(pDevice)); + + // Now initialize the state manager, which we will then + // hand over control of the application to. + CStateManager state_manager(pDevice); + + // Release our handle to the device + pDevice->drop(); + + // Now hand off control to the state manager. + state_manager.Go(); + + // We're done now! Return 0 + return 0; +} +