Jump to content
The simFlight Network Forums

PMDG NGX SDK


Recommended Posts

Some ipc calls in Lua threads are explicitly subjected, in FSUIPC, to a "sleep" of 0 or 1 millisecond. This is in order to make sure other threads, and FS's own main thread, gets enough time. In fact the vast majority of the time needs to be spent in the FS executing threads.

I'm not sure why you are using ipc.set, which stores values in another (permanent) Lua threads's stack so that they can be retrieved by other threads using ipc.get, but obviously there's a process switch involved each time you do that.

Alternatively I would assume that if you are updating FSUIPC offsets from your DLL you'd be doing that directly via the FSUIPC DLL module interface, not via Lua programmed code.

There is really no need for FSUIPC to provide Lua plug-ins with ultra-fast execution speeds. The application here is merely the updating of displays or whatever with read-ots from the NGX. FSUIPC + Lua can easily meet the needs of displays at any rate needed smooth to the eye. The prime aim of FSUIPC in these matters is the provision of useful plug-in facilities which don't detract from or impinge upon the performance of FS in any noticeable, or even, hopefully, measurable way.

Regards

Pete

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

Link to comment
Share on other sites

  • Replies 157
  • Created
  • Last Reply

Top Posters In This Topic

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

That was only a reference back to the alternative idea I suggested, that of providing values to Lua plug-ins (or anything else for that matter) by posting them in offsets, rather than the original idea you had of executing a receiving Lua program.

I wouldn't think too much on that side of things though. If we can get a reasonable understanding on the EULA with PMDG then I'm sure Nico and/or I will sort the offset method out fine. We need PMDG to recognise that utility programs providing transparency for the data made available via their SDK do not in any way constitute "End Use" and are therefore not subject to the EULA. As Nico has pointed out over in the MyCockpits thread, one clause in particular is worrying in that regard.

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.

Yes, that would be the sort of application I would envisage.

Regards

Pete

Link to comment
Share on other sites

That was only a reference back to the alternative idea I suggested, that of providing values to Lua plug-ins (or anything else for that matter) by posting them in offsets, rather than the original idea you had of executing a receiving Lua program.

I wouldn't think too much on that side of things though. If we can get a reasonable understanding on the EULA with PMDG then I'm sure Nico and/or I will sort the offset method out fine. We need PMDG to recognise that utility programs providing transparency for the data made available via their SDK do not in any way constitute "End Use" and are therefore not subject to the EULA. As Nico has pointed out over in the MyCockpits thread, one clause in particular is worrying in that regard.

Yes, that would be the sort of application I would envisage.

Regards

Pete

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.

Link to comment
Share on other sites

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.

Hi,

Here is an example of how to use events to detect offsets changes, both on bit level and whole words. Keep in mind that I'm not a programmer, so it maybe can be done better.

rgs

Roar

-- PMDG 737 NGX LUA code for Opencockpits MCP to be used in FSUIPC

-- File: NGXMCP_202

-- December 2011

-- Roar Kristensen

--***************************************************************************************

-- ** System initial values set **

--***************************************************************************************

-- ** MCP initial values **

hdg_mode = 1

atarm = -1

crsl = 500

crsr = 500

spd = -1

hdg = -1

alt = -1

vsw = -1

MCP_N1 = -1

MCP_Speed = -1

MCP_LvlChg = -1

MCP_VNav = -1

MCP_LNav = -1

MCP_HdgSel = -1

MCP_AltHold = -1

MCP_CMDA = -1

MCP_CMDB = -1

MCP_CWSA = -1

MCP_CWSB = -1

MCP_VORLock = -1

MCP_App = -1

MCP_VS = -1

ipc.writeUB("66E8", 0)

ipc.writeUB("66E9", 0)

ipc.writeUB("66EA", 0)

ipc.writeUB("66EB", 0)

ipc.writeUB("66EC", 0)

ipc.writeUB("66ED", 0)

if ipc.readUB("66E4") == 1 and ipc.readLvar('ngx_switch_378_a') == 100 then

ipc.control(70010, 536870912)

ipc.control(70010, 131072)

else

if ipc.readUB("66E4") == 0 and ipc.readLvar('ngx_switch_378_a') == 0 then

ipc.control(70010, 536870912)

ipc.control(70010, 131072)

end

end

if ipc.readUB("66E5") == 1 and ipc.readLvar('ngx_switch_380_a') == 100 then

ipc.control(70012, 536870912)

ipc.control(70012, 131072)

else

if ipc.readUB("66E5") == 0 and ipc.readLvar('ngx_switch_380_a') == 0 then

ipc.control(70012, 536870912)

ipc.control(70012, 131072)

end

end

if ipc.readUB("66E6") == 0 and ipc.readLvar('ngx_switch_406_a') == 100 then

ipc.control(70038, 536870912)

ipc.control(70038, 131072)

else

if ipc.readUB("66E6") == 1 and ipc.readLvar('ngx_switch_406_a') == 0 then

ipc.control(70038, 536870912)

ipc.control(70038, 131072)

end

end

if ipc.readUB("66E7") == 1 and ipc.readLvar('ngx_switch_407_a') == 100 then

ipc.control(70039, 536870912)

ipc.control(70039, 131072)

else

if ipc.readUB("66E7") == 0 and ipc.readLvar('ngx_switch_407_a') == 0 then

ipc.control(70039, 536870912)

ipc.control(70039, 131072)

end

end

if crsl ~= ipc.readLvar("L:ngx_CRSwindowL") then

crsl = ipc.readLvar("L:ngx_CRSwindowL")

ipc.writeUW("66C0", crsl)

end

if spd ~= ipc.readLvar("L:ngx_SPDwindow") then

spd = ipc.readLvar("L:ngx_SPDwindow")

ipc.writeUW("66C2", spd)

end

if hdg ~= ipc.readLvar("L:ngx_HDGwindow") then

hdg = ipc.readLvar("L:ngx_HDGwindow")

ipc.writeUW("66C4", hdg)

end

if alt ~= ipc.readLvar("L:ngx_ALTwindow") then

alt = ipc.readLvar("L:ngx_ALTwindow")

ipc.writeUW("66C6", ipc.readLvar("L:ngx_ALTwindow") / 100)

end

--if ipc.readLvar("L:ngx_MCP_VS") == 1 then

if vsw ~= ipc.readLvar("L:ngx_VSwindow") then

vsw = -20000

ipc.writeSW("66D0", -20000)

end

if crsr ~= ipc.readLvar("L:ngx_CRSwindowR") then

crsr = ipc.readLvar("L:ngx_CRSwindowR")

ipc.writeUW("66CA", crsr)

end

--***************************************************************************************

-- ** Procedures for reading MCP windows and sending to SIOC via FSUIPC offsets****

--***************************************************************************************

function CRSL_show ()

crsl = ipc.readLvar("L:ngx_CRSwindowL")

ipc.writeUW("66C0", crsl)

end

function SPD_show ()

spd = ipc.readLvar("L:ngx_SPDwindow")

if spd > 1 then

ipc.writeUW("66C2", spd)

else

spd = spd *100

ipc.writeUW("66C2", spd)

end

end

function HDG_show ()

hdg = ipc.readLvar("L:ngx_HDGwindow")

ipc.writeUW("66C4", hdg)

end

function ALT_show ()

alt = ipc.readLvar("L:ngx_ALTwindow")

ipc.writeUW("66C6", alt / 100)

end

function VS_show ()

vsw = ipc.readLvar("L:ngx_VSwindow")

ipc.writeSW("66C8", vsw)

end

function CRSR_show ()

crsr = ipc.readLvar("L:ngx_CRSwindowR")

ipc.writeUW("66CA", crsr)

end

--***************************************************************************************

-- ** Procedures for finding changes in MCP windows and MCP function LEDs****

--***************************************************************************************

function run_update (time)

if crsl ~= ipc.readLvar("L:ngx_CRSwindowL") then

CRSL_show ()

end

if crsr ~= ipc.readLvar("L:ngx_CRSwindowR") then

CRSR_show ()

end

if spd ~= ipc.readLvar("L:ngx_SPDwindow") then

SPD_show ()

end

if hdg ~= ipc.readLvar("L:ngx_HDGwindow") then

HDG_show ()

end

if alt ~= ipc.readLvar("L:ngx_ALTwindow") then

ALT_show ()

end

if vsw ~= ipc.readLvar("L:ngx_VSwindow") then

VS_show ()

end

if ipc.readLvar("L:ngx_MCP_ATArm") ~= atarm then

atarm = ipc.readLvar("L:ngx_MCP_ATArm")

ipc.writeUB("66F0", atarm)

end

if ipc.readLvar("L:ngx_MCP_N1") ~= MCP_N1 then

MCP_N1 = ipc.readLvar("L:ngx_MCP_N1")

ipc.writeUB("66F1", MCP_N1)

end

if ipc.readLvar("L:ngx_MCP_SPEED") ~= MCP_Speed then

MCP_Speed = ipc.readLvar("L:ngx_MCP_SPEED")

ipc.writeUB("66F2", MCP_Speed)

end

if ipc.readLvar("L:ngx_MCP_VNav") ~= MCP_VNav then

MCP_VNav = ipc.readLvar("L:ngx_MCP_VNav")

ipc.writeUB("66F3", MCP_VNav)

end

if ipc.readLvar("L:ngx_MCP_LvlChg") ~= MCP_LvlChg then

MCP_LvlChg = ipc.readLvar("L:ngx_MCP_LvlChg")

ipc.writeUB("66F4", MCP_LvlChg)

end

if ipc.readLvar("L:ngx_MCP_HdgSel") ~= MCP_HdgSel then

MCP_HdgSel = ipc.readLvar("L:ngx_MCP_HdgSel")

ipc.writeUB("66F5", MCP_HdgSel)

end

if ipc.readLvar("L:ngx_MCP_LNav") ~= MCP_LNav then

MCP_LNav = ipc.readLvar("L:ngx_MCP_LNav")

ipc.writeUB("66F6", MCP_LNav)

end

if ipc.readLvar("L:ngx_MCP_VORLock") ~= MCP_VORLock then

MCP_VORLock = ipc.readLvar("L:ngx_MCP_VORLock")

ipc.writeUB("66F7", MCP_VORLock)

end

if ipc.readLvar("L:ngx_MCP_App") ~= MCP_App then

MCP_App = ipc.readLvar("L:ngx_MCP_App")

ipc.writeUB("66F8", MCP_App)

end

if ipc.readLvar("L:ngx_MCP_AltHold") ~= MCP_AltHold then

MCP_AltHold = ipc.readLvar("L:ngx_MCP_AltHold")

ipc.writeUB("66F9", MCP_AltHold)

end

if ipc.readLvar("L:ngx_MCP_VS") ~= MCP_VS then

MCP_VS = ipc.readLvar("L:ngx_MCP_VS")

ipc.writeUB("66FA", MCP_VS)

end

if MCP_CMDA ~= ipc.readLvar("L:ngx_MCP_CMDA") then

MCP_CMDA = ipc.readLvar("L:ngx_MCP_CMDA")

ipc.writeUB("66FB", MCP_CMDA)

end

if MCP_CWSA ~= ipc.readLvar("L:ngx_MCP_CWSA") then

MCP_CWSA = ipc.readLvar("L:ngx_MCP_CWSA")

ipc.writeUB("66FC", MCP_CWSA)

end

if MCP_CMDB ~= ipc.readLvar("L:ngx_MCP_CMDB") then

MCP_CMDB = ipc.readLvar("L:ngx_MCP_CMDB")

ipc.writeUB("66FD", MCP_CMDB)

end

if MCP_CWSB ~= ipc.readLvar("L:ngx_MCP_CWSB") then

MCP_CWSB = ipc.readLvar("L:ngx_MCP_CWSB")

ipc.writeUB("66FE", MCP_CWSB)

end

end

--***************************************************************************************

-- ** MCP switches *******

--***************************************************************************************

function MCP_FD1(off,val)

if ipc.readUB("66EF") == 7 then

if val == 1 and ipc.readLvar('ngx_switch_378_a') == 100 then

ipc.control(70010, 536870912)

ipc.control(70010, 131072)

else

if val == 0 and ipc.readLvar('ngx_switch_378_a') == 0 then

ipc.control(70010, 536870912)

ipc.control(70010, 131072)

end

end

end

end

function MCP_ATARM(off,val)

if ipc.readUB("66EF") == 7 then

if val == 1 and ipc.readLvar('ngx_switch_380_a') == 100 then

ipc.control(70012, 536870912)

ipc.control(70012, 131072)

else

if val == 0 and ipc.readLvar('ngx_switch_380_a') == 0 then

ipc.control(70012, 536870912)

ipc.control(70012, 131072)

end

end

end

end

function MCP_DISENGAGE(off,val)

if ipc.readUB("66EF") == 7 then

if val == 0 and ipc.readLvar('ngx_switch_406_a') == 100 then

ipc.control(70038, 536870912)

ipc.control(70038, 131072)

else

if val == 1 and ipc.readLvar('ngx_switch_406_a') == 0 then

ipc.control(70038, 536870912)

ipc.control(70038, 131072)

end

end

end

end

function MCP_FD2(off,val)

if ipc.readUB("66EF") == 7 then

if val == 1 and ipc.readLvar('ngx_switch_407_a') == 100 then

ipc.control(70039, 536870912)

ipc.control(70039, 131072)

else

if val == 0 and ipc.readLvar('ngx_switch_407_a') == 0 then

ipc.control(70039, 536870912)

ipc.control(70039, 131072)

end

end

end

end

function MCP1(off, val)

if logic.And(val, 0x0010) ~= 0 then

N1 ()

elseif logic.And(val, 0x0020) ~= 0 then

SPEED ()

elseif logic.And(val, 0x0040) ~= 0 then

CO ()

elseif logic.And(val, 0x0080) ~= 0 then

SPD_INTV ()

elseif logic.And(val, 0x0100) ~= 0 then

VNAV ()

elseif logic.And(val, 0x0200) ~= 0 then

LVLCHG ()

elseif logic.And(val, 0x0400) ~= 0 then

HDGSEL ()

elseif logic.And(val, 0x0800) ~= 0 then

HDG_BANK ()

elseif logic.And(val, 0x1000) ~= 0 then

LNAV ()

elseif logic.And(val, 0x2000) ~= 0 then

VORLOC ()

elseif logic.And(val, 0x4000) ~= 0 then

APP ()

elseif logic.And(val, 0x8000) ~= 0 then

ALT_INTV ()

end

end

function MCP2(off, val)

if logic.And(val, 0x0001) ~= 0 then

ALTHLD ()

elseif logic.And(val, 0x0002) ~= 0 then

VS ()

elseif logic.And(val, 0x0004) ~= 0 then

CMDA ()

elseif logic.And(val, 0x0008) ~= 0 then

CWSA ()

elseif logic.And(val, 0x0010) ~= 0 then

CMDB ()

elseif logic.And(val, 0x0020) ~= 0 then

CWSB ()

end

end

--***************************************************************************************

-- ** MCP Dials ********

--***************************************************************************************

function CRSL_chg (off,val)

if val == 255 then

ipc.sleep(0)

else if val > 0 then

local i

for i = 1, val do

ipc.control(70008, 16384)

ipc.sleep (5)

end

ipc.writeUB("66E8", 255)

CRSL_show ()

else if val < 0 then

val = val* -1

local i

for i = 1, val do

ipc.control(70008, 8192)

ipc.sleep (5)

end

ipc.writeUB("66E8", 255)

CRSL_show ()

else if val == 0 then

ipc.writeUB("66E8", 0)

end

end

end

end

end

function SPD_chg (off,val)

if val == 255 then

ipc.sleep(0)

else if val > 0 then

local i

for i = 1, val do

ipc.control(70016, 16384)

ipc.sleep (5)

end

ipc.writeUB("66E9", 255)

SPD_show ()

else if val < 0 then

val = val* -1

local i

for i = 1, val do

ipc.control(70016, 8192)

ipc.sleep (5)

end

ipc.writeUB("66E9", 255)

SPD_show ()

else if val == 0 then

ipc.writeUB("66E9", 0)

end

end

end

end

end

function HDG_chg (off,val)

if hdg_mode == 1 then

if val == 255 then

ipc.sleep(0)

else if val > 0 then

local i

for i = 1, val do

ipc.control(70022, 16384)

ipc.sleep (5)

end

ipc.writeUB("66EA", 255)

HDG_show ()

else if val < 0 then

val = val* -1

local i

for i = 1, val do

ipc.control(70022, 8192)

ipc.sleep (5)

end

ipc.writeUB("66EA", 255)

HDG_show ()

else if val == 0 then

ipc.writeUB("66EA", 0)

end

end

end

end

else

BANK_chg (off,val)

end

end

function BANK_chg (off,val)

if val == 255 then

ipc.sleep(0)

else if val > 0 then

local i

for i = 1, val do

ipc.control(70021, -2147483648)

ipc.control(70021, 524288)

ipc.sleep (5)

end

ipc.writeUB("66EA", 255)

else if val < 0 then

val = val* -1

local i

for i = 1, val do

ipc.control(70021, 536870912)

ipc.control(70021, 131072)

ipc.sleep (5)

end

ipc.writeUB("66EA", 255)

else if val == 0 then

ipc.writeUB("66EA", 0)

end

end

end

end

end

function ALT_chg (off,val)

if val == 255 then

ipc.sleep(0)

else if val > 0 then

local i

for i = 1, val do

ipc.control(70032, 16384)

ipc.sleep (5)

end

ipc.writeUB("66EB", 255)

ALT_show ()

else if val < 0 then

val = val* -1

local i

for i = 1, val do

ipc.control(70032, 8192)

ipc.sleep (5)

end

ipc.writeUB("66EB", 255)

ALT_show ()

else if val == 0 then

ipc.writeUB("66EB", 0)

end

end

end

end

end

function VS_chg (off,val)

if val == 255 then

ipc.sleep(0)

else if val > 0 then

local i

for i = 1, val do

ipc.control(70033, 8192)

ipc.sleep (5)

end

ipc.writeUB("66EC", 255)

VS_show ()

else if val < 0 then

val = val* -1

local i

for i = 1, val do

ipc.control(70033, 16384)

ipc.sleep (5)

end

ipc.writeUB("66EC", 255)

VS_show ()

else if val == 0 then

ipc.writeUB("66EC", 0)

end

end

end

end

end

function CRSR_chg (off,val)

if val == 255 then

ipc.sleep(0)

else if val > 0 then

local i

for i = 1, val do

ipc.control(70041, 16384)

ipc.sleep (5)

end

ipc.writeUB("66ED", 255)

CRSR_show ()

else if val < 0 then

val = val* -1

local i

for i = 1, val do

ipc.control(70041, 8192)

ipc.sleep (5)

end

ipc.writeUB("66ED", 255)

CRSR_show ()

else if val == 0 then

ipc.writeUB("66ED", 0)

end

end

end

end

end

--***************************************************************************************

-- ** MCP buttons **************

--***************************************************************************************

function N1 ()

ipc.control(70013, 536870912)

ipc.control(70013, 131072)

end

function SPEED ()

if ipc.readLvar("L:ngx_MCP_VNav") == 1 then -- go to SPD_INTV instead

ipc.control(70019, 536870912)

ipc.control(70019, 131072)

else

ipc.control(70014, 536870912)

ipc.control(70014, 131072)

end

end

function CO ()

ipc.control(70015, 536870912)

ipc.control(70015, 131072)

end

function SPD_INTV ()

ipc.control(70019, 536870912)

ipc.control(70019, 131072)

end

function ALT_INTV ()

ipc.control(70517, 536870912)

ipc.control(70517, 131072)

end

function HDG_BANK ()

-- toggling HDG / BANK (1/2)

-- HDG = 1, BANK = 2

hdg_mode = 3 - hdg_mode

end

function VNAV ()

ipc.control(70018, 536870912)

ipc.control(70018, 131072)

end

function LVLCHG ()

ipc.control(70023, 536870912)

ipc.control(70023, 131072)

end

function HDGSEL ()

ipc.control(70024, 536870912)

ipc.control(70024, 131072)

end

function LNAV ()

ipc.control(70029, 536870912)

ipc.control(70029, 131072)

end

function VORLOC ()

ipc.control(70028, 536870912)

ipc.control(70028, 131072)

end

function APP ()

ipc.control(70025, 536870912)

ipc.control(70025, 131072)

end

function ALTHLD ()

if ipc.readLvar("L:ngx_MCP_VNav") == 1 then -- go to ALT_INTV instead

ipc.control(70517, 536870912)

ipc.control(70517, 131072)

else

ipc.control(70026, 536870912)

ipc.control(70026, 131072)

end

end

function VS ()

ipc.control(70027, 536870912)

ipc.control(70027, 131072)

end

function CMDA ()

ipc.control(70034, 536870912)

ipc.control(70034, 131072)

end

function CMDB ()

ipc.control(70035, 536870912)

ipc.control(70035, 131072)

end

function CWSA ()

ipc.control(70036, 536870912)

ipc.control(70036, 131072)

end

function CWSB ()

ipc.control(70037, 536870912)

ipc.control(70037, 131072)

end

--***************************************************************************************

-- ** Routines to detect MCP buttons and dials changes **

--***************************************************************************************

event.offset(0x66E4, "UB", "MCP_FD1")

event.offset(0x66E5, "UB", "MCP_ATARM")

event.offset(0x66E6, "UB", "MCP_DISENGAGE")

event.offset(0x66E7, "UB", "MCP_FD2")

event.offset(0x66E0, "UW", "MCP1")

event.offset(0x66E2, "UW", "MCP2")

event.intercept(0x66E8, "SB", "CRSL_chg")

event.intercept(0x66E9, "SB", "SPD_chg")

event.intercept(0x66EA, "SB", "HDG_chg")

event.intercept(0x66EB, "SB", "ALT_chg")

event.intercept(0x66EC, "SB", "VS_chg")

event.intercept(0x66ED, "SB", "CRSR_chg")

--***************************************************************************************

-- ** Timer for MCP diplays and LED update

--***************************************************************************************

event.timer(100, "run_update")

Link to comment
Share on other sites

Hi,

Here is an example of how to use events to detect offsets changes, both on bit level and whole words. Keep in mind that I'm not a programmer, so it maybe can be done better.

rgs

Roar

Thanks Roar. Do the rest of the OC devices work in the same way, listening to certain offsets?

Link to comment
Share on other sites

Thanks Roar. Do the rest of the OC devices work in the same way, listening to certain offsets?

Hi,

The way I have implemented this, yes. The OP sioc software is a event driven program. It does only execute code when a variable change value. Either a variable connected to a specific IOCARD input or a variable linked to a offset.

rgs

Link to comment
Share on other sites

Hi,

The way I have implemented this, yes. The OP sioc software is a event driven program. It does only execute code when a variable change value. Either a variable connected to a specific IOCARD input or a variable linked to a offset.

rgs

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)

Link to comment
Share on other sites

I'm doing something I think should address the offset "issues", being those

1.- I had no way to set offsets in the dll

2.- setting offsets from lua via ipc lib is too slow. 500 iterations take some 20 seconds, so this module would be colmpletely useless for devices that listen to offsets that are being updated from Lua

So I implemented a way to register items to be stored in any offset.

An example:


ngxSDK2Lua.registerOffset("IRS_DisplaySelector", 0x6CCC, "writeUB")
[/CODE]

this would instruct the dll to store any new data in the item "IRS_SysDisplay_R" to the offset 0x6CCC as an unsigned byte. Or..

[CODE]
ngxSDK2Lua.registerOffset("IRS_SysDisplay_R", 0x6DCC, "setbitsUB", 1) -- last param is the mask for setbitsUB
[/CODE]

to assign the IRS_SysDisplay_R boolean to the first bit (least significant) of the offset 0x6DCC

I'll be using a hash map (I think it has direct access to the members) to speed things up

[CODE]
static std::hash_map<std::string, OffsetCall> offsetMappings;
[/CODE]

to retrieve a struct for each mapped item

[CODE]
struct OffsetCall
{
void (*offsetFunction)(DWORD dwOffset, void* valueOrMask);
DWORD dwOffset;
DWORD mask;
};
[/CODE]

then call the offsetFunction with the new value of the item (or the mask for functions like setbitsXX or clearbitsXX)

should be pretty fast me thinks, and it's 100% configurable

Link to comment
Share on other sites

Actually I did understand WHAT you were doing, just not WHY. It just seems rather complicated. Or maybe it's just me?

Yes, that's what I find so complicated. How is this going to work for a user who wants to populate all his hardware displays with indicators and values from the NGX data?

If you wanted to do it that way why not simply use a mechanism like my "event" system. Let the Lua program which is doing the "requiring" call an event function in your C DLL which provides it with the name of the function to be called when a specified value changes. You'd need to build a list of those. Then, at the end of that Lua program, instead of exiting back to FSUIPC, it would need call an "execute" function in your DLL which then processes the dispatches, in a loop as now.

This way you don't need to execute a separate Lua plug-in, it is nice and tidy all in one Lua and one DLL, both running in the one thread. The only trouble is that because the thread never exits back to FSUIPC, that same Lua can't use the FSUIPC event system. (But that applies to your current method too).

The other way is the way I proposed before, which is having a separate thread in the DLL which is maintaining the data copy with functions which supply values on request. The problem with that is how to detect that the Lua plug-in has terminated so that the separate thread can be terminated tidily.

I'm starting to wonder if it wouldn't be much tidier to forget the Lua way of doing it altogether, and just have an EXE program which gets the NGX data and posts them to assigned FSUIPC offsets, which can then be read by any Lua plug-ins, and other programs, even on a WideFS client. I would actually consider building this into FSUIPC (it is easy as it already has a working SimConnect interface), but I don't like some sections of PMDG's EULA. I'd need PMDG's blessing first. Maybe I should write to Mr. Randazzo.

Regards

Pete

Hi Pete,

I don't know what your plans are about doing something for the PMDG NGX in your FSUIPC4 now that the SDK is available.

As Nico don't wanna do a "lekseecon" for the PMDG NGX I have started to make my own " NGXCon" IOCP client to be used for the OpencCockpits SIOC environement.

But, as I am not a "prof" programmer this can take some time before I'm ready.

So to my question:

Are you going to do what you said:

"" I'm starting to wonder if it wouldn't be much tidier to forget the Lua way of doing it altogether, and just have an EXE program which gets the NGX data and posts them to assigned FSUIPC offsets, which can then be read by any Lua plug-ins, and other programs, even on a WideFS client. I would actually consider building this into FSUIPC (it is easy as it already has a working SimConnect interface),""

if so what and what is your timeframe? Then I could do the LUA scripting to get what I want and that is maybe the way to go instead of an dedicated IOCP client based on C++ ( which I need to learn better).

rgs

Link to comment
Share on other sites

I don't know what your plans are about doing something for the PMDG NGX in your FSUIPC4 now that the SDK is available.

I want to provide supporting offsets for at least a significant subset of the data available. I'm not sure if I'll do all of it, but hopefully all those entries which matter to a cockpit builder.

As Nico don't wanna do a "lekseecon" for the PMDG NGX I have started to make my own " NGXCon" IOCP client to be used for the OpencCockpits SIOC environement.

Yes, I noticed.

So to my question:

Are you going to do what you said:

I need an answer from PMDG about my questions regarding the EULA first. Like Nico, I am greatly concerned over several of the clauses, especially the one which would appear to make me responsible for how the data is used -- even though i'm only providing a window onto it and am not the "End User" but a facilitator, just as the SDK is.

I have no direct links with anyone at PMDG these days -- I used to have good relationships with Lefteris but of course he's no longer there. So all I could do is raise the question and request 'permission' through the ticket system, as it says to do in the EULA. That was Sunday morning. There's still no reply now. I've raised it on the NGX support forum too, asking someone from PMDG to email me. Again, nothing. All I can do is wait. :-(

if so what and what is your timeframe?

Once I am okay to go without fear of legal consequences it can be very quick indeed. The code for interfacing to SimConnect client Data is already implemented in FSUIPC4 in any case, as it's used for other things like the AES status and Squawkbox4 transponder modes. I would just need to work out the offset details and map the data. Maybe make some of them writeable as well, with FSUIPC operating the events, but that wouldn't be the first priority which is to get the data out.

Regards

Pete

Link to comment
Share on other sites

I think PMDG have problems with their email server as well, I have never received an email when a reply was made to a support ticket, I have always had to visit the support site again and check to see if a reply had been made, usually they have replied within 24 or so hours. Reading around the forums its seems to be a common problem, maybe there server is blacklisted for some reason.

Link to comment
Share on other sites

I think PMDG have problems with their email server as well, I have never received an email when a reply was made to a support ticket, I have always had to visit the support site again and check to see if a reply had been made, usually they have replied within 24 or so hours.

I have been visiting the support site and checking whether there's a reply yet regularly. I didn't know whether to expect an email or not. I have a short-cut taking me straight there, so I check it as often as i check my email.

Still no joy.

Regards

Pete

Link to comment
Share on other sites

I also sent a ticket asking them if they would mind checking an installer and giving it the OK. Thay was 4 days ago and still no answer either.

My module should be ready for testing in a few days. I think I'll just release it and see what happens

Link to comment
Share on other sites

I have been visiting the support site and checking whether there's a reply yet regularly. I didn't know whether to expect an email or not. I have a short-cut taking me straight there, so I check it as often as i check my email.

Still no joy.

Regards

Pete

Pete,

I guess that they have to consult their lawyers. This may take weeks ;-)

Link to comment
Share on other sites

Pete, this is almost ready, but I'm geting random crashes if I run FSUIPC_Process(&dwResult); right after writing an offset:

FSUIPC_Write(dwOffset, 1, pSrce, &dwResult);

FSUIPC_Process(&dwResult);

If I process the read/writes once after the entire dispatch loop is done, it works fine (probably a better way to go about it anyway)

Not sure how to debug this

Link to comment
Share on other sites

Pete, this is almost ready, but I'm geting random crashes if I run FSUIPC_Process(&dwResult); right after writing an offset:

Crashes in what? Your program or mine? I need more information. If in FS, the crash error code, the module and its offset.

If I process the read/writes once after the entire dispatch loop is done, it works fine (probably a better way to go about it anyway)

The whole point of a separate "Process" call to the "Read" and "Write" calls is for efficiency. The read/write calls simply add a request to a list, in your own memory.

Not sure how to debug this

Aren't you using a development system with a debugger? If should tell you exactly where and why a crash is occurring.

Regards

Pete

Link to comment
Share on other sites

I made a small dll wrapper with just 2 exported methods and an internal SimConnect_CallDispatch thread

void *GetPmdgData()

and

int RaisePMDGEvent(EPmdgEvent event, int parameter)

I use it to Marshal it into C# where I emacs-ed PMDG_NGX_SDK.h into C# structs and enums. If someone is interested I could post or upload some code here.

Link to comment
Share on other sites

I made a small dll wrapper with just 2 exported methods and an internal SimConnect_CallDispatch thread

void *GetPmdgData()

and

int RaisePMDGEvent(EPmdgEvent event, int parameter)

I use it to Marshal it into C# where I emacs-ed PMDG_NGX_SDK.h into C# structs and enums. If someone is interested I could post or upload some code here.

I'm interested if someone can make dll to interface with vb.net!

Link to comment
Share on other sites

I made a small dll wrapper with just 2 exported methods and an internal SimConnect_CallDispatch thread

void *GetPmdgData()

and

int RaisePMDGEvent(EPmdgEvent event, int parameter)

I use it to Marshal it into C# where I emacs-ed PMDG_NGX_SDK.h into C# structs and enums. If someone is interested I could post or upload some code here.

I'm interested in seeing the code. I program mostly in C# and find it too painful to go back to C++.

Link to comment
Share on other sites

I have no idea what's going on. All of a sudden I don't get any PMDG events detected in the dispatch method.

I haven't changed anything in the Simconnect initialization and RequestClientData part.

I get an event dwID 15, then a 2 and nothing else. Have commented out everything except for what's in the example provided by PMDG and still no go.

I know it's not too much info, but maybe it rings a bell... or maybe I could upload the VS project

So frustrating cause it's finished

I'm sure I'm missing something stupid somewhere

Link to comment
Share on other sites

...

So frustrating cause it's finished

I'm sure I'm missing something stupid somewhere

I've seen that a couple of times too, most often it's working again after reloading the ac, don't have a real grip on that yet. If i'll find a clue i'll post it, please do so as well.

Johan

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • 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.