#include #include #include #include #include #include #include "outgauge.h" #include "cars.h" #include "config.h" #include "gauge.h" #include "socket.h" #include "audio.h" #include "text.h" #include "insim.h" #include "network_worker.h" static GLuint s_symbols[1]; 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 */ static int dl_to_sympos[] = { 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.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.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 } }, }; void drawSymbol(int symbol, int on, int map) { 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); } 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(); } int g_outgauge_port; int g_insim_port; int main(int argc, char **argv) { g_fade = 0; int width; int height; int fullscreen; int volume; int rpmleft; int dofade; char *insim_host; 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; network_worker_init(); 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)) { glfwTerminate(); return 0; } glfwSetWindowTitle("GL LFS Dashboard"); 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 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 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 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 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; int running = 1; //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); 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); glGenTextures(1, s_symbols); glBindTexture(GL_TEXTURE_2D, s_symbols[0]); 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 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); // Enable texturing //glEnable(GL_TEXTURE_2D); 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; audio_volume(volume * 0.01); int bing = 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; float maxspeed = 0; float speedtimer = 0; float zoom = 65536.0; while (running) { double curtime = glfwGetTime(); if (curtime >= next) { next = curtime + 0.01; float interval = curtime - last_time; 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 (speedtimer > 0) { speedtimer -= interval; if (speedtimer <= 0) { speedtimer = 0; maxspeed = 0; } } if (g_pressed == 3) { if (g_outgauge.time - g_shift_time > 1000 && g_outgauge.time - g_ctrl_time > 1000) { //if (g_released == 3) //{ 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) { volume -= 10; if (volume < 0) volume = 0; audio_volume(volume * 0.01); audio_play(4, FX_BOP); ack = 1; } if (g_pressed == 2 && volume < 100) { volume += 10; if (volume > 100) volume = 100; audio_volume(volume * 0.01); audio_play(4, FX_BIP); ack = 1; } } } // Acknowledge key release if (g_released) { g_pressed &= ~g_released; g_released = 0; mode_timer = g_outgauge.time; ack = 0; } if (mode && g_outgauge.time - mode_timer > 2000) { mode = 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); height = height > 0 ? height : 1; glViewport(0, 0, width, height); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_ALPHA_TEST); glEnable(GL_LINE_SMOOTH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, width, 0, height, -100, 100); //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; } } 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; } 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; } 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 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; 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(); 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); 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); 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(); } 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; 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(); //glPushMatrix(); //glTranslatef(width * 0.5 + gsize * 1.5, boost.radius * 0.75, 0); 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(); //printf("%f %f\n", g_outgauge.oilpressure, g_outgauge.oiltemp); 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, 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 (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(); 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(); // printf("%f\n", g_outgauge.speed * 2.23693629); running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam( GLFW_OPENED) && !glfwGetMouseButton(1); /* int wheel = glfwGetMouseWheel(); if (wheel >= 1) { zoom = 65536.0 * wheel; } else { zoom = 65536 / (-wheel + 2); } */ //printf("%u %u %u\n", g_outgauge.flags, g_outgauge.dashlights, g_outgauge.showlights); usleep(100); } s_running = 0; audio_deinit(); glfwTerminate(); 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(); return 0; }