Jump to content
The simFlight Network Forums

dazz

Members
  • Posts

    104
  • Joined

  • Last visited

Everything posted by dazz

  1. I've got an idea. I can register two functions in my dll to read and write an offset very much like ipcread & ipc.write do, but without the 1ms sleep limitation
  2. Okay. Obviously keeping the offsets up to date in the dll would mean plug&play for OC devices then (with the corresponding SIOC implementation to listen to the same offset mapping)
  3. I already got the FSUIPC_SDK up and running in my VS project, so I may consider the direct offset writing solution. Question is to define the offset space, it would be from 0x66C0 I guess
  4. Thanks Roar. Do the rest of the OC devices work in the same way, listening to certain offsets?
  5. Ok, so if I got it right you mean the solution you mentioned of storing the data in predefined FSUIPC offsets right at the dll / C++, so that Lua pluggins or anyone can listen via events or read them or whatever. I guess I need to take a look at the FSUIPC_SDK docs. Anyway, I'll leave that to you guys then.
  6. I tried something that makes more sense in the Lua implementation for one of the items, which is writing to my VRInsight device display using the com library. That looks to have no sleeps, it completes almost instantly.
  7. Pete, I was calling ipc.log/ ipc.set, just to test the output of the function call, and the cost in time of the process. It has nothing to do with any implementation decision. Thanks for the clarification on the 1ms thing. The idea was always to transfer / integrate the NGX SDK functionality to the Lua layer in FSUIPC. It's not a client on itself, just an interface. If Lua (or some of the Lua libraries implemented in FSUIPC) has this little performance limitation I still don't think it will be a major issue since like Nico said, only controls that make sense to poll are those belonging to annunciators, lights, displays... and the client can split them in groups that run on their own threads anyway. If something ends ups calling some ipc or any other library with sleeps, it means that it won't be taking up too much CPU time and you can have plenty of those running with no perf issues. I can always mention that in the documentation. One thing I'm not sure about is what you mean by "updating FSUIPC offsets from your DLL directly via the FSUIPC DLL module interface" Would you please mind clarifiying? One of the strong points that I thought my solution had is the flexibility to avoid using offsets, that are a limited to a certain number
  8. Thanks for the explanation Nico. Obviously the modular design in your original Lekseecon for the LDS767 has paid off in the end. Wish I had the knowledge to use classes/objects in C++ but I don't. I don't own the LDS767 but will be very interested in trying your Lekseecon for the NGX if you release it someday. I asked PMDG about the EULA but haven't received an answer yet
  9. No, no. It's not taking more than a couple ms right now, but I only got like 15 items implemented of a total of maybe 450 - 500. I was worried that once it's finished, sending 500 calls to Lua may last too long, but I don't think that many items will change in the same pass. Did a test with 100 calls and only took 70ms. Obviously if someone wants to constantly poll the data, it's on them to program that efficiently, having maybe 3 or 4 threads each taking care of 100 -150 items I just tried calling one of the functions 500 times, simulating a poll pass and the calls from Lua to the registered C functions took 0 (zero) miliseconds. It's only when I print something with ipc.log or store the data with ipc.set that it takes about 500ms. Interestingly enough it takes exactly 500ms, 1ms for each ipc call. If I add a second ipc call, then it's 1s. But the time it takes to execute the static functions calls is negligible
  10. Of course, thanks for another great little tip
  11. Damn, I was copying the size of the pointer memcpy (pDBAK, pS, sizeof(pS)); , not it's content memcpy (pDBAK, pS, sizeof(*pS));
  12. Yeah, makes no sense. I need to see what's going on because I have an array "IRS_annunALIGN[2]" the first position [0] of the array gets updated in the memcpy, the second [1] doesn't
  13. By the way, there seems to be a problem with memcpy. The members are not cloned, so the arrays in the struct are not copied (at least that's what seems to me)
  14. That's what I'm doing now. if an exception is risen upon the call to the Lua function (not implemented, so not requested), that item is not checked for modifications anymore. The new status is still stored in case it needs to be retrieved from Lua by calling to the corresponding registered C++ function. if (bLuaEventCallbacks) { if (bIRS_DisplaySelector && pS->IRS_DisplaySelector != pDBAK->IRS_DisplaySelector) { try { LuaCall<NullT, unsigned char>(LuaGlobal, "IRS_DisplaySelector").call(pDBAK->IRS_DisplaySelector); } catch (...) { bIRS_DisplaySelector = false; } } } memcpy (pDBAK, pS, sizeof(pS)); [/CODE] I will give the option to ignore the first part altogether (passing the bLuaEventCallbacks param to false) and just store the data, with no Lua "callbacks", and just get the data on demand from a set of registered C++ functions (very much like the original idea)
  15. Well, right now I'm checking every single member of the struct for modifications. If something is modified and there's a Lua function implemented, I call the Lua function. I can always use an initialization param to set the plugin to "read-only" so it doesn't call anything and just stores the struct like you said, and then use registered C++ functions to retrieve the data from Lua on-demand. I know you suggested packing all the modifications and sending them in a single call to Lua, or using a C++ event (not sure how to do this, will need to investigate)
  16. Ok, I'll try that. That and the SimConnect help for SimConnect_Open should be enough to get it working. On a side note, I've done several "optimizations" or more precisely, corrected some retarded aspects of my implementation, like opening the Lua file everytime the dispatcher gets called. Also I'm checking if there's a "callback" (I know the name is not very well suited, it should be "event-triggered" or smth like that) Lua function implemented for each item in the NGX to be executed when something in the struct changes. Using a try - catch I omit the call to the Lua function if it's not implemented. More efficient and allows the developer to implement only a subset of the functions I'm still a bit worried about what will happen when I have 400+ items implemented. With 4 of them it works fine right now, but if it takes 500ms or more to update the entire struct, I'm not sure how fluid it's going to be once it's done, or even if it might crash or something. I'll do a test with a long loop.
  17. I'm starting to realise what you meant Pete. For some stupid reason I thought I was getting events from NGX items like "FUEL PUMP: ON" when actually every time there's an event related to the NGX the entire data strct gets updated & stored. I changed the code to use a struct to store the PMDG_NGX_Data struct state instead of individual bool, char, std... and of course since I'm storing the entire struct there's no reason not to implement functions to retrieve that data on demand. I can do that with registered Lua functions, or I could store the struct in FSUIPC offsets instead of a local PMDG_NGX_Data struct. I have also googled the HWND_MESSAGE and most results are responses from you to other noobs in this environment like me in several forums haha. I think I get the idea, it's to only get calls to the dispatcher when a message aimed to the invisible window I need to create arrives, instead of any message and then filtering by the NGX data
  18. Ouch! Sorry about that Nico. I stand corrected
  19. Looks great, but that's just for SIOC - opencockpits devices, isn't it? My idea was to integrate the SDK in Lua, to access all the VRInsight, GoFlight, Linda... facilities. Actually it should work for those opencockpits devices too, for all I know they use FSUIPC. At this point I'm going to finish it no matter what, just for fun. I want to try that HWND_MESSAGE thingy, and if I can implement events in the DLL that trigger Lua scripts (is that what you meant?) then that would be nice too I have the APU EGT showing in the VRInsight display and that's sort of cool, hehe
  20. Of course if you can provide native support in FSUIPC that would be golden. If you have any problems with the EULA eventually and want me to do something different that you may find more useful you can count on me for that. Same Pete Later
  21. For a device that needs to poll the different items status, it would be necessary to store the data in Lua (ipc.set) and then implement the loop that polls the data. It just seemed like an easier solution to me to simply propagate the SDK behaviour to Lua, and then store the data there or just process it as it comes. You're probably right though. I'll think about your suggestions. Keep in mind that I'm 100% new to C++, so I may very well making some stupid decisions without even knowing Anyway, the CTD is fixed and I'm going to give it a rest for now, go have dinner with mom and dad and forget about it for a couple of hours. Pete, thank you very much for your help, seriously
  22. Already debugging. Apparently there's a null pointer in the function I'm using to make the Lua callback
  23. Let me try to explain the idea behind this and feel free to suggest any changes. 1.- In ipc.ready I will do the require "ngxSDK2Lua" [/CODE] this calls the "luaopen_ngxSDK2Lua" function and registers the function "ngxSDKInit" then I call (again in ipc.ready)... [CODE] response = ngxSDK2Lua.ngxSDKInit("C:\\Program Files (x86)\\Microsoft Games\\Microsoft Flight Simulator X\\Modules\\lua\\callback.lua") [/CODE] ...to store the path where the lua functions that implement the module are (and also initialize the SDK). Those are the Lua functions that will be called whenever the SDK detects a change. So for example, now I have the function "luaCallback" that takes the string parameter "LOW PRESS LIGHT: [ON]" when the dispatcher detects that the LEFT_AFT_FUEL_PUMP light has lit Implementing that "luaCallback" function in the "callback.lua" file to send a signal to some panel to lit up a light would be an example of how to use it. So that's what changed, since the SDK is event triggered, I thought I could call the lua part when an event is triggered, instead of having Lua query the data. The code to call those Lua functions is this (found it in the internet): [CODE] if(luaL_loadfile(LuaGlobal, luaPath) || lua_pcall(LuaGlobal, 0, 0, 0)) { // open Lua callback file throw std::string(std::string(lua_tostring(LuaGlobal, -1))); } // Lua callback function std::cout << LuaCall<std::string, std::string>(LuaGlobal, "luaCallback").call("LOW PRESS LIGHT: [ON]") << std::endl; [/CODE] Thanks for the suggestion on debugging, I'll see if I can get that to work
  24. The debugger in VS said: Unhandled exception at 0x76f415ee in fsx.exe: 0xC0000005: Access violation reading location 0x00000000. I have no idea how to debug in this environment EDIT: the callstack ends at > ntdll.dll!76f415ee()
  25. fsx.exe 10.0.61637.0 46fadb14 ngxSDK2Lua.dll 0.0.0.0 4f5b700a c0000005 000226e0 1af0 01ccfed102b9f7ef C:\Program Files (x86)\Microsoft Games\Microsoft Flight Simulator X\fsx.exe C:\Program Files (x86)\Microsoft Games\Microsoft Flight Simulator X\modules\lua\ngxSDK2Lua.dll 7871b4cb-6ac4-11e1-8c55-e556d68d0a19 [/CODE] Doesn't look to me like it has anything to do with FSUIPC. It's crashing right after calling the lua callback function. Maybe it's not returning to the dll execution? I'm thinking maybe spawning a separate thread to make the callbacks Here's my current implementation: 1.- Initialization Lua file. Registers the init function and call it with the lua callback path: [CODE] require "ngxSDK2Lua" ipc.log("In!!!!!!!!!!!!!!!!!!!!!!!!!!!") response = ngxSDK2Lua.ngxSDKInit("C:\\Program Files (x86)\\Microsoft Games\\Microsoft Flight Simulator X\\Modules\\lua\\callback.lua") ipc.log("Result ... " .. response) [/CODE] 2.- ngxSDK2Lua.cpp [CODE] // ngxSDKtoLua.cpp : Defines the exported functions for the DLL application. // #define NGX_VERSION "ngxSDK2Lua 0.1 2012-03-07" #define NGX_AUTHORS "Darío Iriberri" #include <windows.h> #include <tchar.h> #include <stdio.h> #include <strsafe.h> #include <string> #include <iostream> extern "C" { #include "lua-5.1.5\src\lua.h" #include "lua-5.1.5\src\lauxlib.h" #include "lua-5.1.5\src\lualib.h" } #include "SimConnect.h" #include "PMDG_NGX_SDK.h" #include "LuaCall.h" int quit = 0; HANDLE hSimConnect = NULL; bool AircraftRunning = false; PMDG_NGX_Control Control; bool NGX_FuelPumpLAftLight = true; bool NGX_TaxiLightSwitch = false; bool NGX_LogoLightSwitch = false; lua_State* LuaGlobal; const char* luaPath; static enum DATA_REQUEST_ID { DATA_REQUEST, CONTROL_REQUEST, AIR_PATH_REQUEST }; // This function is called when NGX data changes void ProcessNGXData (PMDG_NGX_Data *pS) { // Open Lua File if(luaL_loadfile(LuaGlobal, luaPath) || lua_pcall(LuaGlobal, 0, 0, 0)) { // open Lua callback file throw std::string(std::string(lua_tostring(LuaGlobal, -1))); } // test the data access: // get the state of an annunciator light and display it if (pS->FUEL_annunLOWPRESS_Aft[0] != NGX_FuelPumpLAftLight) { NGX_FuelPumpLAftLight = pS->FUEL_annunLOWPRESS_Aft[0]; if (NGX_FuelPumpLAftLight) { // Lua callback function std::cout << LuaCall<std::string, std::string>(LuaGlobal, "luaCallback").call("LOW PRESS LIGHT: [ON]") << std::endl; } } } void CALLBACK dispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext) { switch(pData->dwID) { case SIMCONNECT_RECV_ID_CLIENT_DATA: // Receive and process the NGX data block { SIMCONNECT_RECV_CLIENT_DATA *pObjData = (SIMCONNECT_RECV_CLIENT_DATA*)pData; switch(pObjData->dwRequestID) { case DATA_REQUEST: { PMDG_NGX_Data *pS = (PMDG_NGX_Data*)&pObjData->dwData; ProcessNGXData(pS); break; } } break; } case SIMCONNECT_RECV_ID_QUIT: { quit = 1; break; } default: printf("\nReceived:%d",pData->dwID); break; } } void initCommunication() { HRESULT hr; if (SUCCEEDED(SimConnect_Open(&hSimConnect, "PMDG NGX Test", NULL, 0, 0, 0))) { printf("\nConnected to Flight Simulator!"); // 1) Set up data connection // Associate an ID with the PMDG data area name hr = SimConnect_MapClientDataNameToID (hSimConnect, PMDG_NGX_DATA_NAME, PMDG_NGX_DATA_ID); // Define the data area structure - this is a required step hr = SimConnect_AddToClientDataDefinition (hSimConnect, PMDG_NGX_DATA_DEFINITION, 0, sizeof(PMDG_NGX_Data), 0, 0); // Sign up for notification of data change. // SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED flag asks for the data to be sent only when some of the data is changed. hr = SimConnect_RequestClientData(hSimConnect, PMDG_NGX_DATA_ID, DATA_REQUEST, PMDG_NGX_DATA_DEFINITION, SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED, 0, 0, 0); // 2) Set up control connection // First method: control data area Control.Event = 0; Control.Parameter = 0; // Associate an ID with the PMDG control area name hr = SimConnect_MapClientDataNameToID (hSimConnect, PMDG_NGX_CONTROL_NAME, PMDG_NGX_CONTROL_ID); // Define the control area structure - this is a required step hr = SimConnect_AddToClientDataDefinition (hSimConnect, PMDG_NGX_CONTROL_DEFINITION, 0, sizeof(PMDG_NGX_Control), 0, 0); // Sign up for notification of control change. hr = SimConnect_RequestClientData(hSimConnect, PMDG_NGX_CONTROL_ID, CONTROL_REQUEST, PMDG_NGX_CONTROL_DEFINITION, SIMCONNECT_CLIENT_DATA_PERIOD_ON_SET, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED, 0, 0, 0); // 3) Request current aircraft .air file path hr = SimConnect_RequestSystemState(hSimConnect, AIR_PATH_REQUEST, "AircraftLoaded"); // 5) Main loop while( quit == 0 ) { // receive and process the NGX data SimConnect_CallDispatch(hSimConnect, dispatchProc, NULL); Sleep(1); } hr = SimConnect_Close(hSimConnect); } else printf("\nUnable to connect!\n"); } //////////////////////////////// // Registering Lua functions. // //////////////////////////////// static int cpp_ngxSDKInit(lua_State *L) { luaPath = luaL_checklstring(L, 1, NULL); LuaGlobal = L; initCommunication(); std::string s(luaPath); s = "NGX SDK CLient Init OK.... Path = " + s; char* c = new char[s.length() + 1]; strcpy(c, s.c_str()); lua_pushstring(L, c); return 1; } extern "C" __declspec(dllexport) int luaopen_ngxSDK2Lua(lua_State *L){ static const luaL_Reg asd [] = { {"ngxSDKInit", cpp_ngxSDKInit}, {NULL,NULL} }; luaL_register(L,"ngxSDK2Lua", asd); return 0; } [/CODE] 3.- callback.lua. Simply prints the result string in the FSUIPC log [CODE] function luaCallback(value) ipc.log("Lua Callback: " .. value) end [/CODE]
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.