Skip to content

Commit 3dc9499

Browse files
author
Scott Vincent
committed
New release
1 parent fdfc415 commit 3dc9499

File tree

4 files changed

+117
-117
lines changed

4 files changed

+117
-117
lines changed

instrument-data-link/instrument-data-link.cpp

Lines changed: 114 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Flight Simulator Instrument Data Link
3-
* Copyright (c) 2023 Scott Vincent
3+
* Copyright (c) 2024 Scott Vincent
44
*/
55

66
#include <windows.h>
@@ -33,20 +33,23 @@ long networkIn;
3333
long networkOut;
3434
#endif
3535

36-
// Comment the following line out if you don't want to reduce rudder sensitivity
37-
//#define RUDDER_SENSITIVITY
36+
// Comment the following line out if you don't have a Raspberry Pi Pico USB device
37+
#define PICO_JOYSTICK
3838

39-
#ifdef RUDDER_SENSITIVITY
39+
#ifdef PICO_JOYSTICK
4040
#include <Mmsystem.h>
4141
#include <joystickapi.h>
4242

43-
void joystickInit();
44-
void joystickRefresh();
43+
void picoInit();
44+
void picoRefresh();
4545

4646
int joystickId = -1;
4747
int joystickRetry = 5;
48+
bool zeroed = false;
49+
double zeroPos[4];
50+
bool modeChange = false;
51+
JOYCAPSA joyCaps;
4852
JOYINFOEX joyInfo;
49-
double rudderSensitivity = 1;
5053
#endif
5154

5255
enum FLIGHT_PHASE {
@@ -71,6 +74,8 @@ bool is747 = false;
7174
bool isK100 = false;
7275
bool isPA28 = false;
7376
bool isAirliner = false;
77+
bool isNewAircraft = false;
78+
char prevAircraft[32] = "\0";
7479
double lastHeading = 0;
7580
int lastSoftkey = 0;
7681
int lastG1000Key = 0;
@@ -216,6 +221,12 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex
216221
isK100 = false;
217222
isPA28 = false;
218223
isAirliner = false;
224+
isNewAircraft = false;
225+
226+
if (strcmp(simVars.aircraft, prevAircraft) != 0) {
227+
strcpy(prevAircraft, simVars.aircraft);
228+
isNewAircraft = true;
229+
}
219230

220231
if (strncmp(simVars.aircraft, "A310", 4) == 0 || strncmp(simVars.aircraft, "Airbus A310", 11) == 0) {
221232
isA310 = true;
@@ -403,6 +414,15 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV* pData, DWORD cbData, void* pContex
403414
completedTakeOff = false;
404415
}
405416

417+
#ifdef PICO_JOYSTICK
418+
// Populate simvars for Pico USB switchbox
419+
picoRefresh();
420+
421+
if (isNewAircraft) {
422+
simVars.sbMode = 0; // Default to autopilot
423+
}
424+
#endif
425+
406426
if (fixedPushback != -1) {
407427
// Pushback goes wrong sometimes (pushbackState == 4)
408428
fixedPushback++;
@@ -560,14 +580,6 @@ void init()
560580
addReadDefs();
561581
mapEvents();
562582

563-
for (int i = 0; i < 7; i++) {
564-
if (i < 4) {
565-
simVars.sbEncoder[i] = 0;
566-
}
567-
simVars.sbButton[i] = 1;
568-
}
569-
simVars.sbMode = 3; // Autopilot / Radio / Instruments
570-
571583
// Start requesting data
572584
if (SimConnect_RequestDataOnSimObject(hSimConnect, REQ_ID, DEF_READ_ALL, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME, 0, 0, 0, 0) != 0) {
573585
printf("Failed to start requesting data\n");
@@ -603,7 +615,7 @@ void cleanUp()
603615

604616
int __cdecl _tmain(int argc, _TCHAR* argv[])
605617
{
606-
printf("Instrument Data Link %s Copyright (c) 2023 Scott Vincent\n", versionString);
618+
printf("Instrument Data Link %s Copyright (c) 2024 Scott Vincent\n", versionString);
607619

608620
// Yield so server can start
609621
Sleep(100);
@@ -952,31 +964,6 @@ void processG1000Events()
952964
time(&lastG1000Press);
953965
}
954966

955-
void processSwitchBox(int joyNum)
956-
{
957-
switch (joyNum) {
958-
case 1: simVars.sbEncoder[0]++; break;
959-
case 2: simVars.sbEncoder[0]--; break;
960-
case 3: simVars.sbButton[0]++; break;
961-
case 4: simVars.sbEncoder[1]++; break;
962-
case 5: simVars.sbEncoder[1]--; break;
963-
case 6: simVars.sbButton[1]++; break;
964-
case 7: simVars.sbEncoder[2]++; break;
965-
case 8: simVars.sbEncoder[2]--; break;
966-
case 9: simVars.sbButton[2]++; break;
967-
case 10: simVars.sbEncoder[3]++; break;
968-
case 11: simVars.sbEncoder[3]--; break;
969-
case 12: simVars.sbButton[3]++; break;
970-
case 13: simVars.sbButton[4]++; break;
971-
case 14: simVars.sbButton[5]++; break;
972-
case 15: simVars.sbButton[6]++; break;
973-
case 17: simVars.sbMode = 1; break; // Autopilot
974-
case 18: simVars.sbMode = 2; break; // Radio
975-
case 19: simVars.sbMode = 3; break; // Instruments
976-
case 20: simVars.sbMode = 4; break; // Navigation
977-
}
978-
}
979-
980967
void processRequest(int bytes)
981968
{
982969
//// For testing only - Leave commented out
@@ -1004,11 +991,6 @@ void processRequest(int bytes)
1004991
}
1005992
writeJetbridgeVar(A310_ENG_IGNITION, value);
1006993
}
1007-
else {
1008-
#ifdef RUDDER_SENSITIVITY
1009-
rudderSensitivity = request.writeData.value + 1;
1010-
#endif
1011-
}
1012994
return;
1013995
}
1014996

@@ -1114,22 +1096,7 @@ void processRequest(int bytes)
11141096
processG1000Events();
11151097
}
11161098

1117-
if (request.writeData.eventId == SWITCHBOX_JOY) {
1118-
processSwitchBox(request.writeData.value);
1119-
if (request.writeData.value > 16) {
1120-
// Mode switch so send reply to client
1121-
EVENT_ID event;
1122-
if (strncmp(simVars.aircraft, "Cessna 152", 10) == 0) {
1123-
event = EVENT_IS_CESSNA_152;
1124-
}
1125-
else {
1126-
event = EVENT_NOT_CESSNA_152;
1127-
}
1128-
sendto(sockfd, (char*)&event, sizeof(int), 0, (SOCKADDR*)&senderAddr, addrSize);
1129-
}
1130-
return;
1131-
}
1132-
else if (request.writeData.eventId == EVENT_RESET_DRONE_FOV) {
1099+
if (request.writeData.eventId == EVENT_RESET_DRONE_FOV) {
11331100
writeJetbridgeVar(DRONE_CAMERA_FOV, 50);
11341101
return;
11351102
}
@@ -1316,10 +1283,6 @@ void server()
13161283
networkOut = 0;
13171284
}
13181285
#endif
1319-
1320-
#ifdef RUDDER_SENSITIVITY
1321-
joystickRefresh();
1322-
#endif
13231286
}
13241287

13251288
free(deltaData);
@@ -1332,77 +1295,120 @@ void server()
13321295
printf("Server stopped\n");
13331296
}
13341297

1335-
#ifdef RUDDER_SENSITIVITY
1336-
void joystickInit()
1298+
#ifdef PICO_JOYSTICK
1299+
/// <summary>
1300+
/// Raspberry Pi Pico button box (4 encoders + 4 buttons) appears as a USB joystick
1301+
/// </summary>
1302+
void picoInit()
13371303
{
1338-
joyInfo.dwSize = sizeof(joyInfo);
1339-
joyInfo.dwFlags = JOY_RETURNU | JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ;
1304+
// Initialise simvars
1305+
simVars.sbMode = 0; // Default to autopilot
1306+
for (int i = 0; i < 7; i++) {
1307+
if (i < 4) {
1308+
simVars.sbEncoder[i] = 0;
1309+
}
1310+
simVars.sbButton[i] = 0;
1311+
}
1312+
1313+
JOYCAPSA joyCaps;
13401314

13411315
for (joystickId = 0; joystickId < 16; joystickId++) {
1342-
MMRESULT res = joyGetPosEx(joystickId, &joyInfo);
1316+
MMRESULT res = joyGetDevCaps(joystickId, &joyCaps, sizeof(joyCaps));
13431317
if (res != JOYERR_NOERROR) {
13441318
continue;
13451319
}
13461320

1347-
// Rudder pedal axis will be centred (and throttles won't be)
1348-
if (joyInfo.dwUpos > 30000 && joyInfo.dwUpos < 36000 && (joyInfo.dwXpos != 32767 || joyInfo.dwYpos != 32767 || joyInfo.dwZpos != 32767)) {
1321+
// Pico has 4 axes and 9 buttons (includes 4 buttons for clickable encoders + a dummy refresh button)
1322+
if (joyCaps.wNumAxes == 4 && joyCaps.wNumButtons == 9) {
13491323
break;
13501324
}
1351-
1352-
//printf("Joystick %d (%d, %d, %d, %d) does not have rudder pedal input\n", joystickId, joyInfo.dwUpos, joyInfo.dwXpos, joyInfo.dwYpos, joyInfo.dwZpos);
13531325
}
13541326

1355-
joyInfo.dwFlags = JOY_RETURNU;
1356-
13571327
if (joystickId < 16) {
1358-
printf("Rudder pedal input found on joystick %d\n", joystickId);
1328+
printf("Found Pico joystick %d\n", joystickId);
1329+
}
1330+
else if (joystickRetry > 0) {
1331+
joystickRetry--;
1332+
joystickId = -1;
13591333
}
13601334
else {
1361-
if (joystickRetry > 0) {
1362-
joystickRetry--;
1363-
joystickId = -1;
1364-
}
1365-
else {
1366-
joystickId = 1;
1367-
printf("Defaulting to joystick %d for rudder pedal input\n", joystickId);
1368-
}
1335+
joystickId = -2;
1336+
printf("No Pico joystick connected\n");
13691337
}
13701338
}
13711339

1372-
/// <summary>
1373-
/// Reads the Rudder Pedal axis and sets vJoy axis 0 with reduced sensitivity.
1374-
/// Sensitivity is reduced to one third until the extremes where it is linearly mapped back to the full value.
1375-
/// To use: In FS2020, map vJoy axis 0 instead of the real rudder pedal axis.
1376-
/// </summary>
1377-
void joystickRefresh()
1340+
void picoRefresh()
13781341
{
13791342
if (joystickId < 0 || joystickId > 15) {
13801343
if (joystickId == -1) {
1381-
joystickInit();
1382-
vJoyInit();
1344+
picoInit();
13831345
}
13841346
return;
13851347
}
13861348

1349+
JOYINFOEX joyInfo;
1350+
joyInfo.dwSize = sizeof(joyInfo);
1351+
joyInfo.dwFlags = JOY_RETURNALL;
1352+
joyInfo.dwButtons = 0xffffffffl;
1353+
13871354
MMRESULT res = joyGetPosEx(joystickId, &joyInfo);
13881355
if (res != JOYERR_NOERROR) {
13891356
return;
13901357
}
13911358

1392-
const int centre = 32767;
1393-
1394-
int rudderPos = joyInfo.dwUpos;
1395-
if (rudderSensitivity > 1) {
1396-
// Reduce sensitivity
1397-
rudderPos = centre + ((rudderPos - centre) / rudderSensitivity);
1359+
// First set of data with buttons = 256 (refresh button) will zeroise all axes
1360+
if (!zeroed && joyInfo.dwButtons == 256) {
1361+
zeroPos[0] = joyInfo.dwXpos;
1362+
zeroPos[1] = joyInfo.dwYpos;
1363+
zeroPos[2] = joyInfo.dwZpos;
1364+
zeroPos[3] = joyInfo.dwRpos;
1365+
zeroed = true;
13981366
}
13991367

1400-
#ifdef vJoyFallback
1401-
// printf("rudder: %d adjusted to %d\n", joyInfo.dwUpos, rudderPos);
1402-
vJoySetAxis(rudderPos);
1403-
#else
1404-
printf("rudder not adjusted as no vJoy\n");
1405-
joystickId = 16;
1406-
#endif
1368+
if (zeroed) {
1369+
// Set simvars
1370+
simVars.sbEncoder[0] = joyInfo.dwXpos - zeroPos[0];
1371+
simVars.sbEncoder[1] = joyInfo.dwYpos - zeroPos[1];
1372+
simVars.sbEncoder[2] = joyInfo.dwZpos - zeroPos[2];
1373+
simVars.sbEncoder[3] = joyInfo.dwRpos - zeroPos[3];
1374+
simVars.sbButton[0] = (joyInfo.dwButtons & 1) > 0;
1375+
simVars.sbButton[1] = (joyInfo.dwButtons & 2) > 0;
1376+
simVars.sbButton[2] = (joyInfo.dwButtons & 4) > 0;
1377+
double button3 = (joyInfo.dwButtons & 8) > 0;
1378+
simVars.sbButton[3] = (joyInfo.dwButtons & 16) > 0;
1379+
simVars.sbButton[4] = (joyInfo.dwButtons & 32) > 0;
1380+
simVars.sbButton[5] = (joyInfo.dwButtons & 64) > 0;
1381+
simVars.sbButton[6] = (joyInfo.dwButtons & 128) > 0;
1382+
1383+
//printf("Axes 0=%.0f, 1=%.0f, 2=%.0f, 3=%.0f buttons 0=%.0f, 1=%.0f, 2=%.0f, 3=%.0f, 4=%.0f, 5=%.0f, 6=%.0f, 7=%.0f, \n",
1384+
// simVars.sbEncoder[0], simVars.sbEncoder[1], simVars.sbEncoder[2], simVars.sbEncoder[3], simVars.sbButton[0], simVars.sbButton[1],
1385+
// simVars.sbButton[2], button3, simVars.sbButton[3], simVars.sbButton[4], simVars.sbButton[5], simVars.sbButton[6]);
1386+
1387+
// Check for mode switch press (plays a sound when switched)
1388+
if (button3 && !modeChange) {
1389+
modeChange = true;
1390+
if (simVars.sbMode > 3) {
1391+
simVars.sbMode = 1;
1392+
}
1393+
else {
1394+
simVars.sbMode++;
1395+
}
1396+
1397+
char soundFile[50];
1398+
switch (int(simVars.sbMode)) {
1399+
case 2: strcpy(soundFile, "Sounds\\Switchbox Radio.wav"); break;
1400+
case 3: strcpy(soundFile, "Sounds\\Switchbox Instruments.wav"); break;
1401+
case 4: strcpy(soundFile, "Sounds\\Switchbox Navigation.wav"); break;
1402+
default: strcpy(soundFile, "Sounds\\Switchbox Autopilot.wav"); break;
1403+
}
1404+
1405+
PlaySound(soundFile, NULL, SND_FILENAME | SND_ASYNC);
1406+
}
1407+
1408+
// Check for mode switch release
1409+
if (modeChange && !button3) {
1410+
modeChange = false;
1411+
}
1412+
}
14071413
}
1408-
#endif // RUDDER_SENSITIVTY
1414+
#endif // PICO_JOYSTICK

instrument-data-link/instrument-data-link.vcxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@
4343
<ConfigurationType>Application</ConfigurationType>
4444
<UseDebugLibraries>true</UseDebugLibraries>
4545
<PlatformToolset>v143</PlatformToolset>
46-
<CharacterSet>Unicode</CharacterSet>
46+
<CharacterSet>MultiByte</CharacterSet>
4747
</PropertyGroup>
4848
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
4949
<ConfigurationType>Application</ConfigurationType>
5050
<UseDebugLibraries>false</UseDebugLibraries>
5151
<PlatformToolset>v143</PlatformToolset>
5252
<WholeProgramOptimization>true</WholeProgramOptimization>
53-
<CharacterSet>Unicode</CharacterSet>
53+
<CharacterSet>MultiByte</CharacterSet>
5454
</PropertyGroup>
5555
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
5656
<ImportGroup Label="ExtensionSettings">

instrument-data-link/simvarDefs.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <stdio.h>
22
#include "simvarDefs.h"
33

4-
const char* versionString = "v2.0.0";
4+
const char* versionString = "v2.0.1";
55

66
const char* SimVarDefs[][2] = {
77
// Vars for Jetbridge (must come first)
@@ -368,10 +368,7 @@ WriteEvent WriteEvents[] = {
368368
{ EVENT_LANDING_PREPARE_CABIN, "EVENT_LANDING_PREPARE_CABIN" },
369369
{ EVENT_SEATS_FOR_LANDING, "EVENT_SEATS_FOR_LANDING" },
370370
{ EVENT_GO_AROUND, "EVENT_GO_AROUND" },
371-
{ EVENT_IS_CESSNA_152, "EVENT_IS_CESSNA_152" },
372-
{ EVENT_NOT_CESSNA_152, "EVENT_NOT_CESSNA_152" },
373371
{ EVENT_RESET_DRONE_FOV, "EVENT_RESET_DRONE_FOV" },
374-
{ SWITCHBOX_JOY, "SWITCHBOX_JOY" },
375372
{ VJOY_BUTTONS, "VJOY_BUTTONS" },
376373
{ VJOY_BUTTON_1, "VJOY_BUTTON_1" },
377374
{ VJOY_BUTTON_2, "VJOY_BUTTON_2" },

instrument-data-link/simvarDefs.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,10 +363,7 @@ enum EVENT_ID {
363363
EVENT_LANDING_PREPARE_CABIN,
364364
EVENT_SEATS_FOR_LANDING,
365365
EVENT_GO_AROUND,
366-
EVENT_IS_CESSNA_152,
367-
EVENT_NOT_CESSNA_152,
368366
EVENT_RESET_DRONE_FOV,
369-
SWITCHBOX_JOY,
370367
VJOY_BUTTONS,
371368
// Buttons must start from 1 and must be sequential until VJOY_BUTTONS_END
372369
VJOY_BUTTON_1,

0 commit comments

Comments
 (0)