From 86dfa2637d9aae841af8b1a73a656b57bf113f72 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 5 Aug 2023 15:54:16 +0100 Subject: [PATCH] Change: Force spaces for indentation, and auto-reformat. Some of the formatting is no longer optimal but it is at least consistent. --- audio.c | 244 +++---- audio.h | 13 +- cars.c | 161 +++-- cars.h | 26 +- config.c | 203 +++--- gauge.c | 369 +++++----- gauge.h | 75 +- gettime.h | 37 +- insim.c | 595 ++++++++-------- insim.h | 1764 +++++++++++++++++++++++----------------------- lfsdash.c | 1678 ++++++++++++++++++++++--------------------- list.h | 132 ++-- network_worker.c | 229 +++--- outgauge.c | 78 +- outgauge.h | 41 +- queue.c | 119 ++-- socket.c | 218 +++--- socket.h | 7 +- text.c | 56 +- text.h | 3 +- timer.c | 100 +-- timer.h | 2 +- worker.c | 174 ++--- worker.h | 22 +- 24 files changed, 3243 insertions(+), 3103 deletions(-) diff --git a/audio.c b/audio.c index 55831c4..464bed6 100644 --- a/audio.c +++ b/audio.c @@ -1,6 +1,6 @@ #include #include -//#include +// #include #include #include #include @@ -14,187 +14,189 @@ ALCdevice *dev; ALCcontext *ctx; -//There is only one listener, and these arrays define the initial set up of the listener for its position, direction, and velocity. The listener is not moving at the start, but can move around any other sound source. -ALfloat listenerPos[]={0.0,0.0,4.0}; -ALfloat listenerVel[]={0.0,0.0,0.0}; -ALfloat listenerOri[]={0.0,0.0,1.0, 0.0,1.0,0.0}; +// There is only one listener, and these arrays define the initial set up of the listener for its position, direction, and velocity. The listener is not moving at the start, but can move around any other sound source. +ALfloat listenerPos[] = {0.0, 0.0, 4.0}; +ALfloat listenerVel[] = {0.0, 0.0, 0.0}; +ALfloat listenerOri[] = {0.0, 0.0, 1.0, 0.0, 1.0, 0.0}; -//Each sound source has similar properties that the listener has. The source0Pos and source0Vel arrays show the position and velocity of the sound source. -ALfloat source0Pos[]={ -2.0, 0.0, 0.0}; -ALfloat source0Vel[]={ 0.0, 0.0, 0.0}; +// Each sound source has similar properties that the listener has. The source0Pos and source0Vel arrays show the position and velocity of the sound source. +ALfloat source0Pos[] = {-2.0, 0.0, 0.0}; +ALfloat source0Vel[] = {0.0, 0.0, 0.0}; -//Sounds need to be stored in an array, similar to textures. Several buffers are needed to contain the sounds and other necessary information. The size, freq, format, and data variables are used when loading the sound files. -ALuint buffer[NUM_BUFFERS]; -ALuint source[NUM_SOURCES]; -ALuint environment[NUM_ENVIRONMENTS]; +// Sounds need to be stored in an array, similar to textures. Several buffers are needed to contain the sounds and other necessary information. The size, freq, format, and data variables are used when loading the sound files. +ALuint buffer[NUM_BUFFERS]; +ALuint source[NUM_SOURCES]; +ALuint environment[NUM_ENVIRONMENTS]; int file_read_int32_le(char *buffer, FILE *file) { - int r = fread(buffer, sizeof(char), 4, file); - uint32_t ret = (uint8_t)buffer[0]; - ret |= (uint8_t)buffer[1] << 8; - ret |= (uint8_t)buffer[2] << 16; - ret |= (uint8_t)buffer[3] << 24; - return ret; + int r = fread(buffer, sizeof(char), 4, file); + uint32_t ret = (uint8_t)buffer[0]; + ret |= (uint8_t)buffer[1] << 8; + ret |= (uint8_t)buffer[2] << 16; + ret |= (uint8_t)buffer[3] << 24; + return ret; } int file_read_int16_le(char *buffer, FILE *file) { - int r = fread(buffer, sizeof(char), 2, file); - uint16_t ret = (uint8_t)buffer[0]; - ret |= (uint8_t)buffer[1] << 8; - return ret; + int r = fread(buffer, sizeof(char), 2, file); + uint16_t ret = (uint8_t)buffer[0]; + ret |= (uint8_t)buffer[1] << 8; + return ret; } void file_ignore_bytes(FILE *file, int bytes) { - fseek(file, bytes, SEEK_CUR); + fseek(file, bytes, SEEK_CUR); } void *file_allocate_and_read_bytes(FILE *file, size_t bytes) { - void *buffer = malloc(bytes); - fread(buffer, 1, bytes, file); - return buffer; + void *buffer = malloc(bytes); + fread(buffer, 1, bytes, file); + return buffer; } -static inline ALenum GetFormatFromInfo(short channels, short bitsPerSample) { - if (channels == 1) - return AL_FORMAT_MONO16; - return AL_FORMAT_STEREO16; +static inline ALenum GetFormatFromInfo(short channels, short bitsPerSample) +{ + if (channels == 1) + return AL_FORMAT_MONO16; + return AL_FORMAT_STEREO16; } void audio_load(const char *filename, ALuint buffer) { - FILE* file = fopen(filename, "rb"); - char xbuffer[5]; - memset(xbuffer, 0, sizeof xbuffer); - if (fread(xbuffer, sizeof(char), 4, file) != 4 || strcmp(xbuffer, "RIFF") != 0) - printf("Not a WAV file: %s\n", xbuffer); + FILE *file = fopen(filename, "rb"); + char xbuffer[5]; + memset(xbuffer, 0, sizeof xbuffer); + if (fread(xbuffer, sizeof(char), 4, file) != 4 || strcmp(xbuffer, "RIFF") != 0) + printf("Not a WAV file: %s\n", xbuffer); - file_read_int32_le(xbuffer, file); + file_read_int32_le(xbuffer, file); - if (fread(xbuffer, sizeof(char), 4, file) != 4 || strcmp(xbuffer, "WAVE") != 0) - printf("Not a WAV file: %s\n", xbuffer); + if (fread(xbuffer, sizeof(char), 4, file) != 4 || strcmp(xbuffer, "WAVE") != 0) + printf("Not a WAV file: %s\n", xbuffer); - if (fread(xbuffer, sizeof(char), 4, file) != 4 || strcmp(xbuffer, "fmt ") != 0) - printf("Invalid WAV file: %s\n", xbuffer); + if (fread(xbuffer, sizeof(char), 4, file) != 4 || strcmp(xbuffer, "fmt ") != 0) + printf("Invalid WAV file: %s\n", xbuffer); - int size = file_read_int32_le(xbuffer, file); - short audioFormat = file_read_int16_le(xbuffer, file); - short channels = file_read_int16_le(xbuffer, file); - int sampleRate = file_read_int32_le(xbuffer, file); - int byteRate = file_read_int32_le(xbuffer, file); - file_read_int16_le(xbuffer, file); - short bitsPerSample = file_read_int16_le(xbuffer, file); + int size = file_read_int32_le(xbuffer, file); + short audioFormat = file_read_int16_le(xbuffer, file); + short channels = file_read_int16_le(xbuffer, file); + int sampleRate = file_read_int32_le(xbuffer, file); + int byteRate = file_read_int32_le(xbuffer, file); + file_read_int16_le(xbuffer, file); + short bitsPerSample = file_read_int16_le(xbuffer, file); - size -= 16; + size -= 16; - file_ignore_bytes(file, size); + file_ignore_bytes(file, size); - if (fread(xbuffer, sizeof(char), 4, file) != 4 || strcmp(xbuffer, "data") != 0) - printf("Invalid WAV file: %s\n", xbuffer); + if (fread(xbuffer, sizeof(char), 4, file) != 4 || strcmp(xbuffer, "data") != 0) + printf("Invalid WAV file: %s\n", xbuffer); - int dataChunkSize = file_read_int32_le(xbuffer, file); - unsigned char* bufferData = file_allocate_and_read_bytes(file, (size_t) dataChunkSize); + int dataChunkSize = file_read_int32_le(xbuffer, file); + unsigned char *bufferData = file_allocate_and_read_bytes(file, (size_t)dataChunkSize); - float duration = (float)(dataChunkSize) / byteRate; - alBufferData(buffer, GetFormatFromInfo(channels, bitsPerSample), bufferData, dataChunkSize, sampleRate); - free(bufferData); - fclose(file); + float duration = (float)(dataChunkSize) / byteRate; + alBufferData(buffer, GetFormatFromInfo(channels, bitsPerSample), bufferData, dataChunkSize, sampleRate); + free(bufferData); + fclose(file); } void audio_init(void) { - dev = alcOpenDevice(NULL); - if (!dev) - { - fprintf(stderr, "Oops\n"); - return; - } + dev = alcOpenDevice(NULL); + if (!dev) + { + fprintf(stderr, "Oops\n"); + return; + } - ctx = alcCreateContext(dev, NULL); - alcMakeContextCurrent(ctx); - if (!ctx) - { - fprintf(stderr, "Oops2\n"); - return; - } + ctx = alcCreateContext(dev, NULL); + alcMakeContextCurrent(ctx); + if (!ctx) + { + fprintf(stderr, "Oops2\n"); + return; + } - alListenerfv(AL_POSITION,listenerPos); - alListenerfv(AL_VELOCITY,listenerVel); - alListenerfv(AL_ORIENTATION,listenerOri); + alListenerfv(AL_POSITION, listenerPos); + alListenerfv(AL_VELOCITY, listenerVel); + alListenerfv(AL_ORIENTATION, listenerOri); - alGetError(); // clear any error messages + alGetError(); // clear any error messages - // Generate buffers, or else no sound will happen! - alGenBuffers(NUM_BUFFERS, buffer); + // Generate buffers, or else no sound will happen! + alGenBuffers(NUM_BUFFERS, buffer); - if (alGetError() != AL_NO_ERROR) { - printf("- Error creating buffers !!\n"); - exit(1); - } + if (alGetError() != AL_NO_ERROR) + { + printf("- Error creating buffers !!\n"); + exit(1); + } - audio_load("off.wav", buffer[FX_OFF]); - audio_load("on.wav", buffer[FX_ON]); - audio_load("bing.wav", buffer[FX_BING]); - audio_load("bip.wav", buffer[FX_BIP]); - audio_load("bop.wav", buffer[FX_BOP]); + audio_load("off.wav", buffer[FX_OFF]); + audio_load("on.wav", buffer[FX_ON]); + audio_load("bing.wav", buffer[FX_BING]); + audio_load("bip.wav", buffer[FX_BIP]); + audio_load("bop.wav", buffer[FX_BOP]); - alGetError(); /* clear error */ - alGenSources(NUM_SOURCES, source); + alGetError(); /* clear error */ + alGenSources(NUM_SOURCES, source); - if (alGetError() != AL_NO_ERROR) - { - printf("- Error creating sources !!\n"); - exit(2); - } + if (alGetError() != AL_NO_ERROR) + { + printf("- Error creating sources !!\n"); + exit(2); + } - int ii; - for (ii = 0; ii < NUM_SOURCES; ii++) - { - alSourcef(source[ii], AL_PITCH, 1.0f); - alSourcef(source[ii], AL_GAIN, 1.0f); - alSourcefv(source[ii], AL_POSITION, source0Pos); - alSourcefv(source[ii], AL_VELOCITY, source0Vel); - //alSourcei(source[0], AL_BUFFER, buffer[0]); - alSourcei(source[ii], AL_LOOPING, AL_FALSE); - } + int ii; + for (ii = 0; ii < NUM_SOURCES; ii++) + { + alSourcef(source[ii], AL_PITCH, 1.0f); + alSourcef(source[ii], AL_GAIN, 1.0f); + alSourcefv(source[ii], AL_POSITION, source0Pos); + alSourcefv(source[ii], AL_VELOCITY, source0Vel); + // alSourcei(source[0], AL_BUFFER, buffer[0]); + alSourcei(source[ii], AL_LOOPING, AL_FALSE); + } } void audio_deinit(void) { - int ii; - for (ii = 0; ii < NUM_SOURCES; ii++) - { - alSourceStop(source[ii]); - } + int ii; + for (ii = 0; ii < NUM_SOURCES; ii++) + { + alSourceStop(source[ii]); + } - alDeleteSources(NUM_SOURCES, source); - alDeleteBuffers(NUM_BUFFERS, buffer); + alDeleteSources(NUM_SOURCES, source); + alDeleteBuffers(NUM_BUFFERS, buffer); - alcMakeContextCurrent(NULL); - alcDestroyContext(ctx); - alcCloseDevice(dev); + alcMakeContextCurrent(NULL); + alcDestroyContext(ctx); + alcCloseDevice(dev); } void audio_volume(float f) { - int ii; - for (ii = 0; ii < NUM_SOURCES; ii++) - { - alSourcef(source[ii], AL_GAIN, f); - } + int ii; + for (ii = 0; ii < NUM_SOURCES; ii++) + { + alSourcef(source[ii], AL_GAIN, f); + } } float frand(float mult) { - return ((float)rand() / (float)RAND_MAX) * mult; + return ((float)rand() / (float)RAND_MAX) * mult; } void audio_play(int s, int b) { - alSourceStop(source[s]); - alSourcei(source[s], AL_BUFFER, buffer[b]); - alSourcePlay(source[s]); + alSourceStop(source[s]); + alSourcei(source[s], AL_BUFFER, buffer[b]); + alSourcePlay(source[s]); } diff --git a/audio.h b/audio.h index 3bc304b..91789b0 100644 --- a/audio.h +++ b/audio.h @@ -1,12 +1,13 @@ #ifndef AUDIO_H #define AUDIO_H -enum { - FX_ON, - FX_OFF, - FX_BING, - FX_BIP, - FX_BOP, +enum +{ + FX_ON, + FX_OFF, + FX_BING, + FX_BIP, + FX_BOP, }; void audio_init(void); diff --git a/cars.c b/cars.c index c76574c..2437ea1 100644 --- a/cars.c +++ b/cars.c @@ -10,110 +10,115 @@ struct car s_cars[MAX_CARS]; #include #include -char* strsep(char** stringp, const char* delim) +char *strsep(char **stringp, const char *delim) { - char* start = *stringp; - char* p; + char *start = *stringp; + char *p; - p = (start != NULL) ? strpbrk(start, delim) : NULL; + p = (start != NULL) ? strpbrk(start, delim) : NULL; - if (p == NULL) - { - *stringp = NULL; - } - else - { - *p = '\0'; - *stringp = p + 1; - } + if (p == NULL) + { + *stringp = NULL; + } + else + { + *p = '\0'; + *stringp = p + 1; + } - return start; + return start; } #endif void init_cars(void) { - memset(s_cars, 0, sizeof s_cars); + memset(s_cars, 0, sizeof s_cars); - FILE *f = fopen("cars.txt", "r"); - if (!f) return; + FILE *f = fopen("cars.txt", "r"); + if (!f) + return; - struct car *car = s_cars; + struct car *car = s_cars; - while (!feof(f)) - { - char buf[1024]; - if (fgets(buf, sizeof buf, f) <= 0) break; - if (*buf == '#') continue; + while (!feof(f)) + { + char buf[1024]; + if (fgets(buf, sizeof buf, f) <= 0) + break; + if (*buf == '#') + continue; - char *bufp = buf, *p; - p = strsep(&bufp, ","); - strncpy(car->tag, p, sizeof car->tag); - p = strsep(&bufp, ","); - strncpy(car->base, p, sizeof car->base); - p = strsep(&bufp, ","); - strncpy(car->cls, p, sizeof car->cls); - p = strsep(&bufp, ","); - car->intake = strtol(p, NULL, 10); - p = strsep(&bufp, ","); - car->weight = strtol(p, NULL, 10); - p = strsep(&bufp, ","); - strncpy(car->name, p, sizeof car->name); - p = strsep(&bufp, ","); - car->maxrpm = strtof(p, NULL); - p = strsep(&bufp, ","); - car->maxfuel = strtof(p, NULL); - p = strsep(&bufp, ","); - car->maxboost = strtof(p, NULL); - p = strsep(&bufp, ","); - car->maxspeed = strtof(p, NULL); + char *bufp = buf, *p; + p = strsep(&bufp, ","); + strncpy(car->tag, p, sizeof car->tag); + p = strsep(&bufp, ","); + strncpy(car->base, p, sizeof car->base); + p = strsep(&bufp, ","); + strncpy(car->cls, p, sizeof car->cls); + p = strsep(&bufp, ","); + car->intake = strtol(p, NULL, 10); + p = strsep(&bufp, ","); + car->weight = strtol(p, NULL, 10); + p = strsep(&bufp, ","); + strncpy(car->name, p, sizeof car->name); + p = strsep(&bufp, ","); + car->maxrpm = strtof(p, NULL); + p = strsep(&bufp, ","); + car->maxfuel = strtof(p, NULL); + p = strsep(&bufp, ","); + car->maxboost = strtof(p, NULL); + p = strsep(&bufp, ","); + car->maxspeed = strtof(p, NULL); - car++; + car++; - if (car - s_cars == MAX_CARS) break; - } + if (car - s_cars == MAX_CARS) + break; + } - fclose(f); + fclose(f); } int get_car(const char tag[4], struct car *car) { - int i; - for (i = 0; i < MAX_CARS; i++) - { - if (!strcmp(s_cars[i].tag, tag)) - { - if (car != NULL) memcpy(car, &s_cars[i], sizeof *car); - return i; - } - } - return -1; + int i; + for (i = 0; i < MAX_CARS; i++) + { + if (!strcmp(s_cars[i].tag, tag)) + { + if (car != NULL) + memcpy(car, &s_cars[i], sizeof *car); + return i; + } + } + return -1; } const char *find_car(const char tag[4], int intake, int weight) { - const struct car *best = NULL; - int i; - for (i = 0; i < MAX_CARS; i++) - { - const struct car *car = s_cars + i; - if (!strcmp(car->base, tag)) - { - if (car->intake <= intake && car->weight <= weight) - { - if (best == NULL || (car->intake >= best->intake && car->weight >= best->weight)) - { - best = s_cars + i; - } - } - } - } - return best->tag; + const struct car *best = NULL; + int i; + for (i = 0; i < MAX_CARS; i++) + { + const struct car *car = s_cars + i; + if (!strcmp(car->base, tag)) + { + if (car->intake <= intake && car->weight <= weight) + { + if (best == NULL || (car->intake >= best->intake && car->weight >= best->weight)) + { + best = s_cars + i; + } + } + } + } + return best->tag; } void update_car(int carnum, float dist, float time, float cons) { - s_cars[carnum].dist += dist; - s_cars[carnum].time += time; - s_cars[carnum].cons += cons; + s_cars[carnum].dist += dist; + s_cars[carnum].time += time; + s_cars[carnum].cons += cons; } diff --git a/cars.h b/cars.h index aa354fe..a62c0b5 100644 --- a/cars.h +++ b/cars.h @@ -5,20 +5,20 @@ struct car { - char tag[4]; - char base[4]; - char cls[20]; - char name[20]; - float maxrpm; - float maxfuel; - float maxboost; - float maxspeed; - int intake; - int weight; + char tag[4]; + char base[4]; + char cls[20]; + char name[20]; + float maxrpm; + float maxfuel; + float maxboost; + float maxspeed; + int intake; + int weight; - float dist; - float time; - float cons; + float dist; + float time; + float cons; }; extern struct car s_cars[MAX_CARS]; diff --git a/config.c b/config.c index 69fe2d2..aa8b965 100644 --- a/config.c +++ b/config.c @@ -7,164 +7,173 @@ struct configitem { - char setting[MAXCONFIGLEN]; - char value[MAXCONFIGLEN]; - struct configitem *next; + char setting[MAXCONFIGLEN]; + char value[MAXCONFIGLEN]; + struct configitem *next; }; static struct { - const char *filename; - struct configitem *head; + const char *filename; + struct configitem *head; } s_config; static void config_free(void) { - struct configitem *prev; - struct configitem *curr = s_config.head; + struct configitem *prev; + struct configitem *curr = s_config.head; - s_config.head = NULL; + s_config.head = NULL; - while (curr != NULL) - { - prev = curr; - curr = curr->next; - free(prev); - } + while (curr != NULL) + { + prev = curr; + curr = curr->next; + free(prev); + } } void config_set_string(const char *key, const char *value) { - struct configitem *item; - struct configitem **itemp = &s_config.head; + struct configitem *item; + struct configitem **itemp = &s_config.head; - while (*itemp != NULL) - { - if (strcasecmp((*itemp)->setting, key) == 0) - { - item = *itemp; - if (value == NULL) - { - *itemp = item->next; - free(item); - } - else - { - strncpy(item->value, value, sizeof item->value); - } - return; - } - itemp = &(*itemp)->next; - } + while (*itemp != NULL) + { + if (strcasecmp((*itemp)->setting, key) == 0) + { + item = *itemp; + if (value == NULL) + { + *itemp = item->next; + free(item); + } + else + { + strncpy(item->value, value, sizeof item->value); + } + return; + } + itemp = &(*itemp)->next; + } - if (value == NULL) return; + if (value == NULL) + return; - *itemp = malloc(sizeof *item); - item = *itemp; + *itemp = malloc(sizeof *item); + item = *itemp; - strncpy(item->setting, key, sizeof item->setting); - strncpy(item->value, value, sizeof item->value); - item->next = NULL; + strncpy(item->setting, key, sizeof item->setting); + strncpy(item->value, value, sizeof item->value); + item->next = NULL; } static void config_rehash(void) { - FILE *f = fopen(s_config.filename, "r"); - if (f == NULL) return; + FILE *f = fopen(s_config.filename, "r"); + if (f == NULL) + return; - config_free(); + config_free(); - while (!feof(f)) - { - char buf[256]; - if (fgets(buf, sizeof buf, f) <= 0) break; + while (!feof(f)) + { + char buf[256]; + if (fgets(buf, sizeof buf, f) <= 0) + break; - /* Ignore comments */ - if (*buf == '#') continue; + /* Ignore comments */ + if (*buf == '#') + continue; - char *n = strchr(buf, '='); - if (n == NULL) continue; - *n++ = '\0'; + char *n = strchr(buf, '='); + if (n == NULL) + continue; + *n++ = '\0'; - char *eol = strchr(n, '\n'); - if (eol != NULL) *eol = '\0'; + char *eol = strchr(n, '\n'); + if (eol != NULL) + *eol = '\0'; - config_set_string(buf, n); - } + config_set_string(buf, n); + } - fclose(f); + fclose(f); } static void config_write(void) { - FILE *f = fopen(s_config.filename, "w"); - if (f == NULL) return; + FILE *f = fopen(s_config.filename, "w"); + if (f == NULL) + return; - struct configitem *curr; - for (curr = s_config.head; curr != NULL; curr = curr->next) - { - fprintf(f, "%s=%s\n", curr->setting, curr->value); - } + struct configitem *curr; + for (curr = s_config.head; curr != NULL; curr = curr->next) + { + fprintf(f, "%s=%s\n", curr->setting, curr->value); + } - fclose(f); + fclose(f); } void config_init(const char *filename) { - s_config.filename = filename; - s_config.head = NULL; + s_config.filename = filename; + s_config.head = NULL; - config_rehash(); + config_rehash(); } void config_deinit(void) { - config_write(); - config_free(); + config_write(); + config_free(); } void config_set_int(const char *setting, int value) { - char c[MAXCONFIGLEN]; - snprintf(c, sizeof c, "%d", value); - config_set_string(setting, c); + char c[MAXCONFIGLEN]; + snprintf(c, sizeof c, "%d", value); + config_set_string(setting, c); } void config_set_float(const char *setting, float value) { - char c[MAXCONFIGLEN]; - snprintf(c, sizeof c, "%f", value); - config_set_string(setting, c); + char c[MAXCONFIGLEN]; + snprintf(c, sizeof c, "%f", value); + config_set_string(setting, c); } int config_get_string(const char *setting, char **value) { - struct configitem *curr; - for (curr = s_config.head; curr != NULL; curr = curr->next) - { - if (strcasecmp(curr->setting, setting) == 0) - { - *value = curr->value; - return 1; - } - } + struct configitem *curr; + for (curr = s_config.head; curr != NULL; curr = curr->next) + { + if (strcasecmp(curr->setting, setting) == 0) + { + *value = curr->value; + return 1; + } + } - *value = NULL; - return 0; + *value = NULL; + return 0; } int config_get_int(const char *setting, int *value) { - char *c, *endptr; - int v; + char *c, *endptr; + int v; - if (!config_get_string(setting, &c)) return 0; + if (!config_get_string(setting, &c)) + return 0; - v = strtol(c, &endptr, 10); - if (*endptr != '\0') return 0; + v = strtol(c, &endptr, 10); + if (*endptr != '\0') + return 0; - *value = v; - return 1; + *value = v; + return 1; } int config_get_float(const char *setting, float *value) @@ -172,10 +181,12 @@ int config_get_float(const char *setting, float *value) char *c, *endptr; float v; - if (!config_get_string(setting, &c)) return 0; + if (!config_get_string(setting, &c)) + return 0; v = strtof(c, &endptr); - if (*endptr != '\0') return 0; + if (*endptr != '\0') + return 0; *value = v; return 1; diff --git a/gauge.c b/gauge.c index f46af37..1e15437 100644 --- a/gauge.c +++ b/gauge.c @@ -11,227 +11,238 @@ void init_gauges(void) void DrawArc(float inner, float outer, float start_angle, float arc_angle, int num_segments) { - num_segments = 72; - float theta = arc_angle / (float)(num_segments - 1);//theta is now calculated from the arc angle instead, the - 1 bit comes from the fact that the arc is open + num_segments = 72; + float theta = arc_angle / (float)(num_segments - 1); // theta is now calculated from the arc angle instead, the - 1 bit comes from the fact that the arc is open - float tangetial_factor = tanf(theta); + float tangetial_factor = tanf(theta); - float radial_factor = cosf(theta); + float radial_factor = cosf(theta); - float xi = inner * sinf(start_angle); //we now start at the start angle - float yi = inner * cosf(start_angle); - float xo = outer * sinf(start_angle); //we now start at the start angle - float yo = outer * cosf(start_angle); + float xi = inner * sinf(start_angle); // we now start at the start angle + float yi = inner * cosf(start_angle); + float xo = outer * sinf(start_angle); // we now start at the start angle + float yo = outer * cosf(start_angle); + glBegin(GL_TRIANGLE_STRIP); // since the arc is not a closed curve, this is a strip now + int ii; + for (ii = 0; ii < num_segments; ii++) + { + glVertex3f(xi, yi, 0); + glVertex3f(xo, yo, 0); - glBegin(GL_TRIANGLE_STRIP);//since the arc is not a closed curve, this is a strip now - int ii; - for(ii = 0; ii < num_segments; ii++) - { - glVertex3f(xi, yi, 0); - glVertex3f(xo, yo, 0); + float txi = -yi; + float tyi = xi; - float txi = -yi; - float tyi = xi; + xi += txi * tangetial_factor; + yi += tyi * tangetial_factor; - xi += txi * tangetial_factor; - yi += tyi * tangetial_factor; + xi *= radial_factor; + yi *= radial_factor; - xi *= radial_factor; - yi *= radial_factor; + float txo = -yo; + float tyo = xo; - float txo = -yo; - float tyo = xo; + xo += txo * tangetial_factor; + yo += tyo * tangetial_factor; - xo += txo * tangetial_factor; - yo += tyo * tangetial_factor; - - xo *= radial_factor; - yo *= radial_factor; - } - glEnd(); + xo *= radial_factor; + yo *= radial_factor; + } + glEnd(); } /* - float theta = 2 * 3.1415926 / (float)num_segments; - float c = cosf(theta);//precalculate the sine and cosine - float s = sinf(theta); - float t; + float theta = 2 * 3.1415926 / (float)num_segments; + float c = cosf(theta);//precalculate the sine and cosine + float s = sinf(theta); + float t; - float x = r;//we start at angle = 0 - float y = 0; + float x = r;//we start at angle = 0 + float y = 0; - glBegin(GL_LINE_LOOP); - int ii; - for(ii = 0; ii < num_segments; ii++) - { - glVertex3f(x + cx, y + cy, 0);//output vertex + glBegin(GL_LINE_LOOP); + int ii; + for(ii = 0; ii < num_segments; ii++) + { + glVertex3f(x + cx, y + cy, 0);//output vertex - //apply the rotation matrix - t = x; - x = c * x - s * y; - y = s * t + c * y; - } - glEnd(); + //apply the rotation matrix + t = x; + x = c * x - s * y; + y = s * t + c * y; + } + glEnd(); }*/ void drawDial(const struct gauge *gauge, float value, int style) { float range = gauge->rangemax - gauge->rangemin; - float angle = gauge->anglemax - gauge->anglemin; + float angle = gauge->anglemax - gauge->anglemin; float cura = (value - gauge->rangemin) / range * angle + gauge->anglemin; - - switch (style) { - case GT_NONE: - break; - case GT_BAR: - glColor4f(gauge->dial.r, gauge->dial.g, gauge->dial.b, gauge->dial.a); - DrawArc(gauge->majorstart, gauge->majorend, cura, cura - gauge->anglemin, 10); - break; - case GT_LINE2: - glColor4f(gauge->dial.r, gauge->dial.g, gauge->dial.b, gauge->dial.a); - glBegin(GL_LINES); - glVertex3f(0, 0, 0); - glVertex3f(sin(cura), cos(cura), 0); - glEnd(); - break; - case GT_LINE: - glColor4f(1.0, 0.0, 0.0, 1.0); - glBegin(GL_LINES); - glVertex3f(sin(cura) * 0.8, cos(cura) * 0.8, 0); - glVertex3f(sin(cura), cos(cura), 0); - glEnd(); - break; - default: - case GT_NEEDLE: - glColor4f(gauge->dial.r, gauge->dial.g, gauge->dial.b, gauge->dial.a); - glRotatef(cura * -180.0 / M_PI, 0.0, 0.0, 1.0); - glBegin(GL_TRIANGLE_STRIP); - //glVertex3f(-0.01, -0.04, 0.0); - //glVertex3f(0.01, -0.04, 0.0); - //glVertex3f(-0.02, 0, 0.0); - //glVertex3f(0.02, 0.0, 0.0); - //glVertex3f(-0.005, 1.0, 0.0); - //glVertex3f(0.005, 1.0, 0.0); - glVertex3f(-0.02, 0.2, 0.0); - glVertex3f(0.02, 0.2, 0.0); - glVertex3f(-0.005, 1.0, 0.0); - glVertex3f(0.005, 1.0, 0.0); - //glVertex3f(0.0, 1.0, 0.0); - glEnd(); - break; - } + case GT_NONE: + break; + case GT_BAR: + glColor4f(gauge->dial.r, gauge->dial.g, gauge->dial.b, gauge->dial.a); + DrawArc(gauge->majorstart, gauge->majorend, cura, cura - gauge->anglemin, 10); + break; + case GT_LINE2: + glColor4f(gauge->dial.r, gauge->dial.g, gauge->dial.b, gauge->dial.a); + glBegin(GL_LINES); + glVertex3f(0, 0, 0); + glVertex3f(sin(cura), cos(cura), 0); + glEnd(); + break; + case GT_LINE: + glColor4f(1.0, 0.0, 0.0, 1.0); + glBegin(GL_LINES); + glVertex3f(sin(cura) * 0.8, cos(cura) * 0.8, 0); + glVertex3f(sin(cura), cos(cura), 0); + glEnd(); + break; + default: + case GT_NEEDLE: + glColor4f(gauge->dial.r, gauge->dial.g, gauge->dial.b, gauge->dial.a); + glRotatef(cura * -180.0 / M_PI, 0.0, 0.0, 1.0); + glBegin(GL_TRIANGLE_STRIP); + // glVertex3f(-0.01, -0.04, 0.0); + // glVertex3f(0.01, -0.04, 0.0); + // glVertex3f(-0.02, 0, 0.0); + // glVertex3f(0.02, 0.0, 0.0); + // glVertex3f(-0.005, 1.0, 0.0); + // glVertex3f(0.005, 1.0, 0.0); + glVertex3f(-0.02, 0.2, 0.0); + glVertex3f(0.02, 0.2, 0.0); + glVertex3f(-0.005, 1.0, 0.0); + glVertex3f(0.005, 1.0, 0.0); + // glVertex3f(0.0, 1.0, 0.0); + glEnd(); + break; + } } - void draw_gauge(const struct gauge *gauge, float value, float red, FTGLfont *font, int gaugetype) { - float range = gauge->rangemax - gauge->rangemin; - float angle = gauge->anglemax - gauge->anglemin; - float major;// = angle / (range / gauge->majorstep + 0.0); - float minor;// = angle / (range / gauge->minorstep + 0.0); - float cura; - float x1, y1, x2, y2; - int ii; + float range = gauge->rangemax - gauge->rangemin; + float angle = gauge->anglemax - gauge->anglemin; + float major; // = angle / (range / gauge->majorstep + 0.0); + float minor; // = angle / (range / gauge->minorstep + 0.0); + float cura; + float x1, y1, x2, y2; + int ii; - float majorstep = gauge->majorstep; - float minorstep = gauge->minorstep; + float majorstep = gauge->majorstep; + float minorstep = gauge->minorstep; - while (1) { - major = angle / (range / majorstep + 0.0); - minor = angle / (range / minorstep + 0.0); - if (fabsf(major) < 12 * M_PI / 180.0) { - majorstep *= 2; - minorstep = majorstep / 2; - } else { - break; - } - } + while (1) + { + major = angle / (range / majorstep + 0.0); + minor = angle / (range / minorstep + 0.0); + if (fabsf(major) < 12 * M_PI / 180.0) + { + majorstep *= 2; + minorstep = majorstep / 2; + } + else + { + break; + } + } - if (value < gauge->rangemin) value = gauge->rangemin; - if (value > gauge->rangemax * 2) value = gauge->rangemax * 2; + if (value < gauge->rangemin) + value = gauge->rangemin; + if (value > gauge->rangemax * 2) + value = gauge->rangemax * 2; - glPushMatrix(); - glScalef(gauge->radius, gauge->radius, 1.0); + glPushMatrix(); + glScalef(gauge->radius, gauge->radius, 1.0); - if (red > 0) { - glLineWidth(1.0); - glColor4f(0.8, 0.0, 0.0, 1.0); + if (red > 0) + { + glLineWidth(1.0); + glColor4f(0.8, 0.0, 0.0, 1.0); - cura = (red - gauge->rangemin) / range * angle + gauge->anglemin; + cura = (red - gauge->rangemin) / range * angle + gauge->anglemin; -/* - float x1 = sin(cura) * gauge->majorstart; - float y1 = cos(cura) * gauge->majorstart; - float x2 = sin(cura) * gauge->majorend; - float y2 = cos(cura) * gauge->majorend; - glBegin(GL_LINES); - glVertex3f(x1, y1, 0); - glVertex3f(x2, y2, 0); - glEnd();*/ + /* + float x1 = sin(cura) * gauge->majorstart; + float y1 = cos(cura) * gauge->majorstart; + float x2 = sin(cura) * gauge->majorend; + float y2 = cos(cura) * gauge->majorend; + glBegin(GL_LINES); + glVertex3f(x1, y1, 0); + glVertex3f(x2, y2, 0); + glEnd();*/ -// printf("%f -> %f\n", cura, gauge->anglemax); - DrawArc(gauge->majorstart, gauge->majorend, gauge->anglemax, gauge->anglemax - cura, 10); - } + // printf("%f -> %f\n", cura, gauge->anglemax); + DrawArc(gauge->majorstart, gauge->majorend, gauge->anglemax, gauge->anglemax - cura, 10); + } - glLineWidth(gauge->minorwidth); - glColor4f(gauge->minor.r, gauge->minor.g, gauge->minor.b, gauge->minor.a); -// for (cura = gauge->anglemin; cura < gauge->anglemax; cura += minor) - for (ii = 0; ii <= range / minorstep; ii++) - { - if (red > 0 && ii * minorstep >= red) { - glColor4f(1.0, 1.0, 1.0, 1.0); - } - float cura = gauge->anglemin + ii * minor; - x1 = sin(cura) * gauge->minorstart; - y1 = cos(cura) * gauge->minorstart; - x2 = sin(cura) * gauge->minorend; - y2 = cos(cura) * gauge->minorend; - glBegin(GL_LINES); - glVertex3f(x1, y1, 0); - glVertex3f(x2, y2, 0); - glEnd(); - } + glLineWidth(gauge->minorwidth); + glColor4f(gauge->minor.r, gauge->minor.g, gauge->minor.b, gauge->minor.a); + // for (cura = gauge->anglemin; cura < gauge->anglemax; cura += minor) + for (ii = 0; ii <= range / minorstep; ii++) + { + if (red > 0 && ii * minorstep >= red) + { + glColor4f(1.0, 1.0, 1.0, 1.0); + } + float cura = gauge->anglemin + ii * minor; + x1 = sin(cura) * gauge->minorstart; + y1 = cos(cura) * gauge->minorstart; + x2 = sin(cura) * gauge->minorend; + y2 = cos(cura) * gauge->minorend; + glBegin(GL_LINES); + glVertex3f(x1, y1, 0); + glVertex3f(x2, y2, 0); + glEnd(); + } - glLineWidth(gauge->majorwidth); - glColor4f(gauge->major.r, gauge->major.g, gauge->major.b, gauge->major.a); -// for (cura = gauge->anglemin; cura < gauge->anglemax; cura += major) - for (ii = 0; ii <= range / majorstep; ii++) - { - if (red > 0 && ii * majorstep > red) { - glColor4f(1.0, 1.0, 1.0, 1.0); - } - float cura = gauge->anglemin + ii * major; - x1 = sin(cura) * gauge->majorstart; - y1 = cos(cura) * gauge->majorstart; - x2 = sin(cura) * gauge->majorend; - y2 = cos(cura) * gauge->majorend; - glBegin(GL_LINES); - glVertex3f(x1, y1, 0); - glVertex3f(x2, y2, 0); - glEnd(); + glLineWidth(gauge->majorwidth); + glColor4f(gauge->major.r, gauge->major.g, gauge->major.b, gauge->major.a); + // for (cura = gauge->anglemin; cura < gauge->anglemax; cura += major) + for (ii = 0; ii <= range / majorstep; ii++) + { + if (red > 0 && ii * majorstep > red) + { + glColor4f(1.0, 1.0, 1.0, 1.0); + } + float cura = gauge->anglemin + ii * major; + x1 = sin(cura) * gauge->majorstart; + y1 = cos(cura) * gauge->majorstart; + x2 = sin(cura) * gauge->majorend; + y2 = cos(cura) * gauge->majorend; + glBegin(GL_LINES); + glVertex3f(x1, y1, 0); + glVertex3f(x2, y2, 0); + glEnd(); - char text[10]; - if (gauge->majorstep > 100) { - snprintf(text, sizeof text, "%d", (int)(ii * majorstep / 1000 + gauge->rangemin)); - } else { - if (range == 1) { - snprintf(text, sizeof text, ii == 0 ? "E" : ii == 1 ? "½" : "F"); - } else { - snprintf(text, sizeof text, "%d", (int)(ii * majorstep + gauge->rangemin)); - } - } + char text[10]; + if (gauge->majorstep > 100) + { + snprintf(text, sizeof text, "%d", (int)(ii * majorstep / 1000 + gauge->rangemin)); + } + else + { + if (range == 1) + { + snprintf(text, sizeof text, ii == 0 ? "E" : ii == 1 ? "½" + : "F"); + } + else + { + snprintf(text, sizeof text, "%d", (int)(ii * majorstep + gauge->rangemin)); + } + } - float scale = (gauge->majorend - gauge->majorstart) * 1.5; - float offs = gauge->majorstart - scale; - drawText(text, font, sin(cura) * offs, cos(cura) * offs, scale, scale, TA_CENTRE, TA_CENTRE); - } + float scale = (gauge->majorend - gauge->majorstart) * 1.5; + float offs = gauge->majorstart - scale; + drawText(text, font, sin(cura) * offs, cos(cura) * offs, scale, scale, TA_CENTRE, TA_CENTRE); + } drawDial(gauge, value, gaugetype); - glPopMatrix(); + glPopMatrix(); } - diff --git a/gauge.h b/gauge.h index a2f052a..5725c30 100644 --- a/gauge.h +++ b/gauge.h @@ -5,60 +5,61 @@ struct colour { - float r, g, b, a; + float r, g, b, a; }; -#define OG_SHIFT 1 // key -#define OG_CTRL 2 // key +#define OG_SHIFT 1 // key +#define OG_CTRL 2 // key -#define OG_TURBO 8192 // show turbo gauge -#define OG_KM 16384 // if not set - user prefers MILES -#define OG_BAR 32768 // if not set - user prefers PSI +#define OG_TURBO 8192 // show turbo gauge +#define OG_KM 16384 // if not set - user prefers MILES +#define OG_BAR 32768 // if not set - user prefers PSI // DL_x - bits for OutGaugePack DashLights and ShowLights enum { - DL_SHIFT, // bit 0 - shift light - DL_FULLBEAM, // bit 1 - full beam - DL_HANDBRAKE, // bit 2 - handbrake - DL_PITSPEED, // bit 3 - pit speed limiter - DL_TC, // bit 4 - TC active or switched off - DL_SIGNAL_L, // bit 5 - left turn signal - DL_SIGNAL_R, // bit 6 - right turn signal - DL_SIGNAL_ANY, // bit 7 - shared turn signal - DL_OILWARN, // bit 8 - oil pressure warning - DL_BATTERY, // bit 9 - battery warning - DL_ABS, // bit 10 - ABS active or switched off - DL_SPARE, // bit 11 - DL_NUM + DL_SHIFT, // bit 0 - shift light + DL_FULLBEAM, // bit 1 - full beam + DL_HANDBRAKE, // bit 2 - handbrake + DL_PITSPEED, // bit 3 - pit speed limiter + DL_TC, // bit 4 - TC active or switched off + DL_SIGNAL_L, // bit 5 - left turn signal + DL_SIGNAL_R, // bit 6 - right turn signal + DL_SIGNAL_ANY, // bit 7 - shared turn signal + DL_OILWARN, // bit 8 - oil pressure warning + DL_BATTERY, // bit 9 - battery warning + DL_ABS, // bit 10 - ABS active or switched off + DL_SPARE, // bit 11 + DL_NUM }; struct gauge { - char name[16]; - float radius; - float anglemin; - float anglemax; - float rangemin; - float rangemax; + char name[16]; + float radius; + float anglemin; + float anglemax; + float rangemin; + float rangemax; - float majorstep; - float majorwidth; - float majorstart; - float majorend; - struct colour major; + float majorstep; + float majorwidth; + float majorstart; + float majorend; + struct colour major; - float minorstep; - float minorwidth; - float minorstart; - float minorend; - struct colour minor; + float minorstep; + float minorwidth; + float minorstart; + float minorend; + struct colour minor; - struct colour dial; + struct colour dial; }; -enum { +enum +{ GT_NONE, GT_NEEDLE, GT_LINE, diff --git a/gettime.h b/gettime.h index 552f493..07104c1 100644 --- a/gettime.h +++ b/gettime.h @@ -32,29 +32,36 @@ static inline LARGE_INTEGER getFILETIMEoffset() static inline int clock_gettime(int X, struct timespec *ts) { - LARGE_INTEGER t; - FILETIME f; - double microseconds; - static LARGE_INTEGER offset; - static double frequencyToMicroseconds; - static int initialized = 0; - static BOOL usePerformanceCounter = 0; + LARGE_INTEGER t; + FILETIME f; + double microseconds; + static LARGE_INTEGER offset; + static double frequencyToMicroseconds; + static int initialized = 0; + static BOOL usePerformanceCounter = 0; - if (!initialized) { + if (!initialized) + { LARGE_INTEGER performanceFrequency; initialized = 1; usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency); - if (usePerformanceCounter) { + if (usePerformanceCounter) + { QueryPerformanceCounter(&offset); frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.; - } else { + } + else + { offset = getFILETIMEoffset(); frequencyToMicroseconds = 10.; } } - if (usePerformanceCounter) { + if (usePerformanceCounter) + { QueryPerformanceCounter(&t); - } else { + } + else + { GetSystemTimeAsFileTime(&f); t.QuadPart = f.dwHighDateTime; t.QuadPart <<= 32; @@ -73,9 +80,9 @@ static inline int clock_gettime(int X, struct timespec *ts) static inline unsigned gettime(void) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; } #endif diff --git a/insim.c b/insim.c index 57040ac..1c160cf 100644 --- a/insim.c +++ b/insim.c @@ -1,4 +1,4 @@ -//#define USE_IPV6 +// #define USE_IPV6 #include #ifdef WIN32 @@ -7,9 +7,9 @@ #include #define MSG_NOSIGNAL 0 #else -//#include +// #include #include -//#include +// #include #endif #include #include @@ -25,7 +25,8 @@ struct conninfo s_conninfo[256]; struct carinfo s_carinfo[256]; -struct insim_buffer { +struct insim_buffer +{ int state; uint8_t buffer[65536]; int pos; @@ -41,339 +42,353 @@ static uint8_t s_send_pos; void insim_queue(const void *buffer, size_t size) { - uint8_t *packet = malloc(size); - memcpy(packet, buffer, size); - queue_produce(s_send_queue, packet); + uint8_t *packet = malloc(size); + memcpy(packet, buffer, size); + queue_produce(s_send_queue, packet); } int insim_dequeue(int fd) { - if (s_send_packet == NULL) queue_consume(s_send_queue, (void *)&s_send_packet); + if (s_send_packet == NULL) + queue_consume(s_send_queue, (void *)&s_send_packet); - if (s_send_packet != NULL) - { - ssize_t s = send(fd, (char *)s_send_packet + s_send_pos, s_send_packet[0] - s_send_pos, MSG_NOSIGNAL); - if (s >= 0) s_send_pos += s; - if (s_send_pos >= s_send_packet[0]) - { - free(s_send_packet); - s_send_packet = 0; - s_send_pos = 0; - return 1; - } - } - return 0; + if (s_send_packet != NULL) + { + ssize_t s = send(fd, (char *)s_send_packet + s_send_pos, s_send_packet[0] - s_send_pos, MSG_NOSIGNAL); + if (s >= 0) + s_send_pos += s; + if (s_send_pos >= s_send_packet[0]) + { + free(s_send_packet); + s_send_packet = 0; + s_send_pos = 0; + return 1; + } + } + return 0; } void insim_request_info(void) { - memset(s_conninfo, 0, sizeof s_conninfo); - memset(s_carinfo, 0, sizeof s_carinfo); + memset(s_conninfo, 0, sizeof s_conninfo); + memset(s_carinfo, 0, sizeof s_carinfo); - struct IS_TINY p; - p.Size = sizeof p; - p.Type = ISP_TINY; - p.ReqI = 2; - p.SubT = TINY_NCN; - insim_queue(&p, sizeof p); + struct IS_TINY p; + p.Size = sizeof p; + p.Type = ISP_TINY; + p.ReqI = 2; + p.SubT = TINY_NCN; + insim_queue(&p, sizeof p); - p.Size = sizeof p; - p.Type = ISP_TINY; - p.ReqI = 3; - p.SubT = TINY_NPL; - insim_queue(&p, sizeof p); + p.Size = sizeof p; + p.Type = ISP_TINY; + p.ReqI = 3; + p.SubT = TINY_NPL; + insim_queue(&p, sizeof p); } void insim_handle_tiny(int fd, const void *buffer) { - const struct IS_TINY *p = buffer; - switch (p->SubT) - { - case TINY_NONE: - { - struct IS_TINY r; - r.Size = sizeof r; - r.Type = ISP_TINY; - r.ReqI = 0; - r.SubT = TINY_NONE; - insim_queue(&r, sizeof r); - break; - } - } + const struct IS_TINY *p = buffer; + switch (p->SubT) + { + case TINY_NONE: + { + struct IS_TINY r; + r.Size = sizeof r; + r.Type = ISP_TINY; + r.ReqI = 0; + r.SubT = TINY_NONE; + insim_queue(&r, sizeof r); + break; + } + } } static void ltc_duty(const char *uname, int state) { - int i; - for (i = 0; i < 256; i++) { - if (!strcmp(uname, s_conninfo[i].uname)) { - s_conninfo[i].state = state; - printf("Player %s state %d\n", uname, state); - return; - } - } + int i; + for (i = 0; i < 256; i++) + { + if (!strcmp(uname, s_conninfo[i].uname)) + { + s_conninfo[i].state = state; + printf("Player %s state %d\n", uname, state); + return; + } + } } void insim_handle_ism(int fd, const void *buffer) { - const struct IS_ISM *p = buffer; + const struct IS_ISM *p = buffer; - printf("Joined %s\n", p->HName); - insim_request_info(); + printf("Joined %s\n", p->HName); + insim_request_info(); } void insim_handle_mso(int fd, const void *buffer) { - return; - const struct IS_MSO *p = buffer; - printf("%d %d %d %d %s\n", p->UCID, p->PLID, p->UserType, p->TextStart, p->Msg); + return; + const struct IS_MSO *p = buffer; + printf("%d %d %d %d %s\n", p->UCID, p->PLID, p->UserType, p->TextStart, p->Msg); - char buf[128], *bufp = buf; - strncpy(buf, p->Msg, sizeof buf); + char buf[128], *bufp = buf; + strncpy(buf, p->Msg, sizeof buf); - int state = 0; - char *name = NULL; + int state = 0; + char *name = NULL; - int i; - for (i = 0; i < 10; i++) { - char *a = strsep(&bufp, " "); - if (a == NULL) return; - if (i == 0 && strcmp(a, "***")) return; - if (i == 1 && (!strcmp(a, "Officer") || !strcmp(a, "Cadet"))) state |= 1; - if (i == 2 && state == 1) name = a; - if (i == 3 && strcmp(a, "has")) return; - if (i == 4 && strcmp(a, "gone")) return; - if (i == 5 && !strcmp(a, "onduty")) ltc_duty(name, 1); - if (i == 5 && !strcmp(a, "offduty")) ltc_duty(name, 0); - } + int i; + for (i = 0; i < 10; i++) + { + char *a = strsep(&bufp, " "); + if (a == NULL) + return; + if (i == 0 && strcmp(a, "***")) + return; + if (i == 1 && (!strcmp(a, "Officer") || !strcmp(a, "Cadet"))) + state |= 1; + if (i == 2 && state == 1) + name = a; + if (i == 3 && strcmp(a, "has")) + return; + if (i == 4 && strcmp(a, "gone")) + return; + if (i == 5 && !strcmp(a, "onduty")) + ltc_duty(name, 1); + if (i == 5 && !strcmp(a, "offduty")) + ltc_duty(name, 0); + } } void insim_handle_ncn(int fd, const void *buffer) { - const struct IS_NCN *p = buffer; - struct conninfo *c = s_conninfo + p->UCID; - memset(c, 0, sizeof *c); - c->active = 1; - strncpy(c->uname, p->UName, sizeof c->uname); - strncpy(c->pname, p->PName, sizeof c->pname); - c->admin = p->Admin; + const struct IS_NCN *p = buffer; + struct conninfo *c = s_conninfo + p->UCID; + memset(c, 0, sizeof *c); + c->active = 1; + strncpy(c->uname, p->UName, sizeof c->uname); + strncpy(c->pname, p->PName, sizeof c->pname); + c->admin = p->Admin; - printf("Know about connection %s (%s) %d\n", c->pname, c->uname, c->admin); + printf("Know about connection %s (%s) %d\n", c->pname, c->uname, c->admin); } void insim_handle_cnl(int fd, const void *buffer) { - const struct IS_CNL *p = buffer; - struct conninfo *c = s_conninfo + p->UCID; - c->active = 0; + const struct IS_CNL *p = buffer; + struct conninfo *c = s_conninfo + p->UCID; + c->active = 0; } void insim_handle_cpr(int fd, const void *buffer) { - const struct IS_CPR *p = buffer; - struct conninfo *c = s_conninfo + p->UCID; - if (c->active == 0) fprintf(stderr, "Rename of inactive connection\n"); - strncpy(c->pname, p->PName, sizeof c->pname); + const struct IS_CPR *p = buffer; + struct conninfo *c = s_conninfo + p->UCID; + if (c->active == 0) + fprintf(stderr, "Rename of inactive connection\n"); + strncpy(c->pname, p->PName, sizeof c->pname); } void insim_handle_npl(int fd, const void *buffer) { - const struct IS_NPL *p = buffer; - struct carinfo *car = s_carinfo + p->PLID; - memset(car, 0, sizeof *car); - car->active = 1; - //strncpy(car->cname, p->CName, sizeof car->cname); - car->ucid = p->UCID; - car->mass = p->H_Mass; - car->intake = p->H_TRes; + const struct IS_NPL *p = buffer; + struct carinfo *car = s_carinfo + p->PLID; + memset(car, 0, sizeof *car); + car->active = 1; + // strncpy(car->cname, p->CName, sizeof car->cname); + car->ucid = p->UCID; + car->mass = p->H_Mass; + car->intake = p->H_TRes; - strncpy(car->cname, find_car(p->CName, car->intake, car->mass), sizeof car->cname); + strncpy(car->cname, find_car(p->CName, car->intake, car->mass), sizeof car->cname); - printf("Car %d joined (%s) - %s\n", p->PLID, car->cname, s_conninfo[car->ucid].uname); + printf("Car %d joined (%s) - %s\n", p->PLID, car->cname, s_conninfo[car->ucid].uname); } void insim_handle_pll(int fd, const void *buffer) { - const struct IS_PLL *p = buffer; - struct carinfo *car = s_carinfo + p->PLID; - car->active = 0; - printf("Car %d left - %s\n", p->PLID, s_conninfo[car->ucid].uname); + const struct IS_PLL *p = buffer; + struct carinfo *car = s_carinfo + p->PLID; + car->active = 0; + printf("Car %d left - %s\n", p->PLID, s_conninfo[car->ucid].uname); } void insim_handle_mci(int fd, const void *buffer) { - const struct IS_MCI *p = buffer; - int i; - for (i = 0; i < p->NumC; i++) - { - const struct CompCar *c = p->Info + i; - struct carinfo *car = s_carinfo + c->PLID; + const struct IS_MCI *p = buffer; + int i; + for (i = 0; i < p->NumC; i++) + { + const struct CompCar *c = p->Info + i; + struct carinfo *car = s_carinfo + c->PLID; - car->position = c->Position; - car->info = c->Info; - car->sp3 = c->Sp3; - car->x = c->X; - car->y = c->Y; - car->z = c->Z; - car->speed = c->Speed; - car->direction = c->Direction; - car->heading = c->Heading; - car->angvel = c->AngVel; + car->position = c->Position; + car->info = c->Info; + car->sp3 = c->Sp3; + car->x = c->X; + car->y = c->Y; + car->z = c->Z; + car->speed = c->Speed; + car->direction = c->Direction; + car->heading = c->Heading; + car->angvel = c->AngVel; - car->hist_x[car->hist] = c->X; - car->hist_y[car->hist] = c->Y; - car->hist_s[car->hist] = c->Speed; - car->hist = (car->hist + 1) % CARPATHSIZE; - } + car->hist_x[car->hist] = c->X; + car->hist_y[car->hist] = c->Y; + car->hist_s[car->hist] = c->Speed; + car->hist = (car->hist + 1) % CARPATHSIZE; + } } typedef void (*insim_handler)(int fd, const void *buffer); static const insim_handler s_handlers[] = -{ - NULL, // ISP_NONE // 0 : not used - NULL, // ISP_ISI // 1 - instruction : insim initialise - NULL, // ISP_VER // 2 - info : version info - insim_handle_tiny, // ISP_TINY // 3 - both ways : multi purpose - NULL, // ISP_SMALL // 4 - both ways : multi purpose - NULL, // ISP_STA // 5 - info : state info - NULL, // ISP_SCH // 6 - instruction : single character - NULL, // ISP_SFP // 7 - instruction : state flags pack - NULL, // ISP_SCC // 8 - instruction : set car camera - NULL, // ISP_CPP // 9 - both ways : cam pos pack - insim_handle_ism, // ISP_ISM // 10 - info : start multiplayer - insim_handle_mso, // ISP_MSO // 11 - info : message out - NULL, // ISP_III // 12 - info : hidden /i message - NULL, // ISP_MST // 13 - instruction : type message or /command - NULL, // ISP_MTC // 14 - instruction : message to a connection - NULL, // ISP_MOD // 15 - instruction : set screen mode - NULL, // ISP_VTN // 16 - info : vote notification - NULL, // ISP_RST // 17 - info : race start - insim_handle_ncn, // ISP_NCN // 18 - info : new connection - insim_handle_cnl, // ISP_CNL // 19 - info : connection left - insim_handle_cpr, // ISP_CPR // 20 - info : connection renamed - insim_handle_npl, // ISP_NPL // 21 - info : new player (joined race) - NULL, // ISP_PLP // 22 - info : player pit (keeps slot in race) - insim_handle_pll, // ISP_PLL // 23 - info : player leave (spectate - loses slot) - NULL, // ISP_LAP // 24 - info : lap time - NULL, // ISP_SPX // 25 - info : split x time - NULL, // ISP_PIT // 26 - info : pit stop start - NULL, // ISP_PSF // 27 - info : pit stop finish - NULL, // ISP_PLA // 28 - info : pit lane enter / leave - NULL, // ISP_CCH // 29 - info : camera changed - NULL, // ISP_PEN // 30 - info : penalty given or cleared - NULL, // ISP_TOC // 31 - info : take over car - NULL, // ISP_FLG // 32 - info : flag (yellow or blue) - NULL, // ISP_PFL // 33 - info : player flags (help flags) - NULL, // ISP_FIN // 34 - info : finished race - NULL, // ISP_RES // 35 - info : result confirmed - NULL, // ISP_REO // 36 - both ways : reorder (info or instruction) - NULL, // ISP_NLP // 37 - info : node and lap packet - insim_handle_mci, // ISP_MCI // 38 - info : multi car info - NULL, // ISP_MSX // 39 - instruction : type message - NULL, // ISP_MSL // 40 - instruction : message to local computer - NULL, // ISP_CRS // 41 - info : car reset - NULL, // ISP_BFN // 42 - both ways : delete buttons / receive button requests - NULL, // ISP_AXI // 43 - info : autocross layout information - NULL, // ISP_AXO // 44 - info : hit an autocross object - NULL, // ISP_BTN // 45 - instruction : show a button on local or remote screen - NULL, // ISP_BTC // 46 - info : sent when a user clicks a button - NULL, // ISP_BTT // 47 - info : sent after typing into a button - NULL, // ISP_RIP // 48 - both ways : replay information packet - NULL, // ISP_SSH // 49 - both ways : screenshot - NULL, // ISP_CON // 50 - info : contact between cars (collision report) - NULL, // ISP_OBH // 51 - info : contact car + object (collision report) - NULL, // ISP_HLV // 52 - info : report incidents that would violate HLVC - NULL, // ISP_PLC // 53 - instruction : player cars - NULL, // ISP_AXM // 54 - both ways : autocross multiple objects - NULL, // ISP_ACR // 55 - info : admin command report + { + NULL, // ISP_NONE // 0 : not used + NULL, // ISP_ISI // 1 - instruction : insim initialise + NULL, // ISP_VER // 2 - info : version info + insim_handle_tiny, // ISP_TINY // 3 - both ways : multi purpose + NULL, // ISP_SMALL // 4 - both ways : multi purpose + NULL, // ISP_STA // 5 - info : state info + NULL, // ISP_SCH // 6 - instruction : single character + NULL, // ISP_SFP // 7 - instruction : state flags pack + NULL, // ISP_SCC // 8 - instruction : set car camera + NULL, // ISP_CPP // 9 - both ways : cam pos pack + insim_handle_ism, // ISP_ISM // 10 - info : start multiplayer + insim_handle_mso, // ISP_MSO // 11 - info : message out + NULL, // ISP_III // 12 - info : hidden /i message + NULL, // ISP_MST // 13 - instruction : type message or /command + NULL, // ISP_MTC // 14 - instruction : message to a connection + NULL, // ISP_MOD // 15 - instruction : set screen mode + NULL, // ISP_VTN // 16 - info : vote notification + NULL, // ISP_RST // 17 - info : race start + insim_handle_ncn, // ISP_NCN // 18 - info : new connection + insim_handle_cnl, // ISP_CNL // 19 - info : connection left + insim_handle_cpr, // ISP_CPR // 20 - info : connection renamed + insim_handle_npl, // ISP_NPL // 21 - info : new player (joined race) + NULL, // ISP_PLP // 22 - info : player pit (keeps slot in race) + insim_handle_pll, // ISP_PLL // 23 - info : player leave (spectate - loses slot) + NULL, // ISP_LAP // 24 - info : lap time + NULL, // ISP_SPX // 25 - info : split x time + NULL, // ISP_PIT // 26 - info : pit stop start + NULL, // ISP_PSF // 27 - info : pit stop finish + NULL, // ISP_PLA // 28 - info : pit lane enter / leave + NULL, // ISP_CCH // 29 - info : camera changed + NULL, // ISP_PEN // 30 - info : penalty given or cleared + NULL, // ISP_TOC // 31 - info : take over car + NULL, // ISP_FLG // 32 - info : flag (yellow or blue) + NULL, // ISP_PFL // 33 - info : player flags (help flags) + NULL, // ISP_FIN // 34 - info : finished race + NULL, // ISP_RES // 35 - info : result confirmed + NULL, // ISP_REO // 36 - both ways : reorder (info or instruction) + NULL, // ISP_NLP // 37 - info : node and lap packet + insim_handle_mci, // ISP_MCI // 38 - info : multi car info + NULL, // ISP_MSX // 39 - instruction : type message + NULL, // ISP_MSL // 40 - instruction : message to local computer + NULL, // ISP_CRS // 41 - info : car reset + NULL, // ISP_BFN // 42 - both ways : delete buttons / receive button requests + NULL, // ISP_AXI // 43 - info : autocross layout information + NULL, // ISP_AXO // 44 - info : hit an autocross object + NULL, // ISP_BTN // 45 - instruction : show a button on local or remote screen + NULL, // ISP_BTC // 46 - info : sent when a user clicks a button + NULL, // ISP_BTT // 47 - info : sent after typing into a button + NULL, // ISP_RIP // 48 - both ways : replay information packet + NULL, // ISP_SSH // 49 - both ways : screenshot + NULL, // ISP_CON // 50 - info : contact between cars (collision report) + NULL, // ISP_OBH // 51 - info : contact car + object (collision report) + NULL, // ISP_HLV // 52 - info : report incidents that would violate HLVC + NULL, // ISP_PLC // 53 - instruction : player cars + NULL, // ISP_AXM // 54 - both ways : autocross multiple objects + NULL, // ISP_ACR // 55 - info : admin command report }; void insim_handle(int fd, const uint8_t *buffer) { - uint8_t type = buffer[1]; - if (type <= ISP_ACR && s_handlers[type] != NULL) - { - s_handlers[type](fd, buffer); - } + uint8_t type = buffer[1]; + if (type <= ISP_ACR && s_handlers[type] != NULL) + { + s_handlers[type](fd, buffer); + } } int insim_recv(int fd, int can_write, int can_read, void *arg) { struct insim_buffer *buffer = arg; - if (can_write && buffer->state == 1) - { - insim_dequeue(fd); - } - if (can_read) - { - if (buffer->pos >= sizeof buffer->buffer) - { - printf("buffer full\n"); - return 0; - } - ssize_t res = recv(fd, (char *)buffer->buffer + buffer->pos, sizeof buffer->buffer - buffer->pos, 0); - if (res == -1) - { - #ifdef WIN32 - if (WSAGetLastError() == WSAECONNRESET) - #else - if (errno == ECONNRESET) - #endif - { - printf("connreset\n"); - return 0; - } - #ifdef WIN32 - else if (WSAGetLastError() != WSAEWOULDBLOCK) - #else - else if (errno != EWOULDBLOCK && errno != EAGAIN) - #endif - { - printf("hmm: %s\n", strerror(errno)); - return 0; - } - } - if (res == 0) - { - printf("nothing received\n"); - return 0; - } + if (can_write && buffer->state == 1) + { + insim_dequeue(fd); + } + if (can_read) + { + if (buffer->pos >= sizeof buffer->buffer) + { + printf("buffer full\n"); + return 0; + } + ssize_t res = recv(fd, (char *)buffer->buffer + buffer->pos, sizeof buffer->buffer - buffer->pos, 0); + if (res == -1) + { +#ifdef WIN32 + if (WSAGetLastError() == WSAECONNRESET) +#else + if (errno == ECONNRESET) +#endif + { + printf("connreset\n"); + return 0; + } +#ifdef WIN32 + else if (WSAGetLastError() != WSAEWOULDBLOCK) +#else + else if (errno != EWOULDBLOCK && errno != EAGAIN) +#endif + { + printf("hmm: %s\n", strerror(errno)); + return 0; + } + } + if (res == 0) + { + printf("nothing received\n"); + return 0; + } - buffer->pos += res; + buffer->pos += res; - while (1) - { - uint8_t size = buffer->buffer[buffer->offset]; - if (size % 4 != 0) - { - printf("invalid packet, size is %d\n", size); - return 0; - } + while (1) + { + uint8_t size = buffer->buffer[buffer->offset]; + if (size % 4 != 0) + { + printf("invalid packet, size is %d\n", size); + return 0; + } - if (buffer->pos - buffer->offset >= size) - { - insim_handle(fd, buffer->buffer + buffer->offset); - } - else - { - break; - } + if (buffer->pos - buffer->offset >= size) + { + insim_handle(fd, buffer->buffer + buffer->offset); + } + else + { + break; + } - if (buffer->pos - buffer->offset > size) - { - buffer->offset += size; - } - else - { - buffer->pos = 0; - buffer->offset = 0; - } - } - } + if (buffer->pos - buffer->offset > size) + { + buffer->offset += size; + } + else + { + buffer->pos = 0; + buffer->offset = 0; + } + } + } - return 1; + return 1; } /* #ifdef USE_IPV6 @@ -394,46 +409,46 @@ static void insim_connect(int fd, void *arg) } s_insim_tcp.state = 1; - s_insim_tcp.pos = 0; - s_insim_tcp.offset = 0; - register_socket(fd, SM_READ | SM_WRITE, &insim_recv, &s_insim_tcp); + s_insim_tcp.pos = 0; + s_insim_tcp.offset = 0; + register_socket(fd, SM_READ | SM_WRITE, &insim_recv, &s_insim_tcp); - fd = network_listen(g_insim_port + 1, 0); + fd = network_listen(g_insim_port + 1, 0); s_insim_udp.state = 2; - s_insim_udp.pos = 0; - s_insim_udp.offset = 0; - register_socket(fd, SM_READ, &insim_recv, &s_insim_udp); + s_insim_udp.pos = 0; + s_insim_udp.offset = 0; + register_socket(fd, SM_READ, &insim_recv, &s_insim_udp); - struct IS_ISI p; - memset(&p, 0, sizeof p); - p.Size = sizeof p; - p.Type = ISP_ISI; - p.ReqI = 0; - p.Zero = 0; - p.UDPPort = g_outgauge_port; //g_insim_port + 1; - p.Flags = ISF_LOCAL; - p.Sp0 = 0; - p.Prefix = 0; - p.Interval = 100; - snprintf(p.Admin, sizeof p.Admin, ""); - snprintf(p.IName, sizeof p.IName, "LFS Dashboard"); - insim_queue(&p, sizeof p); + struct IS_ISI p; + memset(&p, 0, sizeof p); + p.Size = sizeof p; + p.Type = ISP_ISI; + p.ReqI = 0; + p.Zero = 0; + p.UDPPort = g_outgauge_port; // g_insim_port + 1; + p.Flags = ISF_LOCAL; + p.Sp0 = 0; + p.Prefix = 0; + p.Interval = 100; + snprintf(p.Admin, sizeof p.Admin, ""); + snprintf(p.IName, sizeof p.IName, "LFS Dashboard"); + insim_queue(&p, sizeof p); - struct IS_SMALL s; - s.Size = sizeof s; - s.Type = ISP_SMALL; - s.ReqI = 1; - s.SubT = SMALL_SSG; - s.UVal = 1; - insim_queue(&s, sizeof s); + struct IS_SMALL s; + s.Size = sizeof s; + s.Type = ISP_SMALL; + s.ReqI = 1; + s.SubT = SMALL_SSG; + s.UVal = 1; + insim_queue(&s, sizeof s); - insim_request_info(); + insim_request_info(); } void insim_init(const char *hostname, int port) { - s_insim_tcp.state = 0; - s_insim_udp.state = 0; - s_send_queue = queue_new(); - network_connect(hostname, port, &insim_connect, NULL); + s_insim_tcp.state = 0; + s_insim_udp.state = 0; + s_send_queue = queue_new(); + network_connect(hostname, port, &insim_connect, NULL); } diff --git a/insim.h b/insim.h index b75725e..9aabed0 100644 --- a/insim.h +++ b/insim.h @@ -14,13 +14,11 @@ // NOTE : This text file was written with a TAB size equal to 4 spaces. - // INSIM VERSION NUMBER (updated for version 0.6B) // ==================== static const int INSIM_VERSION = 5; - // CHANGES // ======= @@ -51,7 +49,6 @@ static const int INSIM_VERSION = 5; // FIX : OutGaugePack ID was always zero regardless of ID in cfg.txt // FIX : InSim camera with vertical pitch would cause LFS to crash - // TYPES : (all multi-byte types are PC style - lowest byte first) // ===== @@ -70,7 +67,6 @@ static const int INSIM_VERSION = 5; // 100-190 : 100 to 1000 laps... laps = (rl - 100) * 10 + 100 // 191-238 : 1 to 48 hours... hours = rl - 190 - // InSim PACKETS // ============= @@ -81,7 +77,6 @@ static const int INSIM_VERSION = 5; // ReqI : non zero if the packet is a packet request or a reply to a request // Data : the first data byte - // INITIALISING InSim // ================== @@ -113,20 +108,20 @@ struct Vector struct IS_ISI // InSim Init - packet to initialise the InSim system { - uint8_t Size; // 44 - uint8_t Type; // ISP_ISI - uint8_t ReqI; // If non-zero LFS will send an IS_VER packet - uint8_t Zero; // 0 + uint8_t Size; // 44 + uint8_t Type; // ISP_ISI + uint8_t ReqI; // If non-zero LFS will send an IS_VER packet + uint8_t Zero; // 0 - uint16_t UDPPort; // Port for UDP replies from LFS (0 to 65535) - uint16_t Flags; // Bit flags for options (see below) + uint16_t UDPPort; // Port for UDP replies from LFS (0 to 65535) + uint16_t Flags; // Bit flags for options (see below) - uint8_t Sp0; // 0 - uint8_t Prefix; // Special host message prefix character - uint16_t Interval; // Time in ms between NLP or MCI (0 = none) + uint8_t Sp0; // 0 + uint8_t Prefix; // Special host message prefix character + uint16_t Interval; // Time in ms between NLP or MCI (0 = none) - char Admin[16]; // Admin password (if set in LFS) - char IName[16]; // A short name for your program + char Admin[16]; // Admin password (if set in LFS) + char IName[16]; // A short name for your program }; // NOTE 1) UDPPort field when you connect using UDP : @@ -141,17 +136,17 @@ struct IS_ISI // InSim Init - packet to initialise the InSim system // NOTE 3) Flags field (set the relevant bits to turn on the option) : -#define ISF_RES_0 1 // bit 0 : spare -#define ISF_RES_1 2 // bit 1 : spare -#define ISF_LOCAL 4 // bit 2 : guest or single player -#define ISF_MSO_COLS 8 // bit 3 : keep colours in MSO text -#define ISF_NLP 16 // bit 4 : receive NLP packets -#define ISF_MCI 32 // bit 5 : receive MCI packets -#define ISF_CON 64 // bit 6 : receive CON packets -#define ISF_OBH 128 // bit 7 : receive OBH packets -#define ISF_HLV 256 // bit 8 : receive HLV packets -#define ISF_AXM_LOAD 512 // bit 9 : receive AXM when loading a layout -#define ISF_AXM_EDIT 1024 // bit 10 : receive AXM when changing objects +#define ISF_RES_0 1 // bit 0 : spare +#define ISF_RES_1 2 // bit 1 : spare +#define ISF_LOCAL 4 // bit 2 : guest or single player +#define ISF_MSO_COLS 8 // bit 3 : keep colours in MSO text +#define ISF_NLP 16 // bit 4 : receive NLP packets +#define ISF_MCI 32 // bit 5 : receive MCI packets +#define ISF_CON 64 // bit 6 : receive CON packets +#define ISF_OBH 128 // bit 7 : receive OBH packets +#define ISF_HLV 256 // bit 8 : receive HLV packets +#define ISF_AXM_LOAD 512 // bit 9 : receive AXM when loading a layout +#define ISF_AXM_EDIT 1024 // bit 10 : receive AXM when changing objects // In most cases you should not set both ISF_NLP and ISF_MCI flags // because all IS_NLP information is included in the IS_MCI packet. @@ -167,110 +162,108 @@ struct IS_ISI // InSim Init - packet to initialise the InSim system // Messages typed with this prefix will be sent to your InSim program // on the host (in IS_MSO) and not displayed on anyone's screen. - // ENUMERATIONS FOR PACKET TYPES // ============================= enum // the second byte of any packet is one of these { - ISP_NONE, // 0 : not used - ISP_ISI, // 1 - instruction : insim initialise - ISP_VER, // 2 - info : version info - ISP_TINY, // 3 - both ways : multi purpose - ISP_SMALL, // 4 - both ways : multi purpose - ISP_STA, // 5 - info : state info - ISP_SCH, // 6 - instruction : single character - ISP_SFP, // 7 - instruction : state flags pack - ISP_SCC, // 8 - instruction : set car camera - ISP_CPP, // 9 - both ways : cam pos pack - ISP_ISM, // 10 - info : start multiplayer - ISP_MSO, // 11 - info : message out - ISP_III, // 12 - info : hidden /i message - ISP_MST, // 13 - instruction : type message or /command - ISP_MTC, // 14 - instruction : message to a connection - ISP_MOD, // 15 - instruction : set screen mode - ISP_VTN, // 16 - info : vote notification - ISP_RST, // 17 - info : race start - ISP_NCN, // 18 - info : new connection - ISP_CNL, // 19 - info : connection left - ISP_CPR, // 20 - info : connection renamed - ISP_NPL, // 21 - info : new player (joined race) - ISP_PLP, // 22 - info : player pit (keeps slot in race) - ISP_PLL, // 23 - info : player leave (spectate - loses slot) - ISP_LAP, // 24 - info : lap time - ISP_SPX, // 25 - info : split x time - ISP_PIT, // 26 - info : pit stop start - ISP_PSF, // 27 - info : pit stop finish - ISP_PLA, // 28 - info : pit lane enter / leave - ISP_CCH, // 29 - info : camera changed - ISP_PEN, // 30 - info : penalty given or cleared - ISP_TOC, // 31 - info : take over car - ISP_FLG, // 32 - info : flag (yellow or blue) - ISP_PFL, // 33 - info : player flags (help flags) - ISP_FIN, // 34 - info : finished race - ISP_RES, // 35 - info : result confirmed - ISP_REO, // 36 - both ways : reorder (info or instruction) - ISP_NLP, // 37 - info : node and lap packet - ISP_MCI, // 38 - info : multi car info - ISP_MSX, // 39 - instruction : type message - ISP_MSL, // 40 - instruction : message to local computer - ISP_CRS, // 41 - info : car reset - ISP_BFN, // 42 - both ways : delete buttons / receive button requests - ISP_AXI, // 43 - info : autocross layout information - ISP_AXO, // 44 - info : hit an autocross object - ISP_BTN, // 45 - instruction : show a button on local or remote screen - ISP_BTC, // 46 - info : sent when a user clicks a button - ISP_BTT, // 47 - info : sent after typing into a button - ISP_RIP, // 48 - both ways : replay information packet - ISP_SSH, // 49 - both ways : screenshot - ISP_CON, // 50 - info : contact between cars (collision report) - ISP_OBH, // 51 - info : contact car + object (collision report) - ISP_HLV, // 52 - info : report incidents that would violate HLVC - ISP_PLC, // 53 - instruction : player cars - ISP_AXM, // 54 - both ways : autocross multiple objects - ISP_ACR, // 55 - info : admin command report + ISP_NONE, // 0 : not used + ISP_ISI, // 1 - instruction : insim initialise + ISP_VER, // 2 - info : version info + ISP_TINY, // 3 - both ways : multi purpose + ISP_SMALL, // 4 - both ways : multi purpose + ISP_STA, // 5 - info : state info + ISP_SCH, // 6 - instruction : single character + ISP_SFP, // 7 - instruction : state flags pack + ISP_SCC, // 8 - instruction : set car camera + ISP_CPP, // 9 - both ways : cam pos pack + ISP_ISM, // 10 - info : start multiplayer + ISP_MSO, // 11 - info : message out + ISP_III, // 12 - info : hidden /i message + ISP_MST, // 13 - instruction : type message or /command + ISP_MTC, // 14 - instruction : message to a connection + ISP_MOD, // 15 - instruction : set screen mode + ISP_VTN, // 16 - info : vote notification + ISP_RST, // 17 - info : race start + ISP_NCN, // 18 - info : new connection + ISP_CNL, // 19 - info : connection left + ISP_CPR, // 20 - info : connection renamed + ISP_NPL, // 21 - info : new player (joined race) + ISP_PLP, // 22 - info : player pit (keeps slot in race) + ISP_PLL, // 23 - info : player leave (spectate - loses slot) + ISP_LAP, // 24 - info : lap time + ISP_SPX, // 25 - info : split x time + ISP_PIT, // 26 - info : pit stop start + ISP_PSF, // 27 - info : pit stop finish + ISP_PLA, // 28 - info : pit lane enter / leave + ISP_CCH, // 29 - info : camera changed + ISP_PEN, // 30 - info : penalty given or cleared + ISP_TOC, // 31 - info : take over car + ISP_FLG, // 32 - info : flag (yellow or blue) + ISP_PFL, // 33 - info : player flags (help flags) + ISP_FIN, // 34 - info : finished race + ISP_RES, // 35 - info : result confirmed + ISP_REO, // 36 - both ways : reorder (info or instruction) + ISP_NLP, // 37 - info : node and lap packet + ISP_MCI, // 38 - info : multi car info + ISP_MSX, // 39 - instruction : type message + ISP_MSL, // 40 - instruction : message to local computer + ISP_CRS, // 41 - info : car reset + ISP_BFN, // 42 - both ways : delete buttons / receive button requests + ISP_AXI, // 43 - info : autocross layout information + ISP_AXO, // 44 - info : hit an autocross object + ISP_BTN, // 45 - instruction : show a button on local or remote screen + ISP_BTC, // 46 - info : sent when a user clicks a button + ISP_BTT, // 47 - info : sent after typing into a button + ISP_RIP, // 48 - both ways : replay information packet + ISP_SSH, // 49 - both ways : screenshot + ISP_CON, // 50 - info : contact between cars (collision report) + ISP_OBH, // 51 - info : contact car + object (collision report) + ISP_HLV, // 52 - info : report incidents that would violate HLVC + ISP_PLC, // 53 - instruction : player cars + ISP_AXM, // 54 - both ways : autocross multiple objects + ISP_ACR, // 55 - info : admin command report }; enum // the fourth byte of an IS_TINY packet is one of these { - TINY_NONE, // 0 - keep alive : see "maintaining the connection" - TINY_VER, // 1 - info request : get version - TINY_CLOSE, // 2 - instruction : close insim - TINY_PING, // 3 - ping request : external progam requesting a reply - TINY_REPLY, // 4 - ping reply : reply to a ping request - TINY_VTC, // 5 - both ways : game vote cancel (info or request) - TINY_SCP, // 6 - info request : send camera pos - TINY_SST, // 7 - info request : send state info - TINY_GTH, // 8 - info request : get time in hundredths (i.e. SMALL_RTP) - TINY_MPE, // 9 - info : multi player end - TINY_ISM, // 10 - info request : get multiplayer info (i.e. ISP_ISM) - TINY_REN, // 11 - info : race end (return to game setup screen) - TINY_CLR, // 12 - info : all players cleared from race - TINY_NCN, // 13 - info request : get all connections - TINY_NPL, // 14 - info request : get all players - TINY_RES, // 15 - info request : get all results - TINY_NLP, // 16 - info request : send an IS_NLP - TINY_MCI, // 17 - info request : send an IS_MCI - TINY_REO, // 18 - info request : send an IS_REO - TINY_RST, // 19 - info request : send an IS_RST - TINY_AXI, // 20 - info request : send an IS_AXI - AutoX Info - TINY_AXC, // 21 - info : autocross cleared - TINY_RIP, // 22 - info request : send an IS_RIP - Replay Information Packet + TINY_NONE, // 0 - keep alive : see "maintaining the connection" + TINY_VER, // 1 - info request : get version + TINY_CLOSE, // 2 - instruction : close insim + TINY_PING, // 3 - ping request : external progam requesting a reply + TINY_REPLY, // 4 - ping reply : reply to a ping request + TINY_VTC, // 5 - both ways : game vote cancel (info or request) + TINY_SCP, // 6 - info request : send camera pos + TINY_SST, // 7 - info request : send state info + TINY_GTH, // 8 - info request : get time in hundredths (i.e. SMALL_RTP) + TINY_MPE, // 9 - info : multi player end + TINY_ISM, // 10 - info request : get multiplayer info (i.e. ISP_ISM) + TINY_REN, // 11 - info : race end (return to game setup screen) + TINY_CLR, // 12 - info : all players cleared from race + TINY_NCN, // 13 - info request : get all connections + TINY_NPL, // 14 - info request : get all players + TINY_RES, // 15 - info request : get all results + TINY_NLP, // 16 - info request : send an IS_NLP + TINY_MCI, // 17 - info request : send an IS_MCI + TINY_REO, // 18 - info request : send an IS_REO + TINY_RST, // 19 - info request : send an IS_RST + TINY_AXI, // 20 - info request : send an IS_AXI - AutoX Info + TINY_AXC, // 21 - info : autocross cleared + TINY_RIP, // 22 - info request : send an IS_RIP - Replay Information Packet }; enum // the fourth byte of an IS_SMALL packet is one of these { - SMALL_NONE, // 0 : not used - SMALL_SSP, // 1 - instruction : start sending positions - SMALL_SSG, // 2 - instruction : start sending gauges - SMALL_VTA, // 3 - report : vote action - SMALL_TMS, // 4 - instruction : time stop - SMALL_STP, // 5 - instruction : time step - SMALL_RTP, // 6 - info : race time packet (reply to GTH) - SMALL_NLI, // 7 - instruction : set node lap interval + SMALL_NONE, // 0 : not used + SMALL_SSP, // 1 - instruction : start sending positions + SMALL_SSG, // 2 - instruction : start sending gauges + SMALL_VTA, // 3 - report : vote action + SMALL_TMS, // 4 - instruction : time stop + SMALL_STP, // 5 - instruction : time step + SMALL_RTP, // 6 - info : race time packet (reply to GTH) + SMALL_NLI, // 7 - instruction : set node lap interval }; - // GENERAL PURPOSE PACKETS - IS_TINY (4 bytes) and IS_SMALL (8 bytes) // ======================= @@ -282,25 +275,24 @@ enum // the fourth byte of an IS_SMALL packet is one of these struct IS_TINY // General purpose 4 byte packet { - uint8_t Size; // always 4 - uint8_t Type; // always ISP_TINY - uint8_t ReqI; // 0 unless it is an info request or a reply to an info request - uint8_t SubT; // subtype, from TINY_ enumeration (e.g. TINY_RACE_END) + uint8_t Size; // always 4 + uint8_t Type; // always ISP_TINY + uint8_t ReqI; // 0 unless it is an info request or a reply to an info request + uint8_t SubT; // subtype, from TINY_ enumeration (e.g. TINY_RACE_END) }; // IS_SMALL - used for various requests, replies and reports struct IS_SMALL // General purpose 8 byte packet { - uint8_t Size; // always 8 - uint8_t Type; // always ISP_SMALL - uint8_t ReqI; // 0 unless it is an info request or a reply to an info request - uint8_t SubT; // subtype, from SMALL_ enumeration (e.g. SMALL_SSP) + uint8_t Size; // always 8 + uint8_t Type; // always ISP_SMALL + uint8_t ReqI; // 0 unless it is an info request or a reply to an info request + uint8_t SubT; // subtype, from SMALL_ enumeration (e.g. SMALL_SSP) - uint32_t UVal; // value (e.g. for SMALL_SSP this would be the OutSim packet rate) + uint32_t UVal; // value (e.g. for SMALL_SSP this would be the OutSim packet rate) }; - // VERSION REQUEST // =============== @@ -312,14 +304,14 @@ struct IS_SMALL // General purpose 8 byte packet struct IS_VER // VERsion { - uint8_t Size; // 20 - uint8_t Type; // ISP_VERSION - uint8_t ReqI; // ReqI as received in the request packet - uint8_t Zero; + uint8_t Size; // 20 + uint8_t Type; // ISP_VERSION + uint8_t ReqI; // ReqI as received in the request packet + uint8_t Zero; - char Version[8]; // LFS version, e.g. 0.3G - char Product[6]; // Product : DEMO or S1 - uint16_t InSimVer; // InSim Version : increased when InSim packets change + char Version[8]; // LFS version, e.g. 0.3G + char Product[6]; // Product : DEMO or S1 + uint16_t InSimVer; // InSim Version : increased when InSim packets change }; // To request an InSimVersion packet at any time, send this IS_TINY : @@ -327,7 +319,6 @@ struct IS_VER // VERsion // ReqI : non-zero (returned in the reply) // SubT : TINY_VER (request an IS_VER) - // CLOSING InSim // ============= @@ -341,7 +332,6 @@ struct IS_VER // VERsion // You can shut down InSim completely and stop it listening at all by typing /insim=0 // into LFS (or send a MsgTypePack to do the same thing). - // MAINTAINING THE CONNECTION - IMPORTANT // ========================== @@ -369,7 +359,6 @@ struct IS_VER // VERsion // ReqI : non-zero (as received in the request packet) // SubT : TINY_REPLY (reply to ping) - // STATE REPORTING AND REQUESTS // ============================ @@ -377,30 +366,30 @@ struct IS_VER // VERsion struct IS_STA // STAte { - uint8_t Size; // 28 - uint8_t Type; // ISP_STA - uint8_t ReqI; // ReqI if replying to a request packet - uint8_t Zero; + uint8_t Size; // 28 + uint8_t Type; // ISP_STA + uint8_t ReqI; // ReqI if replying to a request packet + uint8_t Zero; - float ReplaySpeed; // 4-byte float - 1.0 is normal speed + float ReplaySpeed; // 4-byte float - 1.0 is normal speed - uint16_t Flags; // ISS state flags (see below) - uint8_t InGameCam; // Which type of camera is selected (see below) - uint8_t ViewPLID; // Unique ID of viewed player (0 = none) + uint16_t Flags; // ISS state flags (see below) + uint8_t InGameCam; // Which type of camera is selected (see below) + uint8_t ViewPLID; // Unique ID of viewed player (0 = none) - uint8_t NumP; // Number of players in race - uint8_t NumConns; // Number of connections including host - uint8_t NumFinished; // Number finished or qualified - uint8_t RaceInProg; // 0 - no race / 1 - race / 2 - qualifying + uint8_t NumP; // Number of players in race + uint8_t NumConns; // Number of connections including host + uint8_t NumFinished; // Number finished or qualified + uint8_t RaceInProg; // 0 - no race / 1 - race / 2 - qualifying - uint8_t QualMins; - uint8_t RaceLaps; // see "RaceLaps" near the top of this document - uint8_t Spare2; - uint8_t Spare3; + uint8_t QualMins; + uint8_t RaceLaps; // see "RaceLaps" near the top of this document + uint8_t Spare2; + uint8_t Spare3; - char Track[6]; // short name for track e.g. FE2R - uint8_t Weather; // 0,1,2... - uint8_t Wind; // 0=off 1=weak 2=strong + char Track[6]; // short name for track e.g. FE2R + uint8_t Weather; // 0,1,2... + uint8_t Wind; // 0=off 1=weak 2=strong }; // InGameCam is the in game selected camera mode (which is @@ -409,21 +398,21 @@ struct IS_STA // STAte // ISS state flags -#define ISS_GAME 1 // in game (or MPR) -#define ISS_REPLAY 2 // in SPR -#define ISS_PAUSED 4 // paused -#define ISS_SHIFTU 8 // SHIFT+U mode -#define ISS_16 16 // UNUSED -#define ISS_SHIFTU_FOLLOW 32 // FOLLOW view -#define ISS_SHIFTU_NO_OPT 64 // SHIFT+U buttons hidden -#define ISS_SHOW_2D 128 // showing 2d display -#define ISS_FRONT_END 256 // entry screen -#define ISS_MULTI 512 // multiplayer mode -#define ISS_MPSPEEDUP 1024 // multiplayer speedup option -#define ISS_WINDOWED 2048 // LFS is running in a window -#define ISS_SOUND_MUTE 4096 // sound is switched off -#define ISS_VIEW_OVERRIDE 8192 // override user view -#define ISS_VISIBLE 16384 // InSim buttons visible +#define ISS_GAME 1 // in game (or MPR) +#define ISS_REPLAY 2 // in SPR +#define ISS_PAUSED 4 // paused +#define ISS_SHIFTU 8 // SHIFT+U mode +#define ISS_16 16 // UNUSED +#define ISS_SHIFTU_FOLLOW 32 // FOLLOW view +#define ISS_SHIFTU_NO_OPT 64 // SHIFT+U buttons hidden +#define ISS_SHOW_2D 128 // showing 2d display +#define ISS_FRONT_END 256 // entry screen +#define ISS_MULTI 512 // multiplayer mode +#define ISS_MPSPEEDUP 1024 // multiplayer speedup option +#define ISS_WINDOWED 2048 // LFS is running in a window +#define ISS_SOUND_MUTE 4096 // sound is switched off +#define ISS_VIEW_OVERRIDE 8192 // override user view +#define ISS_VISIBLE 16384 // InSim buttons visible // To request a StatePack at any time, send this IS_TINY : @@ -441,19 +430,18 @@ struct IS_STA // STAte struct IS_SFP // State Flags Pack { - uint8_t Size; // 8 - uint8_t Type; // ISP_SFP - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 8 + uint8_t Type; // ISP_SFP + uint8_t ReqI; // 0 + uint8_t Zero; - uint16_t Flag; // the state to set - uint8_t OffOn; // 0 = off / 1 = on - uint8_t Sp3; // spare + uint16_t Flag; // the state to set + uint8_t OffOn; // 0 = off / 1 = on + uint8_t Sp3; // spare }; // Other states must be set by using keypresses or messages (see below) - // SCREEN MODE // =========== @@ -461,15 +449,15 @@ struct IS_SFP // State Flags Pack struct IS_MOD // MODe : send to LFS to change screen mode { - uint8_t Size; // 20 - uint8_t Type; // ISP_MOD - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 20 + uint8_t Type; // ISP_MOD + uint8_t ReqI; // 0 + uint8_t Zero; - int32_t Bits16; // set to choose 16-bit - int32_t RR; // refresh rate - zero for default - int32_t Width; // 0 means go to window - int32_t Height; // 0 means go to window + int32_t Bits16; // set to choose 16-bit + int32_t RR; // refresh rate - zero for default + int32_t Width; // 0 means go to window + int32_t Height; // 0 means go to window }; // The refresh rate actually selected by LFS will be the highest available rate @@ -478,7 +466,6 @@ struct IS_MOD // MODe : send to LFS to change screen mode // If Width and Height are both zero, LFS will switch to windowed mode. - // TEXT MESSAGES AND KEY PRESSES // ============================== @@ -491,60 +478,60 @@ struct IS_MOD // MODe : send to LFS to change screen mode struct IS_MSO // MSg Out - system messages and user messages { - uint8_t Size; // 136 - uint8_t Type; // ISP_MSO - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 136 + uint8_t Type; // ISP_MSO + uint8_t ReqI; // 0 + uint8_t Zero; - uint8_t UCID; // connection's unique id (0 = host) - uint8_t PLID; // player's unique id (if zero, use UCID) - uint8_t UserType; // set if typed by a user (see User Values below) - uint8_t TextStart; // first character of the actual text (after player name) + uint8_t UCID; // connection's unique id (0 = host) + uint8_t PLID; // player's unique id (if zero, use UCID) + uint8_t UserType; // set if typed by a user (see User Values below) + uint8_t TextStart; // first character of the actual text (after player name) - char Msg[128]; + char Msg[128]; }; // User Values (for UserType byte) enum { - MSO_SYSTEM, // 0 - system message - MSO_USER, // 1 - normal visible user message - MSO_PREFIX, // 2 - hidden message starting with special prefix (see ISI) - MSO_O, // 3 - hidden message typed on local pc with /o command - MSO_NUM + MSO_SYSTEM, // 0 - system message + MSO_USER, // 1 - normal visible user message + MSO_PREFIX, // 2 - hidden message starting with special prefix (see ISI) + MSO_O, // 3 - hidden message typed on local pc with /o command + MSO_NUM }; // NOTE : Typing "/o MESSAGE" into LFS will send an IS_MSO with UserType = MSO_O struct IS_III // InsIm Info - /i message from user to host's InSim { - uint8_t Size; // 72 - uint8_t Type; // ISP_III - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 72 + uint8_t Type; // ISP_III + uint8_t ReqI; // 0 + uint8_t Zero; - uint8_t UCID; // connection's unique id (0 = host) - uint8_t PLID; // player's unique id (if zero, use UCID) - uint8_t Sp2; - uint8_t Sp3; + uint8_t UCID; // connection's unique id (0 = host) + uint8_t PLID; // player's unique id (if zero, use UCID) + uint8_t Sp2; + uint8_t Sp3; - char Msg[64]; + char Msg[64]; }; struct IS_ACR // Admin Command Report - any user typed an admin command { - uint8_t Size; // 72 - uint8_t Type; // ISP_ACR - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 72 + uint8_t Type; // ISP_ACR + uint8_t ReqI; // 0 + uint8_t Zero; - uint8_t UCID; // connection's unique id (0 = host) - uint8_t Admin; // set if user is an admin - uint8_t Result; // 1 - processed / 2 - rejected / 3 - unknown command - uint8_t Sp3; + uint8_t UCID; // connection's unique id (0 = host) + uint8_t Admin; // set if user is an admin + uint8_t Result; // 1 - processed / 2 - rejected / 3 - unknown command + uint8_t Sp3; - char Text[64]; + char Text[64]; }; // MESSAGES IN (TO LFS) @@ -552,59 +539,59 @@ struct IS_ACR // Admin Command Report - any user typed an admin command struct IS_MST // MSg Type - send to LFS to type message or command { - uint8_t Size; // 68 - uint8_t Type; // ISP_MST - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 68 + uint8_t Type; // ISP_MST + uint8_t ReqI; // 0 + uint8_t Zero; - char Msg[64]; // last byte must be zero + char Msg[64]; // last byte must be zero }; struct IS_MSX // MSg eXtended - like MST but longer (not for commands) { - uint8_t Size; // 100 - uint8_t Type; // ISP_MSX - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 100 + uint8_t Type; // ISP_MSX + uint8_t ReqI; // 0 + uint8_t Zero; - char Msg[96]; // last byte must be zero + char Msg[96]; // last byte must be zero }; struct IS_MSL // MSg Local - message to appear on local computer only { - uint8_t Size; // 132 - uint8_t Type; // ISP_MSL - uint8_t ReqI; // 0 - uint8_t Sound; // sound effect (see Message Sounds below) + uint8_t Size; // 132 + uint8_t Type; // ISP_MSL + uint8_t ReqI; // 0 + uint8_t Sound; // sound effect (see Message Sounds below) - char Msg[128]; // last byte must be zero + char Msg[128]; // last byte must be zero }; struct IS_MTC // Msg To Connection - hosts only - send to a connection / a player / all { - uint8_t Size; // 8 + TEXT_SIZE (TEXT_SIZE = 4, 8, 12... 128) - uint8_t Type; // ISP_MTC - uint8_t ReqI; // 0 - uint8_t Sound; // sound effect (see Message Sounds below) + uint8_t Size; // 8 + TEXT_SIZE (TEXT_SIZE = 4, 8, 12... 128) + uint8_t Type; // ISP_MTC + uint8_t ReqI; // 0 + uint8_t Sound; // sound effect (see Message Sounds below) - uint8_t UCID; // connection's unique id (0 = host / 255 = all) - uint8_t PLID; // player's unique id (if zero, use UCID) - uint8_t Sp2; - uint8_t Sp3; + uint8_t UCID; // connection's unique id (0 = host / 255 = all) + uint8_t PLID; // player's unique id (if zero, use UCID) + uint8_t Sp2; + uint8_t Sp3; -// char Text[TEXT_SIZE]; // up to 128 characters of text - last byte must be zero + // char Text[TEXT_SIZE]; // up to 128 characters of text - last byte must be zero }; // Message Sounds (for Sound byte) enum { - SND_SILENT, - SND_MESSAGE, - SND_SYSMESSAGE, - SND_INVALIDKEY, - SND_ERROR, - SND_NUM + SND_SILENT, + SND_MESSAGE, + SND_SYSMESSAGE, + SND_INVALIDKEY, + SND_ERROR, + SND_NUM }; // You can send individual key presses to LFS with the IS_SCH packet. @@ -614,18 +601,17 @@ enum struct IS_SCH // Single CHaracter { - uint8_t Size; // 8 - uint8_t Type; // ISP_SCH - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 8 + uint8_t Type; // ISP_SCH + uint8_t ReqI; // 0 + uint8_t Zero; - uint8_t CharB; // key to press - uint8_t Flags; // bit 0 : SHIFT / bit 1 : CTRL - uint8_t Spare2; - uint8_t Spare3; + uint8_t CharB; // key to press + uint8_t Flags; // bit 0 : SHIFT / bit 1 : CTRL + uint8_t Spare2; + uint8_t Spare3; }; - // MULTIPLAYER NOTIFICATION // ======================== @@ -633,17 +619,17 @@ struct IS_SCH // Single CHaracter struct IS_ISM // InSim Multi { - uint8_t Size; // 40 - uint8_t Type; // ISP_ISM - uint8_t ReqI; // usually 0 / or if a reply : ReqI as received in the TINY_ISM - uint8_t Zero; + uint8_t Size; // 40 + uint8_t Type; // ISP_ISM + uint8_t ReqI; // usually 0 / or if a reply : ReqI as received in the TINY_ISM + uint8_t Zero; - uint8_t Host; // 0 = guest / 1 = host - uint8_t Sp1; - uint8_t Sp2; - uint8_t Sp3; + uint8_t Host; // 0 = guest / 1 = host + uint8_t Sp1; + uint8_t Sp2; + uint8_t Sp3; - char HName[32]; // the name of the host joined or started + char HName[32]; // the name of the host joined or started }; // On ending or leaving a host, LFS will send this IS_TINY : @@ -658,7 +644,6 @@ struct IS_ISM // InSim Multi // NOTE : If LFS is not in multiplayer mode, the host name in the ISM will be empty. - // VOTE NOTIFY AND CANCEL // ====================== @@ -668,24 +653,24 @@ struct IS_ISM // InSim Multi enum { - VOTE_NONE, // 0 - no vote - VOTE_END, // 1 - end race - VOTE_RESTART, // 2 - restart - VOTE_QUALIFY, // 3 - qualify - VOTE_NUM + VOTE_NONE, // 0 - no vote + VOTE_END, // 1 - end race + VOTE_RESTART, // 2 - restart + VOTE_QUALIFY, // 3 - qualify + VOTE_NUM }; struct IS_VTN // VoTe Notify { - uint8_t Size; // 8 - uint8_t Type; // ISP_VTN - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 8 + uint8_t Type; // ISP_VTN + uint8_t ReqI; // 0 + uint8_t Zero; - uint8_t UCID; // connection's unique id - uint8_t Action; // VOTE_X (Vote Action as defined above) - uint8_t Spare2; - uint8_t Spare3; + uint8_t UCID; // connection's unique id + uint8_t Action; // VOTE_X (Vote Action as defined above) + uint8_t Spare2; + uint8_t Spare3; }; // When a vote is cancelled, LFS sends this IS_TINY @@ -704,7 +689,6 @@ struct IS_VTN // VoTe Notify // ReqI : 0 // SubT : TINY_VTC (VoTe Cancel) - // ALLOWED CARS // ============ @@ -718,17 +702,17 @@ struct IS_VTN // VoTe Notify struct IS_PLC // PLayer Cars { - uint8_t Size; // 12 - uint8_t Type; // ISP_PLC - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 12 + uint8_t Type; // ISP_PLC + uint8_t ReqI; // 0 + uint8_t Zero; - uint8_t UCID; // connection's unique id (0 = host / 255 = all) - uint8_t Sp1; - uint8_t Sp2; - uint8_t Sp3; + uint8_t UCID; // connection's unique id (0 = host / 255 = all) + uint8_t Sp1; + uint8_t Sp2; + uint8_t Sp3; - uint32_t Cars; // allowed cars - see below + uint32_t Cars; // allowed cars - see below }; // XF GTI - 1 @@ -752,7 +736,6 @@ struct IS_PLC // PLayer Cars // BMW SAUBER F1.06 - 0x40000 // FORMULA BMW FB02 - 0x80000 - // RACE TRACKING // ============= @@ -787,26 +770,26 @@ struct IS_PLC // PLayer Cars struct IS_RST // Race STart { - uint8_t Size; // 28 - uint8_t Type; // ISP_RST - uint8_t ReqI; // 0 unless this is a reply to an TINY_RST request - uint8_t Zero; + uint8_t Size; // 28 + uint8_t Type; // ISP_RST + uint8_t ReqI; // 0 unless this is a reply to an TINY_RST request + uint8_t Zero; - uint8_t RaceLaps; // 0 if qualifying - uint8_t QualMins; // 0 if race - uint8_t NumP; // number of players in race - uint8_t Timing; // lap timing (see below) + uint8_t RaceLaps; // 0 if qualifying + uint8_t QualMins; // 0 if race + uint8_t NumP; // number of players in race + uint8_t Timing; // lap timing (see below) - char Track[6]; // short track name - uint8_t Weather; - uint8_t Wind; + char Track[6]; // short track name + uint8_t Weather; + uint8_t Wind; - uint16_t Flags; // race flags (must pit, can reset, etc - see below) - uint16_t NumNodes; // total number of nodes in the path - uint16_t Finish; // node index - finish line - uint16_t Split1; // node index - split 1 - uint16_t Split2; // node index - split 2 - uint16_t Split3; // node index - split 3 + uint16_t Flags; // race flags (must pit, can reset, etc - see below) + uint16_t NumNodes; // total number of nodes in the path + uint16_t Finish; // node index - finish line + uint16_t Split1; // node index - split 1 + uint16_t Split2; // node index - split 2 + uint16_t Split3; // node index - split 3 }; // Lap timing info (for Timing byte) @@ -826,73 +809,73 @@ struct IS_RST // Race STart struct IS_NCN // New ConN { - uint8_t Size; // 56 - uint8_t Type; // ISP_NCN - uint8_t ReqI; // 0 unless this is a reply to a TINY_NCN request - uint8_t UCID; // new connection's unique id (0 = host) + uint8_t Size; // 56 + uint8_t Type; // ISP_NCN + uint8_t ReqI; // 0 unless this is a reply to a TINY_NCN request + uint8_t UCID; // new connection's unique id (0 = host) - char UName[24]; // username - char PName[24]; // nickname + char UName[24]; // username + char PName[24]; // nickname - uint8_t Admin; // 1 if admin - uint8_t Total; // number of connections including host - uint8_t Flags; // bit 2 : remote - uint8_t Sp3; + uint8_t Admin; // 1 if admin + uint8_t Total; // number of connections including host + uint8_t Flags; // bit 2 : remote + uint8_t Sp3; }; struct IS_CNL // ConN Leave { - uint8_t Size; // 8 - uint8_t Type; // ISP_CNL - uint8_t ReqI; // 0 - uint8_t UCID; // unique id of the connection which left + uint8_t Size; // 8 + uint8_t Type; // ISP_CNL + uint8_t ReqI; // 0 + uint8_t UCID; // unique id of the connection which left - uint8_t Reason; // leave reason (see below) - uint8_t Total; // number of connections including host - uint8_t Sp2; - uint8_t Sp3; + uint8_t Reason; // leave reason (see below) + uint8_t Total; // number of connections including host + uint8_t Sp2; + uint8_t Sp3; }; struct IS_CPR // Conn Player Rename { - uint8_t Size; // 36 - uint8_t Type; // ISP_CPR - uint8_t ReqI; // 0 - uint8_t UCID; // unique id of the connection + uint8_t Size; // 36 + uint8_t Type; // ISP_CPR + uint8_t ReqI; // 0 + uint8_t UCID; // unique id of the connection - char PName[24]; // new name - char Plate[8]; // number plate - NO ZERO AT END! + char PName[24]; // new name + char Plate[8]; // number plate - NO ZERO AT END! }; struct IS_NPL // New PLayer joining race (if PLID already exists, then leaving pits) { - uint8_t Size; // 76 - uint8_t Type; // ISP_NPL - uint8_t ReqI; // 0 unless this is a reply to an TINY_NPL request - uint8_t PLID; // player's newly assigned unique id + uint8_t Size; // 76 + uint8_t Type; // ISP_NPL + uint8_t ReqI; // 0 unless this is a reply to an TINY_NPL request + uint8_t PLID; // player's newly assigned unique id - uint8_t UCID; // connection's unique id - uint8_t PType; // bit 0 : female / bit 1 : AI / bit 2 : remote - uint16_t Flags; // player flags + uint8_t UCID; // connection's unique id + uint8_t PType; // bit 0 : female / bit 1 : AI / bit 2 : remote + uint16_t Flags; // player flags - char PName[24]; // nickname - char Plate[8]; // number plate - NO ZERO AT END! + char PName[24]; // nickname + char Plate[8]; // number plate - NO ZERO AT END! - char CName[4]; // car name - char SName[16]; // skin name - MAX_CAR_TEX_NAME - uint8_t Tyres[4]; // compounds + char CName[4]; // car name + char SName[16]; // skin name - MAX_CAR_TEX_NAME + uint8_t Tyres[4]; // compounds - uint8_t H_Mass; // added mass (kg) - uint8_t H_TRes; // intake restriction - uint8_t Model; // driver model - uint8_t Pass; // passengers byte + uint8_t H_Mass; // added mass (kg) + uint8_t H_TRes; // intake restriction + uint8_t Model; // driver model + uint8_t Pass; // passengers byte - int32_t Spare; + int32_t Spare; - uint8_t SetF; // setup flags (see below) - uint8_t NumP; // number in race (same when leaving pits, 1 more if new) - uint8_t Sp2; - uint8_t Sp3; + uint8_t SetF; // setup flags (see below) + uint8_t NumP; // number in race (same when leaving pits, 1 more if new) + uint8_t Sp2; + uint8_t Sp3; }; // NOTE : PType bit 0 (female) is not reported on dedicated host as humans are not loaded @@ -900,114 +883,114 @@ struct IS_NPL // New PLayer joining race (if PLID already exists, then leaving p // Setup flags (for SetF byte) -#define SETF_SYMM_WHEELS 1 -#define SETF_TC_ENABLE 2 -#define SETF_ABS_ENABLE 4 +#define SETF_SYMM_WHEELS 1 +#define SETF_TC_ENABLE 2 +#define SETF_ABS_ENABLE 4 // More... struct IS_PLP // PLayer Pits (go to settings - stays in player list) { - uint8_t Size; // 4 - uint8_t Type; // ISP_PLP - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 4 + uint8_t Type; // ISP_PLP + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id }; struct IS_PLL // PLayer Leave race (spectate - removed from player list) { - uint8_t Size; // 4 - uint8_t Type; // ISP_PLL - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 4 + uint8_t Type; // ISP_PLL + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id }; struct IS_CRS // Car ReSet { - uint8_t Size; // 4 - uint8_t Type; // ISP_CRS - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 4 + uint8_t Type; // ISP_CRS + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id }; struct IS_LAP // LAP time { - uint8_t Size; // 20 - uint8_t Type; // ISP_LAP - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 20 + uint8_t Type; // ISP_LAP + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint32_t LTime; // lap time (ms) - uint32_t ETime; // total time (ms) + uint32_t LTime; // lap time (ms) + uint32_t ETime; // total time (ms) - uint16_t LapsDone; // laps completed - uint16_t Flags; // player flags + uint16_t LapsDone; // laps completed + uint16_t Flags; // player flags - uint8_t Sp0; - uint8_t Penalty; // current penalty value (see below) - uint8_t NumStops; // number of pit stops - uint8_t Sp3; + uint8_t Sp0; + uint8_t Penalty; // current penalty value (see below) + uint8_t NumStops; // number of pit stops + uint8_t Sp3; }; struct IS_SPX // SPlit X time { - uint8_t Size; // 16 - uint8_t Type; // ISP_SPX - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 16 + uint8_t Type; // ISP_SPX + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint32_t STime; // split time (ms) - uint32_t ETime; // total time (ms) + uint32_t STime; // split time (ms) + uint32_t ETime; // total time (ms) - uint8_t Split; // split number 1, 2, 3 - uint8_t Penalty; // current penalty value (see below) - uint8_t NumStops; // number of pit stops - uint8_t Sp3; + uint8_t Split; // split number 1, 2, 3 + uint8_t Penalty; // current penalty value (see below) + uint8_t NumStops; // number of pit stops + uint8_t Sp3; }; struct IS_PIT // PIT stop (stop at pit garage) { - uint8_t Size; // 24 - uint8_t Type; // ISP_PIT - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 24 + uint8_t Type; // ISP_PIT + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint16_t LapsDone; // laps completed - uint16_t Flags; // player flags + uint16_t LapsDone; // laps completed + uint16_t Flags; // player flags - uint8_t Sp0; - uint8_t Penalty; // current penalty value (see below) - uint8_t NumStops; // number of pit stops - uint8_t Sp3; + uint8_t Sp0; + uint8_t Penalty; // current penalty value (see below) + uint8_t NumStops; // number of pit stops + uint8_t Sp3; - uint8_t Tyres[4]; // tyres changed + uint8_t Tyres[4]; // tyres changed - uint32_t Work; // pit work - uint32_t Spare; + uint32_t Work; // pit work + uint32_t Spare; }; struct IS_PSF // Pit Stop Finished { - uint8_t Size; // 12 - uint8_t Type; // ISP_PSF - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 12 + uint8_t Type; // ISP_PSF + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint32_t STime; // stop time (ms) - uint32_t Spare; + uint32_t STime; // stop time (ms) + uint32_t Spare; }; struct IS_PLA // Pit LAne { - uint8_t Size; // 8 - uint8_t Type; // ISP_PLA - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 8 + uint8_t Type; // ISP_PLA + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint8_t Fact; // pit lane fact (see below) - uint8_t Sp1; - uint8_t Sp2; - uint8_t Sp3; + uint8_t Fact; // pit lane fact (see below) + uint8_t Sp1; + uint8_t Sp2; + uint8_t Sp3; }; // IS_CCH : Camera CHange @@ -1020,112 +1003,112 @@ struct IS_PLA // Pit LAne struct IS_CCH // Camera CHange { - uint8_t Size; // 8 - uint8_t Type; // ISP_CCH - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 8 + uint8_t Type; // ISP_CCH + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint8_t Camera; // view identifier (see below) - uint8_t Sp1; - uint8_t Sp2; - uint8_t Sp3; + uint8_t Camera; // view identifier (see below) + uint8_t Sp1; + uint8_t Sp2; + uint8_t Sp3; }; struct IS_PEN // PENalty (given or cleared) { - uint8_t Size; // 8 - uint8_t Type; // ISP_PEN - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 8 + uint8_t Type; // ISP_PEN + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint8_t OldPen; // old penalty value (see below) - uint8_t NewPen; // new penalty value (see below) - uint8_t Reason; // penalty reason (see below) - uint8_t Sp3; + uint8_t OldPen; // old penalty value (see below) + uint8_t NewPen; // new penalty value (see below) + uint8_t Reason; // penalty reason (see below) + uint8_t Sp3; }; struct IS_TOC // Take Over Car { - uint8_t Size; // 8 - uint8_t Type; // ISP_TOC - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 8 + uint8_t Type; // ISP_TOC + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint8_t OldUCID; // old connection's unique id - uint8_t NewUCID; // new connection's unique id - uint8_t Sp2; - uint8_t Sp3; + uint8_t OldUCID; // old connection's unique id + uint8_t NewUCID; // new connection's unique id + uint8_t Sp2; + uint8_t Sp3; }; struct IS_FLG // FLaG (yellow or blue flag changed) { - uint8_t Size; // 8 - uint8_t Type; // ISP_FLG - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 8 + uint8_t Type; // ISP_FLG + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint8_t OffOn; // 0 = off / 1 = on - uint8_t Flag; // 1 = given blue / 2 = causing yellow - uint8_t CarBehind; // unique id of obstructed player - uint8_t Sp3; + uint8_t OffOn; // 0 = off / 1 = on + uint8_t Flag; // 1 = given blue / 2 = causing yellow + uint8_t CarBehind; // unique id of obstructed player + uint8_t Sp3; }; struct IS_PFL // Player FLags (help flags changed) { - uint8_t Size; // 8 - uint8_t Type; // ISP_PFL - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 8 + uint8_t Type; // ISP_PFL + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint16_t Flags; // player flags (see below) - uint16_t Spare; + uint16_t Flags; // player flags (see below) + uint16_t Spare; }; struct IS_FIN // FINished race notification (not a final result - use IS_RES) { - uint8_t Size; // 20 - uint8_t Type; // ISP_FIN - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id (0 = player left before result was sent) + uint8_t Size; // 20 + uint8_t Type; // ISP_FIN + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id (0 = player left before result was sent) - uint32_t TTime; // race time (ms) - uint32_t BTime; // best lap (ms) + uint32_t TTime; // race time (ms) + uint32_t BTime; // best lap (ms) - uint8_t SpA; - uint8_t NumStops; // number of pit stops - uint8_t Confirm; // confirmation flags : disqualified etc - see below - uint8_t SpB; + uint8_t SpA; + uint8_t NumStops; // number of pit stops + uint8_t Confirm; // confirmation flags : disqualified etc - see below + uint8_t SpB; - uint16_t LapsDone; // laps completed - uint16_t Flags; // player flags : help settings etc - see below + uint16_t LapsDone; // laps completed + uint16_t Flags; // player flags : help settings etc - see below }; struct IS_RES // RESult (qualify or confirmed finish) { - uint8_t Size; // 84 - uint8_t Type; // ISP_RES - uint8_t ReqI; // 0 unless this is a reply to a TINY_RES request - uint8_t PLID; // player's unique id (0 = player left before result was sent) + uint8_t Size; // 84 + uint8_t Type; // ISP_RES + uint8_t ReqI; // 0 unless this is a reply to a TINY_RES request + uint8_t PLID; // player's unique id (0 = player left before result was sent) - char UName[24]; // username - char PName[24]; // nickname - char Plate[8]; // number plate - NO ZERO AT END! - char CName[4]; // skin prefix + char UName[24]; // username + char PName[24]; // nickname + char Plate[8]; // number plate - NO ZERO AT END! + char CName[4]; // skin prefix - uint32_t TTime; // race time (ms) - uint32_t BTime; // best lap (ms) + uint32_t TTime; // race time (ms) + uint32_t BTime; // best lap (ms) - uint8_t SpA; - uint8_t NumStops; // number of pit stops - uint8_t Confirm; // confirmation flags : disqualified etc - see below - uint8_t SpB; + uint8_t SpA; + uint8_t NumStops; // number of pit stops + uint8_t Confirm; // confirmation flags : disqualified etc - see below + uint8_t SpB; - uint16_t LapsDone; // laps completed - uint16_t Flags; // player flags : help settings etc - see below + uint16_t LapsDone; // laps completed + uint16_t Flags; // player flags : help settings etc - see below - uint8_t ResultNum; // finish or qualify pos (0 = win / 255 = not added to table) - uint8_t NumRes; // total number of results (qualify doesn't always add a new one) - uint16_t PSeconds; // penalty time in seconds (already included in race time) + uint8_t ResultNum; // finish or qualify pos (0 = win / 255 = not added to table) + uint8_t NumRes; // total number of results (qualify doesn't always add a new one) + uint16_t PSeconds; // penalty time in seconds (already included in race time) }; // IS_REO : REOrder - this packet can be sent in either direction @@ -1140,12 +1123,12 @@ struct IS_RES // RESult (qualify or confirmed finish) struct IS_REO // REOrder (when race restarts after qualifying) { - uint8_t Size; // 36 - uint8_t Type; // ISP_REO - uint8_t ReqI; // 0 unless this is a reply to an TINY_REO request - uint8_t NumP; // number of players in race + uint8_t Size; // 36 + uint8_t Type; // ISP_REO + uint8_t ReqI; // 0 unless this is a reply to an TINY_REO request + uint8_t NumP; // number of players in race - uint8_t PLID[32]; // all PLIDs in new order + uint8_t PLID[32]; // all PLIDs in new order }; // To request an IS_REO packet at any time, send this IS_TINY : @@ -1157,49 +1140,49 @@ struct IS_REO // REOrder (when race restarts after qualifying) enum { - PITLANE_EXIT, // 0 - left pit lane - PITLANE_ENTER, // 1 - entered pit lane - PITLANE_NO_PURPOSE, // 2 - entered for no purpose - PITLANE_DT, // 3 - entered for drive-through - PITLANE_SG, // 4 - entered for stop-go - PITLANE_NUM + PITLANE_EXIT, // 0 - left pit lane + PITLANE_ENTER, // 1 - entered pit lane + PITLANE_NO_PURPOSE, // 2 - entered for no purpose + PITLANE_DT, // 3 - entered for drive-through + PITLANE_SG, // 4 - entered for stop-go + PITLANE_NUM }; // Pit Work Flags enum { - PSE_NOTHING, // bit 0 (1) - PSE_STOP, // bit 1 (2) - PSE_FR_DAM, // bit 2 (4) - PSE_FR_WHL, // etc... - PSE_LE_FR_DAM, - PSE_LE_FR_WHL, - PSE_RI_FR_DAM, - PSE_RI_FR_WHL, - PSE_RE_DAM, - PSE_RE_WHL, - PSE_LE_RE_DAM, - PSE_LE_RE_WHL, - PSE_RI_RE_DAM, - PSE_RI_RE_WHL, - PSE_BODY_MINOR, - PSE_BODY_MAJOR, - PSE_SETUP, - PSE_REFUEL, - PSE_NUM + PSE_NOTHING, // bit 0 (1) + PSE_STOP, // bit 1 (2) + PSE_FR_DAM, // bit 2 (4) + PSE_FR_WHL, // etc... + PSE_LE_FR_DAM, + PSE_LE_FR_WHL, + PSE_RI_FR_DAM, + PSE_RI_FR_WHL, + PSE_RE_DAM, + PSE_RE_WHL, + PSE_LE_RE_DAM, + PSE_LE_RE_WHL, + PSE_RI_RE_DAM, + PSE_RI_RE_WHL, + PSE_BODY_MINOR, + PSE_BODY_MAJOR, + PSE_SETUP, + PSE_REFUEL, + PSE_NUM }; // View identifiers enum { - VIEW_FOLLOW, // 0 - arcade - VIEW_HELI, // 1 - helicopter - VIEW_CAM, // 2 - tv camera - VIEW_DRIVER, // 3 - cockpit - VIEW_CUSTOM, // 4 - custom - VIEW_MAX + VIEW_FOLLOW, // 0 - arcade + VIEW_HELI, // 1 - helicopter + VIEW_CAM, // 2 - tv camera + VIEW_DRIVER, // 3 - cockpit + VIEW_CUSTOM, // 4 - custom + VIEW_MAX }; static const int VIEW_ANOTHER = 255; // viewing another car @@ -1208,89 +1191,89 @@ static const int VIEW_ANOTHER = 255; // viewing another car enum { - LEAVR_DISCO, // 0 - disconnect - LEAVR_TIMEOUT, // 1 - timed out - LEAVR_LOSTCONN, // 2 - lost connection - LEAVR_KICKED, // 3 - kicked - LEAVR_BANNED, // 4 - banned - LEAVR_SECURITY, // 5 - OOS or cheat protection - LEAVR_NUM + LEAVR_DISCO, // 0 - disconnect + LEAVR_TIMEOUT, // 1 - timed out + LEAVR_LOSTCONN, // 2 - lost connection + LEAVR_KICKED, // 3 - kicked + LEAVR_BANNED, // 4 - banned + LEAVR_SECURITY, // 5 - OOS or cheat protection + LEAVR_NUM }; // Penalty values (VALID means the penalty can now be cleared) enum { - PENALTY_NONE, // 0 - PENALTY_DT, // 1 - PENALTY_DT_VALID, // 2 - PENALTY_SG, // 3 - PENALTY_SG_VALID, // 4 - PENALTY_30, // 5 - PENALTY_45, // 6 - PENALTY_NUM + PENALTY_NONE, // 0 + PENALTY_DT, // 1 + PENALTY_DT_VALID, // 2 + PENALTY_SG, // 3 + PENALTY_SG_VALID, // 4 + PENALTY_30, // 5 + PENALTY_45, // 6 + PENALTY_NUM }; // Penalty reasons enum { - PENR_UNKNOWN, // 0 - unknown or cleared penalty - PENR_ADMIN, // 1 - penalty given by admin - PENR_WRONG_WAY, // 2 - wrong way driving - PENR_FALSE_START, // 3 - starting before green light - PENR_SPEEDING, // 4 - speeding in pit lane - PENR_STOP_SHORT, // 5 - stop-go pit stop too short - PENR_STOP_LATE, // 6 - compulsory stop is too late - PENR_NUM + PENR_UNKNOWN, // 0 - unknown or cleared penalty + PENR_ADMIN, // 1 - penalty given by admin + PENR_WRONG_WAY, // 2 - wrong way driving + PENR_FALSE_START, // 3 - starting before green light + PENR_SPEEDING, // 4 - speeding in pit lane + PENR_STOP_SHORT, // 5 - stop-go pit stop too short + PENR_STOP_LATE, // 6 - compulsory stop is too late + PENR_NUM }; // Player flags -#define PIF_SWAPSIDE 1 -#define PIF_RESERVED_2 2 -#define PIF_RESERVED_4 4 -#define PIF_AUTOGEARS 8 -#define PIF_SHIFTER 16 -#define PIF_RESERVED_32 32 -#define PIF_HELP_B 64 -#define PIF_AXIS_CLUTCH 128 -#define PIF_INPITS 256 -#define PIF_AUTOCLUTCH 512 -#define PIF_MOUSE 1024 -#define PIF_KB_NO_HELP 2048 -#define PIF_KB_STABILISED 4096 -#define PIF_CUSTOM_VIEW 8192 +#define PIF_SWAPSIDE 1 +#define PIF_RESERVED_2 2 +#define PIF_RESERVED_4 4 +#define PIF_AUTOGEARS 8 +#define PIF_SHIFTER 16 +#define PIF_RESERVED_32 32 +#define PIF_HELP_B 64 +#define PIF_AXIS_CLUTCH 128 +#define PIF_INPITS 256 +#define PIF_AUTOCLUTCH 512 +#define PIF_MOUSE 1024 +#define PIF_KB_NO_HELP 2048 +#define PIF_KB_STABILISED 4096 +#define PIF_CUSTOM_VIEW 8192 // Tyre compounds (4 byte order : rear L, rear R, front L, front R) enum { - TYRE_R1, // 0 - TYRE_R2, // 1 - TYRE_R3, // 2 - TYRE_R4, // 3 - TYRE_ROAD_SUPER, // 4 - TYRE_ROAD_NORMAL, // 5 - TYRE_HYBRID, // 6 - TYRE_KNOBBLY, // 7 - TYRE_NUM + TYRE_R1, // 0 + TYRE_R2, // 1 + TYRE_R3, // 2 + TYRE_R4, // 3 + TYRE_ROAD_SUPER, // 4 + TYRE_ROAD_NORMAL, // 5 + TYRE_HYBRID, // 6 + TYRE_KNOBBLY, // 7 + TYRE_NUM }; static const int NOT_CHANGED = 255; // Confirmation flags -#define CONF_MENTIONED 1 -#define CONF_CONFIRMED 2 -#define CONF_PENALTY_DT 4 -#define CONF_PENALTY_SG 8 -#define CONF_PENALTY_30 16 -#define CONF_PENALTY_45 32 -#define CONF_DID_NOT_PIT 64 +#define CONF_MENTIONED 1 +#define CONF_CONFIRMED 2 +#define CONF_PENALTY_DT 4 +#define CONF_PENALTY_SG 8 +#define CONF_PENALTY_30 16 +#define CONF_PENALTY_45 32 +#define CONF_DID_NOT_PIT 64 -#define CONF_DISQ (CONF_PENALTY_DT | CONF_PENALTY_SG | CONF_DID_NOT_PIT) -#define CONF_TIME (CONF_PENALTY_30 | CONF_PENALTY_45) +#define CONF_DISQ (CONF_PENALTY_DT | CONF_PENALTY_SG | CONF_DID_NOT_PIT) +#define CONF_TIME (CONF_PENALTY_30 | CONF_PENALTY_45) // Race flags @@ -1313,7 +1296,6 @@ static const int NOT_CHANGED = 255; // bit 6 female // bit 7 rear right - // TRACKING PACKET REQUESTS // ======================== @@ -1327,7 +1309,6 @@ static const int NOT_CHANGED = 255; // SubT : TINY_NLP - request a single IS_NLP // SubT : TINY_MCI - request a set of IS_MCI - // AUTOCROSS // ========= @@ -1345,16 +1326,16 @@ static const int NOT_CHANGED = 255; struct IS_AXI // AutoX Info { - uint8_t Size; // 40 - uint8_t Type; // ISP_AXI - uint8_t ReqI; // 0 unless this is a reply to an TINY_AXI request - uint8_t Zero; + uint8_t Size; // 40 + uint8_t Type; // ISP_AXI + uint8_t ReqI; // 0 unless this is a reply to an TINY_AXI request + uint8_t Zero; - uint8_t AXStart; // autocross start position - uint8_t NumCP; // number of checkpoints - uint16_t NumO; // number of objects + uint8_t AXStart; // autocross start position + uint8_t NumCP; // number of checkpoints + uint16_t NumO; // number of objects - char LName[32]; // the name of the layout last loaded (if loaded locally) + char LName[32]; // the name of the layout last loaded (if loaded locally) }; // On false start or wrong route / restricted area, an IS_PEN packet is sent : @@ -1366,13 +1347,12 @@ struct IS_AXI // AutoX Info struct IS_AXO // AutoX Object { - uint8_t Size; // 4 - uint8_t Type; // ISP_AXO - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 4 + uint8_t Type; // ISP_AXO + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id }; - // CAR TRACKING - car position info sent at constant intervals // ============ @@ -1388,62 +1368,62 @@ struct IS_AXO // AutoX Object struct NodeLap // Car info in 6 bytes - there is an array of these in the NLP (below) { - uint16_t Node; // current path node - uint16_t Lap; // current lap - uint8_t PLID; // player's unique id - uint8_t Position; // current race position : 0 = unknown, 1 = leader, etc... + uint16_t Node; // current path node + uint16_t Lap; // current lap + uint8_t PLID; // player's unique id + uint8_t Position; // current race position : 0 = unknown, 1 = leader, etc... }; struct IS_NLP // Node and Lap Packet - variable size { - uint8_t Size; // 4 + NumP * 6 (PLUS 2 if needed to make it a multiple of 4) - uint8_t Type; // ISP_NLP - uint8_t ReqI; // 0 unless this is a reply to an TINY_NLP request - uint8_t NumP; // number of players in race + uint8_t Size; // 4 + NumP * 6 (PLUS 2 if needed to make it a multiple of 4) + uint8_t Type; // ISP_NLP + uint8_t ReqI; // 0 unless this is a reply to an TINY_NLP request + uint8_t NumP; // number of players in race - struct NodeLap Info[32]; // node and lap of each player, 1 to 32 of these (NumP) + struct NodeLap Info[32]; // node and lap of each player, 1 to 32 of these (NumP) }; // If ISF_MCI flag is set, a set of IS_MCI packets is sent... struct CompCar // Car info in 28 bytes - there is an array of these in the MCI (below) { - uint16_t Node; // current path node - uint16_t Lap; // current lap - uint8_t PLID; // player's unique id - uint8_t Position; // current race position : 0 = unknown, 1 = leader, etc... - uint8_t Info; // flags and other info - see below - uint8_t Sp3; - int32_t X; // X map (65536 = 1 metre) - int32_t Y; // Y map (65536 = 1 metre) - int32_t Z; // Z alt (65536 = 1 metre) - uint16_t Speed; // speed (32768 = 100 m/s) - uint16_t Direction; // car's motion if Speed > 0 : 0 = world y direction, 32768 = 180 deg - uint16_t Heading; // direction of forward axis : 0 = world y direction, 32768 = 180 deg - int16_t AngVel; // signed, rate of change of heading : (16384 = 360 deg/s) + uint16_t Node; // current path node + uint16_t Lap; // current lap + uint8_t PLID; // player's unique id + uint8_t Position; // current race position : 0 = unknown, 1 = leader, etc... + uint8_t Info; // flags and other info - see below + uint8_t Sp3; + int32_t X; // X map (65536 = 1 metre) + int32_t Y; // Y map (65536 = 1 metre) + int32_t Z; // Z alt (65536 = 1 metre) + uint16_t Speed; // speed (32768 = 100 m/s) + uint16_t Direction; // car's motion if Speed > 0 : 0 = world y direction, 32768 = 180 deg + uint16_t Heading; // direction of forward axis : 0 = world y direction, 32768 = 180 deg + int16_t AngVel; // signed, rate of change of heading : (16384 = 360 deg/s) }; // NOTE 1) Info byte - the bits in this byte have the following meanings : -#define CCI_BLUE 1 // this car is in the way of a driver who is a lap ahead -#define CCI_YELLOW 2 // this car is slow or stopped and in a dangerous place +#define CCI_BLUE 1 // this car is in the way of a driver who is a lap ahead +#define CCI_YELLOW 2 // this car is slow or stopped and in a dangerous place -#define CCI_LAG 32 // this car is lagging (missing or delayed position packets) +#define CCI_LAG 32 // this car is lagging (missing or delayed position packets) -#define CCI_FIRST 64 // this is the first compcar in this set of MCI packets -#define CCI_LAST 128 // this is the last compcar in this set of MCI packets +#define CCI_FIRST 64 // this is the first compcar in this set of MCI packets +#define CCI_LAST 128 // this is the last compcar in this set of MCI packets // NOTE 2) Heading : 0 = world y axis direction, 32768 = 180 degrees, anticlockwise from above // NOTE 3) AngVel : 0 = no change in heading, 8192 = 180 degrees per second anticlockwise struct IS_MCI // Multi Car Info - if more than 8 in race then more than one of these is sent { - uint8_t Size; // 4 + NumC * 28 - uint8_t Type; // ISP_MCI - uint8_t ReqI; // 0 unless this is a reply to an TINY_MCI request - uint8_t NumC; // number of valid CompCar structs in this packet + uint8_t Size; // 4 + NumC * 28 + uint8_t Type; // ISP_MCI + uint8_t ReqI; // 0 unless this is a reply to an TINY_MCI request + uint8_t NumC; // number of valid CompCar structs in this packet - struct CompCar Info[8]; // car info for each player, 1 to 8 of these (NumC) + struct CompCar Info[8]; // car info for each player, 1 to 8 of these (NumC) }; // You can change the rate of NLP or MCI after initialisation by sending this IS_SMALL : @@ -1452,7 +1432,6 @@ struct IS_MCI // Multi Car Info - if more than 8 in race then more than one of t // SubT : SMALL_NLI (Node Lap Interval) // UVal : interval (0 means stop, otherwise time interval : 40, 50, 60... 8000 ms) - // CONTACT - reports contacts between two cars if the closing speed is above 0.25 m/s // ======= @@ -1460,100 +1439,98 @@ struct IS_MCI // Multi Car Info - if more than 8 in race then more than one of t struct CarContact // 16 bytes : one car in a contact - two of these in the IS_CON (below) { - uint8_t PLID; - uint8_t Info; // like Info byte in CompCar (CCI_BLUE / CCI_YELLOW / CCI_LAG) - uint8_t Sp2; // spare - int8_t Steer; // front wheel steer in degrees (right positive) + uint8_t PLID; + uint8_t Info; // like Info byte in CompCar (CCI_BLUE / CCI_YELLOW / CCI_LAG) + uint8_t Sp2; // spare + int8_t Steer; // front wheel steer in degrees (right positive) - uint8_t ThrBrk; // high 4 bits : throttle / low 4 bits : brake (0 to 15) - uint8_t CluHan; // high 4 bits : clutch / low 4 bits : handbrake (0 to 15) - uint8_t GearSp; // high 4 bits : gear (15=R) / low 4 bits : spare - uint8_t Speed; // m/s + uint8_t ThrBrk; // high 4 bits : throttle / low 4 bits : brake (0 to 15) + uint8_t CluHan; // high 4 bits : clutch / low 4 bits : handbrake (0 to 15) + uint8_t GearSp; // high 4 bits : gear (15=R) / low 4 bits : spare + uint8_t Speed; // m/s - uint8_t Direction; // car's motion if Speed > 0 : 0 = world y direction, 128 = 180 deg - uint8_t Heading; // direction of forward axis : 0 = world y direction, 128 = 180 deg - int8_t AccelF; // m/s^2 longitudinal acceleration (forward positive) - int8_t AccelR; // m/s^2 lateral acceleration (right positive) + uint8_t Direction; // car's motion if Speed > 0 : 0 = world y direction, 128 = 180 deg + uint8_t Heading; // direction of forward axis : 0 = world y direction, 128 = 180 deg + int8_t AccelF; // m/s^2 longitudinal acceleration (forward positive) + int8_t AccelR; // m/s^2 lateral acceleration (right positive) - int16_t X; // position (1 metre = 16) - int16_t Y; // position (1 metre = 16) + int16_t X; // position (1 metre = 16) + int16_t Y; // position (1 metre = 16) }; struct IS_CON // CONtact - between two cars (A and B are sorted by PLID) { - uint8_t Size; // 40 - uint8_t Type; // ISP_CON - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 40 + uint8_t Type; // ISP_CON + uint8_t ReqI; // 0 + uint8_t Zero; - uint16_t SpClose; // high 4 bits : reserved / low 12 bits : closing speed (10 = 1 m/s) - uint16_t Time; // looping time stamp (hundredths - time since reset - like TINY_GTH) + uint16_t SpClose; // high 4 bits : reserved / low 12 bits : closing speed (10 = 1 m/s) + uint16_t Time; // looping time stamp (hundredths - time since reset - like TINY_GTH) - struct CarContact A; - struct CarContact B; + struct CarContact A; + struct CarContact B; }; // Set the ISF_OBH flag in the IS_ISI to receive object contact reports struct CarContOBJ // 8 bytes : car in a contact with an object { - uint8_t Direction; // car's motion if Speed > 0 : 0 = world y direction, 128 = 180 deg - uint8_t Heading; // direction of forward axis : 0 = world y direction, 128 = 180 deg - uint8_t Speed; // m/s - uint8_t Sp3; + uint8_t Direction; // car's motion if Speed > 0 : 0 = world y direction, 128 = 180 deg + uint8_t Heading; // direction of forward axis : 0 = world y direction, 128 = 180 deg + uint8_t Speed; // m/s + uint8_t Sp3; - int16_t X; // position (1 metre = 16) - int16_t Y; // position (1 metre = 16) + int16_t X; // position (1 metre = 16) + int16_t Y; // position (1 metre = 16) }; struct IS_OBH // OBject Hit - car hit an autocross object or an unknown object { - uint8_t Size; // 24 - uint8_t Type; // ISP_OBH - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 24 + uint8_t Type; // ISP_OBH + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint16_t SpClose; // high 4 bits : reserved / low 12 bits : closing speed (10 = 1 m/s) - uint16_t Time; // looping time stamp (hundredths - time since reset - like TINY_GTH) + uint16_t SpClose; // high 4 bits : reserved / low 12 bits : closing speed (10 = 1 m/s) + uint16_t Time; // looping time stamp (hundredths - time since reset - like TINY_GTH) - struct CarContOBJ C; + struct CarContOBJ C; - int16_t X; // as in ObjectInfo - int16_t Y; // as in ObjectInfo + int16_t X; // as in ObjectInfo + int16_t Y; // as in ObjectInfo - uint8_t Sp0; - uint8_t Sp1; - uint8_t Index; // AXO_x as in ObjectInfo or zero if it is an unknown object - uint8_t OBHFlags; // see below + uint8_t Sp0; + uint8_t Sp1; + uint8_t Index; // AXO_x as in ObjectInfo or zero if it is an unknown object + uint8_t OBHFlags; // see below }; //'BBBBHHBBBBhhhhBBBB' - // OBHFlags byte -#define OBH_LAYOUT 1 // an added object -#define OBH_CAN_MOVE 2 // a movable object -#define OBH_WAS_MOVING 4 // was moving before this hit -#define OBH_ON_SPOT 8 // object in original position +#define OBH_LAYOUT 1 // an added object +#define OBH_CAN_MOVE 2 // a movable object +#define OBH_WAS_MOVING 4 // was moving before this hit +#define OBH_ON_SPOT 8 // object in original position // Set the ISF_HLV flag in the IS_ISI to receive reports of incidents that would violate HLVC struct IS_HLV // Hot Lap Validity - illegal ground / hit wall / speeding in pit lane { - uint8_t Size; // 16 - uint8_t Type; // ISP_HLV - uint8_t ReqI; // 0 - uint8_t PLID; // player's unique id + uint8_t Size; // 16 + uint8_t Type; // ISP_HLV + uint8_t ReqI; // 0 + uint8_t PLID; // player's unique id - uint8_t HLVC; // 0 : ground / 1 : wall / 4 : speeding - uint8_t Sp1; - uint16_t Time; // looping time stamp (hundredths - time since reset - like TINY_GTH) + uint8_t HLVC; // 0 : ground / 1 : wall / 4 : speeding + uint8_t Sp1; + uint16_t Time; // looping time stamp (hundredths - time since reset - like TINY_GTH) - struct CarContOBJ C; + struct CarContOBJ C; }; - // AUTOCROSS OBJECTS - reporting / adding / removing // ================= @@ -1565,29 +1542,29 @@ struct IS_HLV // Hot Lap Validity - illegal ground / hit wall / speeding in pit struct ObjectInfo // Info about a single object - explained in the layout file format { - int16_t X; - int16_t Y; - int8_t Zchar; - uint8_t Flags; - uint8_t Index; - uint8_t Heading; + int16_t X; + int16_t Y; + int8_t Zchar; + uint8_t Flags; + uint8_t Index; + uint8_t Heading; //'2hb3B' }; struct IS_AXM // AutoX Multiple objects - variable size { - uint8_t Size; // 8 + NumO * 8 - uint8_t Type; // ISP_AXM - uint8_t ReqI; // 0 - uint8_t NumO; // number of objects in this packet + uint8_t Size; // 8 + NumO * 8 + uint8_t Type; // ISP_AXM + uint8_t ReqI; // 0 + uint8_t NumO; // number of objects in this packet - uint8_t UCID; // unique id of the connection that sent the packet - uint8_t PMOAction; // see below - uint8_t PMOFlags; // see below - uint8_t Sp3; + uint8_t UCID; // unique id of the connection that sent the packet + uint8_t PMOAction; // see below + uint8_t PMOFlags; // see below + uint8_t Sp3; - struct ObjectInfo Info[30]; // info about each object, 0 to 30 of these + struct ObjectInfo Info[30]; // info about each object, 0 to 30 of these }; //'8B' @@ -1596,11 +1573,11 @@ struct IS_AXM // AutoX Multiple objects - variable size enum { - PMO_LOADING_FILE, // 0 - sent by the layout loading system only - PMO_ADD_OBJECTS, // 1 - adding objects (from InSim or editor) - PMO_DEL_OBJECTS, // 2 - delete objects (from InSim or editor) - PMO_CLEAR_ALL, // 3 - clear all objects (NumO must be zero) - PMO_NUM + PMO_LOADING_FILE, // 0 - sent by the layout loading system only + PMO_ADD_OBJECTS, // 1 - adding objects (from InSim or editor) + PMO_DEL_OBJECTS, // 2 - delete objects (from InSim or editor) + PMO_CLEAR_ALL, // 3 - clear all objects (NumO must be zero) + PMO_NUM }; // Info about the PMOFlags byte (only bit 0 is currently used) : @@ -1632,7 +1609,6 @@ enum // the corresponding IS_AXM that will be output when the packet is processed. Then // you can send the second packet and again wait for the IS_AXM and so on. - // CAR POSITION PACKETS (Initialising OutSim from InSim - See "OutSim" below) // ==================== @@ -1652,7 +1628,6 @@ enum // NOTE : OutSim packets are not InSim packets and don't have a 4-byte header. - // DASHBOARD PACKETS (Initialising OutGauge from InSim - See "OutGauge" below) // ================= @@ -1672,7 +1647,6 @@ enum // NOTE : OutGauge packets are not InSim packets and don't have a 4-byte header. - // CAMERA CONTROL // ============== @@ -1684,15 +1658,15 @@ enum struct IS_SCC // Set Car Camera - Simplified camera packet (not SHIFT+U mode) { - uint8_t Size; // 8 - uint8_t Type; // ISP_SCC - uint8_t ReqI; // 0 - uint8_t Zero; + uint8_t Size; // 8 + uint8_t Type; // ISP_SCC + uint8_t ReqI; // 0 + uint8_t Zero; - uint8_t ViewPLID; // Unique ID of player to view - uint8_t InGameCam; // InGameCam (as reported in StatePack) - uint8_t Sp2; - uint8_t Sp3; + uint8_t ViewPLID; // Unique ID of player to view + uint8_t InGameCam; // InGameCam (as reported in StatePack) + uint8_t Sp2; + uint8_t Sp3; }; // NOTE : Set InGameCam or ViewPLID to 255 to leave that option unchanged. @@ -1707,24 +1681,24 @@ struct IS_SCC // Set Car Camera - Simplified camera packet (not SHIFT+U mode) struct IS_CPP // Cam Pos Pack - Full camera packet (in car OR SHIFT+U mode) { - uint8_t Size; // 32 - uint8_t Type; // ISP_CPP - uint8_t ReqI; // instruction : 0 / or reply : ReqI as received in the TINY_SCP - uint8_t Zero; + uint8_t Size; // 32 + uint8_t Type; // ISP_CPP + uint8_t ReqI; // instruction : 0 / or reply : ReqI as received in the TINY_SCP + uint8_t Zero; - struct Vec Pos; // Position vector + struct Vec Pos; // Position vector - uint16_t H; // heading - 0 points along Y axis - uint16_t P; // pitch - 0 means looking at horizon - uint16_t R; // roll - 0 means no roll + uint16_t H; // heading - 0 points along Y axis + uint16_t P; // pitch - 0 means looking at horizon + uint16_t R; // roll - 0 means no roll - uint8_t ViewPLID; // Unique ID of viewed player (0 = none) - uint8_t InGameCam; // InGameCam (as reported in StatePack) + uint8_t ViewPLID; // Unique ID of viewed player (0 = none) + uint8_t InGameCam; // InGameCam (as reported in StatePack) - float FOV; // 4-byte float : FOV in degrees + float FOV; // 4-byte float : FOV in degrees - uint16_t Time; // Time in ms to get there (0 means instant) - uint16_t Flags; // ISS state flags (see below) + uint16_t Time; // Time in ms to get there (0 means instant) + uint16_t Flags; // ISS state flags (see below) }; // The ISS state flags that can be set are : @@ -1773,7 +1747,6 @@ struct IS_CPP // Cam Pos Pack - Full camera packet (in car OR SHIFT+U mode) // and later send back exactly the same packet to LFS and it will try to replicate // that camera position. - // TIME CONTROL // ============ @@ -1806,7 +1779,6 @@ struct IS_CPP // Cam Pos Pack - Full camera packet (in car OR SHIFT+U mode) // SubT : SMALL_STP (STeP) // UVal : number (number of hundredths of a second to update) - // REPLAY CONTROL // ============== @@ -1816,20 +1788,20 @@ struct IS_CPP // Cam Pos Pack - Full camera packet (in car OR SHIFT+U mode) struct IS_RIP // Replay Information Packet { - uint8_t Size; // 80 - uint8_t Type; // ISP_RIP - uint8_t ReqI; // request : non-zero / reply : same value returned - uint8_t Error; // 0 or 1 = OK / other values are listed below + uint8_t Size; // 80 + uint8_t Type; // ISP_RIP + uint8_t ReqI; // request : non-zero / reply : same value returned + uint8_t Error; // 0 or 1 = OK / other values are listed below - uint8_t MPR; // 0 = SPR / 1 = MPR - uint8_t Paused; // request : pause on arrival / reply : paused state - uint8_t Options; // various options - see below - uint8_t Sp3; + uint8_t MPR; // 0 = SPR / 1 = MPR + uint8_t Paused; // request : pause on arrival / reply : paused state + uint8_t Options; // various options - see below + uint8_t Sp3; - uint32_t CTime; // (hundredths) request : destination / reply : position - uint32_t TTime; // (hundredths) request : zero / reply : replay length + uint32_t CTime; // (hundredths) request : destination / reply : position + uint32_t TTime; // (hundredths) request : zero / reply : replay length - char RName[64]; // zero or replay name - last byte must be zero + char RName[64]; // zero or replay name - last byte must be zero }; // NOTE about RName : @@ -1845,30 +1817,29 @@ struct IS_RIP // Replay Information Packet enum { - RIP_OK, // 0 - OK : completed instruction - RIP_ALREADY, // 1 - OK : already at the destination - RIP_DEDICATED, // 2 - can't run a replay - dedicated host - RIP_WRONG_MODE, // 3 - can't start a replay - not in a suitable mode - RIP_NOT_REPLAY, // 4 - RName is zero but no replay is currently loaded - RIP_CORRUPTED, // 5 - IS_RIP corrupted (e.g. RName does not end with zero) - RIP_NOT_FOUND, // 6 - the replay file was not found - RIP_UNLOADABLE, // 7 - obsolete / future / corrupted - RIP_DEST_OOB, // 8 - destination is beyond replay length - RIP_UNKNOWN, // 9 - unknown error found starting replay - RIP_USER, // 10 - replay search was terminated by user - RIP_OOS, // 11 - can't reach destination - SPR is out of sync + RIP_OK, // 0 - OK : completed instruction + RIP_ALREADY, // 1 - OK : already at the destination + RIP_DEDICATED, // 2 - can't run a replay - dedicated host + RIP_WRONG_MODE, // 3 - can't start a replay - not in a suitable mode + RIP_NOT_REPLAY, // 4 - RName is zero but no replay is currently loaded + RIP_CORRUPTED, // 5 - IS_RIP corrupted (e.g. RName does not end with zero) + RIP_NOT_FOUND, // 6 - the replay file was not found + RIP_UNLOADABLE, // 7 - obsolete / future / corrupted + RIP_DEST_OOB, // 8 - destination is beyond replay length + RIP_UNKNOWN, // 9 - unknown error found starting replay + RIP_USER, // 10 - replay search was terminated by user + RIP_OOS, // 11 - can't reach destination - SPR is out of sync }; // Options byte : some options -#define RIPOPT_LOOP 1 // replay will loop if this bit is set -#define RIPOPT_SKINS 2 // set this bit to download missing skins -#define RIPOPT_FULL_PHYS 4 // use full physics when searching an MPR +#define RIPOPT_LOOP 1 // replay will loop if this bit is set +#define RIPOPT_SKINS 2 // set this bit to download missing skins +#define RIPOPT_FULL_PHYS 4 // use full physics when searching an MPR // NOTE : RIPOPT_FULL_PHYS makes MPR searching much slower so should not normally be used. // This flag was added to allow high accuracy MCI packets to be output when fast forwarding. - // SCREENSHOTS // =========== @@ -1879,30 +1850,29 @@ enum struct IS_SSH // ScreenSHot { - uint8_t Size; // 40 - uint8_t Type; // ISP_SSH - uint8_t ReqI; // request : non-zero / reply : same value returned - uint8_t Error; // 0 = OK / other values are listed below + uint8_t Size; // 40 + uint8_t Type; // ISP_SSH + uint8_t ReqI; // request : non-zero / reply : same value returned + uint8_t Error; // 0 = OK / other values are listed below - uint8_t Sp0; // 0 - uint8_t Sp1; // 0 - uint8_t Sp2; // 0 - uint8_t Sp3; // 0 + uint8_t Sp0; // 0 + uint8_t Sp1; // 0 + uint8_t Sp2; // 0 + uint8_t Sp3; // 0 - char BMP[32]; // name of screenshot file - last byte must be zero + char BMP[32]; // name of screenshot file - last byte must be zero }; // Error codes returned in IS_SSH replies : enum { - SSH_OK, // 0 - OK : completed instruction - SSH_DEDICATED, // 1 - can't save a screenshot - dedicated host - SSH_CORRUPTED, // 2 - IS_SSH corrupted (e.g. BMP does not end with zero) - SSH_NO_SAVE, // 3 - could not save the screenshot + SSH_OK, // 0 - OK : completed instruction + SSH_DEDICATED, // 1 - can't save a screenshot - dedicated host + SSH_CORRUPTED, // 2 - IS_SSH corrupted (e.g. BMP does not end with zero) + SSH_NO_SAVE, // 3 - could not save the screenshot }; - // BUTTONS // ======= @@ -1934,23 +1904,23 @@ enum struct IS_BFN // Button FunctioN - delete buttons / receive button requests { - uint8_t Size; // 8 - uint8_t Type; // ISP_BFN - uint8_t ReqI; // 0 - uint8_t SubT; // subtype, from BFN_ enumeration (see below) + uint8_t Size; // 8 + uint8_t Type; // ISP_BFN + uint8_t ReqI; // 0 + uint8_t SubT; // subtype, from BFN_ enumeration (see below) - uint8_t UCID; // connection to send to or from (0 = local / 255 = all) - uint8_t ClickID; // ID of button to delete (if SubT is BFN_DEL_BTN) - uint8_t Inst; // used internally by InSim - uint8_t Sp3; + uint8_t UCID; // connection to send to or from (0 = local / 255 = all) + uint8_t ClickID; // ID of button to delete (if SubT is BFN_DEL_BTN) + uint8_t Inst; // used internally by InSim + uint8_t Sp3; }; enum // the fourth byte of IS_BFN packets is one of these { - BFN_DEL_BTN, // 0 - instruction : delete one button (must set ClickID) - BFN_CLEAR, // 1 - instruction : clear all buttons made by this insim instance - BFN_USER_CLEAR, // 2 - info : user cleared this insim instance's buttons - BFN_REQUEST, // 3 - user request : SHIFT+B or SHIFT+I - request for buttons + BFN_DEL_BTN, // 0 - instruction : delete one button (must set ClickID) + BFN_CLEAR, // 1 - instruction : clear all buttons made by this insim instance + BFN_USER_CLEAR, // 2 - info : user cleared this insim instance's buttons + BFN_REQUEST, // 3 - user request : SHIFT+B or SHIFT+I - request for buttons }; // NOTE : BFN_REQUEST allows the user to bring up buttons with SHIFT+B or SHIFT+I @@ -1962,22 +1932,22 @@ enum // the fourth byte of IS_BFN packets is one of these struct IS_BTN // BuTtoN - button header - followed by 0 to 240 characters { - uint8_t Size; // 12 + TEXT_SIZE (a multiple of 4) - uint8_t Type; // ISP_BTN - uint8_t ReqI; // non-zero (returned in IS_BTC and IS_BTT packets) - uint8_t UCID; // connection to display the button (0 = local / 255 = all) + uint8_t Size; // 12 + TEXT_SIZE (a multiple of 4) + uint8_t Type; // ISP_BTN + uint8_t ReqI; // non-zero (returned in IS_BTC and IS_BTT packets) + uint8_t UCID; // connection to display the button (0 = local / 255 = all) - uint8_t ClickID; // button ID (0 to 239) - uint8_t Inst; // some extra flags - see below - uint8_t BStyle; // button style flags - see below - uint8_t TypeIn; // max chars to type in - see below + uint8_t ClickID; // button ID (0 to 239) + uint8_t Inst; // some extra flags - see below + uint8_t BStyle; // button style flags - see below + uint8_t TypeIn; // max chars to type in - see below - uint8_t L; // left : 0 - 200 - uint8_t T; // top : 0 - 200 - uint8_t W; // width : 0 - 200 - uint8_t H; // height : 0 - 200 + uint8_t L; // left : 0 - 200 + uint8_t T; // top : 0 - 200 + uint8_t W; // width : 0 - 200 + uint8_t H; // height : 0 - 200 -// char Text[TEXT_SIZE]; // 0 to 240 characters of text + // char Text[TEXT_SIZE]; // 0 to 240 characters of text }; // ClickID byte : this value is returned in IS_BTC and IS_BTT packets. @@ -2004,7 +1974,7 @@ struct IS_BTN // BuTtoN - button header - followed by 0 to 240 characters // Inst byte : mainly used internally by InSim but also provides some extra user flags -#define INST_ALWAYS_ON 128 // if this bit is set the button is visible in all screens +#define INST_ALWAYS_ON 128 // if this bit is set the button is visible in all screens // NOTE : You should not use INST_ALWAYS_ON for most buttons. This is a special flag for buttons // that really must be on in all screens (including the garage and options screens). You will @@ -2014,14 +1984,14 @@ struct IS_BTN // BuTtoN - button header - followed by 0 to 240 characters // BStyle byte : style flags for the button -#define ISB_C1 1 // you can choose a standard -#define ISB_C2 2 // interface colour using -#define ISB_C4 4 // these 3 lowest bits - see below -#define ISB_CLICK 8 // click this button to send IS_BTC -#define ISB_LIGHT 16 // light button -#define ISB_DARK 32 // dark button -#define ISB_LEFT 64 // align text to left -#define ISB_RIGHT 128 // align text to right +#define ISB_C1 1 // you can choose a standard +#define ISB_C2 2 // interface colour using +#define ISB_C4 4 // these 3 lowest bits - see below +#define ISB_CLICK 8 // click this button to send IS_BTC +#define ISB_LIGHT 16 // light button +#define ISB_DARK 32 // dark button +#define ISB_LEFT 64 // align text to left +#define ISB_RIGHT 128 // align text to right // colour 0 : light grey (not user editable) // colour 1 : title colour (default:yellow) @@ -2041,43 +2011,42 @@ struct IS_BTN // BuTtoN - button header - followed by 0 to 240 characters struct IS_BTC // BuTton Click - sent back when user clicks a button { - uint8_t Size; // 8 - uint8_t Type; // ISP_BTC - uint8_t ReqI; // ReqI as received in the IS_BTN - uint8_t UCID; // connection that clicked the button (zero if local) + uint8_t Size; // 8 + uint8_t Type; // ISP_BTC + uint8_t ReqI; // ReqI as received in the IS_BTN + uint8_t UCID; // connection that clicked the button (zero if local) - uint8_t ClickID; // button identifier originally sent in IS_BTN - uint8_t Inst; // used internally by InSim - uint8_t CFlags; // button click flags - see below - uint8_t Sp3; + uint8_t ClickID; // button identifier originally sent in IS_BTN + uint8_t Inst; // used internally by InSim + uint8_t CFlags; // button click flags - see below + uint8_t Sp3; }; // CFlags byte : click flags -#define ISB_LMB 1 // left click -#define ISB_RMB 2 // right click -#define ISB_CTRL 4 // ctrl + click -#define ISB_SHIFT 8 // shift + click +#define ISB_LMB 1 // left click +#define ISB_RMB 2 // right click +#define ISB_CTRL 4 // ctrl + click +#define ISB_SHIFT 8 // shift + click // If the TypeIn byte is set in IS_BTN the user can type text into the button // In that case no IS_BTC is sent - an IS_BTT is sent when the user presses ENTER struct IS_BTT // BuTton Type - sent back when user types into a text entry button { - uint8_t Size; // 104 - uint8_t Type; // ISP_BTT - uint8_t ReqI; // ReqI as received in the IS_BTN - uint8_t UCID; // connection that typed into the button (zero if local) + uint8_t Size; // 104 + uint8_t Type; // ISP_BTT + uint8_t ReqI; // ReqI as received in the IS_BTN + uint8_t UCID; // connection that typed into the button (zero if local) - uint8_t ClickID; // button identifier originally sent in IS_BTN - uint8_t Inst; // used internally by InSim - uint8_t TypeIn; // from original button specification - uint8_t Sp3; + uint8_t ClickID; // button identifier originally sent in IS_BTN + uint8_t Inst; // used internally by InSim + uint8_t TypeIn; // from original button specification + uint8_t Sp3; - char Text[96]; // typed text, zero to TypeIn specified in IS_BTN + char Text[96]; // typed text, zero to TypeIn specified in IS_BTN }; - // OutSim - MOTION SIMULATOR SUPPORT // ====== @@ -2097,17 +2066,17 @@ struct IS_BTT // BuTton Type - sent back when user types into a text entry butto struct OutSimPack { - uint32_t Time; // time in milliseconds (to check order) + uint32_t Time; // time in milliseconds (to check order) - struct Vector AngVel; // 3 floats, angular velocity vector - float Heading; // anticlockwise from above (Z) - float Pitch; // anticlockwise from right (X) - float Roll; // anticlockwise from front (Y) - struct Vector Accel; // 3 floats X, Y, Z - struct Vector Vel; // 3 floats X, Y, Z - struct Vec Pos; // 3 ints X, Y, Z (1m = 65536) + struct Vector AngVel; // 3 floats, angular velocity vector + float Heading; // anticlockwise from above (Z) + float Pitch; // anticlockwise from right (X) + float Roll; // anticlockwise from front (Y) + struct Vector Accel; // 3 floats X, Y, Z + struct Vector Vel; // 3 floats X, Y, Z + struct Vec Pos; // 3 ints X, Y, Z (1m = 65536) - int32_t ID; // optional - only if OutSim ID is specified + int32_t ID; // optional - only if OutSim ID is specified }; // NOTE 1) X and Y axes are on the ground, Z is up. @@ -2116,7 +2085,6 @@ struct OutSimPack // not support any motion systems in particular and cannot accept responsibility // for injuries or deaths connected with the use of such machinery. - // OutGauge - EXTERNAL DASHBOARD SUPPORT // ======== @@ -2136,97 +2104,97 @@ struct OutSimPack struct OutGaugePack { - uint32_t Time; // time in milliseconds (to check order) + uint32_t Time; // time in milliseconds (to check order) - char Car[4]; // Car name - uint16_t Flags; // Info (see OG_x below) - uint8_t Gear; // Reverse:0, Neutral:1, First:2... - uint8_t 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 - uint32_t DashLights; // Dash lights available (see DL_x below) - uint32_t 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 + char Car[4]; // Car name + uint16_t Flags; // Info (see OG_x below) + uint8_t Gear; // Reverse:0, Neutral:1, First:2... + uint8_t 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 + uint32_t DashLights; // Dash lights available (see DL_x below) + uint32_t 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 - int32_t ID; // optional - only if OutGauge ID is specified + int32_t ID; // optional - only if OutGauge ID is specified }; // OG_x - bits for OutGaugePack Flags -#define OG_SHIFT 1 // key -#define OG_CTRL 2 // key +#define OG_SHIFT 1 // key +#define OG_CTRL 2 // key -#define OG_TURBO 8192 // show turbo gauge -#define OG_KM 16384 // if not set - user prefers MILES -#define OG_BAR 32768 // if not set - user prefers PSI +#define OG_TURBO 8192 // show turbo gauge +#define OG_KM 16384 // if not set - user prefers MILES +#define OG_BAR 32768 // if not set - user prefers PSI // DL_x - bits for OutGaugePack DashLights and ShowLights /* enum { - DL_SHIFT, // bit 0 - shift light - DL_FULLBEAM, // bit 1 - full beam - DL_HANDBRAKE, // bit 2 - handbrake - DL_PITSPEED, // bit 3 - pit speed limiter - DL_TC, // bit 4 - TC active or switched off - DL_SIGNAL_L, // bit 5 - left turn signal - DL_SIGNAL_R, // bit 6 - right turn signal - DL_SIGNAL_ANY, // bit 7 - shared turn signal - DL_OILWARN, // bit 8 - oil pressure warning - DL_BATTERY, // bit 9 - battery warning - DL_ABS, // bit 10 - ABS active or switched off - DL_SPARE, // bit 11 - DL_NUM + DL_SHIFT, // bit 0 - shift light + DL_FULLBEAM, // bit 1 - full beam + DL_HANDBRAKE, // bit 2 - handbrake + DL_PITSPEED, // bit 3 - pit speed limiter + DL_TC, // bit 4 - TC active or switched off + DL_SIGNAL_L, // bit 5 - left turn signal + DL_SIGNAL_R, // bit 6 - right turn signal + DL_SIGNAL_ANY, // bit 7 - shared turn signal + DL_OILWARN, // bit 8 - oil pressure warning + DL_BATTERY, // bit 9 - battery warning + DL_ABS, // bit 10 - ABS active or switched off + DL_SPARE, // bit 11 + DL_NUM }; */ ////// struct conninfo { - uint8_t active; - uint8_t admin; - uint8_t state; - char uname[24]; - char pname[24]; + uint8_t active; + uint8_t admin; + uint8_t state; + char uname[24]; + char pname[24]; }; #define CARPATHSIZE 128 struct carinfo { - char cname[4]; - uint8_t active; - uint8_t ucid; - uint8_t mass; - uint8_t intake; + char cname[4]; + uint8_t active; + uint8_t ucid; + uint8_t mass; + uint8_t intake; - uint16_t node; - uint16_t lap; - uint8_t position; - uint8_t info; - uint8_t sp3; - int32_t x; - int32_t y; - int32_t z; - uint16_t speed; - uint16_t direction; - uint16_t heading; - int16_t angvel; + uint16_t node; + uint16_t lap; + uint8_t position; + uint8_t info; + uint8_t sp3; + int32_t x; + int32_t y; + int32_t z; + uint16_t speed; + uint16_t direction; + uint16_t heading; + int16_t angvel; - int32_t hist_x[CARPATHSIZE]; - int32_t hist_y[CARPATHSIZE]; - uint16_t hist_s[CARPATHSIZE]; - int32_t hist; + int32_t hist_x[CARPATHSIZE]; + int32_t hist_y[CARPATHSIZE]; + uint16_t hist_s[CARPATHSIZE]; + int32_t hist; }; extern struct conninfo s_conninfo[256]; diff --git a/lfsdash.c b/lfsdash.c index 49ea0e2..57700bb 100644 --- a/lfsdash.c +++ b/lfsdash.c @@ -16,92 +16,96 @@ static GLuint s_symbols[1]; -struct sympos { - float a, b, c, d; - int flag; - struct colour off; - struct colour on; +struct sympos +{ + float a, b, c, d; + int flag; + struct colour off; + struct colour on; }; /* - DL_SHIFT, // bit 0 - shift light - DL_FULLBEAM, // bit 1 - full beam - DL_HANDBRAKE, // bit 2 - handbrake - DL_PITSPEED, // bit 3 - pit speed limiter - DL_TC, // bit 4 - TC active or switched off - DL_SIGNAL_L, // bit 5 - left turn signal - DL_SIGNAL_R, // bit 6 - right turn signal - DL_SIGNAL_ANY, // bit 7 - shared turn signal - DL_OILWARN, // bit 8 - oil pressure warning - DL_BATTERY, // bit 9 - battery warning - DL_ABS, // bit 10 - ABS active or switched off - DL_SPARE, // bit 11 - */ + DL_SHIFT, // bit 0 - shift light + DL_FULLBEAM, // bit 1 - full beam + DL_HANDBRAKE, // bit 2 - handbrake + DL_PITSPEED, // bit 3 - pit speed limiter + DL_TC, // bit 4 - TC active or switched off + DL_SIGNAL_L, // bit 5 - left turn signal + DL_SIGNAL_R, // bit 6 - right turn signal + DL_SIGNAL_ANY, // bit 7 - shared turn signal + DL_OILWARN, // bit 8 - oil pressure warning + DL_BATTERY, // bit 9 - battery warning + DL_ABS, // bit 10 - ABS active or switched off + DL_SPARE, // bit 11 + */ static int dl_to_sympos[] = { - 18, 0, 12, 17, 11, 15, 16, 2, 10, 9, 14, 13 -}; + 18, 0, 12, 17, 11, 15, 16, 2, 10, 9, 14, 13}; static struct sympos s_sympos[] = { - { 0.0, 0.0, 0.125, 0.125, (1 << DL_FULLBEAM), { 0.1, 0.1, 0.1, 1.0 }, { 0.15, 0.15, 1.0, 1.0 } }, - { 0.125, 0.0, 0.25, 0.125, 0, { 0.1, 0.1, 0.1, 1.0 }, { 0.5, 0.5, 1.0, 1.0 } }, - { 0.25, 0.0, 0.375, 0.125, (1 << DL_SIGNAL_ANY), { 0.1, 0.1, 0.1, 1.0 }, { 0.15, 1.0, 0.15, 1.0 } }, - { 0.375, 0.0, 0.5, 0.125, 0, { 0.1, 0.1, 0.1, 1.0 }, { 0.5, 0.5, 1.0, 1.0 } }, + {0.0, 0.0, 0.125, 0.125, (1 << DL_FULLBEAM), {0.1, 0.1, 0.1, 1.0}, {0.15, 0.15, 1.0, 1.0}}, + {0.125, 0.0, 0.25, 0.125, 0, {0.1, 0.1, 0.1, 1.0}, {0.5, 0.5, 1.0, 1.0}}, + {0.25, 0.0, 0.375, 0.125, (1 << DL_SIGNAL_ANY), {0.1, 0.1, 0.1, 1.0}, {0.15, 1.0, 0.15, 1.0}}, + {0.375, 0.0, 0.5, 0.125, 0, {0.1, 0.1, 0.1, 1.0}, {0.5, 0.5, 1.0, 1.0}}, - { 0.0, 0.125, 0.125, 0.25, 0, { 1.0, 1.0, 1.0, 1.0 }, { 1.0, 0.15, 0.15, 1.0 } }, - { 0.125, 0.125, 0.25, 0.25, 0, { 1.0, 1.0, 1.0, 1.0 }, { 0.15, 0.15, 1.0, 1.0 } }, - { 0.25, 0.125, 0.375, 0.25, 0, { 1.0, 1.0, 1.0, 1.0 }, { 0.15, 0.15, 1.0, 1.0 } }, - { 0.375, 0.125, 0.5, 0.25, 0, { 1.0, 1.0, 1.0, 1.0 }, { 1.0, 0.15, 0.15, 1.0 } }, - { 0.5, 0.125, 0.625, 0.25, 0, { 0.1, 0.1, 0.1, 1.0 }, { 0.15, 0.15, 0.15, 1.0 } }, + {0.0, 0.125, 0.125, 0.25, 0, {1.0, 1.0, 1.0, 1.0}, {1.0, 0.15, 0.15, 1.0}}, + {0.125, 0.125, 0.25, 0.25, 0, {1.0, 1.0, 1.0, 1.0}, {0.15, 0.15, 1.0, 1.0}}, + {0.25, 0.125, 0.375, 0.25, 0, {1.0, 1.0, 1.0, 1.0}, {0.15, 0.15, 1.0, 1.0}}, + {0.375, 0.125, 0.5, 0.25, 0, {1.0, 1.0, 1.0, 1.0}, {1.0, 0.15, 0.15, 1.0}}, + {0.5, 0.125, 0.625, 0.25, 0, {0.1, 0.1, 0.1, 1.0}, {0.15, 0.15, 0.15, 1.0}}, - { 0.0, 0.25, 0.125, 0.375, (1 << DL_BATTERY), { 0.1, 0.1, 0.1, 1.0 }, { 1.0, 0.15, 0.15, 1.0 } }, - { 0.125, 0.25, 0.25, 0.375, (1 << DL_OILWARN), { 0.1, 0.1, 0.1, 1.0 }, { 1.0, 0.15, 0.15, 1.0 } }, - { 0.25, 0.25, 0.375, 0.375, (1 << DL_TC), { 0.1, 0.1, 0.1, 1.0 }, { 1.0, 0.5, 0.0, 1.0 } }, - { 0.375, 0.25, 0.5, 0.375, (1 << DL_HANDBRAKE), { 0.1, 0.1, 0.1, 1.0 }, { 0.15, 0.15, 1.0, 1.0 } }, - { 0.5, 0.25, 0.625, 0.375, 0, { 0.1, 0.1, 0.1, 1.0 }, { 0.25, 0.25, 1.0, 1.0 } }, - { 0.625, 0.25, 0.75, 0.375, (1 << DL_ABS), { 0.1, 0.1, 0.1, 1.0 }, { 1.0, 0.5, 0.0, 1.0 } }, + {0.0, 0.25, 0.125, 0.375, (1 << DL_BATTERY), {0.1, 0.1, 0.1, 1.0}, {1.0, 0.15, 0.15, 1.0}}, + {0.125, 0.25, 0.25, 0.375, (1 << DL_OILWARN), {0.1, 0.1, 0.1, 1.0}, {1.0, 0.15, 0.15, 1.0}}, + {0.25, 0.25, 0.375, 0.375, (1 << DL_TC), {0.1, 0.1, 0.1, 1.0}, {1.0, 0.5, 0.0, 1.0}}, + {0.375, 0.25, 0.5, 0.375, (1 << DL_HANDBRAKE), {0.1, 0.1, 0.1, 1.0}, {0.15, 0.15, 1.0, 1.0}}, + {0.5, 0.25, 0.625, 0.375, 0, {0.1, 0.1, 0.1, 1.0}, {0.25, 0.25, 1.0, 1.0}}, + {0.625, 0.25, 0.75, 0.375, (1 << DL_ABS), {0.1, 0.1, 0.1, 1.0}, {1.0, 0.5, 0.0, 1.0}}, - { 0.0, 0.375, 0.125, 0.5, (1 << DL_SIGNAL_L), { 0.1, 0.1, 0.1, 1.0 }, { 0.15, 1.0, 0.15, 1.0 } }, - { 0.125, 0.375, 0.25, 0.5, (1 << DL_SIGNAL_R), { 0.1, 0.1, 0.1, 1.0 }, { 0.15, 1.0, 0.15, 1.0 } }, - { 0.25, 0.375, 0.375, 0.5, (1 << DL_PITSPEED), { 0.1, 0.1, 0.1, 1.0 }, { 0.15, 1.0, 0.15, 1.0 } }, - { 0.375, 0.375, 0.5, 0.5, (1 << DL_SHIFT), { 0.1, 0.1, 0.1, 1.0 }, { 1.0, 0.15, 0.15, 1.0 } }, + {0.0, 0.375, 0.125, 0.5, (1 << DL_SIGNAL_L), {0.1, 0.1, 0.1, 1.0}, {0.15, 1.0, 0.15, 1.0}}, + {0.125, 0.375, 0.25, 0.5, (1 << DL_SIGNAL_R), {0.1, 0.1, 0.1, 1.0}, {0.15, 1.0, 0.15, 1.0}}, + {0.25, 0.375, 0.375, 0.5, (1 << DL_PITSPEED), {0.1, 0.1, 0.1, 1.0}, {0.15, 1.0, 0.15, 1.0}}, + {0.375, 0.375, 0.5, 0.5, (1 << DL_SHIFT), {0.1, 0.1, 0.1, 1.0}, {1.0, 0.15, 0.15, 1.0}}, - { 0.5, 0.0, 0.625, 0.125, 0, { 1.0, 0.5, 0.0, 1.0 }, { 1.0, 0.15, 0.15, 1.0 } }, + {0.5, 0.0, 0.625, 0.125, 0, {1.0, 0.5, 0.0, 1.0}, {1.0, 0.15, 0.15, 1.0}}, }; void drawSymbol(int symbol, int on, int map) { - if (map) symbol = dl_to_sympos[symbol]; + if (map) + symbol = dl_to_sympos[symbol]; - struct sympos *s = &s_sympos[symbol]; - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, s_symbols[0]); - if (on) { - glColor4f(s->on.r, s->on.g, s->on.b, s->on.a); - } else { - glColor4f(s->off.r, s->off.g, s->off.b, s->off.a); - } - glBegin(GL_QUADS); - glTexCoord2f(s->a, (on ? 0.5 : 1.0) - s->d); - glVertex3f(-0.5, -0.5, 0.0); - glTexCoord2f(s->c, (on ? 0.5 : 1.0) - s->d); - glVertex3f(0.5, -0.5, 0.0); - glTexCoord2f(s->c, (on ? 0.5 : 1.0) - s->b); - glVertex3f(0.5, 0.5, 0.0); - glTexCoord2f(s->a, (on ? 0.5 : 1.0) - s->b); - glVertex3f(-0.5, 0.5, 0.0); - glEnd(); - glDisable(GL_TEXTURE_2D); + struct sympos *s = &s_sympos[symbol]; + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, s_symbols[0]); + if (on) + { + glColor4f(s->on.r, s->on.g, s->on.b, s->on.a); + } + else + { + glColor4f(s->off.r, s->off.g, s->off.b, s->off.a); + } + glBegin(GL_QUADS); + glTexCoord2f(s->a, (on ? 0.5 : 1.0) - s->d); + glVertex3f(-0.5, -0.5, 0.0); + glTexCoord2f(s->c, (on ? 0.5 : 1.0) - s->d); + glVertex3f(0.5, -0.5, 0.0); + glTexCoord2f(s->c, (on ? 0.5 : 1.0) - s->b); + glVertex3f(0.5, 0.5, 0.0); + glTexCoord2f(s->a, (on ? 0.5 : 1.0) - s->b); + glVertex3f(-0.5, 0.5, 0.0); + glEnd(); + glDisable(GL_TEXTURE_2D); } void drawSymbol2(int symbol, int on, int map, float x, float y, float xs, float ys) { - glPushMatrix(); - glTranslatef(x, y, 0.0f); - glScalef(xs, ys, 1.0f); - drawSymbol(symbol, on, map); - glPopMatrix(); + glPushMatrix(); + glTranslatef(x, y, 0.0f); + glScalef(xs, ys, 1.0f); + drawSymbol(symbol, on, map); + glPopMatrix(); } int g_outgauge_port; @@ -109,293 +113,308 @@ int g_insim_port; int main(int argc, char **argv) { - g_fade = 0; + g_fade = 0; - int width; - int height; - int fullscreen; - int volume; - int rpmleft; - int dofade; - char *insim_host; + int width; + int height; + int fullscreen; + int volume; + int rpmleft; + int dofade; + char *insim_host; - float warn_fuel1; - float warn_fuel2; + float warn_fuel1; + float warn_fuel2; - config_init("lfsdash.txt"); - if (!config_get_int("port", &g_outgauge_port)) g_outgauge_port = 4000; - if (!config_get_int("fullscreen", &fullscreen)) fullscreen = 0; - if (!config_get_int("width", &width)) width = 1024; - if (!config_get_int("height", &height)) height = 600; - if (!config_get_int("volume", &volume)) volume = 100; - if (!config_get_int("rpmleft", &rpmleft)) rpmleft = 0; - if (!config_get_int("fade", &dofade)) dofade = 1; - if (!config_get_string("insim_host", &insim_host)) insim_host = strdup("localhost"); - if (!config_get_int("insim_port", &g_insim_port)) g_insim_port = 29999; - if (!config_get_float("warn_fuel1", &warn_fuel1)) warn_fuel1 = 0.05f; - if (!config_get_float("warn_fuel2", &warn_fuel2)) warn_fuel2 = 0.01f; + config_init("lfsdash.txt"); + if (!config_get_int("port", &g_outgauge_port)) + g_outgauge_port = 4000; + if (!config_get_int("fullscreen", &fullscreen)) + fullscreen = 0; + if (!config_get_int("width", &width)) + width = 1024; + if (!config_get_int("height", &height)) + height = 600; + if (!config_get_int("volume", &volume)) + volume = 100; + if (!config_get_int("rpmleft", &rpmleft)) + rpmleft = 0; + if (!config_get_int("fade", &dofade)) + dofade = 1; + if (!config_get_string("insim_host", &insim_host)) + insim_host = strdup("localhost"); + if (!config_get_int("insim_port", &g_insim_port)) + g_insim_port = 29999; + if (!config_get_float("warn_fuel1", &warn_fuel1)) + warn_fuel1 = 0.05f; + if (!config_get_float("warn_fuel2", &warn_fuel2)) + warn_fuel2 = 0.01f; - network_worker_init(); + network_worker_init(); - socket_init(); - outgauge_init(g_outgauge_port); - insim_init(insim_host, g_insim_port); - init_cars(); + socket_init(); + outgauge_init(g_outgauge_port); + insim_init(insim_host, g_insim_port); + init_cars(); glfwInit(); - glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 1); - if (!glfwOpenWindow(width, height, 0, 0, 0, 0, 0, 0, fullscreen ? GLFW_FULLSCREEN : GLFW_WINDOW)) + glfwWindowHint(GLFW_SAMPLES, 1); + GLFWwindow *window = glfwCreateWindow(width, height, "GL LFS Dashboard", fullscreen ? glfwGetPrimaryMonitor() : NULL, NULL); + if (window == NULL) { glfwTerminate(); return 0; } - glfwSetWindowTitle("GL LFS Dashboard"); + glfwSetWindowTitle(window, "GL LFS Dashboard"); - audio_init(); + audio_init(); - struct gauge speed; - speed.radius = 200.0; - speed.anglemin = (180 + 45) * M_PI / 180.0; - speed.anglemax = (180 + 315) * M_PI / 180.0; - speed.rangemin = 0; - speed.rangemax = 160.0; - speed.majorstep = 10.0; - speed.majorwidth = 3.0; - speed.majorstart = 0.9; - speed.majorend = 1.0; - speed.major.r = 0.15; - speed.major.g = 0.15; - speed.major.b = 1.0; - speed.major.a = 1.0; - speed.minorstep = 2.0; - speed.minorwidth = 1.0; - speed.minorstart = 0.95; - speed.minorend = 1.0; - speed.minor.r = 0.15; - speed.minor.g = 0.15; - speed.minor.b = 1.0; - speed.minor.a = 1.0; - speed.dial.r = 1.0; - speed.dial.g = 1.0; - speed.dial.b = 1.0; - speed.dial.a = 0.8; + struct gauge speed; + speed.radius = 200.0; + speed.anglemin = (180 + 45) * M_PI / 180.0; + speed.anglemax = (180 + 315) * M_PI / 180.0; + speed.rangemin = 0; + speed.rangemax = 160.0; + speed.majorstep = 10.0; + speed.majorwidth = 3.0; + speed.majorstart = 0.9; + speed.majorend = 1.0; + speed.major.r = 0.15; + speed.major.g = 0.15; + speed.major.b = 1.0; + speed.major.a = 1.0; + speed.minorstep = 2.0; + speed.minorwidth = 1.0; + speed.minorstart = 0.95; + speed.minorend = 1.0; + speed.minor.r = 0.15; + speed.minor.g = 0.15; + speed.minor.b = 1.0; + speed.minor.a = 1.0; + speed.dial.r = 1.0; + speed.dial.g = 1.0; + speed.dial.b = 1.0; + speed.dial.a = 0.8; - struct gauge speed2; - speed2.radius = 200.0; - speed2.anglemin = (180 + 45) * M_PI / 180.0; - speed2.anglemax = (180 + 315) * M_PI / 180.0; - speed2.rangemin = 0; - speed2.rangemax = 160.0; - speed2.majorstep = 10.0; - speed2.majorwidth = 1.5; - speed2.majorstart = 0.92; - speed2.majorend = 1.0; - speed2.major.r = 0.15; - speed2.major.g = 0.15; - speed2.major.b = 1.0; - speed2.major.a = 0.5; - speed2.minorstep = 2.0; - speed2.minorwidth = 1.0; - speed2.minorstart = 0.95; - speed2.minorend = 1.0; - speed2.minor.r = 0.15; - speed2.minor.g = 0.15; - speed2.minor.b = 1.0; - speed2.minor.a = 0.5; - speed2.dial.r = 1.0; - speed2.dial.g = 1.0; - speed2.dial.b = 1.0; - speed2.dial.a = 0.0; + struct gauge speed2; + speed2.radius = 200.0; + speed2.anglemin = (180 + 45) * M_PI / 180.0; + speed2.anglemax = (180 + 315) * M_PI / 180.0; + speed2.rangemin = 0; + speed2.rangemax = 160.0; + speed2.majorstep = 10.0; + speed2.majorwidth = 1.5; + speed2.majorstart = 0.92; + speed2.majorend = 1.0; + speed2.major.r = 0.15; + speed2.major.g = 0.15; + speed2.major.b = 1.0; + speed2.major.a = 0.5; + speed2.minorstep = 2.0; + speed2.minorwidth = 1.0; + speed2.minorstart = 0.95; + speed2.minorend = 1.0; + speed2.minor.r = 0.15; + speed2.minor.g = 0.15; + speed2.minor.b = 1.0; + speed2.minor.a = 0.5; + speed2.dial.r = 1.0; + speed2.dial.g = 1.0; + speed2.dial.b = 1.0; + speed2.dial.a = 0.0; - struct gauge rpm; - rpm.radius = 200.0; - rpm.anglemin = (180 + 45) * M_PI / 180.0; - rpm.anglemax = (180 + 315) * M_PI / 180.0; - rpm.rangemin = 0; - rpm.rangemax = 10000.0; - rpm.majorstep = 1000.0; - rpm.majorwidth = 3.0; - rpm.majorstart = 0.9; - rpm.majorend = 1.0; - rpm.major.r = 0.15; - rpm.major.g = 0.15; - rpm.major.b = 1.0; - rpm.major.a = 1.0; - rpm.minorstep = 200.0; - rpm.minorwidth = 1.0; - rpm.minorstart = 0.95; - rpm.minorend = 1.0; - rpm.minor.r = 0.15; - rpm.minor.g = 0.15; - rpm.minor.b = 1.0; - rpm.minor.a = 1.0; - rpm.dial.r = 1.0; - rpm.dial.g = 1.0; - rpm.dial.b = 1.0; - rpm.dial.a = 0.8; + struct gauge rpm; + rpm.radius = 200.0; + rpm.anglemin = (180 + 45) * M_PI / 180.0; + rpm.anglemax = (180 + 315) * M_PI / 180.0; + rpm.rangemin = 0; + rpm.rangemax = 10000.0; + rpm.majorstep = 1000.0; + rpm.majorwidth = 3.0; + rpm.majorstart = 0.9; + rpm.majorend = 1.0; + rpm.major.r = 0.15; + rpm.major.g = 0.15; + rpm.major.b = 1.0; + rpm.major.a = 1.0; + rpm.minorstep = 200.0; + rpm.minorwidth = 1.0; + rpm.minorstart = 0.95; + rpm.minorend = 1.0; + rpm.minor.r = 0.15; + rpm.minor.g = 0.15; + rpm.minor.b = 1.0; + rpm.minor.a = 1.0; + rpm.dial.r = 1.0; + rpm.dial.g = 1.0; + rpm.dial.b = 1.0; + rpm.dial.a = 0.8; - struct gauge mpg; - mpg.radius = 160.0; - mpg.anglemin = 120 * M_PI / 180.0; - mpg.anglemax = 60 * M_PI / 180.0; - mpg.rangemin = 0; - mpg.rangemax = 100.0; - mpg.majorstep = 20.0; - mpg.majorwidth = 3.0; - mpg.majorstart = 0.95; - mpg.majorend = 1.0; - mpg.major.r = 0.15; - mpg.major.g = 0.15; - mpg.major.b = 1.0; - mpg.major.a = 1.0; - mpg.minorstep = 10.0; - mpg.minorwidth = 1.0; - mpg.minorstart = 0.95; - mpg.minorend = 1.0; - mpg.minor.r = 0.15; - mpg.minor.g = 0.15; - mpg.minor.b = 1.0; - mpg.minor.a = 1.0; - mpg.dial.r = 1.0; - mpg.dial.g = 1.0; - mpg.dial.b = 1.0; - mpg.dial.a = 0.8; + struct gauge mpg; + mpg.radius = 160.0; + mpg.anglemin = 120 * M_PI / 180.0; + mpg.anglemax = 60 * M_PI / 180.0; + mpg.rangemin = 0; + mpg.rangemax = 100.0; + mpg.majorstep = 20.0; + mpg.majorwidth = 3.0; + mpg.majorstart = 0.95; + mpg.majorend = 1.0; + mpg.major.r = 0.15; + mpg.major.g = 0.15; + mpg.major.b = 1.0; + mpg.major.a = 1.0; + mpg.minorstep = 10.0; + mpg.minorwidth = 1.0; + mpg.minorstart = 0.95; + mpg.minorend = 1.0; + mpg.minor.r = 0.15; + mpg.minor.g = 0.15; + mpg.minor.b = 1.0; + mpg.minor.a = 1.0; + mpg.dial.r = 1.0; + mpg.dial.g = 1.0; + mpg.dial.b = 1.0; + mpg.dial.a = 0.8; - struct gauge boost; - boost.radius = 160.0; - boost.anglemin = 240 * M_PI / 180.0; - boost.anglemax = 300 * M_PI / 180.0; - boost.rangemin = 0.0; - boost.rangemax = 2.0; - boost.majorstep = 0.5; - boost.majorwidth = 2.0; - boost.majorstart = 0.95; - boost.majorend = 1.0; - boost.major.r = 0.15; - boost.major.g = 0.15; - boost.major.b = 1.0; - boost.major.a = 1.0; - boost.minorstep = 0.1; - boost.minorwidth = 1.0; - boost.minorstart = 0.95; - boost.minorend = 1.0; - boost.minor.r = 0.15; - boost.minor.g = 0.15; - boost.minor.b = 1.0; - boost.minor.a = 1.0; - boost.dial.r = 1.0; - boost.dial.g = 1.0; - boost.dial.b = 1.0; - boost.dial.a = 0.8; + struct gauge boost; + boost.radius = 160.0; + boost.anglemin = 240 * M_PI / 180.0; + boost.anglemax = 300 * M_PI / 180.0; + boost.rangemin = 0.0; + boost.rangemax = 2.0; + boost.majorstep = 0.5; + boost.majorwidth = 2.0; + boost.majorstart = 0.95; + boost.majorend = 1.0; + boost.major.r = 0.15; + boost.major.g = 0.15; + boost.major.b = 1.0; + boost.major.a = 1.0; + boost.minorstep = 0.1; + boost.minorwidth = 1.0; + boost.minorstart = 0.95; + boost.minorend = 1.0; + boost.minor.r = 0.15; + boost.minor.g = 0.15; + boost.minor.b = 1.0; + boost.minor.a = 1.0; + boost.dial.r = 1.0; + boost.dial.g = 1.0; + boost.dial.b = 1.0; + boost.dial.a = 0.8; - struct gauge fuel; - fuel.radius = 160.0; - fuel.anglemin = 240 * M_PI / 180.0; - fuel.anglemax = 300 * M_PI / 180.0; - fuel.rangemin = 0.0; - fuel.rangemax = 1.0; - fuel.majorstep = 0.5; - fuel.majorwidth = 2.0; - fuel.majorstart = 0.95; - fuel.majorend = 1.0; - fuel.major.r = 0.15; - fuel.major.g = 0.15; - fuel.major.b = 1.0; - fuel.major.a = 1.0; - fuel.minorstep = 0.1; - fuel.minorwidth = 1.0; - fuel.minorstart = 0.95; - fuel.minorend = 1.0; - fuel.minor.r = 0.15; - fuel.minor.g = 0.15; - fuel.minor.b = 1.0; - fuel.minor.a = 1.0; - fuel.dial.r = 1.0; - fuel.dial.g = 1.0; - fuel.dial.b = 1.0; - fuel.dial.a = 0.8; + struct gauge fuel; + fuel.radius = 160.0; + fuel.anglemin = 240 * M_PI / 180.0; + fuel.anglemax = 300 * M_PI / 180.0; + fuel.rangemin = 0.0; + fuel.rangemax = 1.0; + fuel.majorstep = 0.5; + fuel.majorwidth = 2.0; + fuel.majorstart = 0.95; + fuel.majorend = 1.0; + fuel.major.r = 0.15; + fuel.major.g = 0.15; + fuel.major.b = 1.0; + fuel.major.a = 1.0; + fuel.minorstep = 0.1; + fuel.minorwidth = 1.0; + fuel.minorstart = 0.95; + fuel.minorend = 1.0; + fuel.minor.r = 0.15; + fuel.minor.g = 0.15; + fuel.minor.b = 1.0; + fuel.minor.a = 1.0; + fuel.dial.r = 1.0; + fuel.dial.g = 1.0; + fuel.dial.b = 1.0; + fuel.dial.a = 0.8; - struct gauge oil; - oil.radius = 160.0; - oil.anglemin = 120 * M_PI / 180.0; - oil.anglemax = 60 * M_PI / 180.0; - oil.rangemin = 0.0; - oil.rangemax = 2.0; - oil.majorstep = 0.5; - oil.majorwidth = 2.0; - oil.majorstart = 0.95; - oil.majorend = 1.0; - oil.major.r = 0.15; - oil.major.g = 0.15; - oil.major.b = 1.0; - oil.major.a = 1.0; - oil.minorstep = 0.1; - oil.minorwidth = 1.0; - oil.minorstart = 0.95; - oil.minorend = 1.0; - oil.minor.r = 0.15; - oil.minor.g = 0.15; - oil.minor.b = 1.0; - oil.minor.a = 1.0; - oil.dial.r = 1.0; - oil.dial.g = 1.0; - oil.dial.b = 1.0; - oil.dial.a = 0.8; + struct gauge oil; + oil.radius = 160.0; + oil.anglemin = 120 * M_PI / 180.0; + oil.anglemax = 60 * M_PI / 180.0; + oil.rangemin = 0.0; + oil.rangemax = 2.0; + oil.majorstep = 0.5; + oil.majorwidth = 2.0; + oil.majorstart = 0.95; + oil.majorend = 1.0; + oil.major.r = 0.15; + oil.major.g = 0.15; + oil.major.b = 1.0; + oil.major.a = 1.0; + oil.minorstep = 0.1; + oil.minorwidth = 1.0; + oil.minorstart = 0.95; + oil.minorend = 1.0; + oil.minor.r = 0.15; + oil.minor.g = 0.15; + oil.minor.b = 1.0; + oil.minor.a = 1.0; + oil.dial.r = 1.0; + oil.dial.g = 1.0; + oil.dial.b = 1.0; + oil.dial.a = 0.8; -/* - struct gauge clock; - clock.radius = 60.0; - clock.anglemin = 0 * M_PI / 180.0; - clock.anglemax = 360 * M_PI / 180.0; - clock.rangemin = 0.0; - clock.rangemax = 12.0; - clock.majorstep = 1.0; - clock.majorwidth = 2.0; - clock.majorstart = 0.9; - clock.majorend = 1.0; - clock.major.r = 0.15; - clock.major.g = 0.15; - clock.major.b = 1.0; - clock.major.a = 1.0; - clock.minorstep = 0.25; - clock.minorwidth = 1.0; - clock.minorstart = 0.95; - clock.minorend = 1.0; - clock.minor.r = 0.15; - clock.minor.g = 0.15; - clock.minor.b = 1.0; - clock.minor.a = 1.0; - clock.dial.r = 1.0; - clock.dial.g = 1.0; - clock.dial.b = 1.0; - clock.dial.a = 0.8; -*/ - char text[40]; + /* + struct gauge clock; + clock.radius = 60.0; + clock.anglemin = 0 * M_PI / 180.0; + clock.anglemax = 360 * M_PI / 180.0; + clock.rangemin = 0.0; + clock.rangemax = 12.0; + clock.majorstep = 1.0; + clock.majorwidth = 2.0; + clock.majorstart = 0.9; + clock.majorend = 1.0; + clock.major.r = 0.15; + clock.major.g = 0.15; + clock.major.b = 1.0; + clock.major.a = 1.0; + clock.minorstep = 0.25; + clock.minorwidth = 1.0; + clock.minorstart = 0.95; + clock.minorend = 1.0; + clock.minor.r = 0.15; + clock.minor.g = 0.15; + clock.minor.b = 1.0; + clock.minor.a = 1.0; + clock.dial.r = 1.0; + clock.dial.g = 1.0; + clock.dial.b = 1.0; + clock.dial.a = 0.8; + */ + char text[40]; - //float last_fuel = 1.0; - //float consumption = 0.0; - double next = glfwGetTime(); - double last_time = next; - struct car car; + // float last_fuel = 1.0; + // float consumption = 0.0; + double next = glfwGetTime(); + double last_time = next; + struct car car; - int running = 1; + int running = 1; - //int pthread_create(pthread_t *thread, const pthread_attr_t *attr, - //void *(*start_routine)(void*), void *arg); + // int pthread_create(pthread_t *thread, const pthread_attr_t *attr, + // void *(*start_routine)(void*), void *arg); - pthread_t thread; - pthread_create(&thread, NULL, &socket_run, NULL); + pthread_t thread; + pthread_create(&thread, NULL, &socket_run, NULL); - FTGLfont *font = ftglCreateTextureFont("arialbd.ttf");//"Arial.ttf");//"/usr/share/fonts/truetype/msttcorefonts/Arial.ttf"); - //DS_DIGII - if (!font) return 0; + FTGLfont *font = ftglCreateTextureFont("arialbd.ttf"); //"Arial.ttf");//"/usr/share/fonts/truetype/msttcorefonts/Arial.ttf"); + // DS_DIGII + if (!font) + return 0; - ftglSetFontFaceSize(font, TEXT_SIZE, TEXT_SIZE); + ftglSetFontFaceSize(font, TEXT_SIZE, TEXT_SIZE); glGenTextures(1, s_symbols); glBindTexture(GL_TEXTURE_2D, s_symbols[0]); - glfwLoadTexture2D("symbols512.tga", GLFW_BUILD_MIPMAPS_BIT); +// glfwLoadTexture2D("symbols512.tga", GLFW_BUILD_MIPMAPS_BIT); + + // Use trilinear interpolation for minification glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Use bilinear interpolation for magnification @@ -403,89 +422,101 @@ int main(int argc, char **argv) // Enable texturing //glEnable(GL_TEXTURE_2D); - int s1 = FX_OFF; - int s2 = FX_OFF; - int s3 = FX_OFF; - int s6 = FX_OFF; + int s1 = FX_OFF; + int s2 = FX_OFF; + int s3 = FX_OFF; + int s6 = FX_OFF; - float fade = 0.0f; - float flash = 0.0f; - float binger = 0.0f; + float fade = 0.0f; + float flash = 0.0f; + float binger = 0.0f; - audio_volume(volume * 0.01); + audio_volume(volume * 0.01); - int bing = 0; + int bing = 0; - int mode = 0; - uint32_t mode_timer = 0; - float hold = 0; - int hold2 = 0; - int ack = 0; + int mode = 0; + uint32_t mode_timer = 0; + float hold = 0; + int hold2 = 0; + int ack = 0; - get_car("UF1", &car); - rpm.rangemax = (int)(car.maxrpm / 1000 + 2) * 1000.0; + get_car("UF1", &car); + rpm.rangemax = (int)(car.maxrpm / 1000 + 2) * 1000.0; - float maxspeed = 0; - float speedtimer = 0; - float zoom = 65536.0; + float maxspeed = 0; + float speedtimer = 0; + float zoom = 65536.0; - while (running) { + while (running) + { - double curtime = glfwGetTime(); - if (curtime >= next) - { - next = curtime + 0.01; - float interval = curtime - last_time; + double curtime = glfwGetTime(); + if (curtime >= next) + { + next = curtime + 0.01; + float interval = curtime - last_time; - flash += interval; - if (flash >= 1) flash = 0; + flash += interval; + if (flash >= 1) + flash = 0; - if (bing == 2) - { - binger += interval; - if (binger >= 1) { - binger = 0; - if (!g_fade) audio_play(3, FX_BING); - } - } - last_time = curtime; + if (bing == 2) + { + binger += interval; + if (binger >= 1) + { + binger = 0; + if (!g_fade) + audio_play(3, FX_BING); + } + } + last_time = curtime; - if (speedtimer > 0) { - speedtimer -= interval; - if (speedtimer <= 0) - { - speedtimer = 0; - maxspeed = 0; - } - } + if (speedtimer > 0) + { + speedtimer -= interval; + if (speedtimer <= 0) + { + speedtimer = 0; + maxspeed = 0; + } + } - if (g_pressed == 3) { - if (g_outgauge.time - g_shift_time > 1000 && + if (g_pressed == 3) + { + if (g_outgauge.time - g_shift_time > 1000 && g_outgauge.time - g_ctrl_time > 1000) { - //if (g_released == 3) + // if (g_released == 3) //{ - g_pressed = 0; - g_released = 0; - audio_play(4, FX_BIP); - mode++; - mode_timer = g_outgauge.time; + g_pressed = 0; + g_released = 0; + audio_play(4, FX_BIP); + mode++; + mode_timer = g_outgauge.time; //} } - } + } - if (ack == 0) { - if (mode == 1) { - if (g_pressed == 1 && volume > 0) { + if (ack == 0) + { + if (mode == 1) + { + if (g_pressed == 1 && volume > 0) + { volume -= 10; - if (volume < 0) volume = 0; + if (volume < 0) + volume = 0; audio_volume(volume * 0.01); audio_play(4, FX_BOP); ack = 1; } - if (g_pressed == 2 && volume < 100) { + if (g_pressed == 2 && volume < 100) + { volume += 10; - if (volume > 100) volume = 100; + if (volume > 100) + volume = 100; audio_volume(volume * 0.01); audio_play(4, FX_BIP); ack = 1; @@ -493,7 +524,7 @@ int main(int argc, char **argv) } } - // Acknowledge key release + // Acknowledge key release if (g_released) { g_pressed &= ~g_released; @@ -508,26 +539,27 @@ int main(int argc, char **argv) } /* } - if (g_released == 1) { - volume -= 10; - if (volume < 0) volume = 0; - audio_volume(volume * 0.01); - audio_play(4, FX_BOP); - } - if (g_released == 2) { - volume += 10; - if (volume > 100) volume = 100; - audio_volume(volume * 0.01); - audio_play(4, FX_BIP); - } - if (g_released == 3) { - g_pressed = 0; - g_released = 0; - } - }*/ - } + if (g_released == 1) { + volume -= 10; + if (volume < 0) volume = 0; + audio_volume(volume * 0.01); + audio_play(4, FX_BOP); + } + if (g_released == 2) { + volume += 10; + if (volume > 100) volume = 100; + audio_volume(volume * 0.01); + audio_play(4, FX_BIP); + } + if (g_released == 3) { + g_pressed = 0; + g_released = 0; + } + }*/ + } - glfwGetWindowSize(&width, &height); + + glfwGetFramebufferSize(window, &width, &height); height = height > 0 ? height : 1; glViewport(0, 0, width, height); glClearColor(0.0, 0.0, 0.0, 0.0); @@ -540,421 +572,478 @@ int main(int argc, char **argv) glLoadIdentity(); glOrtho(0, width, 0, height, -100, 100); - //socket_run(); + // socket_run(); - /* Car change */ - if (*g_outgauge.car != '\0' && strcmp(g_outgauge.car, car.tag)) - { - int carnum = get_car(g_outgauge.car, &car); - if (carnum > -1) - { - rpm.rangemax = (int)(car.maxrpm / 1000 + 2) * 1000.0; - } - } + /* Car change */ + if (*g_outgauge.car != '\0' && strcmp(g_outgauge.car, car.tag)) + { + int carnum = get_car(g_outgauge.car, &car); + if (carnum > -1) + { + rpm.rangemax = (int)(car.maxrpm / 1000 + 2) * 1000.0; + } + } - float speedunit = (g_outgauge.flags & OG_KM) ? 3.6 : 2.23693629; - float distunit = (g_outgauge.flags & OG_KM) ? 0.001 : 0.0006215; + float speedunit = (g_outgauge.flags & OG_KM) ? 3.6 : 2.23693629; + float distunit = (g_outgauge.flags & OG_KM) ? 0.001 : 0.0006215; - if (g_outgauge.speed > maxspeed) { - maxspeed = g_outgauge.speed; - speedtimer = 15.0f; - } + if (g_outgauge.speed > maxspeed) + { + maxspeed = g_outgauge.speed; + speedtimer = 15.0f; + } - float litres = g_consumption * car.maxfuel * 60 * 60; - float hurr; - if (g_outgauge.flags & OG_KM) - { - hurr = litres / (g_outgauge.speed * speedunit) * 100; - speed.rangemax = (int)(car.maxspeed * 1.609f / 10) * 10 + 10; - speed2.rangemax = speed.rangemax / 1.609f; - } - else - { - float gal = litres * 0.219969157; - hurr = g_outgauge.speed * speedunit / gal; - //printf("mpg %f\n", hurr); - speed.rangemax = car.maxspeed; - speed2.rangemax = speed.rangemax * 1.609f; - } - if (hurr < 0) hurr = 0; - if (hurr > 100) hurr = 100; + float litres = g_consumption * car.maxfuel * 60 * 60; + float hurr; + if (g_outgauge.flags & OG_KM) + { + hurr = litres / (g_outgauge.speed * speedunit) * 100; + speed.rangemax = (int)(car.maxspeed * 1.609f / 10) * 10 + 10; + speed2.rangemax = speed.rangemax / 1.609f; + } + else + { + float gal = litres * 0.219969157; + hurr = g_outgauge.speed * speedunit / gal; + // printf("mpg %f\n", hurr); + speed.rangemax = car.maxspeed; + speed2.rangemax = speed.rangemax * 1.609f; + } + if (hurr < 0) + hurr = 0; + if (hurr > 100) + hurr = 100; - if (speed.rangemax < 150) { - speed.majorstep = 10; - speed.minorstep = 2; - } else { - speed.majorstep = 20; - speed.minorstep = 10; - } - if (speed2.rangemax < 150) { - speed2.majorstep = 10; - speed2.minorstep = 2; - } else { - speed2.majorstep = 20; - speed2.minorstep = 10; - } + if (speed.rangemax < 150) + { + speed.majorstep = 10; + speed.minorstep = 2; + } + else + { + speed.majorstep = 20; + speed.minorstep = 10; + } + if (speed2.rangemax < 150) + { + speed2.majorstep = 10; + speed2.minorstep = 2; + } + else + { + speed2.majorstep = 20; + speed2.minorstep = 10; + } - float gsize = width * 0.20; - if (gsize > height * 0.4) gsize = height * 0.4; - speed.radius = gsize * 0.9; - speed2.radius = speed.radius * 0.6; - rpm.radius = speed.radius; + float gsize = width * 0.20; + if (gsize > height * 0.4) + gsize = height * 0.4; + speed.radius = gsize * 0.9; + speed2.radius = speed.radius * 0.6; + rpm.radius = speed.radius; - float msize = gsize * 0.2; - float symsize = gsize * 0.22; + float msize = gsize * 0.2; + float symsize = gsize * 0.22; - float sgsize = height * 0.25; - fuel.radius = sgsize * 0.8; - boost.radius = sgsize * 0.8; - mpg.radius = sgsize * 0.8; - oil.radius = sgsize * 0.8; + float sgsize = height * 0.25; + fuel.radius = sgsize * 0.8; + boost.radius = sgsize * 0.8; + mpg.radius = sgsize * 0.8; + oil.radius = sgsize * 0.8; - float lsize = sgsize * 0.16; + float lsize = sgsize * 0.16; - glPushMatrix(); - if (rpmleft) { - glTranslatef(width * 0.5 + gsize * 1.5, height - gsize, 0); - } else { - glTranslatef(width * 0.5 - gsize * 1.5, height - gsize, 0); - } - glColor4f(1.0, 1.0, 1.0, 1.0); - snprintf(text, sizeof text, "%d", (int)(g_outgauge.speed * speedunit)); - drawText(text, font, 20, -speed.radius * 0.8, msize, msize, TA_RIGHT, TA_BOTTOM); - drawText((g_outgauge.flags & OG_KM) ? "km/h" : "mph", font, 26, -speed.radius * 0.8, msize * 0.3, msize * 0.4, TA_LEFT, TA_BOTTOM); - if (g_outgauge.dashlights & (1 << DL_PITSPEED)) { - drawSymbol2(DL_PITSPEED, g_outgauge.showlights & (1 << DL_PITSPEED), 1, 0, gsize * -0.4, symsize * 1.3, symsize * 1.3); - } - if (maxspeed > 0.001f) - { - glPushMatrix(); - glScalef(speed.radius, speed.radius, 1.0); - drawDial(&speed, maxspeed * speedunit, GT_LINE); - glPopMatrix(); - if (speedtimer < 13) - { - snprintf(text, sizeof text, "%0.1f%s", maxspeed * speedunit, (g_outgauge.flags & OG_KM) ? "km/h" : "mph"); - drawText(text, font, 0, -speed.radius * 0.6, msize, msize, TA_CENTRE, TA_BOTTOM); - } - } - draw_gauge(&speed2, 0, -1, font, GT_NONE); - draw_gauge(&speed, g_outgauge.speed * speedunit, -1, font, GT_NEEDLE); - glPopMatrix(); + glPushMatrix(); + if (rpmleft) + { + glTranslatef(width * 0.5 + gsize * 1.5, height - gsize, 0); + } + else + { + glTranslatef(width * 0.5 - gsize * 1.5, height - gsize, 0); + } + glColor4f(1.0, 1.0, 1.0, 1.0); + snprintf(text, sizeof text, "%d", (int)(g_outgauge.speed * speedunit)); + drawText(text, font, 20, -speed.radius * 0.8, msize, msize, TA_RIGHT, TA_BOTTOM); + drawText((g_outgauge.flags & OG_KM) ? "km/h" : "mph", font, 26, -speed.radius * 0.8, msize * 0.3, msize * 0.4, TA_LEFT, TA_BOTTOM); + if (g_outgauge.dashlights & (1 << DL_PITSPEED)) + { + drawSymbol2(DL_PITSPEED, g_outgauge.showlights & (1 << DL_PITSPEED), 1, 0, gsize * -0.4, symsize * 1.3, symsize * 1.3); + } + if (maxspeed > 0.001f) + { + glPushMatrix(); + glScalef(speed.radius, speed.radius, 1.0); + drawDial(&speed, maxspeed * speedunit, GT_LINE); + glPopMatrix(); + if (speedtimer < 13) + { + snprintf(text, sizeof text, "%0.1f%s", maxspeed * speedunit, (g_outgauge.flags & OG_KM) ? "km/h" : "mph"); + drawText(text, font, 0, -speed.radius * 0.6, msize, msize, TA_CENTRE, TA_BOTTOM); + } + } + draw_gauge(&speed2, 0, -1, font, GT_NONE); + draw_gauge(&speed, g_outgauge.speed * speedunit, -1, font, GT_NEEDLE); + glPopMatrix(); - glPushMatrix(); - if (rpmleft) { - glTranslatef(width * 0.5 - gsize * 1.5, height - gsize, 0); - } else { - glTranslatef(width * 0.5 + gsize * 1.5, height - gsize, 0); - } - glColor4f(1.0, 1.0, 1.0, 1.0); - snprintf(text, sizeof text, "%d", (int)(g_outgauge.rpm)); - drawText(text, font, 40, -rpm.radius * 0.8, msize, msize, TA_RIGHT, TA_BOTTOM); - drawText("rpm", font, 46, -rpm.radius * 0.8, msize * 0.3, msize * 0.4, TA_LEFT, TA_BOTTOM); - if (g_outgauge.dashlights & (1 << DL_SHIFT)) { - drawSymbol2(DL_SHIFT, g_outgauge.showlights & (1 << DL_SHIFT), 1, 0, gsize * -0.4, symsize * 1.3, symsize * 1.3); - } - draw_gauge(&rpm, g_outgauge.rpm, car.maxrpm, font, GT_NEEDLE); - glPopMatrix(); + glPushMatrix(); + if (rpmleft) + { + glTranslatef(width * 0.5 - gsize * 1.5, height - gsize, 0); + } + else + { + glTranslatef(width * 0.5 + gsize * 1.5, height - gsize, 0); + } + glColor4f(1.0, 1.0, 1.0, 1.0); + snprintf(text, sizeof text, "%d", (int)(g_outgauge.rpm)); + drawText(text, font, 40, -rpm.radius * 0.8, msize, msize, TA_RIGHT, TA_BOTTOM); + drawText("rpm", font, 46, -rpm.radius * 0.8, msize * 0.3, msize * 0.4, TA_LEFT, TA_BOTTOM); + if (g_outgauge.dashlights & (1 << DL_SHIFT)) + { + drawSymbol2(DL_SHIFT, g_outgauge.showlights & (1 << DL_SHIFT), 1, 0, gsize * -0.4, symsize * 1.3, symsize * 1.3); + } + draw_gauge(&rpm, g_outgauge.rpm, car.maxrpm, font, GT_NEEDLE); + glPopMatrix(); - if (g_owncar == g_outgauge.playerid) { - glPushMatrix(); - glTranslatef(width * 0.5 - gsize * 1.5, fuel.radius * 0.75, 0); - drawSymbol2(4, 0, 0, fuel.radius * -0.65, 0, lsize, lsize); - if (g_outgauge.fuel <= warn_fuel2) { - if (flash < 0.5) { - drawSymbol2(19, 1, 0, -fuel.radius * 0.6, -fuel.radius * 0.3, lsize, lsize); - } - } - else if (g_outgauge.fuel <= warn_fuel1) { - drawSymbol2(19, 0, 0, -fuel.radius * 0.6, -fuel.radius * 0.3, lsize * 0.6, lsize * 0.6); - } - draw_gauge(&fuel, g_outgauge.fuel, -1, font, GT_BAR); + if (g_owncar == g_outgauge.playerid) + { + glPushMatrix(); + glTranslatef(width * 0.5 - gsize * 1.5, fuel.radius * 0.75, 0); + drawSymbol2(4, 0, 0, fuel.radius * -0.65, 0, lsize, lsize); + if (g_outgauge.fuel <= warn_fuel2) + { + if (flash < 0.5) + { + drawSymbol2(19, 1, 0, -fuel.radius * 0.6, -fuel.radius * 0.3, lsize, lsize); + } + } + else if (g_outgauge.fuel <= warn_fuel1) + { + drawSymbol2(19, 0, 0, -fuel.radius * 0.6, -fuel.radius * 0.3, lsize * 0.6, lsize * 0.6); + } + draw_gauge(&fuel, g_outgauge.fuel, -1, font, GT_BAR); - drawSymbol2(5, 0, 0, mpg.radius * 0.65, 0, lsize, lsize); - draw_gauge(&mpg, hurr, -1, font, GT_BAR); + drawSymbol2(5, 0, 0, mpg.radius * 0.65, 0, lsize, lsize); + draw_gauge(&mpg, hurr, -1, font, GT_BAR); - float tcsize = sgsize * 0.08; + float tcsize = sgsize * 0.08; - glColor4f(1.0, 1.0, 1.0, 1.0); - drawText("Trip Computer", font, 0, tcsize * 4.8, tcsize, tcsize, TA_CENTRE, TA_BOTTOM); - //snprintf(text, sizeof text, "dist %0.1f time %0.1f fuel %0.1f", s_cars[carnum].dist * distunit, s_cars[carnum].time, s_cars[carnum].cons); - snprintf(text, sizeof text, "Rem: %0.1f%%", g_outgauge.fuel * 100); - drawText(text, font, -fuel.radius * 0.3, tcsize * 3.6, tcsize, tcsize, TA_LEFT, TA_BOTTOM); - snprintf(text, sizeof text, "Eco: %0.1f %s", hurr, (g_outgauge.flags & OG_KM) ? "l/100km" : "mpg"); - drawText(text, font, -fuel.radius * 0.3, tcsize * 2.4, tcsize, tcsize, TA_LEFT, TA_BOTTOM); + glColor4f(1.0, 1.0, 1.0, 1.0); + drawText("Trip Computer", font, 0, tcsize * 4.8, tcsize, tcsize, TA_CENTRE, TA_BOTTOM); + // snprintf(text, sizeof text, "dist %0.1f time %0.1f fuel %0.1f", s_cars[carnum].dist * distunit, s_cars[carnum].time, s_cars[carnum].cons); + snprintf(text, sizeof text, "Rem: %0.1f%%", g_outgauge.fuel * 100); + drawText(text, font, -fuel.radius * 0.3, tcsize * 3.6, tcsize, tcsize, TA_LEFT, TA_BOTTOM); + snprintf(text, sizeof text, "Eco: %0.1f %s", hurr, (g_outgauge.flags & OG_KM) ? "l/100km" : "mpg"); + drawText(text, font, -fuel.radius * 0.3, tcsize * 2.4, tcsize, tcsize, TA_LEFT, TA_BOTTOM); - float dist = litres / (g_outgauge.speed * speedunit) * (g_outgauge.fuel * car.maxfuel) * distunit; - snprintf(text, sizeof text, "Dist: %0.1f %s", dist, (g_outgauge.flags & OG_KM) ? "km" : "miles"); - drawText(text, font, -fuel.radius * 0.3, tcsize * 1.2, tcsize, tcsize, TA_LEFT, TA_BOTTOM); + float dist = litres / (g_outgauge.speed * speedunit) * (g_outgauge.fuel * car.maxfuel) * distunit; + snprintf(text, sizeof text, "Dist: %0.1f %s", dist, (g_outgauge.flags & OG_KM) ? "km" : "miles"); + drawText(text, font, -fuel.radius * 0.3, tcsize * 1.2, tcsize, tcsize, TA_LEFT, TA_BOTTOM); - glPopMatrix(); - } + glPopMatrix(); + } - glPushMatrix(); - glTranslatef(width * 0.5 + gsize * 1.5, oil.radius * 0.75, 0); + glPushMatrix(); + glTranslatef(width * 0.5 + gsize * 1.5, oil.radius * 0.75, 0); - if (g_outgauge.flags & OG_TURBO) - { - if (g_outgauge.flags & OG_BAR) { - boost.majorstep = 0.4; - boost.minorstep = 0.1; - } else { - boost.majorstep = 2.0; - boost.minorstep = 1.0; - } - float mult = (g_outgauge.flags & OG_BAR) ? 1.0 : 14.5037738; - boost.rangemax = (int)(car.maxboost * mult / boost.majorstep + 1) * boost.majorstep; + if (g_outgauge.flags & OG_TURBO) + { + if (g_outgauge.flags & OG_BAR) + { + boost.majorstep = 0.4; + boost.minorstep = 0.1; + } + else + { + boost.majorstep = 2.0; + boost.minorstep = 1.0; + } + float mult = (g_outgauge.flags & OG_BAR) ? 1.0 : 14.5037738; + boost.rangemax = (int)(car.maxboost * mult / boost.majorstep + 1) * boost.majorstep; - drawSymbol2(6, 0, 0, boost.radius * -0.65, 0, lsize, lsize); - draw_gauge(&boost, g_outgauge.turbo * mult, -1, font, GT_BAR); - } + drawSymbol2(6, 0, 0, boost.radius * -0.65, 0, lsize, lsize); + draw_gauge(&boost, g_outgauge.turbo * mult, -1, font, GT_BAR); + } - //drawSymbol2(7, 0, 0, oil.radius * 0.65, 0, lsize, lsize); - //draw_gauge(&oil, g_outgauge.oiltemp, -1, font, GT_BAR); - glPopMatrix(); + // drawSymbol2(7, 0, 0, oil.radius * 0.65, 0, lsize, lsize); + // draw_gauge(&oil, g_outgauge.oiltemp, -1, font, GT_BAR); + glPopMatrix(); - //glPushMatrix(); - //glTranslatef(width * 0.5 + gsize * 1.5, boost.radius * 0.75, 0); + // glPushMatrix(); + // glTranslatef(width * 0.5 + gsize * 1.5, boost.radius * 0.75, 0); - time_t rawtime; + time_t rawtime; time(&rawtime); struct tm *timeinfo = localtime(&rawtime); - //draw_gauge(&clock, (timeinfo->tm_hour % 12) + timeinfo->tm_min / 60.0, -1, font, GT_NEEDLE); - //glPopMatrix(); + // draw_gauge(&clock, (timeinfo->tm_hour % 12) + timeinfo->tm_min / 60.0, -1, font, GT_NEEDLE); + // glPopMatrix(); - //printf("%f %f\n", g_outgauge.oilpressure, g_outgauge.oiltemp); + // printf("%f %f\n", g_outgauge.oilpressure, g_outgauge.oiltemp); - float symspace = symsize * -1.2; + float symspace = symsize * -1.2; - /* - glPushMatrix(); - glTranslatef(width * 0.5 + symspace, height - gsize * 0.25 + symspace * 6, 0.0f); - input.radius = symsize * 0.5; - input.dial.r = 0; input.dial.g = 0; input.dial.b = 1; - draw_gauge(&input, g_outgauge.clutch, -1, font, GT_BAR); - glTranslatef(-symspace, 0, 0); - input.dial.r = 1; input.dial.g = 0; input.dial.b = 0; - draw_gauge(&input, g_outgauge.brake, -1, font, GT_BAR); - glTranslatef(-symspace, 0, 0); - input.dial.r = 0; input.dial.g = 1; input.dial.b = 0; - draw_gauge(&input, g_outgauge.throttle, -1, font, GT_BAR); - glPopMatrix(); - */ + /* + glPushMatrix(); + glTranslatef(width * 0.5 + symspace, height - gsize * 0.25 + symspace * 6, 0.0f); + input.radius = symsize * 0.5; + input.dial.r = 0; input.dial.g = 0; input.dial.b = 1; + draw_gauge(&input, g_outgauge.clutch, -1, font, GT_BAR); + glTranslatef(-symspace, 0, 0); + input.dial.r = 1; input.dial.g = 0; input.dial.b = 0; + draw_gauge(&input, g_outgauge.brake, -1, font, GT_BAR); + glTranslatef(-symspace, 0, 0); + input.dial.r = 0; input.dial.g = 1; input.dial.b = 0; + draw_gauge(&input, g_outgauge.throttle, -1, font, GT_BAR); + glPopMatrix(); + */ - glPushMatrix(); - glTranslatef(width * 0.5, height - gsize * 0.25, 0.0f); + glPushMatrix(); + glTranslatef(width * 0.5, height - gsize * 0.25, 0.0f); - if (g_outgauge.dashlights & (1 << DL_SIGNAL_ANY)) - { - drawSymbol2(DL_SIGNAL_ANY, g_outgauge.showlights & (1 << DL_SIGNAL_ANY), 1, 0, 0, symsize, symsize); - } else { - if (g_outgauge.dashlights & (1 << DL_SIGNAL_L)) { - drawSymbol2(DL_SIGNAL_L, g_outgauge.showlights & (1 << DL_SIGNAL_L), 1, -symsize * 0.75, 0, symsize, symsize); - } - if (g_outgauge.dashlights & (1 << DL_SIGNAL_R)) { - drawSymbol2(DL_SIGNAL_R, g_outgauge.showlights & (1 << DL_SIGNAL_R), 1, symsize * 0.75, 0, symsize, symsize); - } - } - if (g_outgauge.dashlights & (1 << DL_FULLBEAM)) { - drawSymbol2(DL_FULLBEAM, g_outgauge.showlights & (1 << DL_FULLBEAM), 1, 0, symspace, symsize, symsize); - } - if (g_outgauge.dashlights & (1 << DL_HANDBRAKE)) { - drawSymbol2(DL_HANDBRAKE, g_outgauge.showlights & (1 << DL_HANDBRAKE), 1, 0, symspace * 2, symsize, symsize); - } - if (g_outgauge.dashlights & (1 << DL_ABS)) { - drawSymbol2(DL_ABS, g_outgauge.showlights & (1 << DL_ABS), 1, 0, symspace * 3, symsize, symsize); - } - if (g_outgauge.dashlights & (1 << DL_TC)) { - drawSymbol2(DL_TC, g_outgauge.showlights & (1 << DL_TC), 1, 0, symspace * 4, symsize, symsize); - } - if (g_outgauge.dashlights & (1 << DL_OILWARN)) { - if (g_outgauge.dashlights & (1 << DL_BATTERY)) { - drawSymbol2(DL_BATTERY, g_outgauge.showlights & (1 << DL_BATTERY), 1, -symsize * 0.75, symspace * 5, symsize, symsize); - } - drawSymbol2(DL_OILWARN, g_outgauge.showlights & (1 << DL_OILWARN), 1, symsize * 0.75, symspace * 5, symsize, symsize); - } else { - if (g_outgauge.dashlights & (1 << DL_BATTERY)) { - drawSymbol2(DL_BATTERY, g_outgauge.showlights & (1 << DL_BATTERY), 1, 0, symspace * 5, symsize, symsize); - } - } - glPopMatrix(); - - glPushMatrix(); - glTranslatef(width, 0, 0); - glScalef(-height * 0.075, height * 0.075, 1.0); - glColor4f(0.15, 1.0, 0.15, 0.8); - glBegin(GL_TRIANGLE_STRIP); - glVertex3f(0.0, 0.0, 0.0); - glVertex3f(0.25, 0.0, 0.0); - glVertex3f(0.0, g_outgauge.throttle, 0.0); - glVertex3f(0.25, g_outgauge.throttle, 0.0); - glEnd(); - glColor4f(1.0, 0.15, 0.15, 0.8); - glBegin(GL_TRIANGLE_STRIP); - glVertex3f(0.30, 0.0, 0.0); - glVertex3f(0.55, 0.0, 0.0); - glVertex3f(0.30, g_outgauge.brake, 0.0); - glVertex3f(0.55, g_outgauge.brake, 0.0); - glEnd(); - glColor4f(0.15, 0.15, 1.0, 0.8); - glBegin(GL_TRIANGLE_STRIP); - glVertex3f(0.60, 0.0, 0.0); - glVertex3f(0.85, 0.0, 0.0); - glVertex3f(0.60, g_outgauge.clutch, 0.0); - glVertex3f(0.85, g_outgauge.clutch, 0.0); - glEnd(); - glPopMatrix(); - - glPushMatrix(); - glColor4f(0.15, 0.15, 1.0, 1.0); - glTranslatef(width * 0.5, 0, 0.0f); - if (g_outgauge.gear == 0) { - snprintf(text, sizeof text, "R"); - } else if (g_outgauge.gear == 1) { - snprintf(text, sizeof text, "N"); - } else { - snprintf(text, sizeof text, "%d", g_outgauge.gear - 1); - } - drawText(text, font, 0, sgsize * 0.7, sgsize * 0.7, sgsize * 0.7, TA_CENTRE, TA_BOTTOM); - snprintf(text, sizeof text, "%s", s_carinfo[g_outgauge.playerid].cname); - drawText(text, font, 0, sgsize * 0.4, sgsize * 0.2, sgsize * 0.2, TA_CENTRE, TA_BOTTOM); - snprintf(text, sizeof text, "%s", s_conninfo[s_carinfo[g_outgauge.playerid].ucid].uname); - drawText(text, font, 0, sgsize * 0.2, sgsize * 0.15, sgsize * 0.15, TA_CENTRE, TA_BOTTOM); - //snprintf(text, sizeof text, "dist %0.1f time %0.1f fuel %0.1f", s_cars[carnum].dist * distunit, s_cars[carnum].time, s_cars[carnum].cons); - //snprintf(text, sizeof text, "p %d r %d; %d %d, %u", g_pressed, g_released, volume, mode, mode_timer); - //drawText(text, font, 0, sgsize * 1.2, sgsize * 0.2, sgsize * 0.2, TA_CENTRE, TA_CENTRE); - //snprintf(text, sizeof text, "s %u c %u; %u", g_shift_time, g_ctrl_time, g_outgauge.time); - //drawText(text, font, 0, sgsize * 1.5, sgsize * 0.2, sgsize * 0.2, TA_CENTRE, TA_CENTRE); - snprintf(text, sizeof text, "%02d:%02d", timeinfo->tm_hour, timeinfo->tm_min); - drawText(text, font, 0, sgsize * 1.3, sgsize * 0.2, sgsize * 0.2, TA_CENTRE, TA_BOTTOM); - glPopMatrix(); -/* - int ox = s_carinfo[g_outgauge.playerid].x; - int oy = s_carinfo[g_outgauge.playerid].y; - int oz = s_carinfo[g_outgauge.playerid].z; - int head = s_carinfo[g_outgauge.playerid].heading; - int speed = s_carinfo[g_outgauge.playerid].speed; - - glPushMatrix(); - glTranslatef(width / 2, height / 2, 0); - int i; - for (i = 0; i < 256; i++) - { - struct carinfo *ci = s_carinfo + i; - if (!ci->active) continue; - - float dx = (ci->x - ox) / zoom; - float dy = (ci->y - oy) / zoom; - - //float ddx = (ci->x - ox) / 65536.0; - //float ddy = (ci->y - oy) / 65536.0; - //ci->dist = sqrtf(ddx * ddx + ddy * ddy); - -// if (ci->dist >= width / 2 && ci->dist >= height / 2) continue; - - const struct conninfo *pi = s_conninfo + ci->ucid; - int idx = (ci->x - ox) >> 16; - int idy = (ci->y - oy) >> 16; - int dist = sqrt(idx * idx + idy * idy); - - snprintf(text, sizeof text, "%s - %d (%0.1f %s)", pi->uname, dist, (ci->speed - speed) / 327.68f * speedunit, (g_outgauge.flags & OG_KM) ? "km/h" : "mph"); - //printf("%d %s %d %d\n", i, text, head / 182, ci->heading / 182); - - glPushMatrix(); - glRotatef(-head / 182.0444f, 0.0, 0.0, 1.0); - glTranslatef(dx, dy, 0); - if (ci->hist > 0) { - glBegin(GL_LINE_STRIP); - int j; - for (j = CARPATHSIZE; j > 0; j--) - { - int d = (j + ci->hist - 1) % CARPATHSIZE; - if (ci->hist_x[d] == 0 && ci->hist_y[d] == 0) continue; - glColor4f(ci->hist_s[d] / 32768.0f, 1.0 - ci->hist_s[d] / 32768.0f, 0.0, 0.9); - glVertex3f((ci->hist_x[d] - ci->x) / zoom, (ci->hist_y[d] - ci->y) / zoom, 0.0); - } - glEnd(); + if (g_outgauge.dashlights & (1 << DL_SIGNAL_ANY)) + { + drawSymbol2(DL_SIGNAL_ANY, g_outgauge.showlights & (1 << DL_SIGNAL_ANY), 1, 0, 0, symsize, symsize); + } + else + { + if (g_outgauge.dashlights & (1 << DL_SIGNAL_L)) + { + drawSymbol2(DL_SIGNAL_L, g_outgauge.showlights & (1 << DL_SIGNAL_L), 1, -symsize * 0.75, 0, symsize, symsize); } - if (pi->state == 1) { - glColor4f(1.0, 0.0, 0.0, 0.5); - } else if (pi->state == 2) { - glColor4f(0.0, 1.0, 1.0, 0.5); - } else { - glColor4f(2.0, 1.0, 1.0, 0.5); - } - glRotatef(head / 182.0444f, 0.0, 0.0, 1.0); - drawText(text, font, 5, 3, 10, 10, TA_LEFT, TA_TOP); - glRotatef(-(head - ci->heading) / 182.0444, 0.0, 0.0, 1.0); - glBegin(GL_TRIANGLES); - glVertex3f(0, 5, 0); - glVertex3f(2.5, -5, 0); - glVertex3f(-2.5, -5, 0); - glEnd(); + if (g_outgauge.dashlights & (1 << DL_SIGNAL_R)) + { + drawSymbol2(DL_SIGNAL_R, g_outgauge.showlights & (1 << DL_SIGNAL_R), 1, symsize * 0.75, 0, symsize, symsize); + } + } + if (g_outgauge.dashlights & (1 << DL_FULLBEAM)) + { + drawSymbol2(DL_FULLBEAM, g_outgauge.showlights & (1 << DL_FULLBEAM), 1, 0, symspace, symsize, symsize); + } + if (g_outgauge.dashlights & (1 << DL_HANDBRAKE)) + { + drawSymbol2(DL_HANDBRAKE, g_outgauge.showlights & (1 << DL_HANDBRAKE), 1, 0, symspace * 2, symsize, symsize); + } + if (g_outgauge.dashlights & (1 << DL_ABS)) + { + drawSymbol2(DL_ABS, g_outgauge.showlights & (1 << DL_ABS), 1, 0, symspace * 3, symsize, symsize); + } + if (g_outgauge.dashlights & (1 << DL_TC)) + { + drawSymbol2(DL_TC, g_outgauge.showlights & (1 << DL_TC), 1, 0, symspace * 4, symsize, symsize); + } + if (g_outgauge.dashlights & (1 << DL_OILWARN)) + { + if (g_outgauge.dashlights & (1 << DL_BATTERY)) + { + drawSymbol2(DL_BATTERY, g_outgauge.showlights & (1 << DL_BATTERY), 1, -symsize * 0.75, symspace * 5, symsize, symsize); + } + drawSymbol2(DL_OILWARN, g_outgauge.showlights & (1 << DL_OILWARN), 1, symsize * 0.75, symspace * 5, symsize, symsize); + } + else + { + if (g_outgauge.dashlights & (1 << DL_BATTERY)) + { + drawSymbol2(DL_BATTERY, g_outgauge.showlights & (1 << DL_BATTERY), 1, 0, symspace * 5, symsize, symsize); + } + } + glPopMatrix(); - glPopMatrix(); - } - glPopMatrix(); - */ + glPushMatrix(); + glTranslatef(width, 0, 0); + glScalef(-height * 0.075, height * 0.075, 1.0); + glColor4f(0.15, 1.0, 0.15, 0.8); + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(0.25, 0.0, 0.0); + glVertex3f(0.0, g_outgauge.throttle, 0.0); + glVertex3f(0.25, g_outgauge.throttle, 0.0); + glEnd(); + glColor4f(1.0, 0.15, 0.15, 0.8); + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(0.30, 0.0, 0.0); + glVertex3f(0.55, 0.0, 0.0); + glVertex3f(0.30, g_outgauge.brake, 0.0); + glVertex3f(0.55, g_outgauge.brake, 0.0); + glEnd(); + glColor4f(0.15, 0.15, 1.0, 0.8); + glBegin(GL_TRIANGLE_STRIP); + glVertex3f(0.60, 0.0, 0.0); + glVertex3f(0.85, 0.0, 0.0); + glVertex3f(0.60, g_outgauge.clutch, 0.0); + glVertex3f(0.85, g_outgauge.clutch, 0.0); + glEnd(); + glPopMatrix(); - int os1 = (g_outgauge.showlights & (1 << DL_SIGNAL_L)) ? FX_ON : FX_OFF; - int os2 = (g_outgauge.showlights & (1 << DL_SIGNAL_R)) ? FX_ON : FX_OFF; - int os3 = (g_outgauge.showlights & (1 << DL_SIGNAL_ANY)) ? FX_ON : FX_OFF; - int os6 = (g_outgauge.showlights & (1 << DL_PITSPEED)) ? FX_ON : FX_OFF; + glPushMatrix(); + glColor4f(0.15, 0.15, 1.0, 1.0); + glTranslatef(width * 0.5, 0, 0.0f); + if (g_outgauge.gear == 0) + { + snprintf(text, sizeof text, "R"); + } + else if (g_outgauge.gear == 1) + { + snprintf(text, sizeof text, "N"); + } + else + { + snprintf(text, sizeof text, "%d", g_outgauge.gear - 1); + } + drawText(text, font, 0, sgsize * 0.7, sgsize * 0.7, sgsize * 0.7, TA_CENTRE, TA_BOTTOM); + snprintf(text, sizeof text, "%s", s_carinfo[g_outgauge.playerid].cname); + drawText(text, font, 0, sgsize * 0.4, sgsize * 0.2, sgsize * 0.2, TA_CENTRE, TA_BOTTOM); + snprintf(text, sizeof text, "%s", s_conninfo[s_carinfo[g_outgauge.playerid].ucid].uname); + drawText(text, font, 0, sgsize * 0.2, sgsize * 0.15, sgsize * 0.15, TA_CENTRE, TA_BOTTOM); + // snprintf(text, sizeof text, "dist %0.1f time %0.1f fuel %0.1f", s_cars[carnum].dist * distunit, s_cars[carnum].time, s_cars[carnum].cons); + // snprintf(text, sizeof text, "p %d r %d; %d %d, %u", g_pressed, g_released, volume, mode, mode_timer); + // drawText(text, font, 0, sgsize * 1.2, sgsize * 0.2, sgsize * 0.2, TA_CENTRE, TA_CENTRE); + // snprintf(text, sizeof text, "s %u c %u; %u", g_shift_time, g_ctrl_time, g_outgauge.time); + // drawText(text, font, 0, sgsize * 1.5, sgsize * 0.2, sgsize * 0.2, TA_CENTRE, TA_CENTRE); + snprintf(text, sizeof text, "%02d:%02d", timeinfo->tm_hour, timeinfo->tm_min); + drawText(text, font, 0, sgsize * 1.3, sgsize * 0.2, sgsize * 0.2, TA_CENTRE, TA_BOTTOM); + glPopMatrix(); + /* + int ox = s_carinfo[g_outgauge.playerid].x; + int oy = s_carinfo[g_outgauge.playerid].y; + int oz = s_carinfo[g_outgauge.playerid].z; + int head = s_carinfo[g_outgauge.playerid].heading; + int speed = s_carinfo[g_outgauge.playerid].speed; - if (s1 != os1) { - s1 = os1; - if (!g_fade) audio_play(0, s1); - } - if (s2 != os2) { - s2 = os2; - if (!g_fade) audio_play(1, s2); - } - if (s3 != os3) { - s3 = os3; - if (!g_fade) audio_play(2, s3); - } - if (s6 != os6) { - s6 = os6; - if (!g_fade) audio_play(5, s6); - } + glPushMatrix(); + glTranslatef(width / 2, height / 2, 0); + int i; + for (i = 0; i < 256; i++) + { + struct carinfo *ci = s_carinfo + i; + if (!ci->active) continue; - if (g_outgauge.fuel > warn_fuel1 || g_outgauge.rpm == 0) - { - bing = 0; - } - else if (g_outgauge.fuel <= warn_fuel2) - { - bing = 2; - } - else if (bing != 1 && g_outgauge.fuel <= warn_fuel1) - { - bing = 1; - if (!g_fade) audio_play(3, FX_BING); - } + float dx = (ci->x - ox) / zoom; + float dy = (ci->y - oy) / zoom; - if (g_fade && fade < 0.8) { - fade = fade + 0.01; - } else if (!g_fade && fade > 0.0) { - fade = fade - 0.01; - } + //float ddx = (ci->x - ox) / 65536.0; + //float ddy = (ci->y - oy) / 65536.0; + //ci->dist = sqrtf(ddx * ddx + ddy * ddy); - //glPopMatrix(); + // if (ci->dist >= width / 2 && ci->dist >= height / 2) continue; - if (dofade && fade > 0) { - glColor4f(0.0, 0.0, 0.0, fade); - glBegin(GL_QUADS); - glVertex3f(0.0, 0.0, 0.0); - glVertex3f(width, 0.0, 0.0); - glVertex3f(width, height, 0.0); - glVertex3f(0.0, height, 0.0); - glEnd(); - } + const struct conninfo *pi = s_conninfo + ci->ucid; + int idx = (ci->x - ox) >> 16; + int idy = (ci->y - oy) >> 16; + int dist = sqrt(idx * idx + idy * idy); - glfwSwapBuffers(); + snprintf(text, sizeof text, "%s - %d (%0.1f %s)", pi->uname, dist, (ci->speed - speed) / 327.68f * speedunit, (g_outgauge.flags & OG_KM) ? "km/h" : "mph"); + //printf("%d %s %d %d\n", i, text, head / 182, ci->heading / 182); -// printf("%f\n", g_outgauge.speed * 2.23693629); + glPushMatrix(); + glRotatef(-head / 182.0444f, 0.0, 0.0, 1.0); + glTranslatef(dx, dy, 0); + if (ci->hist > 0) { + glBegin(GL_LINE_STRIP); + int j; + for (j = CARPATHSIZE; j > 0; j--) + { + int d = (j + ci->hist - 1) % CARPATHSIZE; + if (ci->hist_x[d] == 0 && ci->hist_y[d] == 0) continue; + glColor4f(ci->hist_s[d] / 32768.0f, 1.0 - ci->hist_s[d] / 32768.0f, 0.0, 0.9); + glVertex3f((ci->hist_x[d] - ci->x) / zoom, (ci->hist_y[d] - ci->y) / zoom, 0.0); + } + glEnd(); + } + if (pi->state == 1) { + glColor4f(1.0, 0.0, 0.0, 0.5); + } else if (pi->state == 2) { + glColor4f(0.0, 1.0, 1.0, 0.5); + } else { + glColor4f(2.0, 1.0, 1.0, 0.5); + } + glRotatef(head / 182.0444f, 0.0, 0.0, 1.0); + drawText(text, font, 5, 3, 10, 10, TA_LEFT, TA_TOP); + glRotatef(-(head - ci->heading) / 182.0444, 0.0, 0.0, 1.0); + glBegin(GL_TRIANGLES); + glVertex3f(0, 5, 0); + glVertex3f(2.5, -5, 0); + glVertex3f(-2.5, -5, 0); + glEnd(); - running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam( GLFW_OPENED) && !glfwGetMouseButton(1); + glPopMatrix(); + } + glPopMatrix(); + */ + + int os1 = (g_outgauge.showlights & (1 << DL_SIGNAL_L)) ? FX_ON : FX_OFF; + int os2 = (g_outgauge.showlights & (1 << DL_SIGNAL_R)) ? FX_ON : FX_OFF; + int os3 = (g_outgauge.showlights & (1 << DL_SIGNAL_ANY)) ? FX_ON : FX_OFF; + int os6 = (g_outgauge.showlights & (1 << DL_PITSPEED)) ? FX_ON : FX_OFF; + + if (s1 != os1) + { + s1 = os1; + if (!g_fade) + audio_play(0, s1); + } + if (s2 != os2) + { + s2 = os2; + if (!g_fade) + audio_play(1, s2); + } + if (s3 != os3) + { + s3 = os3; + if (!g_fade) + audio_play(2, s3); + } + if (s6 != os6) + { + s6 = os6; + if (!g_fade) + audio_play(5, s6); + } + + if (g_outgauge.fuel > warn_fuel1 || g_outgauge.rpm == 0) + { + bing = 0; + } + else if (g_outgauge.fuel <= warn_fuel2) + { + bing = 2; + } + else if (bing != 1 && g_outgauge.fuel <= warn_fuel1) + { + bing = 1; + if (!g_fade) + audio_play(3, FX_BING); + } + + if (g_fade && fade < 0.8) + { + fade = fade + 0.01; + } + else if (!g_fade && fade > 0.0) + { + fade = fade - 0.01; + } + + // glPopMatrix(); + + if (dofade && fade > 0) + { + glColor4f(0.0, 0.0, 0.0, fade); + glBegin(GL_QUADS); + glVertex3f(0.0, 0.0, 0.0); + glVertex3f(width, 0.0, 0.0); + glVertex3f(width, height, 0.0); + glVertex3f(0.0, height, 0.0); + glEnd(); + } + + glfwSwapBuffers(window); + glfwPollEvents(); + + // printf("%f\n", g_outgauge.speed * 2.23693629); + + running = !glfwGetKey(window, GLFW_KEY_ESCAPE) && glfwGetWindowAttrib( GLFW_OPENED) && !glfwGetMouseButton(1); /* int wheel = glfwGetMouseWheel(); if (wheel >= 1) { @@ -965,30 +1054,29 @@ int main(int argc, char **argv) */ //printf("%u %u %u\n", g_outgauge.flags, g_outgauge.dashlights, g_outgauge.showlights); - usleep(100); - } + usleep(100); + } - s_running = 0; + s_running = 0; - audio_deinit(); + audio_deinit(); - glfwTerminate(); + glfwTerminate(); - network_worker_deinit(); + network_worker_deinit(); - config_set_int("port", g_outgauge_port); - config_set_int("fullscreen", fullscreen); - config_set_int("width", width); - config_set_int("height", height); - config_set_int("volume", volume); - config_set_int("rpmleft", rpmleft); - config_set_int("fade", dofade); - config_set_string("insim_host", insim_host); - config_set_int("insim_port", g_insim_port); - config_set_float("warn_fuel1", warn_fuel1); - config_set_float("warn_fuel2", warn_fuel2); - config_deinit(); + config_set_int("port", g_outgauge_port); + config_set_int("fullscreen", fullscreen); + config_set_int("width", width); + config_set_int("height", height); + config_set_int("volume", volume); + config_set_int("rpmleft", rpmleft); + config_set_int("fade", dofade); + config_set_string("insim_host", insim_host); + config_set_int("insim_port", g_insim_port); + config_set_float("warn_fuel1", warn_fuel1); + config_set_float("warn_fuel2", warn_fuel2); + config_deinit(); - return 0; + return 0; } - diff --git a/list.h b/list.h index a9b4dd7..5718f62 100644 --- a/list.h +++ b/list.h @@ -3,70 +3,72 @@ #include -#define LIST(X, T, compare_func) \ -struct X ## _list_t \ -{ \ - size_t used; \ - size_t size; \ - T *items; \ -}; \ -\ -static inline void X ## _list_init(struct X ## _list_t *list) \ -{ \ - list->used = 0; \ - list->size = 0; \ - list->items = NULL; \ -} \ -\ -static inline void X ## _list_free(struct X ## _list_t *list) \ -{ \ - free(list->items); \ -} \ -\ -static inline void X ## _list_add(struct X ## _list_t *list, T item) \ -{ \ - if (list->used >= list->size) \ - { \ - list->size += 64U; \ - T *new_items = realloc(list->items, sizeof *list->items * list->size); \ - if (new_items == NULL) \ - { \ - fprintf(stderr, "Reallocating %s list to %u items (%u bytes) failed\n", #X, (unsigned)list->size, (unsigned)(sizeof *list->items * list->size)); \ - list->size -= 64U; \ - return; \ - } \ - list->items = new_items; \ - } \ - list->items[list->used++] = item; \ -} \ -\ -static inline void X ## _list_del_item(struct X ## _list_t *list, T item) \ -{ \ - size_t i; \ - for (i = 0; i < list->used; i++) \ - { \ - if (compare_func(&list->items[i], &item)) { \ - list->items[i] = list->items[--list->used]; \ - return; \ - } \ - } \ -} \ -\ -static inline void X ## _list_del_index(struct X ## _list_t *list, size_t index) \ -{ \ - list->items[index] = list->items[--list->used]; \ -} \ -\ -static inline int X ## _list_contains(struct X ## _list_t *list, T item) \ -{ \ - size_t i; \ - for (i = 0; i < list->used; i++) \ - { \ - if (compare_func(&list->items[i], &item)) { \ - return 1; \ - } \ - } \ - return 0; \ -} +#define LIST(X, T, compare_func) \ + struct X##_list_t \ + { \ + size_t used; \ + size_t size; \ + T *items; \ + }; \ + \ + static inline void X##_list_init(struct X##_list_t *list) \ + { \ + list->used = 0; \ + list->size = 0; \ + list->items = NULL; \ + } \ + \ + static inline void X##_list_free(struct X##_list_t *list) \ + { \ + free(list->items); \ + } \ + \ + static inline void X##_list_add(struct X##_list_t *list, T item) \ + { \ + if (list->used >= list->size) \ + { \ + list->size += 64U; \ + T *new_items = realloc(list->items, sizeof *list->items * list->size); \ + if (new_items == NULL) \ + { \ + fprintf(stderr, "Reallocating %s list to %u items (%u bytes) failed\n", #X, (unsigned)list->size, (unsigned)(sizeof *list->items * list->size)); \ + list->size -= 64U; \ + return; \ + } \ + list->items = new_items; \ + } \ + list->items[list->used++] = item; \ + } \ + \ + static inline void X##_list_del_item(struct X##_list_t *list, T item) \ + { \ + size_t i; \ + for (i = 0; i < list->used; i++) \ + { \ + if (compare_func(&list->items[i], &item)) \ + { \ + list->items[i] = list->items[--list->used]; \ + return; \ + } \ + } \ + } \ + \ + static inline void X##_list_del_index(struct X##_list_t *list, size_t index) \ + { \ + list->items[index] = list->items[--list->used]; \ + } \ + \ + static inline int X##_list_contains(struct X##_list_t *list, T item) \ + { \ + size_t i; \ + for (i = 0; i < list->used; i++) \ + { \ + if (compare_func(&list->items[i], &item)) \ + { \ + return 1; \ + } \ + } \ + return 0; \ + } #endif /* LIST_H */ diff --git a/network_worker.c b/network_worker.c index f72e18e..6b6fc5e 100644 --- a/network_worker.c +++ b/network_worker.c @@ -14,7 +14,7 @@ #include #endif #include -//#include "network.h" +// #include "network.h" #include "network_worker.h" #include "socket.h" #include "worker.h" @@ -23,124 +23,124 @@ static struct worker s_network_worker; struct network_job { - char *host; - int port; - network_callback callback; - void *data; + char *host; + int port; + network_callback callback; + void *data; }; int resolve(const char *hostname, int port, struct sockaddr_in *addr) { - struct addrinfo *ai; - struct addrinfo hints; - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_INET; - #ifndef WIN32 - hints.ai_flags = AI_ADDRCONFIG; - #endif - hints.ai_socktype = SOCK_STREAM; + struct addrinfo *ai; + struct addrinfo hints; + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET; +#ifndef WIN32 + hints.ai_flags = AI_ADDRCONFIG; +#endif + hints.ai_socktype = SOCK_STREAM; - char port_name[6]; - snprintf(port_name, sizeof port_name, "%u", port); + char port_name[6]; + snprintf(port_name, sizeof port_name, "%u", port); - int e = getaddrinfo(hostname, port_name, &hints, &ai); + int e = getaddrinfo(hostname, port_name, &hints, &ai); - if (e != 0) - { - fprintf(stderr, "getaddrinfo: %s\n", strerror(errno)); - return 0; - } + if (e != 0) + { + fprintf(stderr, "getaddrinfo: %s\n", strerror(errno)); + return 0; + } - struct addrinfo *runp; - for (runp = ai; runp != NULL; runp = runp->ai_next) - { - struct sockaddr_in *ai_addr = (struct sockaddr_in *)runp->ai_addr; + struct addrinfo *runp; + for (runp = ai; runp != NULL; runp = runp->ai_next) + { + struct sockaddr_in *ai_addr = (struct sockaddr_in *)runp->ai_addr; - /* Take the first address */ - *addr = *ai_addr; - break; - } + /* Take the first address */ + *addr = *ai_addr; + break; + } - freeaddrinfo(ai); + freeaddrinfo(ai); - return 1; + return 1; } static void network_worker(void *arg) { - struct network_job *job = arg; + struct network_job *job = arg; - if (job->callback != NULL) - { - struct sockaddr_in addr; - if (!resolve(job->host, job->port, &addr)) - { - fprintf(stderr, "Unable to resolve %s:%d\n", job->host, job->port); - if (job->callback != NULL) - { - job->callback(-1, job->data); - } - } - else if (job->callback != NULL) - { - int fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) - { - #ifdef WIN32 - fprintf(stderr, "socket: %d\n", WSAGetLastError()); - #else - fprintf(stderr, "socket: %s\n", strerror(errno)); - #endif - } - else - { - socket_set_nonblock(fd); - socket_set_nodelay(fd); - if (connect(fd, (struct sockaddr *)&addr, sizeof addr) < 0) - { - #ifdef WIN32 - if (WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEWOULDBLOCK) - { - fprintf(stderr, "connect: %d\n", WSAGetLastError()); - fd = -1; - } - #else - if (errno != EINPROGRESS && errno != EWOULDBLOCK) - { - fprintf(stderr, "connect: %s\n", strerror(errno)); - fd = -1; - } - #endif - } - } - job->callback(fd, job->data); - } - } + if (job->callback != NULL) + { + struct sockaddr_in addr; + if (!resolve(job->host, job->port, &addr)) + { + fprintf(stderr, "Unable to resolve %s:%d\n", job->host, job->port); + if (job->callback != NULL) + { + job->callback(-1, job->data); + } + } + else if (job->callback != NULL) + { + int fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) + { +#ifdef WIN32 + fprintf(stderr, "socket: %d\n", WSAGetLastError()); +#else + fprintf(stderr, "socket: %s\n", strerror(errno)); +#endif + } + else + { + socket_set_nonblock(fd); + socket_set_nodelay(fd); + if (connect(fd, (struct sockaddr *)&addr, sizeof addr) < 0) + { +#ifdef WIN32 + if (WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEWOULDBLOCK) + { + fprintf(stderr, "connect: %d\n", WSAGetLastError()); + fd = -1; + } +#else + if (errno != EINPROGRESS && errno != EWOULDBLOCK) + { + fprintf(stderr, "connect: %s\n", strerror(errno)); + fd = -1; + } +#endif + } + } + job->callback(fd, job->data); + } + } - free(job->host); - free(job); + free(job->host); + free(job); } void network_worker_init(void) { - worker_init(&s_network_worker, "network", 60000, 1, network_worker); + worker_init(&s_network_worker, "network", 60000, 1, network_worker); } void network_worker_deinit(void) { - worker_deinit(&s_network_worker); + worker_deinit(&s_network_worker); } void *network_connect(const char *host, int port, network_callback callback, void *data) { - struct network_job *job = malloc(sizeof *job); - job->host = strdup(host); - job->port = port; - job->callback = callback; - job->data = data; + struct network_job *job = malloc(sizeof *job); + job->host = strdup(host); + job->port = port; + job->callback = callback; + job->data = data; - worker_queue(&s_network_worker, job); - return job; + worker_queue(&s_network_worker, job); + return job; } int network_listen(int port, int tcp) @@ -153,42 +153,43 @@ int network_listen(int port, int tcp) fd = socket(AF_INET, tcp ? SOCK_STREAM : SOCK_DGRAM, 0); #endif - if (fd < 0) - { + if (fd < 0) + { #ifdef WIN32 - fprintf(stderr, "socket: %d\n", WSAGetLastError()); + fprintf(stderr, "socket: %d\n", WSAGetLastError()); #else - fprintf(stderr, "socket: %s\n", strerror(errno)); + fprintf(stderr, "socket: %s\n", strerror(errno)); #endif - return -1; - } + return -1; + } #ifdef USE_IPV6 struct sockaddr_in6 serv_addr; - serv_addr.sin6_family = AF_INET6; - serv_addr.sin6_addr = in6addr_any; - serv_addr.sin6_port = htons(port); + serv_addr.sin6_family = AF_INET6; + serv_addr.sin6_addr = in6addr_any; + serv_addr.sin6_port = htons(port); #else struct sockaddr_in serv_addr; - serv_addr.sin_family = AF_INET; - serv_addr.sin_addr.s_addr = INADDR_ANY; - serv_addr.sin_port = htons(port); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = INADDR_ANY; + serv_addr.sin_port = htons(port); #endif - int on = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof on) == -1) - { - fprintf(stderr, "setsockopt: Could not set SO_REUSEADDR: %s\n", strerror(errno)); - } + int on = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof on) == -1) + { + fprintf(stderr, "setsockopt: Could not set SO_REUSEADDR: %s\n", strerror(errno)); + } - if (bind(fd, (struct sockaddr *)&serv_addr, sizeof serv_addr) < 0) - { - fprintf(stderr, "bind: %s\n", strerror(errno)); - return -1; - } + if (bind(fd, (struct sockaddr *)&serv_addr, sizeof serv_addr) < 0) + { + fprintf(stderr, "bind: %s\n", strerror(errno)); + return -1; + } - socket_set_nonblock(fd); - if (tcp) socket_set_nodelay(fd); + socket_set_nonblock(fd); + if (tcp) + socket_set_nodelay(fd); - return fd; + return fd; } diff --git a/outgauge.c b/outgauge.c index 0d63e6a..a11f1ab 100644 --- a/outgauge.c +++ b/outgauge.c @@ -1,8 +1,8 @@ -//#define USE_IPV6 +// #define USE_IPV6 #ifdef WIN32 #include -//#include +// #include #else #include #include @@ -31,52 +31,55 @@ float g_consumption; int outgauge_recv(int fd, int can_write, int can_read, void *arg) { - if (can_read) - { + if (can_read) + { struct outgauge o; ssize_t len = recv(fd, (char *)&o, sizeof o, 0); /* Ignore out of order packet */ - //if (o.time < s_prev_time) + // if (o.time < s_prev_time) - if (o.rpm < 0) o.rpm = 0; + if (o.rpm < 0) + o.rpm = 0; memcpy(&g_outgauge, &o, len); g_fade &= ~1; - g_released |= g_pressed & (~(o.flags & 3)); + g_released |= g_pressed & (~(o.flags & 3)); - if (!(g_pressed & 1) && (o.flags & 1)) g_shift_time = o.time; - if (!(g_pressed & 2) && (o.flags & 2)) g_ctrl_time = o.time; - g_pressed |= (o.flags & 3); + if (!(g_pressed & 1) && (o.flags & 1)) + g_shift_time = o.time; + if (!(g_pressed & 2) && (o.flags & 2)) + g_ctrl_time = o.time; + g_pressed |= (o.flags & 3); - if (g_owncar != o.playerid) - { - if (o.fuel > 0) - { + if (g_owncar != o.playerid) + { + if (o.fuel > 0) + { g_owncar = o.playerid; g_consumption = 0; s_car = get_car(o.car, NULL); s_prev_fuel = o.fuel; g_fade &= ~2; - } + } else { g_fade |= 2; } - } - else - { - g_fade &= ~2; - } + } + else + { + g_fade &= ~2; + } - if (s_prev_time > 0) - { - if (o.fuel > s_prev_fuel) - { - g_consumption = 0; - } - else - { + if (s_prev_time > 0) + { + if (o.fuel > s_prev_fuel) + { + g_consumption = 0; + } + else + { float interval = (o.time - s_prev_time) * 0.001; if (interval > 0) { @@ -88,18 +91,19 @@ int outgauge_recv(int fd, int can_write, int can_read, void *arg) update_car(s_car, o.speed * interval, interval, g_consumption); } } - } - } - s_prev_time = o.time; - s_prev_fuel = o.fuel; - } + } + } + s_prev_time = o.time; + s_prev_fuel = o.fuel; + } - return 1; + return 1; } void outgauge_init(int port) { - int fd = network_listen(port, 0); - if (fd < 0) return; - register_socket(fd, SM_READ, &outgauge_recv, NULL); + int fd = network_listen(port, 0); + if (fd < 0) + return; + register_socket(fd, SM_READ, &outgauge_recv, NULL); } diff --git a/outgauge.h b/outgauge.h index 1f9eede..19147c5 100644 --- a/outgauge.h +++ b/outgauge.h @@ -5,26 +5,26 @@ struct outgauge { - uint32_t time; - char car[4]; - uint16_t flags; - uint8_t gear; - uint8_t playerid; - float speed; - float rpm; - float turbo; - float enginetemp; - float fuel; - float oilpressure; - float oiltemp; - uint32_t dashlights; - uint32_t showlights; - float throttle; - float brake; - float clutch; - char display1[16]; - char display2[16]; - uint32_t id; + uint32_t time; + char car[4]; + uint16_t flags; + uint8_t gear; + uint8_t playerid; + float speed; + float rpm; + float turbo; + float enginetemp; + float fuel; + float oilpressure; + float oiltemp; + uint32_t dashlights; + uint32_t showlights; + float throttle; + float brake; + float clutch; + char display1[16]; + char display2[16]; + uint32_t id; }; extern struct outgauge g_outgauge; @@ -37,7 +37,6 @@ extern int g_released; extern uint32_t g_shift_time; extern uint32_t g_ctrl_time; - void outgauge_init(int port); #endif /* OUTGAUGE_H */ diff --git a/queue.c b/queue.c index be68b92..9d54871 100644 --- a/queue.c +++ b/queue.c @@ -4,95 +4,96 @@ struct queue_object_t { - struct queue_object_t *next; - void *data; + struct queue_object_t *next; + void *data; }; struct queue_t { - pthread_mutex_t produce_mutex; - pthread_mutex_t consume_mutex; - struct queue_object_t *head; - struct queue_object_t *tail; - struct queue_object_t *divider; + pthread_mutex_t produce_mutex; + pthread_mutex_t consume_mutex; + struct queue_object_t *head; + struct queue_object_t *tail; + struct queue_object_t *divider; }; struct queue_t *queue_new(void) { - struct queue_t *queue = malloc(sizeof *queue); - struct queue_object_t *qo = malloc(sizeof *qo); - qo->next = NULL; - qo->data = NULL; + struct queue_t *queue = malloc(sizeof *queue); + struct queue_object_t *qo = malloc(sizeof *qo); + qo->next = NULL; + qo->data = NULL; - queue->head = qo; - queue->tail = qo; - queue->divider = qo; + queue->head = qo; + queue->tail = qo; + queue->divider = qo; - pthread_mutex_init(&queue->produce_mutex, NULL); - pthread_mutex_init(&queue->consume_mutex, NULL); + pthread_mutex_init(&queue->produce_mutex, NULL); + pthread_mutex_init(&queue->consume_mutex, NULL); - return queue; + return queue; } void queue_delete(struct queue_t *queue) { - int n = 0; - while (queue->head != NULL) - { - struct queue_object_t *qo = queue->head; - queue->head = qo->next; + int n = 0; + while (queue->head != NULL) + { + struct queue_object_t *qo = queue->head; + queue->head = qo->next; - //free(qo->data); - free(qo); - n++; - } + // free(qo->data); + free(qo); + n++; + } - pthread_mutex_destroy(&queue->produce_mutex); - pthread_mutex_destroy(&queue->consume_mutex); + pthread_mutex_destroy(&queue->produce_mutex); + pthread_mutex_destroy(&queue->consume_mutex); - free(queue); + free(queue); } int queue_produce(struct queue_t *queue, void *data) { - if (queue == NULL) return 0; + if (queue == NULL) + return 0; - struct queue_object_t *qo = malloc(sizeof *qo); - qo->next = NULL; - qo->data = data; + struct queue_object_t *qo = malloc(sizeof *qo); + qo->next = NULL; + qo->data = data; - /* Lock needed? */ - pthread_mutex_lock(&queue->produce_mutex); - queue->tail->next = qo; - queue->tail = qo; - /* */ + /* Lock needed? */ + pthread_mutex_lock(&queue->produce_mutex); + queue->tail->next = qo; + queue->tail = qo; + /* */ - int n = 0; - while (queue->head != queue->divider) - { - struct queue_object_t *qo = queue->head; - queue->head = qo->next; + int n = 0; + while (queue->head != queue->divider) + { + struct queue_object_t *qo = queue->head; + queue->head = qo->next; - //free(qo->data); - free(qo); - n++; - } - pthread_mutex_unlock(&queue->produce_mutex); + // free(qo->data); + free(qo); + n++; + } + pthread_mutex_unlock(&queue->produce_mutex); - return 1; + return 1; } int queue_consume(struct queue_t *queue, void **data) { - pthread_mutex_lock(&queue->consume_mutex); - if (queue->divider != queue->tail) - { - *data = queue->divider->next->data; - queue->divider = queue->divider->next; - pthread_mutex_unlock(&queue->consume_mutex); - return 1; - } + pthread_mutex_lock(&queue->consume_mutex); + if (queue->divider != queue->tail) + { + *data = queue->divider->next->data; + queue->divider = queue->divider->next; + pthread_mutex_unlock(&queue->consume_mutex); + return 1; + } - pthread_mutex_unlock(&queue->consume_mutex); - return 0; + pthread_mutex_unlock(&queue->consume_mutex); + return 0; } diff --git a/socket.c b/socket.c index 244e8fe..07f1838 100644 --- a/socket.c +++ b/socket.c @@ -1,5 +1,5 @@ #ifndef WIN32 -//#define USE_POLL +// #define USE_POLL #endif #include @@ -28,15 +28,15 @@ int s_running; struct socket_t { - int fd; - int mode; - socket_func socket_func; - void *arg; + int fd; + int mode; + socket_func socket_func; + void *arg; }; static inline int socket_compare(struct socket_t **a, struct socket_t **b) { - return (*a)->fd == (*b)->fd; + return (*a)->fd == (*b)->fd; } LIST(socket, struct socket_t *, socket_compare) @@ -50,99 +50,105 @@ static int s_epoll_fd = -1; #ifdef USE_POLL static struct socket_t *socket_get_by_fd(int fd) { - size_t i; - for (i = 0; i < s_sockets.used; i++) - { - struct socket_t *s = s_sockets.items[i]; - if (s->fd == fd) return s; - } + size_t i; + for (i = 0; i < s_sockets.used; i++) + { + struct socket_t *s = s_sockets.items[i]; + if (s->fd == fd) + return s; + } - return NULL; + return NULL; } #endif void register_socket(int fd, int mode, socket_func socket_func, void *arg) { - struct socket_t *s = malloc(sizeof *s); - s->fd = fd; - s->mode = mode; - s->socket_func = socket_func; - s->arg = arg; + struct socket_t *s = malloc(sizeof *s); + s->fd = fd; + s->mode = mode; + s->socket_func = socket_func; + s->arg = arg; - pthread_mutex_lock(&s_sockets_mutex); - socket_list_add(&s_sockets, s); + pthread_mutex_lock(&s_sockets_mutex); + socket_list_add(&s_sockets, s); #ifdef USE_POLL - if (s_epoll_fd == -1) - { - s_epoll_fd = epoll_create(32); - if (s_epoll_fd == -1) fprintf(stderr, "register_socket(): epoll_create: %s\n", strerror(errno)); - } + if (s_epoll_fd == -1) + { + s_epoll_fd = epoll_create(32); + if (s_epoll_fd == -1) + fprintf(stderr, "register_socket(): epoll_create: %s\n", strerror(errno)); + } - struct epoll_event ev; - ev.events = EPOLLIN; - ev.data.ptr = s; - int r = epoll_ctl(s_epoll_fd, EPOLL_CTL_ADD, fd, &ev); - if (r == -1) fprintf(stderr, "register_socket(): epoll_ctl: %s\n", strerror(errno)); + struct epoll_event ev; + ev.events = EPOLLIN; + ev.data.ptr = s; + int r = epoll_ctl(s_epoll_fd, EPOLL_CTL_ADD, fd, &ev); + if (r == -1) + fprintf(stderr, "register_socket(): epoll_ctl: %s\n", strerror(errno)); #endif /* USE_POLL */ - pthread_mutex_unlock(&s_sockets_mutex); + pthread_mutex_unlock(&s_sockets_mutex); } void socket_flag_write(int fd) { #ifdef USE_POLL - struct epoll_event ev; - ev.events = EPOLLIN | EPOLLOUT; - ev.data.ptr = socket_get_by_fd(fd);; - int r = epoll_ctl(s_epoll_fd, EPOLL_CTL_MOD, fd, &ev); - if (r == -1) fprintf(stderr, "socket_flag_write(): epoll_ctl: %s\n", strerror(errno)); + struct epoll_event ev; + ev.events = EPOLLIN | EPOLLOUT; + ev.data.ptr = socket_get_by_fd(fd); + ; + int r = epoll_ctl(s_epoll_fd, EPOLL_CTL_MOD, fd, &ev); + if (r == -1) + fprintf(stderr, "socket_flag_write(): epoll_ctl: %s\n", strerror(errno)); #endif /* USE_POLL */ } void socket_clear_write(int fd) { #ifdef USE_POLL - struct epoll_event ev; - ev.events = EPOLLIN; - ev.data.ptr = socket_get_by_fd(fd); - int r = epoll_ctl(s_epoll_fd, EPOLL_CTL_MOD, fd, &ev); - if (r == -1) fprintf(stderr, "socket_clear_write(): epoll_ctl: %s\n", strerror(errno)); + struct epoll_event ev; + ev.events = EPOLLIN; + ev.data.ptr = socket_get_by_fd(fd); + int r = epoll_ctl(s_epoll_fd, EPOLL_CTL_MOD, fd, &ev); + if (r == -1) + fprintf(stderr, "socket_clear_write(): epoll_ctl: %s\n", strerror(errno)); #endif /* USE_POLL */ } void deregister_socket(int fd) { - struct socket_t s; - s.fd = fd; + struct socket_t s; + s.fd = fd; - pthread_mutex_lock(&s_sockets_mutex); - socket_list_del_item(&s_sockets, &s); - pthread_mutex_unlock(&s_sockets_mutex); + pthread_mutex_lock(&s_sockets_mutex); + socket_list_del_item(&s_sockets, &s); + pthread_mutex_unlock(&s_sockets_mutex); } void socket_init(void) { - #ifdef WIN32 - WSADATA WSA_Data; - WSAStartup (0x101, & WSA_Data); - #endif +#ifdef WIN32 + WSADATA WSA_Data; + WSAStartup(0x101, &WSA_Data); +#endif pthread_mutex_init(&s_sockets_mutex, NULL); } void socket_deinit(void) { - if (s_sockets.used > 0) - { - fprintf(stderr, "[network] socket_deinit(): %u sockets remaining in list\n", (unsigned)s_sockets.used); - } + if (s_sockets.used > 0) + { + fprintf(stderr, "[network] socket_deinit(): %u sockets remaining in list\n", (unsigned)s_sockets.used); + } #ifdef USE_POLL - close(s_epoll_fd); + close(s_epoll_fd); #endif - socket_list_free(&s_sockets); + socket_list_free(&s_sockets); } void socket_set_nonblock(int fd) @@ -151,23 +157,23 @@ void socket_set_nonblock(int fd) u_long iMode = 1; ioctlsocket(fd, FIONBIO, &iMode); #else - int flags = fcntl(fd, F_GETFL, 0); - int res = fcntl(fd, F_SETFL, flags | O_NONBLOCK); - if (res != 0) - { - fprintf(stderr, "[network] socket_set_nonblocK(): Could not set nonblocking IO: %s\n", strerror(errno)); - } + int flags = fcntl(fd, F_GETFL, 0); + int res = fcntl(fd, F_SETFL, flags | O_NONBLOCK); + if (res != 0) + { + fprintf(stderr, "[network] socket_set_nonblocK(): Could not set nonblocking IO: %s\n", strerror(errno)); + } #endif } void socket_set_nodelay(int fd) { - int b = 1; - int res = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&b, sizeof b); - if (res != 0) - { - fprintf(stderr, "[network] socket_set_nonblock(): Could not set TCP_NODELAY: %s\n", strerror(errno)); - } + int b = 1; + int res = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&b, sizeof b); + if (res != 0) + { + fprintf(stderr, "[network] socket_set_nonblock(): Could not set TCP_NODELAY: %s\n", strerror(errno)); + } } #ifdef USE_POLL @@ -176,26 +182,27 @@ void socket_set_nodelay(int fd) void *socket_run(void *arg) { - s_running = 1; + s_running = 1; - while (s_running) - { - struct epoll_event events[EPOLL_EVENTS]; - int n = epoll_wait(s_epoll_fd, events, EPOLL_EVENTS, 10000); - if (n == -1) fprintf(stderr, "socket_run(): epoll_wait: %s\n", strerror(errno)); + while (s_running) + { + struct epoll_event events[EPOLL_EVENTS]; + int n = epoll_wait(s_epoll_fd, events, EPOLL_EVENTS, 10000); + if (n == -1) + fprintf(stderr, "socket_run(): epoll_wait: %s\n", strerror(errno)); - int i; - for (i = 0; i < n; i++) - { - struct socket_t *s = events[i].data.ptr; - int state = s->socket_func(s->fd, !!(events[i].events & EPOLLOUT), !!(events[i].events & EPOLLIN), s->arg); - if (!state) - { - close(s->fd); - s->fd = -1; - } - } - } + int i; + for (i = 0; i < n; i++) + { + struct socket_t *s = events[i].data.ptr; + int state = s->socket_func(s->fd, !!(events[i].events & EPOLLOUT), !!(events[i].events & EPOLLIN), s->arg); + if (!state) + { + close(s->fd); + s->fd = -1; + } + } + } } #else /* USE_POLL */ @@ -204,8 +211,8 @@ void *socket_run(void *arg) { s_running = 1; - while (s_running) - { + while (s_running) + { unsigned i; int n; @@ -219,11 +226,13 @@ void *socket_run(void *arg) for (i = 0; i < s_sockets.used; i++) { int fd = s_sockets.items[i]->fd; - if (fd >= 0) - { - if (s_sockets.items[i]->mode & SM_READ ) FD_SET(fd, &read_fd); - if (s_sockets.items[i]->mode & SM_WRITE) FD_SET(fd, &write_fd); - } + if (fd >= 0) + { + if (s_sockets.items[i]->mode & SM_READ) + FD_SET(fd, &read_fd); + if (s_sockets.items[i]->mode & SM_WRITE) + FD_SET(fd, &write_fd); + } } tv.tv_sec = 10; @@ -235,27 +244,28 @@ void *socket_run(void *arg) fprintf(stderr, "select: %s\n", strerror(errno)); return NULL; } - if (n == 0) continue; + if (n == 0) + continue; for (i = 0; i < s_sockets.used; i++) { struct socket_t *s = s_sockets.items[i]; int can_write = FD_ISSET(s->fd, &write_fd); - int can_read = FD_ISSET(s->fd, &read_fd); + int can_read = FD_ISSET(s->fd, &read_fd); if (can_write || can_read) { - int state = s->socket_func(s->fd, can_write, can_read, s->arg); - if (!state) - { - close(s->fd); - s->fd = -1; - } + int state = s->socket_func(s->fd, can_write, can_read, s->arg); + if (!state) + { + close(s->fd); + s->fd = -1; + } } } - } - printf("Socket thread finished\n"); - return NULL; + } + printf("Socket thread finished\n"); + return NULL; } #endif /* USE_POLL */ diff --git a/socket.h b/socket.h index 77caf02..db1ec1b 100644 --- a/socket.h +++ b/socket.h @@ -3,12 +3,13 @@ extern int s_running; -enum { - SM_READ = 1, +enum +{ + SM_READ = 1, SM_WRITE = 2, }; -typedef int(*socket_func)(int fd, int can_write, int can_read, void *arg); +typedef int (*socket_func)(int fd, int can_write, int can_read, void *arg); void register_socket(int fd, int mode, socket_func socket_func, void *arg); void deregister_socket(int fd); diff --git a/text.c b/text.c index c6efbfa..9a03127 100644 --- a/text.c +++ b/text.c @@ -5,28 +5,40 @@ void drawText(const char *text, FTGLfont *font, float x, float y, float xs, float ys, int xa, int ya) { float bounds[6]; - ftglGetFontBBox(font, text, -1, bounds); - int cx = bounds[3] - bounds[0]; - int cy = bounds[4] - bounds[1]; + ftglGetFontBBox(font, text, -1, bounds); + int cx = bounds[3] - bounds[0]; + int cy = bounds[4] - bounds[1]; - float ox = 0, oy = 0; - switch (xa) - { - case TA_LEFT: ox = 0; break; - case TA_RIGHT: ox = -1; break; - case TA_CENTRE: ox = -0.5; break; - } - switch (ya) - { - case TA_TOP: oy = -1; break; - case TA_BOTTOM: oy = 0; break; - case TA_CENTRE: oy = -0.5; break; - } + float ox = 0, oy = 0; + switch (xa) + { + case TA_LEFT: + ox = 0; + break; + case TA_RIGHT: + ox = -1; + break; + case TA_CENTRE: + ox = -0.5; + break; + } + switch (ya) + { + case TA_TOP: + oy = -1; + break; + case TA_BOTTOM: + oy = 0; + break; + case TA_CENTRE: + oy = -0.5; + break; + } - glPushMatrix(); - glTranslatef(x, y, 0.0f); - glScalef(xs / TEXT_SIZE, ys / TEXT_SIZE, 1.0f); - glTranslatef(cx * ox, cy * oy, 0.0f); - ftglRenderFont(font, text, FTGL_RENDER_ALL); - glPopMatrix(); + glPushMatrix(); + glTranslatef(x, y, 0.0f); + glScalef(xs / TEXT_SIZE, ys / TEXT_SIZE, 1.0f); + glTranslatef(cx * ox, cy * oy, 0.0f); + ftglRenderFont(font, text, FTGL_RENDER_ALL); + glPopMatrix(); } diff --git a/text.h b/text.h index 49943f1..373a352 100644 --- a/text.h +++ b/text.h @@ -3,7 +3,8 @@ #define TEXT_SIZE 64 -enum { +enum +{ TA_LEFT, TA_RIGHT, TA_TOP, diff --git a/timer.c b/timer.c index 24cde1a..aa13c9a 100644 --- a/timer.c +++ b/timer.c @@ -7,17 +7,17 @@ struct timer_t { - char *name; - unsigned interval; - timer_func_t timer_func; - void *arg; + char *name; + unsigned interval; + timer_func_t timer_func; + void *arg; - unsigned next_trigger; + unsigned next_trigger; }; static inline int timer_t_compare(struct timer_t **a, struct timer_t **b) { - return *a == *b; + return *a == *b; } LIST(timer, struct timer_t *, timer_t_compare) @@ -26,76 +26,76 @@ static pthread_mutex_t s_timers_mutex; struct timer_t *register_timer(const char *name, unsigned interval, timer_func_t timer_func, void *arg, int wait) { - struct timer_t *t = malloc(sizeof *t); - t->name = strdup(name); - t->interval = interval; - t->timer_func = timer_func; - t->arg = arg; + struct timer_t *t = malloc(sizeof *t); + t->name = strdup(name); + t->interval = interval; + t->timer_func = timer_func; + t->arg = arg; - /* Make timer run on next tick */ - t->next_trigger = gettime() + (wait ? t->interval : 0); + /* Make timer run on next tick */ + t->next_trigger = gettime() + (wait ? t->interval : 0); - pthread_mutex_lock(&s_timers_mutex); - timer_list_add(&s_timers, t); - pthread_mutex_unlock(&s_timers_mutex); + pthread_mutex_lock(&s_timers_mutex); + timer_list_add(&s_timers, t); + pthread_mutex_unlock(&s_timers_mutex); - fprintf(stderr, "Registered %s timer with %u ms interval\n", name, interval); + fprintf(stderr, "Registered %s timer with %u ms interval\n", name, interval); - return t; + return t; } void deregister_timer(struct timer_t *t) { - timer_list_del_item(&s_timers, t); + timer_list_del_item(&s_timers, t); - fprintf(stderr, "Deregistered %s timer\n", t->name); + fprintf(stderr, "Deregistered %s timer\n", t->name); - free(t->name); - free(t); + free(t->name); + free(t); } void timers_deinit(void) { - while (s_timers.used > 0) - { - deregister_timer(s_timers.items[0]); - } + while (s_timers.used > 0) + { + deregister_timer(s_timers.items[0]); + } - timer_list_free(&s_timers); + timer_list_free(&s_timers); } void process_timers(unsigned tick) { - unsigned i; + unsigned i; - for (i = 0; i < s_timers.used; i++) - { - struct timer_t *t = s_timers.items[i]; - if (tick >= t->next_trigger) - { - t->next_trigger = tick + t->interval; - t->timer_func(t->arg); - } - } + for (i = 0; i < s_timers.used; i++) + { + struct timer_t *t = s_timers.items[i]; + if (tick >= t->next_trigger) + { + t->next_trigger = tick + t->interval; + t->timer_func(t->arg); + } + } } void timer_set_interval(struct timer_t *t, unsigned interval) { - /* Adjust next triggering */ - t->next_trigger += (interval - t->interval); - t->interval = interval; + /* Adjust next triggering */ + t->next_trigger += (interval - t->interval); + t->interval = interval; } void timer_set_interval_by_name(const char *name, unsigned interval) { - unsigned i; - for (i = 0; i < s_timers.used; i++) - { - struct timer_t *t = s_timers.items[i]; - if (strcmp(t->name, name) == 0) - { - timer_set_interval(t, interval); - return; - } - } + unsigned i; + for (i = 0; i < s_timers.used; i++) + { + struct timer_t *t = s_timers.items[i]; + if (strcmp(t->name, name) == 0) + { + timer_set_interval(t, interval); + return; + } + } } diff --git a/timer.h b/timer.h index abe6c38..9dd1217 100644 --- a/timer.h +++ b/timer.h @@ -1,7 +1,7 @@ #ifndef TIMER_H #define TIMER_H -typedef void(*timer_func_t)(void *arg); +typedef void (*timer_func_t)(void *arg); struct timer_t; diff --git a/worker.c b/worker.c index 8baef49..9778834 100644 --- a/worker.c +++ b/worker.c @@ -1,133 +1,133 @@ #ifdef WIN32 -//#include +// #include #endif #include #include #include #include #include -//#include +// #include #include #include "queue.h" #include "worker.h" -//#include "mcc.h" +// #include "mcc.h" #include "gettime.h" void *worker_thread(void *arg) { - struct worker *worker = arg; + struct worker *worker = arg; - bool timeout = false; - int jobs = 0; - //pid_t tid = (pid_t)syscall(SYS_gettid); - unsigned tid = 0; + bool timeout = false; + int jobs = 0; + // pid_t tid = (pid_t)syscall(SYS_gettid); + unsigned tid = 0; #ifndef WIN32 - nice(worker->nice); + nice(worker->nice); #endif - fprintf(stderr, "Queue worker %s thread (%u) started with nice %d\n", worker->name, tid, worker->nice); + fprintf(stderr, "Queue worker %s thread (%u) started with nice %d\n", worker->name, tid, worker->nice); - while (1) - { - struct timespec ts; - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += worker->timeout; + while (1) + { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_sec += worker->timeout; - int s = sem_timedwait(&worker->sem, &ts); - if (s == -1) - { - worker->thread_timeout = true; - if (errno == ETIMEDOUT) { - timeout = true; - break; - } - fprintf(stderr, "Queue worker %s thread (%u): %s\n", worker->name, tid, strerror(errno)); - break; - } + int s = sem_timedwait(&worker->sem, &ts); + if (s == -1) + { + worker->thread_timeout = true; + if (errno == ETIMEDOUT) + { + timeout = true; + break; + } + fprintf(stderr, "Queue worker %s thread (%u): %s\n", worker->name, tid, strerror(errno)); + break; + } - void *data; - if (queue_consume(worker->queue, &data)) - { - /* Null item added to the queue indicate we should exit. */ - if (data == NULL) break; + void *data; + if (queue_consume(worker->queue, &data)) + { + /* Null item added to the queue indicate we should exit. */ + if (data == NULL) + break; - worker->callback(data); - jobs++; - } - } + worker->callback(data); + jobs++; + } + } - if (timeout) - { - fprintf(stderr, "Queue worker %s thread (%u) exiting after %d jobs due to timeout\n", worker->name, tid, jobs); - } - else - { - fprintf(stderr, "Queue worker %s thread (%u) exiting after %d jobs\n", worker->name, tid, jobs); - } + if (timeout) + { + fprintf(stderr, "Queue worker %s thread (%u) exiting after %d jobs due to timeout\n", worker->name, tid, jobs); + } + else + { + fprintf(stderr, "Queue worker %s thread (%u) exiting after %d jobs\n", worker->name, tid, jobs); + } - return NULL; + return NULL; } void worker_init(struct worker *worker, const char *name, unsigned timeout, int nice, worker_callback callback) { - memset(worker, 0, sizeof *worker); + memset(worker, 0, sizeof *worker); - strncpy(worker->name, name, sizeof worker->name); - worker->thread_valid = false; - worker->thread_timeout = false; - worker->timeout = timeout / 1000; - worker->nice = nice; + strncpy(worker->name, name, sizeof worker->name); + worker->thread_valid = false; + worker->thread_timeout = false; + worker->timeout = timeout / 1000; + worker->nice = nice; - worker->queue = queue_new(); - worker->callback = callback; - sem_init(&worker->sem, 0, 0); + worker->queue = queue_new(); + worker->callback = callback; + sem_init(&worker->sem, 0, 0); - fprintf(stderr, "Queue worker %s initialised\n", worker->name); + fprintf(stderr, "Queue worker %s initialised\n", worker->name); } void worker_deinit(struct worker *worker) { - if (worker->thread_valid) - { - if (!worker->thread_timeout) - { - if (queue_produce(worker->queue, NULL)) - { - sem_post(&worker->sem); - } - } + if (worker->thread_valid) + { + if (!worker->thread_timeout) + { + if (queue_produce(worker->queue, NULL)) + { + sem_post(&worker->sem); + } + } - pthread_join(worker->thread, NULL); - } + pthread_join(worker->thread, NULL); + } - queue_delete(worker->queue); + queue_delete(worker->queue); - fprintf(stderr, "Queue worker %s deinitialised\n", worker->name); + fprintf(stderr, "Queue worker %s deinitialised\n", worker->name); } void worker_queue(struct worker *worker, void *data) { - if (worker->thread_timeout) - { - pthread_join(worker->thread, NULL); - worker->thread_timeout = false; - worker->thread_valid = false; - } + if (worker->thread_timeout) + { + pthread_join(worker->thread, NULL); + worker->thread_timeout = false; + worker->thread_valid = false; + } - if (!worker->thread_valid) - { - worker->thread_valid = (pthread_create(&worker->thread, NULL, &worker_thread, worker) == 0); - } + if (!worker->thread_valid) + { + worker->thread_valid = (pthread_create(&worker->thread, NULL, &worker_thread, worker) == 0); + } - if (queue_produce(worker->queue, data)) - { - sem_post(&worker->sem); - } - else - { - fprintf(stderr, "Queue worker %s unable to queue\n", worker->name); - } + if (queue_produce(worker->queue, data)) + { + sem_post(&worker->sem); + } + else + { + fprintf(stderr, "Queue worker %s unable to queue\n", worker->name); + } } - - diff --git a/worker.h b/worker.h index 158bcce..350a5ae 100644 --- a/worker.h +++ b/worker.h @@ -4,24 +4,24 @@ #include #include -typedef void(*worker_callback)(void *arg); +typedef void (*worker_callback)(void *arg); struct worker { - char name[16]; - int thread_valid; - int thread_timeout; - unsigned timeout; - int nice; + char name[16]; + int thread_valid; + int thread_timeout; + unsigned timeout; + int nice; - struct queue_t *queue; - pthread_t thread; - worker_callback callback; - sem_t sem; + struct queue_t *queue; + pthread_t thread; + worker_callback callback; + sem_t sem; }; void worker_init(struct worker *worker, const char *name, unsigned timeout, int nice, worker_callback callback); void worker_deinit(struct worker *worker); -void worker_queue(struct worker* worker, void *data); +void worker_queue(struct worker *worker, void *data); #endif /* WORKER_H */