The online racing simulator
DashLights OutGauge Problem (Language C)
Hello,

I try to write a C-program to get the LFS-UDP-Packets of LFS to put them to my UART Interface.
All variables like Gear or Brake etc. works fine. I got them from the packet per 'memcpy' and I print there out to console.
But the "dash lights lamps" are always 'on' immaterial what I do (see attachment picture and source code).

I try to make a simple bit operations for each flags.
I mean, bit operations are quite simple like ( x & 1). That's it but it doesn't work.

Could you tell me, where is my mistake? Thanks in advance.

Here is my source code:


typedef struct OutGaugePack
{
unsigned Time; // time in milliseconds (to check order)
char Car[4]; // Car name
WORD Flags; // Info (see OG_x below)
byte Gear; // Reverse:0, Neutral:1, First:2...
byte SpareB;
float Speed; // M/S
float RPM; // RPM
float Turbo; // BAR
float EngTemp; // C
float Fuel; // 0 to 1
float OilPressure; // BAR
float OilTemp; // C
unsigned DashLights; // Dash lights available (see DL_x below)
unsigned ShowLights; // Dash lights currently switched on
float Throttle; // 0 to 1
float Brake; // 0 to 1
float Clutch; // 0 to 1
char Display1[16]; // Usually Fuel
char Display2[16]; // Usually Settings
//int ID; // optional - only if OutGauge ID is specified
}LFSPACKET;
.
.
LFSPACKET aktuellesPacket;
.
.
memcpy(&aktuellesPacket,&buffer,sizeof(LFSPACKET));
.
.
/* Works fine --------------------------------- */
printf("Clutch : %3.1f \%\n", (aktuellesPacket.Clutch*100));

/* Doesn't work -------------------------------- */
printf("\n\nFLAGS shown as HEX = %x", aktuellesPacket.DashLights);

if((aktuellesPacket.DashLights & 1) == 1)printf("\nSHIFT!");
if(aktuellesPacket.DashLights & 4) printf("\t\tPit Speed Limiter");
if(aktuellesPacket.DashLights & 3) printf("\tHandbrake\n");
if(aktuellesPacket.DashLights & 11) printf("ABS");
if(aktuellesPacket.DashLights & 8) printf("\t\tTC");
if(aktuellesPacket.DashLights & 2) printf("\t\t\tFull Beam\n");
if(aktuellesPacket.DashLights & 9) printf("Indicator Left");
if(aktuellesPacket.DashLights & 7) printf("\tIndicator Right");
if(aktuellesPacket.DashLights & 8) printf("\t\tHazard Lights\n");
if(aktuellesPacket.DashLights & 9) printf("Oil Pressure");
if(aktuellesPacket.DashLights & 10) printf("\tBattery");
.
.
.

Attached images
LFS OutGauge 1.JPG
aktuellesPacket.DashLights is the problem..

Quote :unsigned DashLights; // Dash lights available (see DL_x below)
unsigned ShowLights; // Dash lights currently switched on

change to aktuellesPacket.ShowLights
Great
yes, that was my mistake.
When I press the "Pit Limiter" now, it works. Okay, the ABS and TC lamps goes on but that a problem that I can fix

Thanks a lot David
No Problem buddy, I encontered the same problem myself
Well, I still have problems with the ShowLights. There are not doing what the game itself does. For Example, when I pull the handbrake during driving, 3 or 4 flags goes on. A really curios behaviour .

Well, I going to bed and think about it. Tomorrow I going to check my code and read books about 4 Byte bit operations. I guess, there I have a understanding problem .
Just noticed, did you by any chance implement the DL_-Enum as provided in the new InSim.txt? That's obviously wrong as it will enumerate 0,1,2,3 instead of 0,1,2,4,8 as a bitmask.
In C it should be
enum
{
DL_SHIFT = 1, // bit 0 - shift light
DL_FULLBEAM = 2, // bit 1 - full beam
DL_HANDBRAKE = 4, // bit 2 - handbrake
DL_PITSPEED = 8, // bit 3 - pit speed limiter
DL_TC = 16, // bit 4 - TC active or switched off
DL_SIGNAL_L = 32, // bit 5 - left turn signal
DL_SIGNAL_R = 64, // bit 6 - right turn signal
DL_SIGNAL_ANY = 128, // bit 7 - shared turn signal
DL_OILWARN = 256, // bit 8 - oil pressure warning
DL_BATTERY = 512, // bit 9 - battery warning
DL_ABS = 1024, // bit 10 - ABS active or switched off
DL_SPARE = 2048, // bit 11
};

AFAIK there is no reasonable C++ enum variant to accomplish this, so it's back to #defines or consts in C++.
Little absent-minded right now though, so forgive me if I'm completely wrong
Yes, I change to 1,2,4,8,16.... and it works as it should. Thanks a lot for this tip.

Well, learning by doing .
I did a lot of bit operations exercises at school but this mistake it quite a beginner fault...
I just spent the last hour working this out! It is wrong, as far as I can see. Convert the enum in InSim.txt to this...

#define DL_SHIFT 1
#define DL_FULLBEAM 2
#define DL_HANDBRAKE 4
#define DL_PITSPEED 8
#define DL_TC 16
#define DL_SIGNAL_L 32
#define DL_SIGNAL_R 64
#define DL_SIGNAL_ANY 128
#define DL_OILWARN 256
#define DL_BATTERY 512
#define DL_ABS 1024
#define DL_SPARE 2048

... and it works fine. Someone can correct me if I'm overlooking something, but it does seem like this is a mistake in InSim.txt.
That enum looks like valid C++ code from my eyes, I've used things such as it before. What makes it valid is setting each "id = value" ie (DL_TC = 16"). An enum will just increment the value associated with an id from the previous value set; starting at 0.


enum
{
ZERO,
ONE,
TWO,
};

is the same as

enum
{
ZERO = 0,
ONE = 1,
TWO = 2,
};

and this is possible as well.

enum
{
ZERO = 0,
TWO = 2,
THREE,
};

I don't see how #define and enum values would be causing any issues. DarkTimes you could try;
int enumX = EDL_SHIFT | EDL_HANDBRAKE;
int defineX = DDL_SHIFT | EDL_HANDBRAKE;

and see if there are by chance discrepancies, though I doubt it from what I have learned about the C++ language. (You can see that all values in the enum are changed to EDL and all values using defines would changed be DDL)

If perhaps there is a difference I would like to know because I always have preferred #defines in certain cases like this but never knew doing this would (or could) cause issues. Good luck.
The issue is that the enum is defined in InSim.txt as...

1
2
3
4
5
6
etc..

When it should really be...

1
2
4
8
16
32
64
etc..

The enum provided compiles, it's just wrong.
Ahh... I get what you mean now, so the values inside InSim.txt just need to be updated. I mis-understood because the enum shown had 1,2,4,8... which were the same values in the defines. But yes, it would compile and work; I guess it just needs an update!
I, too, thought this was a bug and pointed it out to Scawen here. As you can read there, it's not a bug, but rather Scawen's internal way of implementing it. Like I said in that thread, though, you save yourself the shift if you define them as bitmask and not as regular enum.

FGED GREDG RDFGDR GSFDG