// Custom Commands

 //  ***********************************
 //
 //  MANIPULATOR CODE EXAMPLE
 //
 //  This example program illustrates control of X-Plane DataRefs using custom manipulators.
 //  Pumping the flap lever manipulator will lower the flaps a fractional amount.  Raising 
 //  the flap selector manipulator will change the direction of flap movement.  
 //	
 //  For this example to work it is necessary to use AC3D to create two handle animations in  
 //  the aircraft cockpit using the custom datarefs BSUB/Aircraft/FlapPumpPosition and  
 //  BSUB/Aircraft/FlapSelectorPosition for the rotations.  Both handles must be identified  
 //  as axis manipulators with 0 to 1 limits and grabber hand cursor.  
 //
 //  For clarity this code has not been optimized.  
 //
 //  Blue side up,
 //  Bob
 //	
 //  Bob@RogerThat.ca
 //
 //  ***********************************
 
 
 #define XPLM200 = 1;
 
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include "XPLMDataAccess.h"
 #include "XPLMPlugin.h"
 #include "XPLMProcessing.h"
 
 #define MSG_ADD_DATAREF 0x01000000
 
 XPLMDataRef FlapRatioDataRef = NULL;                 // Existing dataref
 
 XPLMDataRef FlapPumpPositionDataRef = NULL;          // Custom dataref 
 XPLMDataRef FlapSelectorPositionDataRef = NULL;      // Custom dataref
 
 
 float	GetFlapPumpPositionDRCB(void* inRefcon);
 void	SetFlapPumpPositionDRCB(void* inRefcon, float outValue);
 
 float	GetFlapSelectorPositionDRCB(void* inRefcon);
 void	SetFlapSelectorPositionDRCB(void* inRefcon, float outValue);
 
 float	FlapPumpPositionFLCB(float elapsedMe, float elapsedSim, int counter, void * refcon);
 
 float FlapPumpPosition = 0;
 float FlapSelectorPosition = 1;          // Flap selector lever is down position at startup
 float FlapSelectorDirectionFlag = 1;     // Flap lever will pump flaps downwards at startup
 
 PLUGIN_API int XPluginStart(
                                            char *          outName,
                                            char *          outSig,
                                            char *          outDesc)
 {
          strcpy(outName, "Flap Manipulator Example");
          strcpy(outSig, "BlueSideUpBob.Flap Manipulator Example");
          strcpy(outDesc, "Manipulating flap selector and flap pump levers raise and lower flaps.");
 
 // CREATE DATAREFS, FIND DATAREFS FOR FLAP LEVER
 
 FlapPumpPositionDataRef = XPLMRegisterDataAccessor(
 
     "BSUB/Aircraft/FlapPumpPosition",
     xplmType_Float,          // The types we support 
     1,                       // Writable 
     NULL, NULL,              // Integer accessors  
     GetFlapPumpPositionDRCB, SetFlapPumpPositionDRCB,     // Float accessors 
     NULL, NULL,              // Doubles accessors 
     NULL, NULL,              // Int array accessors 
     NULL, NULL,              // Float array accessors 
     NULL, NULL,              // Raw data accessors 
     NULL, NULL);             // Refcons not used 
 
 FlapSelectorPositionDataRef = XPLMRegisterDataAccessor(
 
     "BSUB/Aircraft/FlapSelectorPosition",
     xplmType_Float,
     1,
     NULL, NULL,
     GetFlapSelectorPositionDRCB, SetFlapSelectorPositionDRCB,
     NULL, NULL,
     NULL, NULL,
     NULL, NULL,
     NULL, NULL,
     NULL, NULL);
 
 FlapPumpPositionDataRef = XPLMFindDataRef ("BSUB/Aircraft/FlapPumpPosition");
 FlapSelectorPositionDataRef = XPLMFindDataRef ("BSUB/Aircraft/FlapSelectorPosition");
 FlapRatioDataRef = XPLMFindDataRef("sim/cockpit2/controls/flap_ratio");
 
 XPLMSetDataf(FlapPumpPositionDataRef, 0);
 XPLMSetDataf(FlapSelectorPositionDataRef, 0);
 
 XPLMRegisterFlightLoopCallback(FlapPumpPositionFLCB, 0.0, NULL);
 XPLMSetFlightLoopCallbackInterval(FlapPumpPositionFLCB, 0.01, 1, NULL);	
 
 return 1;	
 }
 
 
 PLUGIN_API void	XPluginStop(void)
 {	
     XPLMUnregisterDataAccessor(FlapPumpPositionDataRef);
     XPLMUnregisterDataAccessor(FlapSelectorPositionDataRef);
     XPLMUnregisterFlightLoopCallback(FlapPumpPositionFLCB, NULL);				
 }
 
 
 PLUGIN_API int XPluginEnable(void)
 {
     return 1;
 }
 
 
 PLUGIN_API void XPluginDisable(void)
 {
 
 }
 
 
 
 PLUGIN_API void XPluginReceiveMessage(
                 XPLMPluginID	inFromWho,
                 long			inMessage,
                 void *			inParam)
 {
 }
 
 
 
 float	GetFlapPumpPositionDRCB(void* inRefcon)
 {
     return FlapPumpPosition;
 }
 
 
 void	SetFlapPumpPositionDRCB(void* inRefcon, float inValue)
 {
     FlapPumpPosition = inValue;
 }
 
 
 float	GetFlapSelectorPositionDRCB(void* inRefcon)
 {
     return FlapSelectorPosition;
 }
 
 
 void	SetFlapSelectorPositionDRCB(void* inRefcon, float inValue)
 {
     FlapSelectorPosition = inValue;
 }
 
 
 float  FlapPumpPositionFLCB(
                              float                inElapsedSinceLastCall,    
                              float                inElapsedTimeSinceLastFlightLoop,    
                              int                  inCounter,    
                              void *               inRefcon)
 {	
     float CurrentPumpPosition;
     static float FlapPumpLastPosition = 0; 
     float DeltaPumpPosition; 
     static float FlapDeflection = 0;
     int FlapSelectorDirection;
 
     CurrentPumpPosition = XPLMGetDataf(FlapPumpPositionDataRef);           // Where is handle now? 
     DeltaPumpPosition = CurrentPumpPosition - FlapPumpLastPosition;        // Has handle moved? 
     if (DeltaPumpPosition == 0) {return 0.1;}                              // No.  Check again later.  
 
     FlapPumpLastPosition = CurrentPumpPosition;                            //  SetUp for next cycle.  
 
     if (DeltaPumpPosition < 0) {DeltaPumpPosition = - DeltaPumpPosition;}  // Allows pumping on push and pull strokes.
 
     FlapSelectorPosition = XPLMGetDataf(FlapSelectorPositionDataRef);      // Where is the flap selector handle now? 
     if(FlapSelectorPosition > 0.9) {FlapSelectorDirection = 1;}            // If flap selector is down lower flaps.  
     if(FlapSelectorPosition < 0.1) {FlapSelectorDirection = 0;}            // If flap selector is up raise flaps.
 
     if(FlapSelectorDirection == 1)                                         // Move flaps down 1/10 of flap lever amount
     {
          FlapDeflection = XPLMGetDataf(FlapRatioDataRef) + DeltaPumpPosition * 0.1;
          if (FlapDeflection > 1){FlapDeflection = 1;}                      // Limit flap ratio between 0 and 1.  
          XPLMSetDataf(FlapRatioDataRef, FlapDeflection);                   // Set flaps a proportional amount. 
     } 
 
     if(FlapSelectorDirection == 0)                                         //  Move flaps up
     {
          FlapDeflection = XPLMGetDataf(FlapRatioDataRef) - DeltaPumpPosition * 0.1;	
          if (FlapDeflection < 0){FlapDeflection = 0;}
          XPLMSetDataf(FlapRatioDataRef, FlapDeflection);
     }
 
 return 0.1;
 }

One comment on “Custom Manipulator Controlling X-Plane

  1. Visual Studio 2019
    First writing a plugin of any kind. Got to the last step and had the DataAccess, plugin, and processing header files included, and have their paths in the included directory for my main.cpp file, and i also added them to the dll project as a whole.
    Despite that ( the compiler actively recognizes the methods and everything else from the header files) when building,
    I get this error:
    Error LNK2019 unresolved external symbol __imp__XPLMFindDataRef referenced in function _XPluginStart
    Severity Code Description Project File Line Suppression State
    Error LNK2019 unresolved external symbol __imp__XPLMGetDataf referenced in function (void function to print values i accesed)

Leave a Reply

Your email address will not be published. Required fields are marked *

Please do not report bugs in the blog comments.
Only bugs reported via the X-Plane Bug Reporter are tracked.