A final thing to mention about our cListener class is that it has a virtual void install(cCritter *pcritter) method. We attach a listener to a critter with the cCritter::setListener(cListener *plistener) method, and the setListener code calls plistener->install(this) to give the listener a chance to make any necessary adjustments to the critter that is going to start using it.
The default behavior of cListener::install(cCritter *pcritter) is simply to match the pcritter 's motion matrix to its attitude matrix to get things off to a good start ? this match will not automatically be TRUE, as we normally do not lock the player critter's attitude to its motion. One other use for install is to temporarily set a critter's maximum speed to a very high value when it uses a cListenerCursor.
In the case of the viewer listeners, the install methods also set the cCritterViewer _perspective field to FALSE for the two-dimensional cListenerViewerOrtho and to TRUE for the three-dimensional cListenerViewerFly and cListenerViewerRide. A final wrinkle is that the cListenerViewerFly locks the viewer critter's attitude matrix to its motion matrix ? as here we are effectively flying a camera around; while cListenerViewerOrtho does not lock the viewer critter attitude to its motion ? because we want this viewer always to be staring down the z-axis at the world, even if we are moving it to the left and right. More details can be found in the listener.cpp file.