#include #include #include void hexagram_cluster_resize(hexagram_cluster *cluster, double width, double height) { /* * Ensure correct cluster aspect ratio */ if (width / height > 32.0 / 15.0) { width = height * (32.0 / 15.0); } else { height = width * (15.0 / 32.0); } hexagram_tacho_init(&cluster->tacho, width * 0.2, height * 0.5, height * 0.4, 6500.0); hexagram_speedo_init(&cluster->speedo, width * 0.8, height * 0.5, height * 0.4); hexagram_thermo_init(&cluster->thermo, width * 0.43, height * 0.76, height * 0.13, 240.0); hexagram_fuel_init(&cluster->fuel, width * 0.57, height * 0.76, height * 0.13, 0.125); hexagram_mfd_init(&cluster->mfd, width * 0.42, height * 0.10, width * 0.16, height * 0.50); cluster->width = width; cluster->height = height; } void hexagram_cluster_init(hexagram_cluster *cluster, double width, double height) { hexagram_cluster_resize(cluster, width, height); memset(&cluster->state, '\0', sizeof(cluster->state)); } hexagram_cluster *hexagram_cluster_new(double width, double height) { hexagram_cluster *cluster; if ((cluster = malloc(sizeof(*cluster))) == NULL) { goto error_malloc_cluster; } hexagram_cluster_init(cluster, width, height); return cluster; error_malloc_cluster: return NULL; } int hexagram_cluster_update(hexagram_cluster *cluster, struct can_frame *frame) { switch (frame->can_id) { case 0x280: { cluster->state.rpm = 0.25 * (double)(frame->data[2] | (frame->data[3] << 8)); return 1; } case 0x288: { cluster->state.temp = 0.75 * (double)(frame->data[1] - 48); return 1; } case 0x320: { cluster->state.fuel = (double)(frame->data[2] & 0xf) / 16.0; return 1; } case 0x5a0: { cluster->state.rps = 0.001 * (double)(frame->data[1] | (frame->data[2] << 8)); return 1; } } return 0; } void hexagram_cluster_draw_bg(hexagram_cluster *cluster, cairo_t *cr) { /* * Paint canvas black */ cairo_set_source_rgb(cr, 0, 0, 0); cairo_paint(cr); hexagram_tacho_draw_face(&cluster->tacho, cr); hexagram_speedo_draw_face(&cluster->speedo, cr); hexagram_thermo_draw_face(&cluster->thermo, cr); hexagram_fuel_draw_face(&cluster->fuel, cr); hexagram_mfd_draw(&cluster->mfd, cr); } void hexagram_cluster_draw_fg(hexagram_cluster *cluster, cairo_t *cr) { hexagram_tacho_draw_needle(&cluster->tacho, cr, cluster->state.rpm); hexagram_speedo_draw_needle(&cluster->speedo, cr, (2.00152 * cluster->state.rps * 3600) / 1000.0); hexagram_thermo_draw_needle(&cluster->thermo, cr, cluster->state.temp); hexagram_fuel_draw_needle(&cluster->fuel, cr, cluster->state.fuel); }