The online racing simulator
Reading outgauge indicators bits
Hello. I have problem with reading indicators bits. Other values are OK. I am total noob in C++ so i edited some codes from forum. Everything is ok but i still cant read informations from Spare3. std::cout << bits[X] << std::endl; is always 0

#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <winsock.h>
#include <bitset>

#define HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
((((unsigned long)(n) & 0xFF00)) << 8) | \
((((unsigned long)(n) & 0xFF0000)) >> 8) | \
((((unsigned long)(n) & 0xFF000000)) >> 24))

#define NTOHL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
((((unsigned long)(n) & 0xFF00)) << 8) | \
((((unsigned long)(n) & 0xFF0000)) >> 8) | \
((((unsigned long)(n) & 0xFF000000)) >> 24))


#define MYPORT 55321 // the port users will be connecting to

using namespace std;

typedef struct
{
unsigned int Time; // time in milliseconds (to check order)

char Car [4]; // Car name
unsigned short Flags; // OG_FLAGS (see below)
unsigned char Gear; // Reverse:0, Neutral:1, First:2...
float Speed; // M/S
float SpareB;
float RPM; // RPM
float Turbo; // BAR
float EngTemp; // C
float Fuel; // 0 to 1
float OilPress; // BAR
float Spare1;
unsigned Spare2;
unsigned Spare3;
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;
} __attribute__ ((packed)) OutGaugePacket;


float floatSwap (float value)
{

char raw_speed[4];
raw_speed[0]= ((char*)&value)[ 3 ];
raw_speed[1]= ((char*)&value)[ 2 ];
raw_speed[2]= ((char*)&value)[ 1 ];
raw_speed[3]= ((char*)&value)[ 0 ];

float speed = reinterpret_cast<float&>(raw_speed);
return speed;
}

int main(void)
{
int sockfd; // let's make a file descriptor
OutGaugePacket og_packet; // let's create an packet
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
int addr_len;
int numbytes;
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA data;
memset(&(og_packet),'\0',96); // zero out the struct

cout << "a" << endl;

if (WSAStartup(wVersionRequested, &data) != 0)
{
perror("first");
exit(1);
}

cout << "a" << endl;

//let's create the socket
if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}

cout << "a" << endl;

// setting up our contact information here
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct

cout << "a" << endl;

//binding our socket to a port and address
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
addr_len = sizeof(struct sockaddr);


for (;;){
// receiving the goodies
if ((numbytes=recvfrom(sockfd, (char *)&og_packet, sizeof(OutGaugePacket) , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
}

cout << "Time" << NTOHL(og_packet.Time) << endl;
cout << "Car" << og_packet.Car << endl;
cout << "Gear" << og_packet.Gear-1 << endl;
cout << "SpareB" << og_packet.SpareB << endl;
cout << "Speed" << floatSwap(og_packet.Speed)*3.6 << endl;
cout << "RPM" << floatSwap(og_packet.RPM) << endl;
cout << "Turbo" << floatSwap(og_packet.Turbo) << endl;
cout << "EngTemp" << floatSwap(og_packet.EngTemp) << endl;
cout << "Fuel" << floatSwap(og_packet.Fuel) << endl;
cout << "OilPress" << floatSwap(og_packet.OilPress) << endl;
cout << "Spare1" << floatSwap(og_packet.Spare1) << endl;
cout << "Spare2" << floatSwap(og_packet.Spare2) << endl;
cout << "Spare3" << floatSwap(og_packet.Spare3) << endl;
std::bitset<sizeof(int)> bits(og_packet.Spare3);
std::cout << bits[0] << std::endl;
std::cout << bits[1] << std::endl;
std::cout << bits[2] << std::endl;
std::cout << bits[3] << std::endl;
std::cout << bits[4] << std::endl;
std::cout << bits[5] << std::endl;
std::cout << bits[6] << std::endl;
std::cout << bits[7] << std::endl;
std::cout << bits[8] << std::endl;
cout << "Throttle" << (floatSwap(og_packet.Throttle) * 100) << endl;
cout << "Brake" << (floatSwap(og_packet.Brake)* 100) << endl;
cout << "Clutch" << (floatSwap(og_packet.Clutch)* 100) << endl;
cout << "Display1" << og_packet.Display1 << endl;
cout << "Display2" << og_packet.Display2 << endl;
cout << "ID" << NTOHL(og_packet.ID) << endl;
}

closesocket(sockfd);
WSACleanup();

return 0;
}

The source you're experimenting with uses the old OutGauge format. Refer to LFS/docs/InSim.txt for the new format.
Thank you. I think It works. Another problem is that there is delay. I don't know why (Is it because i stop console output when i press slider?). Do you know about some really simple form framework where I can output these variables ?

#include <stdlib.h>
#include <iostream>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <winsock.h>
#include <bitset>

#define MYPORT 55321 // the port users will be connecting to

using namespace std;

typedef struct
{
unsigned int Time; // time in milliseconds (to check order)

char Car[4]; // Car name
unsigned short Flags; // OG_FLAGS (see below)
unsigned char Gear; // Reverse:0, Neutral:1, First:2...
unsigned char PLID; // Unique ID of viewed player (0 = none)
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;
} __attribute__ ((packed)) OutGaugePacket;

int main(void)
{
int sockfd; // let's make a file descriptor
OutGaugePacket og_packet; // let's create an packet
struct sockaddr_in my_addr; // my address information
struct sockaddr_in their_addr; // connector's address information
int addr_len;
int numbytes;
WORD wVersionRequested = MAKEWORD(1,1);
WSADATA data;
memset(&(og_packet),'\0',96); // zero out the struct

cout << "a" << endl;

if (WSAStartup(wVersionRequested, &data) != 0)
{
perror("first");
exit(1);
}

cout << "a" << endl;

//let's create the socket
if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}

cout << "a" << endl;

// setting up our contact information here
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT); // short, network byte order
my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct

cout << "a" << endl;

//binding our socket to a port and address
if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
perror("bind");
exit(1);
}
addr_len = sizeof(struct sockaddr);


for (;;){
// receiving the goodies
if ((numbytes=recvfrom(sockfd, (char *)&og_packet, sizeof(OutGaugePacket) , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
}

cout << "Time " << og_packet.Time << endl;
cout << "Car " << og_packet.Car << endl;
cout << "Gear " << int(og_packet.Gear) << endl;
cout << "PLID " << int(og_packet.PLID) << endl;
cout << "Speed " << og_packet.Speed << endl;
cout << "RPM " << og_packet.RPM << endl;
cout << "Turbo " << og_packet.Turbo << endl;
cout << "EngTemp " << og_packet.EngTemp << endl;
cout << "Fuel " << og_packet.Fuel << endl;
cout << "OilPressure " << og_packet.OilPressure << endl;
cout << "OilTemp " << og_packet.OilTemp << endl;
cout << "DashLights " << og_packet.DashLights << endl;
cout << "ShowLights " << og_packet.ShowLights << endl;
cout << bitset<CHAR_BIT>( og_packet.ShowLights ) << endl; // Yeah i know - only 8 bits...
cout << "Throttle " << og_packet.Throttle << endl;
cout << "Brake " << og_packet.Brake << endl;
cout << "Clutch " << og_packet.Clutch << endl;
cout << "Display1 " << og_packet.Display1 << endl;
cout << "Display2 " << og_packet.Display2 << endl;
cout << "ID " << og_packet.ID << endl;
}

closesocket(sockfd);
WSACleanup();

return 0;
}

OutGauge Mode 2
OutGauge Delay 1
OutGauge IP 127.0.0.1
OutGauge Port 55321
OutGauge ID 2

I'm not sure what the default behavior of Windows command prompt is, but if the program's execution is paused, the OutGauge packets are buffered until the program resumes. The program would then read the buffered packets first which would look like a delay on the output.
Yeah, That's it. Thank you. I am playing with Qt framework now.
I am glad that here is some experienced programmer.
I have some bits of Qt networking + OutGauge code laying around somewhere in case you need it...
It will be nice if u show it. Is not Qt framework simple c++ with forms creator ?
Qt is complete framework for software development built on top of C++ with abstractions for GUI, Networking, Multimedia and all sorts of other nice stuff. A Qt way of handling OutGauge could look like this


<?php 
#include <QtCore/QByteArray>
#include <QtCore/QDataStream>
#include <QtCore/QDebug>
#include <QtCore/QString>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QUdpSocket>
const QHostAddress ADDR ("127.0.0.1");
const 
quint16 PORT 30000;

QUdpSocketogSocket = new QUdpSocket();
if (
ogSocket.bind(ADDRPORT)) {
   
connect(ogSocketSIGNAL(readyRead()), thisSLOT(getPacket()));
else
   
qDebug() << "Cannot bind socket.";

--------------------------------------------

void getPacket() {
   
QByteArray buffer;
   
qint64 length ogSocket->PendingDatagramSize();
   if (
length == 92 || length == 96) {
      
/* This is an OutGauge packet */
      
buffer.resize(length);
      
ogSocket->readDatagram(buffer.data(), lengthNULLNULL);
   } else {
      
/* Not an OutGauge packet, skip it */
      
ogSocket->readDatagram(buffer.data(), 0NULLNULL);
      return;
   }

   
/* Extract data from the packet */
   
deserialize(bufferlength);
}

void deserialize(const QByteArrayarqint64 len)
{
   
qint32 m_Time;
   
quint8 m_rawCar[4];
   
quint32 m_Flags;
   
quint8 m_Gear;
   
quint8 m_PLID;
   
float m_Speed;
   
float m_RPM;
   
float m_Turbo;
   
float m_EngTemp;
   
float m_Fuel;
   
float m_OilPressure;
   
float m_OilTemp;
   
quint32 m_DashLights;
   
quint32 m_ShowLights;
   
float m_Throttle;
   
float m_Brake;
   
float m_Clutch;
   
quint8 m_rawDisplay1[16];
   
quint8 m_rawDisplay2[16];
   
qint32 m_ID;   

   
QDataStream stream(ar);
   
stream.setByteOrder(QDataStream::LittleEndian);
   
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);

   
stream >> m_Time;
   for (
int i 04i++)
      
stream >> m_rawCar[i];

   
stream >> m_Flags >> m_Gear >> m_PLID >> m_Speed >> m_RPM >> m_Turbo >> m_EngTemp >> m_Fuel >> m_OilPressure >> m_OilTemp >> m_DashLights >> m_ShowLights >> m_Throttle >> m_Brake >> m_Clutch;
   for (
int i 016i++)
      
stream >> m_rawDisplay1[i];
   for (
int i 016i++)
      
stream >> m_rawDisplay2[i];

   if (
len == 96)
      
stream >> m_ID;

  
QString m_Car QString::fromLatin1((const char*)m_rawCar);
  
QString m_Display1 QString::fromLatin1((const char*)m_rawDisplay1);
  
QString m_Display2 QString::fromLatin1((const char*)m_rawDisplay2);
}
?>


FGED GREDG RDFGDR GSFDG