Si no tienes un comando implementado en X-Plane, necesitas un custom command. Eso requiere un plugin.
Es muy sencillo de hacer, pero requiere saber C o Python.
Quiero hacer un plugin que permita hacer custom command a partir de un XML donde digas como se llama el custom command, que dataref quieres que modifique, con que valores, etc. EL objetivo es que las personas que no sepan de programación puedan crearse sun propios comandos.
Lo haré en Python para que sea multi plataforma. Pero como no conozco mucho este lenguaje y me está costando bastante encontrar documentación clara, voy lento.
Ejemplo de plugin en Python, no crea un custom command, pero igual te sirve de algo. Alguno que crea custom commands lo tengo hecho, pero en C, y su código fuente, aunque realizado por mi en su totalidad, no es decisión solo mia su publicación, de todo o parte.
"""
Curso 04 - Creacion de custom DataRefs
Written by Kha29096335 22-5-2009.
This script is released under the terms and conditions of the GNU GPL (General Public License) wich is included within the downloaded ZIP-file.
The script uses a custom DataRef 'curso04/aircraft/parts/acf_first_three_gears_down' to indicate if the first three gears of the plane are deployed (value 1) or not (value 0)
"""
# PI_curso_01.py
from XPLMPlugin import *
from XPLMProcessing import *
from XPLMDataAccess import *
from SandyBarbourUtilities import *
class PythonInterface:
def XPluginStart(self):
#Plugin registration data
self.Name = "Curso04"
self.Sig = "Carlos Esteban.python.curso04"
self.Desc = "Sets custom DataRefs example"
"""
Constants for custom DataRef registration in DatarefEditor plugin (only needed for testing purposes)
If you want to see how your custom DataRef works, you can use DatarefEditor. You must register your custom DataRef
in DatarefEditor and after this you can query DatarefEditor plugin to view the value of your custom DataRef
"""
#Value of the message to be passed to the DatarefEditor plugin to register a DataRef
self.MSG_ADD_DATAREF = 0x01000000
#We use XPLMFindPluginBySignature to get the X-Plane internal address for the DatarefEditor plugin by signature in order to send a 'register DataRef' message to him. This constant is the return value for XPLMFindPluginBySignature if does not find the given plugin
self.XPLM_NO_PLUGIN_ID = -1
#End of constants for DatarefEditor registration
#Flag for custom DataRef published in DatarefEditor - We need to publish our custom DataRef only one time, this flag is used to check if the DataRef is yet registered to avoid more than one registration at each loopback call
self.acf_first_three_gears_down_DatarefEditor_Published = False
#Internal variable creation and default value - This variable will keep the value for our custom DataRef
self.first_three_gears_down = 0
#Getting references to used datarefs
self.acf_gear_deploy_dataref = XPLMFindDataRef("sim/aircraft/parts/acf_gear_deploy")
#Main loop callback
self.SimLoopCB = self.SimLoopCallback
XPLMRegisterFlightLoopCallback(self, self.SimLoopCB, 1, 0)
return self.Name, self.Sig, self.Desc
def XPluginStop(self):
#Loopback main loop destruction
XPLMUnregisterFlightLoopCallback(self, self.SimLoopCB, 1)
pass
def XPluginEnable(self):
#Registration of the custom DataRef functions for curso04/aircraft/parts/acf_first_three_gears_down
#When our plugin is loaded, it needs register all custom DataRefs in X-Plane (one accessor for each custom DataRef)
self.fn_address = self.fn_first_three_gears_down
self.Accesor1 = XPLMRegisterDataAccessor(self, "curso04/aircraft/parts/acf_first_three_gears_down", 1, 0, self.fn_address, None, None, None, None, None, None, None, None, None, None, None, 0, 0)
return 1
def XPluginDisable(self):
#Unregistration of the custom DataRef
#When out plugin is unloaded, we need unregister all customs DataRefs because they will be unavailable
XPLMUnregisterDataAccessor(self, self.Accesor1)
pass
def SimLoopCallback(self, elapsedMe, elapsedSim, counter, refcon):
#Publication on the DatarefEditor plugin for testing purposes
#We will register our custom DataRef in DatarefEditor if it is not register yet (checking the flag)
if(not self.acf_first_three_gears_down_DatarefEditor_Published):
#We look for the DatarefEditor's internal id to send the 'register DataRef' message to him
PluginID = XPLMFindPluginBySignature("xplanesdk.examples.DataRefEditor")
#If the id for DatarefEditor is found, we send the message
if (PluginID != self.XPLM_NO_PLUGIN_ID):
XPLMSendMessageToPlugin(PluginID, self.MSG_ADD_DATAREF, "curso04/aircraft/parts/acf_first_three_gears_down")
#We set the status of the DataRef to 'published in DatarefEditor'
self.acf_first_three_gears_down_DatarefEditor_Published = True
#Sets the custom DataRef based on first tree gears status
self.acf_gear_deploy_values = []
XPLMGetDatavf(self.acf_gear_deploy_dataref, self.acf_gear_deploy_values, 0, 3)
all_down_flag = True
if(len(self.acf_gear_deploy_values) > 0):
for i in range(len(self.acf_gear_deploy_values)):
if (self.acf_gear_deploy_values[i] < 1.0):
all_down_flag = False
if(all_down_flag == True):
self.first_three_gears_down = 1
else:
self.first_three_gears_down = 0
return 1
#We need define this function because DatarefEditor sends back a message when we send a message to him
def XPluginReceiveMessage(self, inFromWho, inMessage, inParam):
pass
#Function to return the custom dataref value - The two parameters definition are needed in Python, only inRefcon is needed in C
def fn_first_three_gears_down(self, inRefcon):
return self.first_three_gears_down
Lo que si te puedo decir es que para registrar un custom command en X-Plane, primero necesitas definir la variable que alvergará el identificador interno en X-Plane del custom command, así:
XPLMCommandRef my_command = NULL;
Despues definir la función en tu plugin que será llamada al invocar el command desde X-Plane, por ejemplo:
//Este es el prototipo no la definición
int int_command_handler(XPLMCommandRef inCommand, XPLMCommandPhase inPhase, void * inRefcon);
Despues necesitas crear el custom command y que X-Plane te devuelva el identificador interno, así:
my_command = XPLMCreateCommand("<nombre commnad>", "<command description>");
Y luego tendrás que asociar el identificador interno de X-Plane para el command con tu función en el plugin, así:
XPLMRegisterCommandHandler(my_command, int_command_handler, 1, (void *) 0);
En el código de parada del plugin tendrás que desregistrar los custom commands, por ejemplo con este código:
PLUGIN_API void XPluginStop(void)
{
//Unregistration of custom Commands
XPLMUnregisterCommandHandler(my_command, int_command_handler, 0, 0);
}
Todo lo anterior, salvo el primer ejemplo en Python, está en C
En tu caso, con lo que dices que quieres hacer, yo probaría a registrar varios nombres de command -que finalmente leeras del XML- apuntando hacia la misma función. Es decir, tu en tu plugin, para cualquiera de esos custom commands la función llamada sería la misma y, dentro de ella, distinguir qué es lo que debe hacer, es decir, distinguir que DataRef está asociado al command. Esto creo que debería ser así porque para N commands necesitas tener ya definidas en tu plugin N funciones, una para cada uno, pero esas definiciones no puedes hacerlas en tiempo de ejecución, porque seria algo así como cambiar el fuente a medida que se ejecuta -aunque en Python es posible hacer algo similar, generar código desde el propio código y hacer que se ejecute-.
Dado que solo tendrías una función reaccionando a varios commands, necesitas saber desde cual de ellos ha sido llamada, igual podrías evaluar el parámetro inCommand de tu función, mira la documentación del SDK para saber si es posible por esa vía. Tendrás que tener también un vector con las asociaciones entre nombre de command y nombre de DataRef a modificar.
Te puedo adelantar, que este tipo de programación, aunque posible, reduce el rendimiento del simulador, dado que tendrás que usar con casi toda seguridad la función del SDK
XPLMFindDataRef que es bastante costosa, por lo tanto, cuando llegue el momento, te suguiero que uses otro vector para cachear los nombres de los DataRefs con los identificadores internos en X-Plane, para tener que invocar la función
XPLMFindDataRef solo una vez por cada DataRef a modificar.
No se si me he explicado.
Espero te sirva de algo de ayuda.
Un saludo.