Page 1 of 1

Flight Simulator link (VB to PB), need help!

Posted: Mon Sep 13, 2010 4:48 pm
by neumanix
First I'd better explain what all this is about...

I want to be able to communicate with MS Flight Simulator through the FSUIPC dll. You can download the FSUIPC SDK here: http://www.schiratti.com/files/dowson/F ... amp=010309

There are examples for C, ASM, VB etc. included, but unfortunately nothing for PB. If you're not familiar with MS Flight Simulator, read the FSUIPC for Programmers.pdf also included.

Re: Need help converting this C code to PB

Posted: Mon Sep 13, 2010 9:33 pm
by IdeasVacuum
Hi neumanix

If you study the VB example, you should be able to get somewhere with PB, then come back to the forum with the bits you couldn't figure out.

Re: Need help converting this C code to PB

Posted: Thu Sep 30, 2010 10:58 pm
by neumanix
I took your advice and followed the VB example. Before I get my beginner hopes up, I'd like to check with you how I'm doing so far, and a couple of questions too...

For example, here is a function declaration in VB:

Code: Select all

Declare Function CreateFileMapping& Lib "kernel32" Alias _
        "CreateFileMappingA" (ByVal hFile As Long, _
        ByVal lpFileMappingAttributes As Long, ByVal _
        flProtect As Long, ByVal dwMaximumSizeHigh As Long, _
        ByVal dwMaximumSizeLow As Long, ByVal lpName As String)
And here is what I did in PB:

Code: Select all

If result.l=OpenLibrary(2,"kernel32")
  End
EndIf

Procedure CreateFileMapping(hFile.l, lpFileMappingAttributes.l, flProtect.l, dwMaximumSizeHigh.l, dwMaximumSizeLow.l, lpName.s)
  ProcedureReturn(CallFunction(2,"CreateFileMappingA", hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, Val(lpName)))
EndProcedure
Is this correct?

And this in VB:

Code: Select all

Public Const SMTO_BLOCK = &H1
Public Const PAGE_READWRITE = 4&
In PB I wrote this:

Code: Select all

#SMTO_BLOCK = $1
#PAGE_READWRITE = 4
Is this OK?

What about this in VB: Dim szName As String * 24

Is that equal to Dim szName(24) in PB ?

And here is where I'm stuck at the moment (the following code is VB):

Code: Select all

If (Not FSUIPC_Read(&H3304, 4, VarPtr(FSUIPC_Version), dwResult)) Then
      FSUIPC_Close
      FSUIPC_Open = False
      Exit Function
    End If
Is VarPtr(FSUIPC_Version) translated to @FSUIPC_Version in PB?

And this "Exit Function" is found in many places. It seems like the program should end at these points, so I just used "END" instead. Is that correct?

The FSUIPC_Read() function seems to be in a .lib called FSUIPC_USER.lib and this along with a header file is found in the C/C++ version of the SDK.
How do I use this is PB?

The link to the SDK is in my first post.

Really appreciate any help I can get!

Re: Flight Simulator link (VB to PB), need help!

Posted: Fri Oct 01, 2010 4:18 am
by Vitor_BossĀ®
What about this in VB: Dim szName As String * 24

Is that equal to Dim szName(24) in PB ?
This "Dim szName(24)" means an Array.

Try this:

Dim szName.s = Space(24)

Re: Flight Simulator link (VB to PB), need help!

Posted: Fri Oct 01, 2010 12:51 pm
by infratec
Hi,

for import functions in PureBASIC, you should use Prototypes.
So it looks like this

Code: Select all

Prototype.l CreateFileMappingA(hFile.l, lpAttributes.l, flProtect.l, dwMaximumSizeHigh.l, dwMaximumSizeLow.l, lpName.s)

If OpenLibrary(0,"kernel32")
  CFMapping.CreateFileMappingA = GetFunction(0, "CreateFileMappingA")
EndIf
But I'm not 100% sure about the the types in the declaration.
You have to check them.

Than you can use CFMapping() as your imported function.

Bernd

Re: Flight Simulator link (VB to PB), need help!

Posted: Fri Oct 01, 2010 6:13 pm
by neumanix
Thanks for the advice, I'll check it out.

Re: Flight Simulator link (VB to PB), need help!

Posted: Sat Oct 02, 2010 1:55 am
by neumanix
I think I'm getting closer to getting this to work. I hadn't read through the VB source enough to see that the FSUIPC_read function is indeed there so no .lib needed it seems.
It's not working yet though, but here is what I've got so far. Ofcourse, if you don't have any version of MS Flight Simulator it's harder to help, but maybe you can spot some errors.
It does compile, but doesn't quite work yet. Probably lots of noob errors :)

Here's the file to include: (fsuipc.pbi)

Code: Select all

Prototype.l RtlMoveMemory(destination.i, source.i, length.l)
Prototype.l RtlZeroMemory(destination.i, length.l)
Prototype.l dwMilliseconds(dwMilliseconds.l)
Prototype.l FindWindowExA(hWnd1.l, hWnd2.l, lpsz1.s, lpsz2.s)
Prototype.l RegisterWindowMessageA(lpString.s)
Prototype.l GetCurrentProcessId()
Prototype.l GlobalAddAtomA(lpString.s)
Prototype.l CreateFileMappingA(hFile.l, lpFileMappingAttributes.l, flProtect.l, dwMaximumSizeHigh.l, dwMaximumSizeLow.l, lpName.s)
Prototype.l GetLastError()
Prototype.l MapViewOfFileEx(hFileMappingObject.l, dwDesiredAccess.l, dwFileOffsetHigh.l, dwFileOffsetLow.l, dwNumberOfBytesToMap.l, lpBaseAddress.i)
Prototype.l GlobalDeleteAtom(nAtom.i)
Prototype.l UnmapViewOfFile(lpBaseAddress.l)
Prototype.l CloseHandle(hObject.l)
Prototype.l SendMessageTimeoutA(hWnd.l, Msg.l, wParam.l, lParam.l, fuFlags.l, uTimeout.l, lpdwResult.l)

If OpenLibrary(1,"user32.dll")
  Global FindWindowEx.FindWindowExA=GetFunction(1,"FindWindowExA")
  Global RegisterWindowMessage.RegisterWindowMessageA=GetFunction(1,"RegisterWindowMessageA")
  Global SendMessageTimeout.SendMessageTimeoutA=GetFunction(1,"SendMessageTimeoutA")
EndIf

If OpenLibrary(2,"kernel32.dll")
  Global CopyMem.RtlMoveMemory=GetFunction(2,"RtlMoveMemory")
  Global ZeroMemory.RtlZeroMemory=GetFunction(2,"RtlZeroMemory")
  Global Sleep.dwMilliseconds=GetFunction(2,"dwMilliseconds")
  Global GetCurrentProcId.GetCurrentProcessId=GetFunction(2,"GetCurrentProcessId")
  Global AddAtom.GlobalAddAtomA=GetFunction(2,"GlobalAddAtomA")
  Global CreateFileMapping.CreateFileMappingA=GetFunction(2,"CreateFileMappingA")
  Global GetLastErr.GetLastError=GetFunction(2,"GetLastError")
  Global MapViewOfFile.MapViewOfFileEx=GetFunction(2,"MapViewOfFileEx")
  Global DeleteAtom.GlobalDeleteAtom=GetFunction(2,"GlobalDeleteAtom")
  Global UnmapVOF.UnmapViewOfFile=GetFunction(2,"UnmapViewOfFile")
  Global CloseHdl.CloseHandle=GetFunction(2,"CloseHandle") 
EndIf


#SMTO_BLOCK = $1
#PAGE_READWRITE = 4
#NO_ERROR = 0
#ERROR_ALREADY_EXISTS = 183
#SECTION_MAP_WRITE = $2
#FILE_MAP_WRITE = #SECTION_MAP_WRITE

; FSUIPC Specifics

;Supported sims

#SIM_ANY = 0
#SIM_FS98 = 1
#SIM_FS2K = 2
#SIM_CFS2 = 3
#SIM_CFS1 = 4
#SIM_FLY = 5
#SIM_FS2K2 = 6
#SIM_FS2K4 = 7
#SIM_FSX = 8
#SIM_ESP = 9

;Error numbers

#FSUIPC_ERR_OK = 0
#FSUIPC_ERR_OPEN = 1 ; Attempt to Open when already Open
#FSUIPC_ERR_NOFS = 2 ; Cannot link to FSUIPC or WideClient
#FSUIPC_ERR_REGMSG = 3 ; Failed to Register common message with Windows
#FSUIPC_ERR_ATOM = 4 ; Failed to create Atom for mapping filename
#FSUIPC_ERR_MAP = 5 ; Failed to create a file mapping object
#FSUIPC_ERR_VIEW = 6 ; Failed to open a view to the file map
#FSUIPC_ERR_VERSION = 7 ; Incorrect version of FSUIPC, or not FSUIPC
#FSUIPC_ERR_WRONGFS = 8 ; Sim is not version requested
#FSUIPC_ERR_NOTOPEN = 9 ; Call cannot execute, link not Open
#FSUIPC_ERR_NODATA = 10 ; Call cannot execute: no requests accumulated
#FSUIPC_ERR_TIMEOUT = 11 ; IPC timed out all retries
#FSUIPC_ERR_SENDMSG = 12 ; IPC sendmessage failed all retries
#FSUIPC_ERR_DATA = 13 ; IPC request contains bad data
#FSUIPC_ERR_RUNNING = 14 ; Maybe running on WideClient, but FS not running on Server, or wrong FSUIPC
#FSUIPC_ERR_SIZE = 15 ; Read or Write request cannot be added, memory for Process is full

; define the DWORD structure
Structure DWORD
  Byt0.b
  Byt1.b
  Byt2.b
  Byt3.b
EndStructure

; global variables for the UIPC communication
Global FSUIPC_Version.l
Global FSUIPC_FS_Version.l
Global FSUIPC_Lib_Version.l
Global m_hWnd.l
Global m_msg.l
Global m_atom.l
Global m_hMap.l
Global m_pView.l
Global m_pNext.l

#LIB_VERSION = 2004
#MAX_SIZE = $7F00
FS6IPC_MSGNAME1.s = "FSASMLIB:IPC"
FS6IPC_MSGNAME2.s = "EFISFSCOM:IPC"
#FS6IPC_MESSAGE_SUCCESS = 1
#FS6IPC_MESSAGE_FAILURE = 0

; IPC message types

#FS6IPC_READSTATEDATA_ID = 1
#FS6IPC_WRITESTATEDATA_ID = 2
#FS6IPC_SPECIALREQUEST_ID =$ABAC

; declare the record types for reading and writing comms with UIPC

Structure FS6IPC_READSTATEDATA_HDR
  dwId.l
  dwOffset.l
  nBytes.l
  pDest.l
EndStructure

Structure FS6IPC_WRITESTATEDATA_HDR
  dwId.l
  dwOffset.l
  nBytes.l
EndStructure


;--- Read request ---

Procedure FSUIPC_READ(dwOffset.l, dwSize.l, pDest.l, dwResult.l)
  pHdr.FS6IPC_READSTATEDATA_HDR
  ; check link is open
  If m_pView=0
    dwResult = #FSUIPC_ERR_NOTOPEN
    FSUIPC_Read = #False
    ProcedureReturn
  EndIf
  
  ;Check have space for this request (including terminator)
  If ((((m_pNext) - (m_pView)) + 4 + (dwSize + SizeOf(pHdr))) > #MAX_SIZE)
    dwResult = #FSUIPC_ERR_SIZE
    FSUIPC_Read = #False
    ProcedureReturn
  EndIf
  
  ; Initialise header For Read request
  pHdr\dwId = #FS6IPC_READSTATEDATA_ID
  pHdr\dwOffset = dwOffset
  pHdr\nBytes = dwSize
  pHdr\pDest = pDest
  CopyMem(m_pNext, pHdr, SizeOf(pHdr))
  
  ; Move pointer past the Record
  m_pNext = m_pNext + SizeOf(pHdr)
  If dwSize <> 0
    ; Zero the reception area, so rubbish won't be returned
    ZeroMemory(m_pNext, dwSize)
    ; Update the pointer ready For more Data
    m_pNext = m_pNext + dwSize
  EndIf
  
  dwResult = #FSUIPC_ERR_OK
  FSUIPC_Read = #True
EndProcedure


;--- Process read/write ---

Procedure FSUIPC_Process(dwResult.l) 
dwError.l
pdw.i
pHdrR.FS6IPC_READSTATEDATA_HDR
pHdrW.FS6IPC_WRITESTATEDATA_HDR
i.i=0

  If m_pView = 0
    dwResult = #FSUIPC_ERR_NOTOPEN
    FSUIPC_Process = #False
    ProcedureReturn
  EndIf

  If m_pView = m_pNext
    dwResult = #FSUIPC_ERR_NODATA
    FSUIPC_Process = #False
    ProcedureReturn
  EndIf

  ZeroMemory(m_pNext, 4) ; Terminator
  m_pNext = m_pView

 ; send the request (allow up to 9 tries)
 While (i < 10) And ((SendMessageTimeout(m_hWnd, m_msg, m_atom, 0, #SMTO_BLOCK, 2000, dwError)) = 0)
 ;                         m_hWnd,              // FS6 window handle
 ;                         m_msg,               // our registered message id
 ;                         m_atom,              // wParam: name of file-mapping object
 ;                         0,                   // lParam: offset of request into file-mapping obj
 ;                         SMTO_BLOCK,          // halt this thread until we get a response
 ;                         2000,                // time out interval
 ;                         dwError)) = 0) do begin  // return value
    i = i + 1
    Sleep(100) ; Allow for things to happen
 Wend

  If i >= 10   ; Failed all tries
    If GetLastErr() = 0
      dwResult = #FSUIPC_ERR_TIMEOUT
    Else
      dwResult = #FSUIPC_ERR_SENDMSG
    FSUIPC_Process = #False
    ProcedureReturn
    EndIf
  EndIf
; did IPC like the data request?
  If dwError <> #FS6IPC_MESSAGE_SUCCESS
    ; no...
    dwResult = #FSUIPC_ERR_DATA
    FSUIPC_Process = #False
    ProcedureReturn
  EndIf

; Decode and store results of Read requests
  m_pNext = m_pView
  CopyMem(pdw, m_pNext, SizeOf(pdw))

While pdw <> 0
    Select pdw
        Case #FS6IPC_READSTATEDATA_ID
          ; copy the data we read into the user's buffer
          CopyMem(pHdrR, m_pNext, SizeOf(pHdrR))
          m_pNext = m_pNext + SizeOf(pHdrR)
          If (pHdrR\pDest <> 0) And (pHdrR\nBytes <> 0)
            CopyMem(pHdrR\pDest, m_pNext, pHdrR\nBytes)
          EndIf
          m_pNext = m_pNext + pHdrR\nBytes
            
        Case #FS6IPC_WRITESTATEDATA_ID
          ; This is a write, so there's no returned Data To store
          CopyMem(pHdrW, m_pNext, SizeOf(pHdrW))
          m_pNext = m_pNext + SizeOf(pHdrW) + pHdrW\nBytes
              
        Default
          ; Error! So terminate the scan
          m_pNext = m_pView
          Break         ; !?! or end
    EndSelect
    
    CopyMem(pdw, m_pNext, SizeOf(pdw))
  Wend

  m_pNext = m_pView
  dwResult = #FSUIPC_ERR_OK
  FSUIPC_Process = #True
EndProcedure

;--- Write request ---
Procedure FSUIPC_Write(dwOffset.l, dwSize.l, pSrce.l, dwResult.l)
  pHdr.FS6IPC_WRITESTATEDATA_HDR

  ; abort if necessary
  If m_pView = 0
    dwResult = #FSUIPC_ERR_NOTOPEN
    FSUIPC_Write = #False
    ProcedureReturn
  EndIf

  ; Check have space for this request (including terminator)
  If ((((m_pNext) - (m_pView)) + 4 + (dwSize + SizeOf(pHdr))) > #MAX_SIZE)
    dwResult = #FSUIPC_ERR_SIZE
    FSUIPC_Write = #False
    ProcedureReturn
  EndIf

  ; Initialise header for write request
  pHdr\dwId = #FS6IPC_WRITESTATEDATA_ID
  pHdr\dwOffset = dwOffset
  pHdr\nBytes = dwSize
  CopyMem(m_pNext, pHdr, SizeOf(pHdr))

  ; Move pointer past the record
  m_pNext = m_pNext + SizeOf(pHdr)
  If dwSize <> 0
    ; Copy in the data to be written
    CopyMem(m_pNext, pSrce, dwSize)
    ; Update the pointer ready for more data
    m_pNext = m_pNext + dwSize
  EndIf

  dwResult = #FSUIPC_ERR_OK
  FSUIPC_Write = #True
EndProcedure

;--- Null Terminated String Write request ---
Procedure FSUIPC_WriteS(dwOffset.l, dwSize.l, pSrce.s, dwResult.l)
  pHdr.FS6IPC_WRITESTATEDATA_HDR

  ; abort if necessary
  If m_pView = 0
    dwResult = #FSUIPC_ERR_NOTOPEN
    FSUIPC_WriteS = #False
    ProcedureReturn
  EndIf

  ; Check have space for this request (including terminator)
  If ((((m_pNext) - (m_pView)) + 4 + (dwSize + SizeOf(pHdr))) > #MAX_SIZE)
    dwResult = #FSUIPC_ERR_SIZE
    FSUIPC_WriteS = #False
    ProcedureReturn
  EndIf

  ; Initialise header for write request
  pHdr\dwId = FS6IPC_WRITESTATEDATA_ID
  pHdr\dwOffset = dwOffset
  pHdr\nBytes = dwSize
  CopyMem(m_pNext, pHdr, SizeOf(pHdr))

  ; Move pointer past the record
  m_pNext = m_pNext + SizeOf(pHdr)
  If dwSize <> 0
    ; Copy in the data to be written
    CopyMem(m_pNext, Val(pSrce), dwSize)
    ; Update the pointer ready for more data
    m_pNext = m_pNext + dwSize
  EndIf

  dwResult = #FSUIPC_ERR_OK
  FSUIPC_WriteS = #True
EndProcedure

; --- Stop the Client ---

Procedure FSUIPC_Close()
  m_hWnd = 0
  m_msg = 0
  m_pNext = 0
  
  If (m_atom <> 0)
    DeleteAtom(m_atom)
    m_atom = 0
  EndIf
    
  If (m_pView <> 0)
    UnmapVOF(m_pView)
    m_pView = 0
  EndIf
    
  If (m_hMap <> 0)
    CloseHdl(m_hMap)
    m_hMap = 0
  EndIf
EndProcedure

Procedure FSUIPC_Initialization()
  m_hWnd = 0
  m_msg = 0
  m_atom = 0
  m_hMap = 0
  m_pView = 0
  m_pNext = 0
EndProcedure

; --- Start the Client ---
; returns TRUE if successful, FALSE otherwise,
; If FALSE dwResult contains the "error-code"

Procedure FSUIPC_Open(dwFSReq.l, dwResult.l)
  szName.s=Space(24)
  fWideFS.i = #False
  nTry.i = 0
  i.i = 0
  
  ;abort if already started
  If (m_pView <> 0)
    dwResult = #FSUIPC_ERR_OPEN
    FSUIPC_Open = #False
    ProcedureReturn
  EndIf
    
  FSUIPC_Version = 0
  FSUIPC_FS_Version = 0
 
  ; Connect via FSUIPC, which is known to be FSUIPC's own
  ; And isn't subject To user modification
  
  m_hWnd = FindWindowEx(0, 0, "UIPCMAIN", "")
  If (m_hWnd = 0)
    ; If there's no UIPCMAIN, we may be using WideClient
    ; which only simulates FS98
    m_hWnd = FindWindowEx(0, 0, "FS98MAIN", "")
    fWideFS = #True
    If (m_hWnd = 0)
      dwResult = FSUIPC_ERR_NOFS
      FSUIPC_Open = #False
      ProcedureReturn
    EndIf
  EndIf
  
  ; register the window message
  m_msg = RegisterWindowMessage(FS6IPC_MSGNAME1.s)
  If (m_msg = 0)
    dwResult = FSUIPC_ERR_REGMSG
    FSUIPC_Open = #False
    ProcedureReturn
  EndIf
  
  ; create the name of our file-mapping object
  nTry = nTry + 1 ; Ensures a unique string is used in case user closes and reopens
  szName = FS6IPC_MSGNAME1 + ":" + Hex(GetCurrentProcId) + ":" + Hex(nTry) + Chr(0)
    
  ; stuff the name into a global atom
  m_atom = AddAtom(szName)
  If (m_atom = 0)
    dwResult = FSUIPC_ERR_ATOM
    FSUIPC_Close()
    FSUIPC_Open = #False
    ProcedureReturn
  EndIf
  
  ; create the file-mapping object
  ; use system paging file
  
  m_hMap = CreateFileMapping($FFFFFFFF, 0, #PAGE_READWRITE, 0, #MAX_SIZE + 256, szName)
  
  If (m_hMap = Null) Or (GetLastErr() = #ERROR_ALREADY_EXISTS)
    dwResult = #FSUIPC_ERR_MAP
    FSUIPC_Close()
    FSUIPC_Open = #False
    ProcedureReturn
  EndIf
  
  ; get a view of the file-mapping object
  m_pView = MapViewOfFile(m_hMap, #FILE_MAP_WRITE, 0, 0, 0, 0) ; ?!?
  If m_pView = 0
    dwResult = #FSUIPC_ERR_VIEW
    FSUIPC_Close()
    FSUIPC_Open = #False
    ProcedureReturn
  EndIf
  
  ; Okay, now determine FSUIPC version AND FS type
  m_pNext = m_pView
    
  ; Try up to 5 times with a 100msec rest between each
  ; Note that WideClient returns zeros initially, whilst waiting
  ; for the Server to get the data
  While ((i < 5) And ((FSUIPC_Version = 0) Or (FSUIPC_FS_Version = 0)))
    i = i + 1
    ; Read FSUIPC version
    If (Not FSUIPC_Read($3304, 4, @FSUIPC_Version, dwResult)) ; !?!
      FSUIPC_Close()
      FSUIPC_Open = #False
      ProcedureReturn
    EndIf

  ; And FS version And validity check pattern
    If (Not FSUIPC_Read($3308, 4, @FSUIPC_FS_Version, dwResult))
      FSUIPC_Close()
      FSUIPC_Open = #False
      ProcedureReturn
    EndIf
    
  ; write our Library version number To a special Read-only offset
  ; This is to assist diagnosis from FSUIPC logging
  ; But only do this on first try
  If (i < 2) And (Not FSUIPC_Write($330A, 2, @FSUIPC_Lib_Version, dwResult))
    FSUIPC_Close()
    FSUIPC_Open = #False
    ProcedureReturn
  EndIf
  
  ; Actually send the request and get the responses ("process")
    If Not (FSUIPC_Process(dwResult))
      FSUIPC_Close()
      FSUIPC_Open = #False
      ProcedureReturn
    EndIf

    ; Maybe running on WideClient, and need another try
    Sleep(100) ; Give it a chance
  Wend
      
  ; Only allow running on FSUIPC 1.998e or later
  ; with correct check pattern &HFADE
  If ((FSUIPC_Version < $19980005) Or ((FSUIPC_FS_Version & $FFFF0000) <> $FADE0000))
    If fWideFS
      dwResult = #FSUIPC_ERR_RUNNING
    Else
      dwResult = #FSUIPC_ERR_VERSION
    FSUIPC_Close()
    FSUIPC_Open = #False
    ProcedureReturn
  EndIf
 EndIf 
  ; grab the FS version number
  FSUIPC_FS_Version = (FSUIPC_FS_Version & $FFFF)
  
  ; Optional version-specific request made?  If so and wrong version, return error
  If (dwFSReq <> 0) And (dwFSReq <> FSUIPC_FS_Version)
    dwResult = #FSUIPC_ERR_WRONGFS
    FSUIPC_Close()
    FSUIPC_Open = #False
    ProcedureReturn
  EndIf

  dwResult = #FSUIPC_ERR_OK
  FSUIPC_Open = #True
EndProcedure
And here's a small test program that should (but doesn't) display some info when MS Flightsim (with FSUIPC) is running:

Code: Select all

IncludeFile "FSUIPC.pbi"

dwResult.l

Dim ResultText.s(15)
ResultText(0)="Okay"
ResultText(1)="Attempt to Open when already Open"
ResultText(2)="Cannot link to FSUIPC or WideClient"
ResultText(3)="Failed to Register common message with Windows"
ResultText(4)="Failed to create Atom for mapping filename"
ResultText(5)="Failed to create a file mapping object"
ResultText(6)="Failed to open a view to the file map"
ResultText(7)="Incorrect version of FSUIPC, or not FSUIPC"
ResultText(8)="Sim is not version requested"
ResultText(9)="Call cannot execute, link not Open"
ResultText(10)="Call cannot execute: no requests accumulated"
ResultText(11)="IPC timed out all retries"
ResultText(12)="IPC sendmessage failed all retries"
ResultText(13)="IPC request contains bad data"
ResultText(14)="Maybe running on WideClient, but FS not running on Server, or wrong FSUIPC"
ResultText(15)="Read or Write request cannot be added, memory for Process is full"

Dim SimulationText.s(9)
SimulationText(0)="Any"
SimulationText(1)="FS98"
SimulationText(2)="FS2K"
SimulationText(3)="CFS2"
SimulationText(4)="CFS1"
SimulationText(5)="FLY"
SimulationText(6)="FS2002"
SimulationText(7)="FS2004"
SimulationText(8)="FSX"
SimulationText(9)="ESP"

FSUIPC_Initialization()

; Try to connect to FSUIPC (or WideFS)

If FSUIPC_Open(#SIM_ANY, dwResult)
  Debug ResultText(dwResult)
  Debug SimulationText(FSUIPC_FS_VERSION)
Else
  Debug "Can't Connect: "
EndIf
End