mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
refactor: Remove FSUIPC
This commit is contained in:
@@ -6,8 +6,8 @@ add_executable(samples_miscsim
|
||||
samplemiscsim.h
|
||||
samplesfscommon.cpp
|
||||
samplesfscommon.h
|
||||
samplesfsuipc.cpp
|
||||
samplesfsuipc.h
|
||||
# samplesfsuipc.cpp
|
||||
# samplesfsuipc.h
|
||||
samplesfsx.cpp
|
||||
samplesfsx.h
|
||||
samplesmodelmapping.cpp
|
||||
@@ -24,9 +24,3 @@ target_link_libraries(samples_miscsim core misc Qt::Core)
|
||||
if(WIN32)
|
||||
target_link_libraries(samples_miscsim fscommon)
|
||||
endif()
|
||||
|
||||
if(SWIFT_WIN32)
|
||||
target_link_libraries(samples_miscsim fsuipc_32)
|
||||
elseif(SWIFT_WIN64)
|
||||
target_link_libraries(samples_miscsim fsuipc_64)
|
||||
endif()
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "samplesfscommon.h"
|
||||
#include "samplesfsuipc.h"
|
||||
#include "samplesfsx.h"
|
||||
#include "samplesmodelmapping.h"
|
||||
#include "samplesp3d.h"
|
||||
@@ -47,7 +46,6 @@ int main(int argc, char *argv[])
|
||||
streamOut << "3 .. Mappings" << Qt::endl;
|
||||
streamOut << "4 .. vPilot rules" << Qt::endl;
|
||||
streamOut << "5 .. P3D cfg files" << Qt::endl;
|
||||
streamOut << "6 .. FSUIPC read" << Qt::endl;
|
||||
streamOut << "x .. exit" << Qt::endl;
|
||||
QString i = streamIn.readLine().toLower().trimmed();
|
||||
|
||||
@@ -57,7 +55,6 @@ int main(int argc, char *argv[])
|
||||
else if (i.startsWith("3")) { CSamplesModelMapping::samples(streamOut, streamIn); }
|
||||
else if (i.startsWith("4")) { CSamplesVPilotRules::samples(streamOut, streamIn); }
|
||||
else if (i.startsWith("5")) { CSamplesP3D::samplesMisc(streamOut); }
|
||||
else if (i.startsWith("6")) { CSamplesFsuipc::samplesFsuipc(streamOut); }
|
||||
else if (i.startsWith("x"))
|
||||
{
|
||||
run = false;
|
||||
|
||||
@@ -26,14 +26,6 @@ if(SWIFT_BUILD_FSX_PLUGIN OR SWIFT_BUILD_P3D_PLUGIN OR SWIFT_BUILD_MSFS_PLUGIN)
|
||||
add_subdirectory(fsxcommon)
|
||||
endif()
|
||||
|
||||
if(SWIFT_WIN32 AND (SWIFT_BUILD_FS9_PLUGIN OR SWIFT_BUILD_FSX_PLUGIN OR SWIFT_BUILD_P3D_PLUGIN))
|
||||
add_subdirectory(fsuipc32)
|
||||
endif()
|
||||
|
||||
if(SWIFT_WIN64 AND (SWIFT_BUILD_P3D_PLUGIN OR SWIFT_BUILD_MSFS_PLUGIN))
|
||||
add_subdirectory(fsuipc64)
|
||||
endif()
|
||||
|
||||
if(SWIFT_BUILD_FS9_PLUGIN)
|
||||
add_subdirectory(fs9)
|
||||
endif()
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||
|
||||
add_library(fscommon SHARED
|
||||
fsuipc.h
|
||||
fsuipcdummy.cpp
|
||||
fsuipcimpl.cpp
|
||||
# fsuipc.h
|
||||
# fsuipcdummy.cpp
|
||||
# fsuipcimpl.cpp
|
||||
simulatorfscommon.cpp
|
||||
simulatorfscommon.h
|
||||
simulatorfscommonfunctions.h
|
||||
@@ -13,14 +13,6 @@ add_library(fscommon SHARED
|
||||
|
||||
target_compile_definitions(fscommon PRIVATE BUILD_FSCOMMON_LIB)
|
||||
|
||||
if(SWIFT_WIN32)
|
||||
target_compile_definitions(fscommon PRIVATE SWIFT_USING_FSUIPC32)
|
||||
target_link_libraries(fscommon PUBLIC fsuipc_32)
|
||||
elseif (SWIFT_WIN64)
|
||||
target_compile_definitions(fscommon PRIVATE SWIFT_USING_FSUIPC64)
|
||||
target_link_libraries(fscommon PUBLIC fsuipc_64)
|
||||
endif()
|
||||
|
||||
target_link_libraries(fscommon
|
||||
PUBLIC
|
||||
Qt::Core
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
# SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||
|
||||
add_library(fsuipc_32 STATIC FSUIPC_User.h IPCuser.c IPCuser.h NewWeather.h)
|
||||
@@ -1,62 +0,0 @@
|
||||
#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_
|
||||
@@ -1,338 +0,0 @@
|
||||
/* 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
|
||||
******************************************************************************/
|
||||
@@ -1,29 +0,0 @@
|
||||
#include <Windows.h>
|
||||
|
||||
#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;
|
||||
@@ -1,125 +0,0 @@
|
||||
// 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
|
||||
@@ -1,4 +0,0 @@
|
||||
# SPDX-FileCopyrightText: Copyright (C) swift Project Community / Contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
|
||||
|
||||
add_library(fsuipc_64 STATIC FSUIPC_User64.h IPCuser64.c IPCuser64.h NewWeather.h)
|
||||
@@ -1,64 +0,0 @@
|
||||
#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_
|
||||
@@ -1,357 +0,0 @@
|
||||
/* 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;
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 = 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_PTR dwError = 0;
|
||||
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
|
||||
******************************************************************************/
|
||||
@@ -1,31 +0,0 @@
|
||||
#include <Windows.h>
|
||||
|
||||
#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)
|
||||
@@ -1,125 +0,0 @@
|
||||
// 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
|
||||
Reference in New Issue
Block a user