]> git.mxchange.org Git - flightgear.git/blobdiff - src/MultiPlayer/mpplayer.cxx
- don't abort if remote model isn't installed; output missing model's
[flightgear.git] / src / MultiPlayer / mpplayer.cxx
index 40ba5c5f98492a7401145321047bdff518314d09..20b255ad56a5256ba6641f763b2f383154c2466f 100644 (file)
 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 //
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef FG_MPLAYER_AS
 
 /******************************************************************
 * $Id$
 #include "mpplayer.hxx"
 
 #include <stdlib.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
+#if !(defined(_MSC_VER) || defined(__MINGW32__))
+# include <netdb.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+#endif
 #include <plib/netSocket.h>
+#include <plib/sg.h>
+
+#include <simgear/scene/model/modellib.hxx>
 
 #include <Main/globals.hxx>
-#include <Model/loader.hxx>
 #include <Scenery/scenery.hxx>
 
 
@@ -64,6 +73,7 @@ MPPlayer::MPPlayer() {
     m_bInitialised = false;
     m_LastUpdate = 0;
     m_PlayerAddress.set("localhost", 0);
+    m_sCallsign = "none";
 
 
 }
@@ -97,15 +107,18 @@ bool MPPlayer::Open(const string &sAddress, const int &iPort, const string &sCal
 
         // If the player is remote then load the model
         if (!bLocalPlayer) {
-
-             LoadModel();
-
+             try {
+                 LoadModel();
+             } catch (...) {
+                 SG_LOG( SG_NETWORK, SG_ALERT, "Failed to load remote model '" << sModelName << "'." );
+                 return false;
+             }
         }
 
         m_bInitialised = bSuccess;
 
     } else {
-        cerr << "MPPlayer::Open - Attempt to open an already open player connection." << endl;
+        SG_LOG( SG_NETWORK, SG_ALERT, "MPPlayer::Open - Attempt to open an already open player connection." );
         bSuccess = false;
     }
 
@@ -122,15 +135,26 @@ bool MPPlayer::Open(const string &sAddress, const int &iPort, const string &sCal
 ******************************************************************/
 void MPPlayer::Close(void) {
 
-
     // Remove the model from the game
-    if (!m_bLocalPlayer) {
-        globals->get_scenery()->get_scene_graph()->removeKid(m_ModelSel);
+    if (m_bInitialised && !m_bLocalPlayer) {
+
+        // Disconnect the model from the transform, then the transform from the scene.
+        m_ModelTrans->removeKid(m_Model);
+        globals->get_scenery()->get_aircraft_branch()->removeKid( m_ModelTrans);
+
+        // Flush the model loader so that it erases the model from its list of
+        // models.
+        globals->get_model_lib()->flush1();
+
+        // Assume that plib/ssg deletes the model and transform as their
+        // refcounts should be zero.
+
     }
 
     m_bInitialised = false;
     m_bUpdated = false;
     m_LastUpdate = 0;
+    m_sCallsign = "none";
 
 }
 
@@ -145,7 +169,7 @@ void MPPlayer::SetPosition(const sgMat4 PlayerPosMat4) {
 
     // Save the position matrix and update time
     if (m_bInitialised) {
-        memcpy(m_ModelPos, PlayerPosMat4, sizeof(sgMat4));
+        sgCopyMat4(m_ModelPos, PlayerPosMat4);
         time(&m_LastUpdate);
         m_bUpdated = true;
     }
@@ -157,26 +181,24 @@ void MPPlayer::SetPosition(const sgMat4 PlayerPosMat4) {
 /******************************************************************
 * Name: Draw
 * Description: Updates the position for the player's model
-* The state of the player (old, initialised etc)
-* is returned.
+* The state of the player's data is returned.
 ******************************************************************/
-int MPPlayer::Draw(void) {
+MPPlayer::TPlayerDataState MPPlayer::Draw(void) {
 
-    int iResult = PLAYER_DATA_NOT_AVAILABLE;
+    MPPlayer::TPlayerDataState eResult = PLAYER_DATA_NOT_AVAILABLE;
 
     sgCoord sgPlayerCoord;
 
-    if (m_bInitialised) {
+    if (m_bInitialised && !m_bLocalPlayer) {
         if ((time(NULL) - m_LastUpdate < TIME_TO_LIVE)) {
             // Peform an update if it has changed since the last update
             if (m_bUpdated) {
 
                 // Transform and update player model
-                m_ModelSel->select(1);
                 sgSetCoord( &sgPlayerCoord, m_ModelPos);
                 m_ModelTrans->setTransform( &sgPlayerCoord );
 
-                iResult = PLAYER_DATA_AVAILABLE;
+                eResult = PLAYER_DATA_AVAILABLE;
 
                 // Clear the updated flag so that the position data
                 // is only available if it has changed
@@ -185,12 +207,12 @@ int MPPlayer::Draw(void) {
 
         // Data has not been updated for some time.
         } else {
-            iResult = PLAYER_DATA_EXPIRED;
+            eResult = PLAYER_DATA_EXPIRED;
         }
 
     }
 
-    return iResult;
+    return eResult;
 
 }
 
@@ -225,18 +247,24 @@ bool MPPlayer::CompareCallsign(const char *sCallsign) const {
 void MPPlayer::LoadModel(void) {
 
 
-   m_ModelSel = new ssgSelector;
-   m_ModelTrans = new ssgTransform;
+    m_ModelTrans = new ssgTransform;
+
+    // Load the model
+    m_Model = globals->get_model_lib()->load_model( globals->get_fg_root(),
+                                                    m_sModelName,
+                                                    globals->get_props(),
+                                                    globals->get_sim_time_sec() );
+    m_Model->clrTraversalMaskBits( SSGTRAV_HOT );
 
-   ssgEntity *Model = globals->get_model_loader()->load_model(m_sModelName);
-   Model->clrTraversalMaskBits( SSGTRAV_HOT );
-   m_ModelTrans->addKid( Model );
-   m_ModelSel->addKid( m_ModelTrans );
-   ssgFlatten( Model );
-   ssgStripify( m_ModelSel );
+    // Add model to transform
+    m_ModelTrans->addKid( m_Model );
 
-   globals->get_scenery()->get_scene_graph()->addKid( m_ModelSel );
-   globals->get_scenery()->get_scene_graph()->addKid(  Model );
+    // Optimise model and transform
+    ssgFlatten( m_Model );
+    ssgStripify( m_ModelTrans );
+
+    // Place on scene under aircraft branch
+    globals->get_scenery()->get_aircraft_branch()->addKid( m_ModelTrans );
 
 
 }
@@ -252,8 +280,7 @@ void MPPlayer::FillPosMsg(T_MsgHdr *MsgHdr, T_PositionMsg *PosMsg) {
 
     strncpy(PosMsg->sModel, m_sModelName.c_str(), MAX_MODEL_NAME_LEN);
     PosMsg->sModel[MAX_MODEL_NAME_LEN - 1] = '\0';
-
-    memcpy(PosMsg->PlayerPos, m_ModelPos, sizeof(sgMat4));
+    sgCopyMat4(PosMsg->PlayerPos, m_ModelPos);
 
 
 }
@@ -281,7 +308,7 @@ void MPPlayer::FillMsgHdr(T_MsgHdr *MsgHdr, const int iMsgId) {
             break;
     }
 
-    inet_aton(m_PlayerAddress.getHost(), &address);
+    address.s_addr = inet_addr( m_PlayerAddress.getHost() );
     MsgHdr->lReplyAddress = address.s_addr;
 
     MsgHdr->iReplyPort = m_PlayerAddress.getPort();
@@ -292,3 +319,5 @@ void MPPlayer::FillMsgHdr(T_MsgHdr *MsgHdr, const int iMsgId) {
 
 }
 
+#endif // FG_MPLAYER_AS
+