--- David Luff <[EMAIL PROTECTED]> wrote:
> On 12/11/02 at 1:09 PM ace project wrote:
> 
> >Our (ACE/ICE) multiplayer engine is ready to draw
> >planes in the game now, but I cant seem to figure
> out
> >how to add them to the drawing graph in a way that
> I
> >can actually see them.
> >
> >Does anyone know how to do this or know the
> pitfalls
> >why is it failing ?
> >
> >
> 
> Leon,
> 
> The following code will put a C172 floating above
> the San Fransisco runway
> about 100m down from the startup location if it is
> instantiated and the
> Init and Update functions called:
> 
> ...
> Dave

I got Flight Gear to show the model a hour ago, I made
some *stupid* mistake reading out a variable from a
function (which forgot to copy a variable and it
default was wrong). I fixed that bug a couple of days
ago but it came back to hunt me :(


Now I have a plane in my sight, letting it fly is the
next goal. If the FGModelPlacement.update() capable of
this or is it never tested before ?

(Plz note that my 2nd PC is a AMD Athlon 550mhz with
384mb RAM and a slow Matrox G450 16mb that is running
Flight Gear at only 4 to 16 fps (OS Debian Woody))


This slow PC can also be the source of my little
problem. Feel free to test the code...


Added the source of my -current- fgPeer-class have to
only rendering code in them.

init(...) gets called when the peer is added to the
peer list and update() gets called everytime
fgSubsystem.update() is called.

Any thing missing ?

Any help would be really appreciated,


Leon

=====
My Flight Gear Multiplayer Stuff (work-in-progress):
http://www.kbs.twi.tudelft.nl/People/Students/L.Otte/

OK, I admit it: My girlfriend's just an object to me. 
Unfortunately, there is some information hiding, but 
thankfully, she's fairly encapsulated, nicely modular, and 
has a very well defined interface!

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com
#include "fgPeer.h"

#include <simgear/constants.h>
#include <simgear/misc/props.hxx>
#include <Main/fg_props.hxx>
#include "mpeSocket.h"
#include "mpePosition.h"
#include <Model/loader.hxx>

/* ****************************************************************************\
* fgPeer implementation starts here                                         *
\******************************************************************************/

void fgPeer::init(const string &path,SGPropertyNode* rootnode) {
	/* 'ispeer' gets set in CONSTRUCTOR, keep it that way !!! */

	ssgEntity* fgd_obj=globals->get_model_loader()->load_model("Models/Geometry/tuxcopter.ac"); /* <--hardcoded instead of 'path' */
	fgd_obj->clrTraversalMaskBits(SSGTRAV_HOT);
	_position->addKid(fgd_obj);
	_selector->addKid(_position);
	ssgFlatten(fgd_obj);
	ssgStripify(fgd_obj);
	//globals->get_scenery()->get_scene_graph()->addKid(getSceneGraph());

	if(rootnode!=0) {
		root=rootnode;
	} else {
		root=fgGetNode("/tmp/fgPeer",true);
	}

	timeout_timer.reset();
	timeout=10; /* in seconds */

	setPassive(false);
	setNonClientHost(false);

	setFlags(0);
	setFlaps(false);
	setLandingGears(false);
}

void fgPeer::clear() { }

void fgPeer::setPosition(mpePosition* pos) { 
	setLongitudeDeg(pos->getLongitude()*SG_RADIANS_TO_DEGREES);
	setLatitudeDeg (pos->getLatitude() *SG_RADIANS_TO_DEGREES);
	setElevationFt (pos->getAltitude() *SG_METER_TO_FEET);

	setRollDeg     (pos->getPhi()      *SG_RADIANS_TO_DEGREES);
	setPitchDeg    (pos->getTheta()    *SG_RADIANS_TO_DEGREES);
	setHeadingDeg  (pos->getPsi()      *SG_RADIANS_TO_DEGREES);
}

mpePosition fgPeer::getPosition() {
	mpePosition pos;
	pos.setLongitude(getLongitudeDeg()*SG_DEGREES_TO_RADIANS);
	pos.setLatitude(getLatitudeDeg()*SG_DEGREES_TO_RADIANS);
	pos.setAltitude(getElevationFt()*SG_FEET_TO_METER);

	pos.setPhi(getRollDeg()*SG_DEGREES_TO_RADIANS);
	pos.setTheta(getPitchDeg()*SG_DEGREES_TO_RADIANS);
	pos.setPsi(getHeadingDeg()*SG_DEGREES_TO_RADIANS);

	return(pos);
}

void fgPeer::setPassive       (bool pasv)             { root->setBoolValue("isPassiveHost"      ,pasv  ); }
void fgPeer::setNonClientHost (bool nch)              { root->setBoolValue("isNonClientHost"    ,nch   ); }
//void fgPeer::setFOV           (int _fov)              {  fov->setIntValue (_fov                        ); }
void fgPeer::setFlags         (u8 _flags)             { root->setIntValue ("flags"              ,_flags); }
void fgPeer::setState(mpe_enums::STATE_values _state) { root->setIntValue ("state"              ,_state); }
void fgPeer::setFlaps         (bool _flaps)           { root->setBoolValue("flaps-enabled"      ,_flaps); }
void fgPeer::setLandingGears  (bool lg)               { root->setBoolValue("landinggear-enabled",lg    ); }


int         fgPeer::getTimeoutValue () { return(timeout);         }
u16         fgPeer::getID           () { return(root->getIntValue("id",0));                             }
//int         fgPeer::getFOV          () { return(root->getIntValue("field-of-view",MPE_CLIENT_DEF_FOV)); }
u8          fgPeer::getFlags        () { return(root->getIntValue("flags"        ,0                 )); }
cchar*      fgPeer::getNickname     () { return(root->getStringValue("callsign"  ,"unset"           )); }
cchar*      fgPeer::getFDM          () { return(root->getStringValue("flight-model","unset"         )); }
cchar*      fgPeer::getPlaneName    () { return(root->getStringValue("plane-name","unset"           )); }
cchar*      fgPeer::getPlaneID      () { return(root->getStringValue("plane-id","unset"             )); }
bool        fgPeer::getFlaps        () { return(root->getBoolValue("flaps-enabled",false            )); }
bool        fgPeer::getLandingGears () { return(root->getBoolValue("landinggear-enabled",false      )); }

void fgPeer::setTimeoutValue(int _timeout) { 
	timeout=_timeout; /* x2 to avoid (double)10!=(int)10 type errors. */
	timeout_timer.setMaxDelta(timeout*2);
}

bool fgPeer::setNickname(cchar* _nickname) {
	bool rv;
	int len=strlen(_nickname);
	if(len<len_record_part) {
		root->setStringValue("callsign",_nickname);	
		rv=true; /* Value is set succesfully */
	} else {
		char tmp[len_record_part];
		memcpy(tmp,_nickname,len_record_part-1);
		tmp[len_record_part-1]=0;
		root->setStringValue("callsign",tmp);
		rv=false; /* Value has been set incompletely */
	}
	return(rv);
}

bool fgPeer::setFDM(cchar* _fdm) {
	bool rv;
	int len=strlen(_fdm);
	if(len<len_record_part) {
		root->setStringValue("flight-model",_fdm);	
		rv=true; /* Value is set succesfully */
	} else {
		char tmp[len_record_part];
		memcpy(tmp,_fdm,len_record_part-1);
		tmp[len_record_part-1]=0;
		root->setStringValue("flight-model",tmp);
		rv=false; /* Value has been set incompletely */
	}
	return(rv);
}

bool fgPeer::setPlaneName(cchar* _planename) {
	bool rv;
	int len=strlen(_planename);
	if(len<len_record_part) {
		root->setStringValue("plane-name",_planename);	
		rv=true; /* Value is set succesfully */
	} else {
		char tmp[len_record_part];
		memcpy(tmp,_planename,len_record_part-1);
		tmp[len_record_part-1]=0;
		root->setStringValue("plane-name",tmp);
		rv=false; /* Value has been set incompletely */
	}
	return(rv);
}

bool fgPeer::setPlaneID(cchar* _planeid) {
	bool rv;
	int len=strlen(_planeid);
	if(len<len_record_part) {
		root->setStringValue("plane-id",_planeid);	
		rv=true; /* Value is set succesfully */
	} else {
		char tmp[len_record_part];
		memcpy(tmp,_planeid,len_record_part-1);
		tmp[len_record_part-1]=0;
		root->setStringValue("plane-id",tmp);
		rv=false; /* Value has been set incompletely */
	}
	return(rv);
}

bool fgPeer::isPassive() { return(root->getBoolValue("isPassive",false)); }
bool fgPeer::isNonClientHost() { return(root->getBoolValue("isNonClienthost",false)); }

void fgPeer::updateStayAlive() { timeout_timer.reset(); }

bool fgPeer::isTimedOut() {
	if(timeout==0) {
		return(false); /* Does never timeout... (dangerous) */
	} else {
		timeout_timer.update();
		return( timeout_timer.getAbsTime()>timeout);
	}
}

bool fgPeer::isBandwidthFull() {
	return(false); /* not yet implemented */
}

void fgPeer::updatePosition(mpePosition* _pos) {
	setPosition(_pos);
	timeout_timer.update();
}

mpe_version fgPeer::getClientVersion() { 
	mpe_version ver;
	ver.major     =root->getIntValue("version/client-major",MPE_CLIENT_VERSION_MAJOR);
	ver.minor     =root->getIntValue("version/client-minor",MPE_CLIENT_VERSION_MINOR);
	ver.patchlevel=root->getIntValue("version/client-patch",MPE_CLIENT_VERSION_PATCH);
	return(ver);
}

mpe_version fgPeer::getServerVersion() {
	mpe_version ver;
	ver.major     =root->getIntValue("version/client-major",MPE_CLIENT_VERSION_MAJOR);
	ver.minor     =root->getIntValue("version/client-minor",MPE_CLIENT_VERSION_MINOR);
	ver.patchlevel=root->getIntValue("version/client-patch",MPE_CLIENT_VERSION_PATCH);
	return(ver);
}

void fgPeer::setClientVersion(mpe_version ver) {
	root->setIntValue("version/client-major",ver.major);
	root->setIntValue("version/client-minor",ver.minor);
	root->setIntValue("version/client-patch",ver.patchlevel);
}

void fgPeer::setServerVersion(mpe_version ver) {
	root->setIntValue("version/server-major",ver.major);
	root->setIntValue("version/server-minor",ver.minor);
	root->setIntValue("version/server-patch",ver.patchlevel);
}

void fgPeer::setID(u16 _id) { 
	root->setIntValue ("id",_id); 
}

fgPeer::~fgPeer() { 
//    globals->get_scenery()->get_models_branch()->removeKid(
//	getSceneGraph()
//    );
}

ostream& operator<<(ostream& output,fgPeer client) {
	mpe_version ver_client=client.getClientVersion();
	mpe_version ver_server=client.getServerVersion();

	output
		<< "---------------------------------------" << std::endl
		<< " playerid=" << client.getID()
		<< " passiveHost=" << (bool)client.isPassive();

	output
		<< " timeout=" << client.getTimeoutValue()
		<< " version server=" << (int)ver_server.major 
		<< "." << (int)ver_server.minor
		<< "." << (int)ver_server.patchlevel
		<< " version client=" << (int)ver_client.major 
		<< "." << (int)ver_client.minor
		<< "." << (int)ver_client.patchlevel
		<< " nickname=" << client.getNickname()
		<< " fdm=" << client.getFDM()
		<< " planename=" << client.getPlaneName()
		<< " planeid=" << client.getPlaneID()
		<< std::endl;
	return(output);
}
#ifndef _FG_CLIENT_H_
#define _FG_CLIENT_H_

#ifdef HAVE_CONFIG_H
#	include <config.h>
#endif

#ifndef FG_NETWORK_MPE
#	error This class is Flight Gear specific, use mpeClient instead !
#endif

#include "mpeGlobals.h"
#include <Main/globals.hxx>
#include <Scenery/scenery.hxx>
#include "mpeClient_interface.h"
#include <simgear/compiler.h>
#include <plib/ul.h>
#include <Model/model.hxx>


/** only defined here, NOT implemented (see simgear/misc/props.hxx for that). */
class SGPropertyNode; 

/**
* This class contains all information that a client might want to know about
* all his peers (other clients on same server) and itself. The clients implement
* this class in combination with mpeClientHandler to communicate with the server.
*/
class fgPeer:public FGModelPlacement {
public:
	static const int len_record_part=50;

protected:
	SGPropertyNode* root;

	int timeout;
	
	ulClock timeout_timer;
		
public:
	/* Constructor */
	fgPeer() { 
		init("Models/Geometry/glider.ac",0);
		globals->get_scenery()->get_models_branch()->addKid(
		    getSceneGraph()
		);
	}

	void init(const string &path, SGPropertyNode* rootnode);
	
	/** Cleans up all variables/structures/etc. */
	void clear(); 

	/*  destructor */
	virtual ~fgPeer();

	/**
	* Returns a value to indicate whether this client should be kicked from the server
	* for not sending any packets to the server. (Client timed out)
	*/
	bool isTimedOut(); /* 'True' means that he gets kicked automagickly */

	/**
	* Set the time out value (in Seconds?).
	* 0 means it does not time out, this is very abusable, use with care.
	*/
	void setTimeoutValue(int _timeout);	

	int getTimeoutValue();

	/**
	* Updates the position of this client. This function also updates the time out
	* and is for that reason the preferred function to be used on the server side.
	*/
	void updatePosition(mpePosition* _pos); /* Also updates timeout */

	/** Updates only the time-out timer, so that the client does not time out too fast. */
	void updateStayAlive(); /* Only updates timeout */

	/**
	* Sets the position of this client. This function does not update the time-out
	* and can be used for serverside position prediction (not implemented).
	*/
	void setPosition(mpePosition* _pos);

	/**
	* Returns the last known position of this client received from the server.
	* (thus no extrapolation). The client itself <B>may</B> maintain the variable
	* for itself, but this is not implemented atm. 
	*/
	mpePosition getPosition();	

	/** Sets the status of the landing gears. */
	void setLandingGears(bool _landinggears);
	
	/** Returns the status of the landing gears. */
	bool getLandingGears();
	
	/** Sets the status of the flaps. */
	void setFlaps(bool _flaps);
	
	/** Returns the status of the flaps. */
	bool getFlaps();
	
	/**
	* Sets the address of the server. This function is used to block packets from unknown
	* hosts (kind of weak 1 port firewall).
	*/
	void setServerAddress(mpeAddress _server);

	/**
	* Sets the address of the client itself. This function is used at the server side
	* to test what client-record we are processing.
	*/
	void setClientAddress(mpeAddress _client);
	
	/**
	* Returns the address of the server. This function is used to block packets from
	* unknown hosts (kind of weak 1 port firewall).
	* Please note that this IS IMPLEMENTED. So if you have some weird firewall/NAT settings
	* you might get bitten by this feature.
	*/
	mpeAddress getServerAddress();

	/* 
	* Returns the address of this client. Only used on the server-side atm, so please
	* do NOT rely on it while using it on the client side. Used getLocalHost() instead.
	*/
	mpeAddress getClientAddress();

	/**
	* Sets that this is a passive client and that it only wants to receive data and
	* does not actually play. Can be used for external plugins such as a radar screen.
	*/
	void setPassive(bool pasv); 

	/**
	* Indicates that this is a passive client and that it only wants to receive data and
	* does not actually play. Can be used for external plugins such as a radar screen.
	*/
	bool isPassive();

	/**
	* Sets that this is a nonClientHost. This client has a reduced packet set and can be
	* used to make networked input modules.<BR>
	* <B>Not supported! Use at your own risk & debugging time!</B>		
	*/
	void setNonClientHost(bool _nonClientHost);
	
	/** Return whether or not this is a non-Client Host. */
	bool isNonClientHost();
	 
	/**
	* Indicates that this client cannot send/receive anymore packets this second because
	* its bandwidth is full. (not implemented yet)
	*/
	bool isBandwidthFull();

	/** Sets the unique ID for this client. This ID is assigned by the server. */
	void setID(u16 _id);
 
 	/** Returns the unique ID for this client. This ID is assigned by the server.*/
	u16 getID();
	
	/** Returns a previous position of this client for backtracking/debugging. */
	mpePosition getBacklogPosition(u16 _pos);

	/** Returns the current state of the connection (hopefully) */
	mpe_enums::STATE_values getState();
	
	/** Sets the current state of the connection (according to the client itself) */
	void setState(mpe_enums::STATE_values _state);

//	void setFOV(int _fov);
//	int getFOV();
	void setFlags(u8 _flags);
	u8 getFlags();

	cchar* getNickname();
	cchar* getFDM();
	cchar* getPlaneName();
	cchar* getPlaneID();
	
	mpe_version getClientVersion();
	mpe_version getServerVersion();

	bool setNickname(cchar* _nickname);
	bool setFDM(cchar* _fdm);
	bool setPlaneName(cchar* _planename);
	bool setPlaneID(cchar* _planeid);
	
	void setClientVersion(mpe_version _ver_client);
	void setServerVersion(mpe_version _ver_server);
};

ostream& operator<<(ostream& output, fgPeer client);
#endif /* _MPE_CLIENT_H_ */

Reply via email to