diff --git a/externals b/externals index 02df5fe08..73be1b8c3 160000 --- a/externals +++ b/externals @@ -1 +1 @@ -Subproject commit 02df5fe088e8a7650364d423b25d737574dbc501 +Subproject commit 73be1b8c372118a3da82494af8a4106d1ae72ed3 diff --git a/src/plugins/simulator/fs9/fs9.pro b/src/plugins/simulator/fs9/fs9.pro index 8b546cfad..47ae9cf30 100644 --- a/src/plugins/simulator/fs9/fs9.pro +++ b/src/plugins/simulator/fs9/fs9.pro @@ -8,10 +8,7 @@ TEMPLATE = lib CONFIG += plugin shared CONFIG += blackmisc blackcore -LIBS += -lsimulatorfscommon -lFSUIPC_User -luuid - -# required for FSUIPC -win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib +LIBS += -lsimulatorfscommon -lfsuipc -luuid DEPENDPATH += . $$SourceRoot/src INCLUDEPATH += . $$SourceRoot/src diff --git a/src/plugins/simulator/fscommon/fscommon.pro b/src/plugins/simulator/fscommon/fscommon.pro index 09a7fe5c0..fac1d891d 100644 --- a/src/plugins/simulator/fscommon/fscommon.pro +++ b/src/plugins/simulator/fscommon/fscommon.pro @@ -14,12 +14,14 @@ INCLUDEPATH += . $$SourceRoot/src SOURCES += *.cpp HEADERS += *.h -contains(BLACK_CONFIG, FSUIPC): DEFINES += SWIFT_USING_FSUIPC - -LIBS += -lFSUIPC_User - -# required for FSUIPC -win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib +contains(BLACK_CONFIG, FSUIPC) { + equals(WORD_SIZE,32) { + DEFINES += SWIFT_USING_FSUIPC32 + } + equals(WORD_SIZE,64) { + DEFINES += SWIFT_USING_FSUIPC64 + } +} DESTDIR = $$DestRoot/lib diff --git a/src/plugins/simulator/fscommon/fsuipcdummy.cpp b/src/plugins/simulator/fscommon/fsuipcdummy.cpp index 89d72893b..9912c2190 100644 --- a/src/plugins/simulator/fscommon/fsuipcdummy.cpp +++ b/src/plugins/simulator/fscommon/fsuipcdummy.cpp @@ -7,7 +7,7 @@ * contained in the LICENSE file. */ -#ifndef SWIFT_USING_FSUIPC +#if !defined(SWIFT_USING_FSUIPC32) && !defined(SWIFT_USING_FSUIPC64) #include "fsuipc.h" @@ -75,4 +75,4 @@ namespace BlackSimPlugin } // namespace } // namespace -#endif //SWIFT_USING_FSUIPC +#endif // !defined(SWIFT_USING_FSUIPC32) && !defined(SWIFT_USING_FSUIPC64) diff --git a/src/plugins/simulator/fscommon/fsuipcimpl.cpp b/src/plugins/simulator/fscommon/fsuipcimpl.cpp index 6f75749ba..c8d4b48dc 100644 --- a/src/plugins/simulator/fscommon/fsuipcimpl.cpp +++ b/src/plugins/simulator/fscommon/fsuipcimpl.cpp @@ -7,7 +7,7 @@ * contained in the LICENSE file. */ -#ifdef SWIFT_USING_FSUIPC +#if defined(SWIFT_USING_FSUIPC32) || defined(SWIFT_USING_FSUIPC64) #ifndef NOMINMAX #define NOMINMAX @@ -16,8 +16,16 @@ #include "fsuipc.h" #include // bug in FSUIPC_User.h, windows.h not included, so we have to import it first -#include "FSUIPC/FSUIPC_User.h" -#include "FSUIPC/NewWeather.h" + +#ifdef SWIFT_USING_FSUIPC32 + #include "../fsuipc32/FSUIPC_User.h" + #include "../fsuipc32/NewWeather.h" +#endif + +#ifdef SWIFT_USING_FSUIPC64 + #include "../fsuipc64/FSUIPC_User64.h" + #include "../fsuipc64/NewWeather.h" +#endif #include "blackmisc/simulation/fscommon/bcdconversions.h" #include "blackmisc/logmessage.h" @@ -500,4 +508,4 @@ namespace BlackSimPlugin } // namespace } // namespace -#endif //SWIFT_USING_FSUIPC +#endif // defined(SWIFT_USING_FSUIPC32) || defined(SWIFT_USING_FSUIPC64) diff --git a/src/plugins/simulator/fsuipc32/FSUIPC_User.h b/src/plugins/simulator/fsuipc32/FSUIPC_User.h new file mode 100644 index 000000000..807893fa7 --- /dev/null +++ b/src/plugins/simulator/fsuipc32/FSUIPC_User.h @@ -0,0 +1,60 @@ +#ifndef _FSUIPC_H_ +#define _FSUIPC_H_ + +// Supported Sims +#define SIM_ANY 0 +#define SIM_FS98 1 +#define SIM_FS2K 2 +#define SIM_CFS2 3 +#define SIM_CFS1 4 +#define SIM_FLY 5 +#define SIM_FS2K2 6 +#define SIM_FS2K4 7 +#define SIM_FSX 8 +#define SIM_ESP 9 +#define SIM_P3D 10 + +// Error numbers +#define FSUIPC_ERR_OK 0 +#define FSUIPC_ERR_OPEN 1 // Attempt to Open when already Open +#define FSUIPC_ERR_NOFS 2 // Cannot link to FSUIPC or WideClient +#define FSUIPC_ERR_REGMSG 3 // Failed to Register common message with Windows +#define FSUIPC_ERR_ATOM 4 // Failed to create Atom for mapping filename +#define FSUIPC_ERR_MAP 5 // Failed to create a file mapping object +#define FSUIPC_ERR_VIEW 6 // Failed to open a view to the file map +#define FSUIPC_ERR_VERSION 7 // Incorrect version of FSUIPC, or not FSUIPC +#define FSUIPC_ERR_WRONGFS 8 // Sim is not version requested +#define FSUIPC_ERR_NOTOPEN 9 // Call cannot execute, link not Open +#define FSUIPC_ERR_NODATA 10 // Call cannot execute: no requests accumulated +#define FSUIPC_ERR_TIMEOUT 11 // IPC timed out all retries +#define FSUIPC_ERR_SENDMSG 12 // IPC sendmessage failed all retries +#define FSUIPC_ERR_DATA 13 // IPC request contains bad data +#define FSUIPC_ERR_RUNNING 14 // Maybe running on WideClient, but FS not running on Server, or wrong FSUIPC +#define FSUIPC_ERR_SIZE 15 // Read or Write request cannot be added, memory for Process is full + +#ifdef __cplusplus +extern "C" { +#endif + +// Globals accessible from main code +extern DWORD FSUIPC_Version; // HIWORD is 1000 x Version Number, minimum 1998 + // LOWORD is build letter, with a = 1 etc. For 1998 this must be at least 5 (1998e) +extern DWORD FSUIPC_FS_Version; + // FS98=1, FS2k=2, CFS2=3. See above. +extern DWORD FSUIPC_Lib_Version; + // HIWORD is 1000 x version, LOWORD is build letter, a = 1 etc. + +// Library routines +extern BOOL FSUIPC_Open(DWORD dwFSReq, DWORD *pdwResult); // For use externally (IPCuser.lib) +extern BOOL FSUIPC_Open2(DWORD dwFSReq, DWORD *pdwResult, BYTE *pMem, DWORD dwSize); // For use internally (ModuleUser.lib) +extern void FSUIPC_Close(void); +extern BOOL FSUIPC_Read(DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pdwResult); +extern BOOL FSUIPC_ReadSpecial(DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pdwResult); +extern BOOL FSUIPC_Write(DWORD dwOffset, DWORD dwSize, void *pSrce, DWORD *pdwResult); +extern BOOL FSUIPC_Process(DWORD *pdwResult); + +#ifdef __cplusplus +} +#endif + +#endif // _FSUIPC_H_ diff --git a/src/plugins/simulator/fsuipc32/IPCuser.c b/src/plugins/simulator/fsuipc32/IPCuser.c new file mode 100644 index 000000000..554fd3ecb --- /dev/null +++ b/src/plugins/simulator/fsuipc32/IPCuser.c @@ -0,0 +1,338 @@ +/* IPCUSER.C User interface library for FSUIPC +******************************************************************************* + +Started: 28th November 2000 + +With acknowledgements to Adam Szofran (author of original FS6IPC). + +******************************************************************************/ + +#define LIB_VERSION 2002 // 2.002 +#define MAX_SIZE 0x7F00 // Largest data (kept below 32k to avoid + // any possible 16-bit sign problems) + +#include "IPCuser.h" + +/****************************************************************************** + IPC client stuff +******************************************************************************/ + +DWORD FSUIPC_Version = 0; +DWORD FSUIPC_FS_Version = 0; +DWORD FSUIPC_Lib_Version = LIB_VERSION; + +static HWND m_hWnd = 0; // FS6 window handle +static UINT m_msg = 0; // id of registered window message +static ATOM m_atom = 0; // global atom containing name of file-mapping object +static HANDLE m_hMap = 0; // handle of file-mapping object +static BYTE* m_pView = 0; // pointer to view of file-mapping object +static BYTE* m_pNext = 0; + +/****************************************************************************** + FSUIPC_Close +******************************************************************************/ + +// Stop the client +void FSUIPC_Close(void) +{ m_hWnd = 0; + m_msg = 0; + + if (m_atom) + { GlobalDeleteAtom(m_atom); + m_atom = 0; + } + + if (m_pView) + { UnmapViewOfFile((LPVOID)m_pView); + m_pView = 0; + } + + if (m_hMap) + { CloseHandle(m_hMap); + m_hMap = 0; + } +} + +/****************************************************************************** + FSUIPC_Open +******************************************************************************/ + +// Start the client +// return: TRUE if successful, FALSE otherwise +BOOL FSUIPC_Open(DWORD dwFSReq, DWORD *pdwResult) +{ wchar_t szName[MAX_PATH]; + static int nTry = 0; + BOOL fWideFS = FALSE; + int i = 0; + + // abort if already started + if (m_pView) + { *pdwResult = FSUIPC_ERR_OPEN; + return FALSE; + } + + // Clear version information, so know when connected + FSUIPC_Version = FSUIPC_FS_Version = 0; + + // Connect via FSUIPC, which is known to be FSUIPC's own + // and isn't subject to user modificiation + m_hWnd = FindWindowEx(NULL, NULL, L"UIPCMAIN", NULL); + if (!m_hWnd) + { // If there's no UIPCMAIN, we may be using WideClient + // which only simulates FS98 + m_hWnd = FindWindowEx(NULL, NULL, L"FS98MAIN", NULL); + fWideFS = TRUE; + if (!m_hWnd) + { *pdwResult = FSUIPC_ERR_NOFS; + return FALSE; + } + } + + // register the window message + m_msg = RegisterWindowMessage(FS6IPC_MSGNAME1); + if (m_msg == 0) + { *pdwResult = FSUIPC_ERR_REGMSG; + return FALSE; + } + + // create the name of our file-mapping object + nTry++; // Ensures a unique string is used in case user closes and reopens + wsprintf(szName, FS6IPC_MSGNAME1 ":%X:%X", GetCurrentProcessId(), nTry); + + // stuff the name into a global atom + m_atom = GlobalAddAtom(szName); + if (m_atom == 0) + { *pdwResult = FSUIPC_ERR_ATOM; + FSUIPC_Close(); + return FALSE; + } + + // create the file-mapping object + m_hMap = CreateFileMapping( + (HANDLE)0xFFFFFFFF, // use system paging file + NULL, // security + PAGE_READWRITE, // protection + 0, MAX_SIZE+256, // size + szName); // name + + if ((m_hMap == 0) || (GetLastError() == ERROR_ALREADY_EXISTS)) + { *pdwResult = FSUIPC_ERR_MAP; + FSUIPC_Close(); + return FALSE; + } + + // get a view of the file-mapping object + m_pView = (BYTE*)MapViewOfFile(m_hMap, FILE_MAP_WRITE, 0, 0, 0); + if (m_pView == NULL) + { *pdwResult = FSUIPC_ERR_VIEW; + FSUIPC_Close(); + return FALSE; + } + + // 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 zeroes initially, whilst waiting + // for the Server to get the data + while ((i++ < 5) && ((FSUIPC_Version == 0) || (FSUIPC_FS_Version == 0))) + { // Read FSUIPC version + if (!FSUIPC_Read(0x3304, 4, &FSUIPC_Version, pdwResult)) + { FSUIPC_Close(); + return FALSE; + } + + // and FS version and validity check pattern + if (!FSUIPC_Read(0x3308, 4, &FSUIPC_FS_Version, pdwResult)) + { FSUIPC_Close(); + return FALSE; + } + + // 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) && !FSUIPC_Write(0x330a, 2, &FSUIPC_Lib_Version, pdwResult)) + { FSUIPC_Close(); + return FALSE; + } + + // Actually send the requests and get the responses ("process") + if (!FSUIPC_Process(pdwResult)) + { FSUIPC_Close(); + return FALSE; + } + + // Maybe running on WideClient, and need another try + Sleep(100); // Give it a chance + } + + // Only allow running on FSUIPC 1.998e or later + // with correct check pattern 0xFADE + if ((FSUIPC_Version < 0x19980005) || ((FSUIPC_FS_Version & 0xFFFF0000L) != 0xFADE0000)) + { *pdwResult = fWideFS ? FSUIPC_ERR_RUNNING : FSUIPC_ERR_VERSION; + FSUIPC_Close(); + return FALSE; + } + + FSUIPC_FS_Version &= 0xffff; // Isolates the FS version number + if (dwFSReq && (dwFSReq != FSUIPC_FS_Version)) // Optional user specific FS request + { *pdwResult = FSUIPC_ERR_WRONGFS; + FSUIPC_Close(); + return FALSE; + } + + *pdwResult = FSUIPC_ERR_OK; + return TRUE; +} + +/****************************************************************************** + FSUIPC_Process +******************************************************************************/ + +BOOL FSUIPC_Process(DWORD *pdwResult) +{ DWORD dwError; + DWORD *pdw; + FS6IPC_READSTATEDATA_HDR *pHdrR; + FS6IPC_WRITESTATEDATA_HDR *pHdrW; + int i = 0; + + if (!m_pView) + { *pdwResult = FSUIPC_ERR_NOTOPEN; + return FALSE; + } + + if (m_pView == m_pNext) + { *pdwResult = FSUIPC_ERR_NODATA; + return FALSE; + } + + ZeroMemory(m_pNext, 4); // Terminator + m_pNext = m_pView; + + // send the request (allow up to 9 tries) + while ((++i < 10) && !SendMessageTimeout( + 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)) // return value + { Sleep(100); // Allow for things to happen + } + + if (i >= 10) // Failed all tries? + { *pdwResult = GetLastError() == 0 ? FSUIPC_ERR_TIMEOUT : FSUIPC_ERR_SENDMSG; + return FALSE; + } + + if (dwError != FS6IPC_MESSAGE_SUCCESS) + { *pdwResult = FSUIPC_ERR_DATA; // FSUIPC didn't like something in the data! + return FALSE; + } + + // Decode and store results of Read requests + pdw = (DWORD *) m_pView; + + while (*pdw) + { switch (*pdw) + { case FS6IPC_READSTATEDATA_ID: + pHdrR = (FS6IPC_READSTATEDATA_HDR *) pdw; + m_pNext += sizeof(FS6IPC_READSTATEDATA_HDR); + if (pHdrR->pDest && pHdrR->nBytes) + CopyMemory(pHdrR->pDest, m_pNext, pHdrR->nBytes); + m_pNext += pHdrR->nBytes; + break; + + case FS6IPC_WRITESTATEDATA_ID: + // This is a write, so there's no returned data to store + pHdrW = (FS6IPC_WRITESTATEDATA_HDR *) pdw; + m_pNext += sizeof(FS6IPC_WRITESTATEDATA_HDR) + pHdrW->nBytes; + break; + + default: + // Error! So terminate the scan + *pdw = 0; + break; + } + + pdw = (DWORD *) m_pNext; + } + + m_pNext = m_pView; + *pdwResult = FSUIPC_ERR_OK; + return TRUE; +} + +/****************************************************************************** + FSUIPC_Read +******************************************************************************/ + +BOOL FSUIPC_Read(DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pdwResult) +{ FS6IPC_READSTATEDATA_HDR *pHdr = (FS6IPC_READSTATEDATA_HDR *) m_pNext; + + // Check link is open + if (!m_pView) + { *pdwResult = FSUIPC_ERR_NOTOPEN; + return FALSE; + } + + // Check have space for this request (including terminator) + if (((m_pNext - m_pView) + 4 + (dwSize + sizeof(FS6IPC_READSTATEDATA_HDR))) > MAX_SIZE) + { *pdwResult = FSUIPC_ERR_SIZE; + return FALSE; + } + + // Initialise header for read request + pHdr->dwId = FS6IPC_READSTATEDATA_ID; + pHdr->dwOffset = dwOffset; + pHdr->nBytes = dwSize; + pHdr->pDest = (BYTE *) pDest; + + // Zero the reception area, so rubbish won't be returned + if (dwSize) ZeroMemory(&m_pNext[sizeof(FS6IPC_READSTATEDATA_HDR)], dwSize); + + // Update the pointer ready for more data + m_pNext += sizeof(FS6IPC_READSTATEDATA_HDR) + dwSize; + + *pdwResult = FSUIPC_ERR_OK; + return TRUE; +} + +/****************************************************************************** + FSUIPC_Write +******************************************************************************/ + +BOOL FSUIPC_Write(DWORD dwOffset, DWORD dwSize, void *pSrce, DWORD *pdwResult) +{ FS6IPC_WRITESTATEDATA_HDR *pHdr = (FS6IPC_WRITESTATEDATA_HDR *) m_pNext; + + // check link is open + if (!m_pView) + { *pdwResult = FSUIPC_ERR_NOTOPEN; + return FALSE; + } + + // Check have spce for this request (including terminator) + if (((m_pNext - m_pView) + 4 + (dwSize + sizeof(FS6IPC_WRITESTATEDATA_HDR))) > MAX_SIZE) + { *pdwResult = FSUIPC_ERR_SIZE; + return FALSE; + } + + // Initialise header for write request + pHdr->dwId = FS6IPC_WRITESTATEDATA_ID; + pHdr->dwOffset = dwOffset; + pHdr->nBytes = dwSize; + + // Copy in the data to be written + if (dwSize) CopyMemory(&m_pNext[sizeof(FS6IPC_WRITESTATEDATA_HDR)], pSrce, dwSize); + + // Update the pointer ready for more data + m_pNext += sizeof(FS6IPC_WRITESTATEDATA_HDR) + dwSize; + + *pdwResult = FSUIPC_ERR_OK; + return TRUE; +} + +/****************************************************************************** + End of IPCuser module +******************************************************************************/ diff --git a/src/plugins/simulator/fsuipc32/IPCuser.h b/src/plugins/simulator/fsuipc32/IPCuser.h new file mode 100644 index 000000000..3d1f34374 --- /dev/null +++ b/src/plugins/simulator/fsuipc32/IPCuser.h @@ -0,0 +1,29 @@ +#include + +#include "FSUIPC_User.h" + +#define FS6IPC_MSGNAME1 L"FsasmLib:IPC" + +#define FS6IPC_MESSAGE_SUCCESS 1 +#define FS6IPC_MESSAGE_FAILURE 0 + +// IPC message types +#define FS6IPC_READSTATEDATA_ID 1 +#define FS6IPC_WRITESTATEDATA_ID 2 + +// read request structure +typedef struct tagFS6IPC_READSTATEDATA_HDR +{ + DWORD dwId; // FS6IPC_READSTATEDATA_ID + DWORD dwOffset; // state table offset + DWORD nBytes; // number of bytes of state data to read + void* pDest; // destination buffer for data (client use only) +} FS6IPC_READSTATEDATA_HDR; + +// write request structure +typedef struct tagFS6IPC_WRITESTATEDATA_HDR +{ + DWORD dwId; // FS6IPC_WRITESTATEDATA_ID + DWORD dwOffset; // state table offset + DWORD nBytes; // number of bytes of state data to write +} FS6IPC_WRITESTATEDATA_HDR; diff --git a/src/plugins/simulator/fsuipc32/NewWeather.h b/src/plugins/simulator/fsuipc32/NewWeather.h new file mode 100644 index 000000000..76afd7f38 --- /dev/null +++ b/src/plugins/simulator/fsuipc32/NewWeather.h @@ -0,0 +1,120 @@ +// Wind structure (size 16 bytes) +typedef struct _NewWind +{ unsigned short UpperAlt; // Metres + unsigned short Speed; // Knots + unsigned short Gust; // Max gust speed difference, knots + unsigned short Direction; // usual 65536 = 360 units + unsigned char Turbulence; // 0-4 + unsigned char Shear; // 0-3 + unsigned short Variance; // direction variability, same units as Direction + unsigned short SpeedFract; // 1/65536ths of Knots, for more accurate vector calcs + unsigned short GapAbove; // Metres + // This is the gap from the top of surface altitude to first layer's base + // GapAbove is ignored in layers other than the surface layer, and needs + // FSUIC 4.748 or 3.998k minimum. +} NewWind; + +// Visibility structure (size 8 bytes) +typedef struct _NewVis +{ unsigned short UpperAlt; // Metres + signed short LowerAlt; // Metres + unsigned short Range; // in 1/100ths sm + unsigned short Spare; +} NewVis; + +// Cloud structure (size 16 bytes) +typedef struct _NewCloud +{ unsigned short UpperAlt; // Metres + unsigned short LowerAlt; // Metres + unsigned short Deviation; // Metres + unsigned char Coverage; // Octas, 0-8 + unsigned char Type; // 1-10 + unsigned char Turbulence; // 0-4 + unsigned char Icing; // 0-4 + signed short PrecipBase; // Metres + unsigned char PrecipType; // 0-2 + unsigned char PrecipRate; // 0-5 + unsigned char TopShape; // ? + unsigned char Spare; +} NewCloud; + +// Temperature structure (size 8 bytes) +typedef struct _NewTemp +{ unsigned short Alt; // Metres + short Day; // Degrees C + short DayNightVar; // Degrees C + short DewPoint; // Degrees C +} NewTemp; + +// Pressure structure (size 4 bytes) +typedef struct _NewPress +{ unsigned short Pressure; // 16 x mb + short Drift; // ? Maybe +} NewPress; + +// Structure mapped to FSUIPC offsets +// C000, C400, C800 and CC00 +typedef struct _NewWeather +{ unsigned short uCommand; // C000 C400 C800 CC00 + unsigned short uFlags; // C002 C402 C802 CC02 // Not used until FSX - see below + unsigned int ulSignature; // C004 C404 C804 CC04 + char chICAO[4]; // C008 C408 C808 CC08 + unsigned short uDynamics; // C00C C40C C80C CC0C // 0=none, 4=extreme + unsigned short uSeconds; // C00E C40E C80E CC0E // FSX only -- see below + double dLatitude; // C010 C410 C810 CC10 // LLA zero for GLOB or unknown ICAO + double dLongitude; // C018 C418 C818 CC18 + int nElevation; // C020 C420 C820 CC20 // metres * 65536 + unsigned int ulTimeStamp; // C024 C424 C824 CC24 // mSecs since start of session + NewPress Press; // C028 C428 C828 CC28 + NewVis Vis; // C02C C42C C82C CC2C // Base Vis -- for upper Vis layers see + int nTempCtr; // C034 C434 C834 CC34 // Number of temperature layers + NewTemp Temp[24]; // C038 C438 C838 CC38 + int nWindsCtr; // C0F8 C4F8 C8F8 CCF8 // Number of wind layers + NewWind Wind[24]; // C0FC C4FC C8FC CCFC + int nCloudsCtr; // C27C C67C CA7C CE7C // Number of Cloud layers (max 16 in FSX, was 24 + NewCloud Cloud[16]; // C280 C680 CA80 CE80 + char chUTCstamp[6]; // C380 C780 CB80 CF80 // UTC time stamp on METAR (internal use) + unsigned short fWriteback; // C386 C786 CB86 CF86 // Flags for writing back to FSX (internal use only) + unsigned long ulSettingTimeStamp; // C388 c788 CB88 CF88 // Timestamp METAR sent (internal use) + int nUpperVisCtr; // C38C C78C CB8C CF8C // Number of upper Vis layer (new in FSX) + NewVis UpperVis[12]; // C390 C790 CB90 CF90 + unsigned short uSpare[8]; // C3F0 C7F0 CBF0 CFF0 +} NewWeather; + +#define MAXVISLAYERS 12 +#define MAXTEMPLAYERS 24 +#define MAXWINDLAYERS 24 +#define MAXCLOUDLAYERS 16 + +// Commands (for set weather area only) +#define NW_SET 1 // Set weather via FSUIPC user filters +#define NW_SETEXACT 2 // Set weather bypassing user filters +#define NW_CLEAR 3 // Clear all weather, but leave dynamic setting alone +#define NW_DYNAMICS 4 // Set weather dynamics (from uDynamics value) +#define NW_GLOBAL 5 // (FSX) Put FS into Global weather mode +// You sohuld write only 'GLOB' weather after this, which will be applied everywhere. + +#define NW_METAR 128 // DON'T USE! (Internal setting when weather written via string at B000. (FSX)) + +#define NW_SET_PENDING 257 // Set weather using filters, but don't activate in FS yet +#define NW_SETEXACT_PENDING 258 // Set weather bypassing filters, but don't activate in FS yet + +#define NW_ACTIVATE 256 // Activate pending weather settings + +// Flags for FSX weather setting +#define NWF_SECONDS 1 +/* Set this flag if "Seconds" value is to be used in setting weather in FSX + This applies to weather set via NWI values or via the NEXT Metar string + written to B000. It's a "one shot" flag, cleared after use. + + The Seconds value determines whether the weather change is effective + immediately or after a delay, gradually "blending" into the existing + weather. +*/ + +// The 4 distinct areas are used as follows: +// C000 - read only, maintains current interpolated weather at aircraft +// C400 - read only, maintains last written global weather values +// C800 - write area to set weather according to Command, flags, etc etc. +// CC00 - selected read (via signature + ICAO), reads weather at weather station or GLOB + diff --git a/src/plugins/simulator/fsuipc32/fsuipc32.pro b/src/plugins/simulator/fsuipc32/fsuipc32.pro new file mode 100644 index 000000000..1a042b62b --- /dev/null +++ b/src/plugins/simulator/fsuipc32/fsuipc32.pro @@ -0,0 +1,20 @@ +load(common_pre) + +requires(equals(WORD_SIZE,32)) + +QT += core dbus xml network + +TARGET = fsuipc +TEMPLATE = lib + +CONFIG += staticlib + +DEPENDPATH += . $$SourceRoot/src +INCLUDEPATH += . $$SourceRoot/src + +HEADERS += *.h +SOURCES += *.c + +DESTDIR = $$DestRoot/lib + +load(common_post) diff --git a/src/plugins/simulator/fsuipc64/FSUIPC_User64.h b/src/plugins/simulator/fsuipc64/FSUIPC_User64.h new file mode 100644 index 000000000..17b2fec28 --- /dev/null +++ b/src/plugins/simulator/fsuipc64/FSUIPC_User64.h @@ -0,0 +1,62 @@ +#ifndef _FSUIPC_H_ +#define _FSUIPC_H_ + +// Supported Sims +#define SIM_ANY 0 +#define SIM_FS98 1 +#define SIM_FS2K 2 +#define SIM_CFS2 3 +#define SIM_CFS1 4 +#define SIM_FLY 5 +#define SIM_FS2K2 6 +#define SIM_FS2K4 7 +#define SIM_FSX 8 +#define SIM_ESP 9 +#define SIM_P3D 10 +#define SIM_FSX64 11 +#define SIM_P3D64 12 + +// Error numbers +#define FSUIPC_ERR_OK 0 +#define FSUIPC_ERR_OPEN 1 // Attempt to Open when already Open +#define FSUIPC_ERR_NOFS 2 // Cannot link to FSUIPC or WideClient +#define FSUIPC_ERR_REGMSG 3 // Failed to Register common message with Windows +#define FSUIPC_ERR_ATOM 4 // Failed to create Atom for mapping filename +#define FSUIPC_ERR_MAP 5 // Failed to create a file mapping object +#define FSUIPC_ERR_VIEW 6 // Failed to open a view to the file map +#define FSUIPC_ERR_VERSION 7 // Incorrect version of FSUIPC, or not FSUIPC +#define FSUIPC_ERR_WRONGFS 8 // Sim is not version requested +#define FSUIPC_ERR_NOTOPEN 9 // Call cannot execute, link not Open +#define FSUIPC_ERR_NODATA 10 // Call cannot execute: no requests accumulated +#define FSUIPC_ERR_TIMEOUT 11 // IPC timed out all retries +#define FSUIPC_ERR_SENDMSG 12 // IPC sendmessage failed all retries +#define FSUIPC_ERR_DATA 13 // IPC request contains bad data +#define FSUIPC_ERR_RUNNING 14 // Maybe running on WideClient, but FS not running on Server, or wrong FSUIPC +#define FSUIPC_ERR_SIZE 15 // Read or Write request cannot be added, memory for Process is full + +#ifdef __cplusplus +extern "C" { +#endif + +// Globals accessible from main code +extern DWORD FSUIPC_Version; // HIWORD is 1000 x Version Number, minimum 1998 + // LOWORD is build letter, with a = 1 etc. For 1998 this must be at least 5 (1998e) +extern DWORD FSUIPC_FS_Version; + // FS98=1, FS2k=2, CFS2=3. See above. +extern DWORD FSUIPC_Lib_Version; + // HIWORD is 1000 x version, LOWORD is build letter, a = 1 etc. + +// Library routines +extern BOOL FSUIPC_Open(DWORD dwFSReq, DWORD *pdwResult); // For use externally (IPCuser.lib) +extern BOOL FSUIPC_Open2(DWORD dwFSReq, DWORD *pdwResult, BYTE *pMem, DWORD dwSize); // For use internally (ModuleUser.lib) +extern void FSUIPC_Close(void); +extern BOOL FSUIPC_Read(DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pdwResult); +extern BOOL FSUIPC_ReadSpecial(DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pdwResult); +extern BOOL FSUIPC_Write(DWORD dwOffset, DWORD dwSize, void *pSrce, DWORD *pdwResult); +extern BOOL FSUIPC_Process(DWORD *pdwResult); + +#ifdef __cplusplus +}; +#endif + +#endif // _FSUIPC_H_ diff --git a/src/plugins/simulator/fsuipc64/IPCuser64.c b/src/plugins/simulator/fsuipc64/IPCuser64.c new file mode 100644 index 000000000..25c0e9e95 --- /dev/null +++ b/src/plugins/simulator/fsuipc64/IPCuser64.c @@ -0,0 +1,347 @@ +/* IPCUSER64.C User interface library for FSUIPC +******************************************************************************* + +Started: 28th November 2000 + +With acknowledgements to Adam Szofran (author of original FS6IPC). + +******************************************************************************/ + +#define LIB_VERSION 2002 // 2.002 +#define MAX_SIZE 0x7F00 // Largest data (kept below 32k to avoid + // any possible 16-bit sign problems) + +#include "IPCuser64.h" +#include "FSUIPC_User64.h" + +#define FS6IPC_MSGNAME1 L"FsasmLib:IPC" + +/****************************************************************************** + IPC client stuff +******************************************************************************/ + +DWORD FSUIPC_Version = 0; +DWORD FSUIPC_FS_Version = 0; +DWORD FSUIPC_Lib_Version = LIB_VERSION; + +static HWND m_hWnd = 0; // FS6 window handle +static UINT m_msg = 0; // id of registered window message +static ATOM m_atom = 0; // global atom containing name of file-mapping object +static HANDLE m_hMap = 0; // handle of file-mapping object +static BYTE* m_pView = 0; // pointer to view of file-mapping object +static BYTE* m_pNext = 0; + +/****************************************************************************** + FSUIPC_Close +******************************************************************************/ + +// Stop the client +void FSUIPC_Close(void) +{ m_hWnd = 0; + m_msg = 0; + + if (m_atom) + { GlobalDeleteAtom(m_atom); + m_atom = 0; + } + + if (m_pView) + { UnmapViewOfFile((LPVOID)m_pView); + m_pView = 0; + } + + if (m_hMap) + { CloseHandle(m_hMap); + m_hMap = 0; + } +} + +/****************************************************************************** + FSUIPC_Open +******************************************************************************/ + +// Start the client +// return: TRUE if successful, FALSE otherwise +BOOL FSUIPC_Open(DWORD dwFSReq, DWORD *pdwResult) +{ wchar_t szName[MAX_PATH]; + static int nTry = 0; + int i = 0; + + // abort if already started + if (m_pView) + { *pdwResult = FSUIPC_ERR_OPEN; + return FALSE; + } + + // Clear version information, so know when connected + FSUIPC_Version = FSUIPC_FS_Version = 0; + + // Connect via FSUIPC, which is known to be FSUIPC's own + // and isn't subject to user modificiation + m_hWnd = FindWindowEx(NULL, NULL, L"UIPCMAIN", NULL); + if (!m_hWnd) + { *pdwResult = FSUIPC_ERR_NOFS; + return FALSE; + } + + // register the window message + m_msg = RegisterWindowMessage(FS6IPC_MSGNAME1); + if (m_msg == 0) + { *pdwResult = FSUIPC_ERR_REGMSG; + return FALSE; + } + + // create the name of our file-mapping object + nTry++; // Ensures a unique string is used in case user closes and reopens + wsprintf(szName, FS6IPC_MSGNAME1 ":%X:%X", GetCurrentProcessId(), nTry); + + // stuff the name into a global atom + m_atom = GlobalAddAtom(szName); + if (m_atom == 0) + { *pdwResult = FSUIPC_ERR_ATOM; + FSUIPC_Close(); + return FALSE; + } + + // create the file-mapping object + m_hMap = CreateFileMapping( + INVALID_HANDLE_VALUE, // use system paging file + NULL, // security + PAGE_READWRITE, // protection + 0, MAX_SIZE+256, // size + szName); // name + + if ((m_hMap == 0) || (GetLastError() == ERROR_ALREADY_EXISTS)) + { *pdwResult = FSUIPC_ERR_MAP; + FSUIPC_Close(); + return FALSE; + } + + // get a view of the file-mapping object + m_pView = (BYTE*)MapViewOfFile(m_hMap, FILE_MAP_WRITE, 0, 0, 0); + if (m_pView == NULL) + { *pdwResult = FSUIPC_ERR_VIEW; + FSUIPC_Close(); + return FALSE; + } + + // Okay, now determine FSUIPC version AND FS type + m_pNext = m_pView; + + // Try up to 5 times with a 100mSec rest between each + while ((i++ < 5) && ((FSUIPC_Version == 0) || (FSUIPC_FS_Version == 0))) + { // Read FSUIPC version + if (!FSUIPC_Read(0x3304, 4, &FSUIPC_Version, pdwResult)) + { FSUIPC_Close(); + return FALSE; + } + + // and FS version and validity check pattern + if (!FSUIPC_Read(0x3308, 4, &FSUIPC_FS_Version, pdwResult)) + { FSUIPC_Close(); + return FALSE; + } + + // 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) && !FSUIPC_Write(0x330a, 2, &FSUIPC_Lib_Version, pdwResult)) + { FSUIPC_Close(); + return FALSE; + } + + // Actually send the requests and get the responses ("process") + if (!FSUIPC_Process(pdwResult)) + { FSUIPC_Close(); + return FALSE; + } + + // Maybe running on WideClient, and need another try + Sleep(100); // Give it a chance + } + + // Only allow running on FSUIPC 1.998e or later + // with correct check pattern 0xFADE + if ((FSUIPC_Version < 0x19980005) || ((FSUIPC_FS_Version & 0xFFFF0000L) != 0xFADE0000)) + { *pdwResult = FSUIPC_ERR_VERSION; + FSUIPC_Close(); + return FALSE; + } + + FSUIPC_FS_Version &= 0xffff; // Isolates the FS version number + if (dwFSReq && (dwFSReq != FSUIPC_FS_Version)) // Optional user specific FS request + { *pdwResult = FSUIPC_ERR_WRONGFS; + FSUIPC_Close(); + return FALSE; + } + + *pdwResult = FSUIPC_ERR_OK; + return TRUE; +} + +/****************************************************************************** + FSUIPC_Process +******************************************************************************/ + +BOOL FSUIPC_Process(DWORD *pdwResult) +{ DWORD_PTR dwError; + DWORD *pdw; + F64IPC_READSTATEDATA_HDR *pHdrR; + FS6IPC_WRITESTATEDATA_HDR *pHdrW; + int i = 0; + + if (!m_pView) + { *pdwResult = FSUIPC_ERR_NOTOPEN; + return FALSE; + } + + if (m_pView == m_pNext) + { *pdwResult = FSUIPC_ERR_NODATA; + return FALSE; + } + + ZeroMemory(m_pNext, 4); // Terminator + m_pNext = m_pView; + + // send the request (allow up to 9 tries) + while ((++i < 10) && !SendMessageTimeout( + 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)) // return value + { Sleep(100); // Allow for things to happen + } + + if (i >= 10) // Failed all tries? + { *pdwResult = GetLastError() == 0 ? FSUIPC_ERR_TIMEOUT : FSUIPC_ERR_SENDMSG; + return FALSE; + } + + if (dwError != FS6IPC_MESSAGE_SUCCESS) + { *pdwResult = FSUIPC_ERR_DATA; // FSUIPC didn't like something in the data! + return FALSE; + } + + // Decode and store results of Read requests + pdw = (DWORD *) m_pView; + + while (*pdw) + { switch (*pdw) + { case F64IPC_READSTATEDATA_ID: + pHdrR = (F64IPC_READSTATEDATA_HDR *) pdw; + m_pNext += sizeof(F64IPC_READSTATEDATA_HDR); + if (pHdrR->pDest && pHdrR->nBytes) + CopyMemory(pHdrR->pDest, m_pNext, pHdrR->nBytes); + m_pNext += pHdrR->nBytes; + break; + + case FS6IPC_WRITESTATEDATA_ID: + // This is a write, so there's no returned data to store + pHdrW = (FS6IPC_WRITESTATEDATA_HDR *) pdw; + m_pNext += sizeof(FS6IPC_WRITESTATEDATA_HDR) + pHdrW->nBytes; + break; + + default: + // Error! So terminate the scan + *pdw = 0; + break; + } + + pdw = (DWORD *) m_pNext; + } + + m_pNext = m_pView; + *pdwResult = FSUIPC_ERR_OK; + return TRUE; +} + +/****************************************************************************** + FSUIPC_ReadCommon +******************************************************************************/ + +BOOL FSUIPC_ReadCommon(BOOL fSpecial, DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pResult) +{ F64IPC_READSTATEDATA_HDR *pHdr = (F64IPC_READSTATEDATA_HDR *) m_pNext; + + if (!m_pView) + { *pResult = FSUIPC_ERR_NOTOPEN; + return FALSE; + } + + if (((m_pNext - m_pView) + (dwSize + sizeof(F64IPC_READSTATEDATA_HDR))) > MAX_SIZE) + { *pResult = FSUIPC_ERR_SIZE; + return FALSE; + } + + pHdr->dwId = F64IPC_READSTATEDATA_ID; + pHdr->dwOffset = dwOffset; + pHdr->nBytes = dwSize; + pHdr->pDest = (BYTE *) pDest; + + // Initialise the reception area, so rubbish won't be returned + if (dwSize) + { if (fSpecial) CopyMemory(&m_pNext[sizeof(F64IPC_READSTATEDATA_HDR)], pDest, dwSize); + else ZeroMemory(&m_pNext[sizeof(F64IPC_READSTATEDATA_HDR)], dwSize); + } + + m_pNext += sizeof(F64IPC_READSTATEDATA_HDR) + dwSize; + + *pResult = FSUIPC_ERR_OK; + return TRUE; +} + +/****************************************************************************** + FSUIPC_Read +******************************************************************************/ + +BOOL FSUIPC_Read(DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pResult) +{ return FSUIPC_ReadCommon(FALSE, dwOffset, dwSize, pDest, pResult); +} + +/****************************************************************************** + FSUIPC_ReadSpecial +******************************************************************************/ + +BOOL FSUIPC_ReadSpecial(DWORD dwOffset, DWORD dwSize, void *pDest, DWORD *pResult) +{ return FSUIPC_ReadCommon(TRUE, dwOffset, dwSize, pDest, pResult); +} + +/****************************************************************************** + FSUIPC_Write +******************************************************************************/ + +BOOL FSUIPC_Write(DWORD dwOffset, DWORD dwSize, void *pSrce, DWORD *pdwResult) +{ FS6IPC_WRITESTATEDATA_HDR *pHdr = (FS6IPC_WRITESTATEDATA_HDR *) m_pNext; + + // check link is open + if (!m_pView) + { *pdwResult = FSUIPC_ERR_NOTOPEN; + return FALSE; + } + + // Check have spce for this request (including terminator) + if (((m_pNext - m_pView) + 4 + (dwSize + sizeof(FS6IPC_WRITESTATEDATA_HDR))) > MAX_SIZE) + { *pdwResult = FSUIPC_ERR_SIZE; + return FALSE; + } + + // Initialise header for write request + pHdr->dwId = FS6IPC_WRITESTATEDATA_ID; + pHdr->dwOffset = dwOffset; + pHdr->nBytes = dwSize; + + // Copy in the data to be written + if (dwSize) CopyMemory(&m_pNext[sizeof(FS6IPC_WRITESTATEDATA_HDR)], pSrce, dwSize); + + // Update the pointer ready for more data + m_pNext += sizeof(FS6IPC_WRITESTATEDATA_HDR) + dwSize; + + *pdwResult = FSUIPC_ERR_OK; + return TRUE; +} + +/****************************************************************************** + End of IPCuser64 module +******************************************************************************/ diff --git a/src/plugins/simulator/fsuipc64/IPCuser64.h b/src/plugins/simulator/fsuipc64/IPCuser64.h new file mode 100644 index 000000000..5788fd4fb --- /dev/null +++ b/src/plugins/simulator/fsuipc64/IPCuser64.h @@ -0,0 +1,32 @@ +#include + +#include "FSUIPC_User64.h" + +#define FS6IPC_MESSAGE_SUCCESS 1 +#define FS6IPC_MESSAGE_FAILURE 0 + +// IPC message types +#define F64IPC_READSTATEDATA_ID 4 +#define FS6IPC_WRITESTATEDATA_ID 2 + +#pragma pack (push, r1, 1) + +// read request structure +typedef struct tagF64IPC_READSTATEDATA_HDR +{ + DWORD dwId; // F64IPC_READSTATEDATA_ID + DWORD dwOffset; // state table offset + DWORD nBytes; // number of bytes of state data to read + void* pDest; // destination buffer for data (client use only) +} F64IPC_READSTATEDATA_HDR; + +// write request structure +typedef struct tagFS6IPC_WRITESTATEDATA_HDR +{ + DWORD dwId; // FS6IPC_WRITESTATEDATA_ID + DWORD dwOffset; // state table offset + DWORD nBytes; // number of bytes of state data to write +} FS6IPC_WRITESTATEDATA_HDR; + +#pragma pack (pop, r1) + diff --git a/src/plugins/simulator/fsuipc64/NewWeather.h b/src/plugins/simulator/fsuipc64/NewWeather.h new file mode 100644 index 000000000..76afd7f38 --- /dev/null +++ b/src/plugins/simulator/fsuipc64/NewWeather.h @@ -0,0 +1,120 @@ +// Wind structure (size 16 bytes) +typedef struct _NewWind +{ unsigned short UpperAlt; // Metres + unsigned short Speed; // Knots + unsigned short Gust; // Max gust speed difference, knots + unsigned short Direction; // usual 65536 = 360 units + unsigned char Turbulence; // 0-4 + unsigned char Shear; // 0-3 + unsigned short Variance; // direction variability, same units as Direction + unsigned short SpeedFract; // 1/65536ths of Knots, for more accurate vector calcs + unsigned short GapAbove; // Metres + // This is the gap from the top of surface altitude to first layer's base + // GapAbove is ignored in layers other than the surface layer, and needs + // FSUIC 4.748 or 3.998k minimum. +} NewWind; + +// Visibility structure (size 8 bytes) +typedef struct _NewVis +{ unsigned short UpperAlt; // Metres + signed short LowerAlt; // Metres + unsigned short Range; // in 1/100ths sm + unsigned short Spare; +} NewVis; + +// Cloud structure (size 16 bytes) +typedef struct _NewCloud +{ unsigned short UpperAlt; // Metres + unsigned short LowerAlt; // Metres + unsigned short Deviation; // Metres + unsigned char Coverage; // Octas, 0-8 + unsigned char Type; // 1-10 + unsigned char Turbulence; // 0-4 + unsigned char Icing; // 0-4 + signed short PrecipBase; // Metres + unsigned char PrecipType; // 0-2 + unsigned char PrecipRate; // 0-5 + unsigned char TopShape; // ? + unsigned char Spare; +} NewCloud; + +// Temperature structure (size 8 bytes) +typedef struct _NewTemp +{ unsigned short Alt; // Metres + short Day; // Degrees C + short DayNightVar; // Degrees C + short DewPoint; // Degrees C +} NewTemp; + +// Pressure structure (size 4 bytes) +typedef struct _NewPress +{ unsigned short Pressure; // 16 x mb + short Drift; // ? Maybe +} NewPress; + +// Structure mapped to FSUIPC offsets +// C000, C400, C800 and CC00 +typedef struct _NewWeather +{ unsigned short uCommand; // C000 C400 C800 CC00 + unsigned short uFlags; // C002 C402 C802 CC02 // Not used until FSX - see below + unsigned int ulSignature; // C004 C404 C804 CC04 + char chICAO[4]; // C008 C408 C808 CC08 + unsigned short uDynamics; // C00C C40C C80C CC0C // 0=none, 4=extreme + unsigned short uSeconds; // C00E C40E C80E CC0E // FSX only -- see below + double dLatitude; // C010 C410 C810 CC10 // LLA zero for GLOB or unknown ICAO + double dLongitude; // C018 C418 C818 CC18 + int nElevation; // C020 C420 C820 CC20 // metres * 65536 + unsigned int ulTimeStamp; // C024 C424 C824 CC24 // mSecs since start of session + NewPress Press; // C028 C428 C828 CC28 + NewVis Vis; // C02C C42C C82C CC2C // Base Vis -- for upper Vis layers see + int nTempCtr; // C034 C434 C834 CC34 // Number of temperature layers + NewTemp Temp[24]; // C038 C438 C838 CC38 + int nWindsCtr; // C0F8 C4F8 C8F8 CCF8 // Number of wind layers + NewWind Wind[24]; // C0FC C4FC C8FC CCFC + int nCloudsCtr; // C27C C67C CA7C CE7C // Number of Cloud layers (max 16 in FSX, was 24 + NewCloud Cloud[16]; // C280 C680 CA80 CE80 + char chUTCstamp[6]; // C380 C780 CB80 CF80 // UTC time stamp on METAR (internal use) + unsigned short fWriteback; // C386 C786 CB86 CF86 // Flags for writing back to FSX (internal use only) + unsigned long ulSettingTimeStamp; // C388 c788 CB88 CF88 // Timestamp METAR sent (internal use) + int nUpperVisCtr; // C38C C78C CB8C CF8C // Number of upper Vis layer (new in FSX) + NewVis UpperVis[12]; // C390 C790 CB90 CF90 + unsigned short uSpare[8]; // C3F0 C7F0 CBF0 CFF0 +} NewWeather; + +#define MAXVISLAYERS 12 +#define MAXTEMPLAYERS 24 +#define MAXWINDLAYERS 24 +#define MAXCLOUDLAYERS 16 + +// Commands (for set weather area only) +#define NW_SET 1 // Set weather via FSUIPC user filters +#define NW_SETEXACT 2 // Set weather bypassing user filters +#define NW_CLEAR 3 // Clear all weather, but leave dynamic setting alone +#define NW_DYNAMICS 4 // Set weather dynamics (from uDynamics value) +#define NW_GLOBAL 5 // (FSX) Put FS into Global weather mode +// You sohuld write only 'GLOB' weather after this, which will be applied everywhere. + +#define NW_METAR 128 // DON'T USE! (Internal setting when weather written via string at B000. (FSX)) + +#define NW_SET_PENDING 257 // Set weather using filters, but don't activate in FS yet +#define NW_SETEXACT_PENDING 258 // Set weather bypassing filters, but don't activate in FS yet + +#define NW_ACTIVATE 256 // Activate pending weather settings + +// Flags for FSX weather setting +#define NWF_SECONDS 1 +/* Set this flag if "Seconds" value is to be used in setting weather in FSX + This applies to weather set via NWI values or via the NEXT Metar string + written to B000. It's a "one shot" flag, cleared after use. + + The Seconds value determines whether the weather change is effective + immediately or after a delay, gradually "blending" into the existing + weather. +*/ + +// The 4 distinct areas are used as follows: +// C000 - read only, maintains current interpolated weather at aircraft +// C400 - read only, maintains last written global weather values +// C800 - write area to set weather according to Command, flags, etc etc. +// CC00 - selected read (via signature + ICAO), reads weather at weather station or GLOB + diff --git a/src/plugins/simulator/fsuipc64/fsuipc64.pro b/src/plugins/simulator/fsuipc64/fsuipc64.pro new file mode 100644 index 000000000..b934314eb --- /dev/null +++ b/src/plugins/simulator/fsuipc64/fsuipc64.pro @@ -0,0 +1,20 @@ +load(common_pre) + +requires(equals(WORD_SIZE,64)) + +QT += core dbus xml network + +TARGET = fsuipc +TEMPLATE = lib + +CONFIG += staticlib + +DEPENDPATH += . $$SourceRoot/src +INCLUDEPATH += . $$SourceRoot/src + +HEADERS += *.h +SOURCES += *.c + +DESTDIR = $$DestRoot/lib + +load(common_post) diff --git a/src/plugins/simulator/fsx/fsx.pro b/src/plugins/simulator/fsx/fsx.pro index e50fc0dbd..67a9da1fb 100644 --- a/src/plugins/simulator/fsx/fsx.pro +++ b/src/plugins/simulator/fsx/fsx.pro @@ -10,10 +10,7 @@ TEMPLATE = lib CONFIG += plugin shared CONFIG += blackmisc blackcore -LIBS += -lsimulatorfscommon -lsimulatorfsxcommon -lSimConnect -lFSUIPC_User - -# required for FSUIPC -win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib +LIBS += -lsimulatorfscommon -lsimulatorfsxcommon -lfsuipc -lSimConnect DEPENDPATH += . $$SourceRoot/src INCLUDEPATH += . $$SourceRoot/src diff --git a/src/plugins/simulator/fsxcommon/fsxcommon.pro b/src/plugins/simulator/fsxcommon/fsxcommon.pro index 8d523b158..1770077ae 100644 --- a/src/plugins/simulator/fsxcommon/fsxcommon.pro +++ b/src/plugins/simulator/fsxcommon/fsxcommon.pro @@ -8,11 +8,6 @@ TEMPLATE = lib CONFIG += staticlib CONFIG += blackmisc blackcore blackgui -LIBS += -lsimulatorfscommon -lSimConnect -lFSUIPC_User - -# required for FSUIPC -win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib - DEPENDPATH += . $$SourceRoot/src INCLUDEPATH += . $$SourceRoot/src diff --git a/src/plugins/simulator/p3d/p3d.pro b/src/plugins/simulator/p3d/p3d.pro index ac6f2eeb9..a14577e5c 100644 --- a/src/plugins/simulator/p3d/p3d.pro +++ b/src/plugins/simulator/p3d/p3d.pro @@ -10,10 +10,7 @@ TEMPLATE = lib CONFIG += plugin shared CONFIG += blackmisc blackcore -LIBS += -lsimulatorfscommon -lsimulatorfsxcommon -lSimConnect -lFSUIPC_User - -# required for FSUIPC -win32:!win32-g++*: QMAKE_LFLAGS += /NODEFAULTLIB:LIBC.lib +LIBS += -lsimulatorfscommon -lsimulatorfsxcommon -lfsuipc -lSimConnect DEPENDPATH += . $$SourceRoot/src INCLUDEPATH += . $$SourceRoot/src diff --git a/src/plugins/simulator/simulator.pro b/src/plugins/simulator/simulator.pro index 9ebb63a65..c90b5dd6e 100644 --- a/src/plugins/simulator/simulator.pro +++ b/src/plugins/simulator/simulator.pro @@ -4,6 +4,8 @@ TEMPLATE = subdirs CONFIG += ordered contains(BLACK_CONFIG,FSX|FS9|P3D) { + SUBDIRS += fsuipc32 + SUBDIRS += fsuipc64 SUBDIRS += fscommon } contains(BLACK_CONFIG,FSX|P3D) { @@ -17,7 +19,7 @@ contains(BLACK_CONFIG,FSX) { SUBDIRS += fsx SUBDIRS += fsxconfig } -contains(BLACK_CONFIG,FS9) { +contains(BLACK_CONFIG,FS9):contains(BLACK_CONFIG,FSUIPC) { SUBDIRS += fs9 } contains(BLACK_CONFIG,XPlane) {