diff options
| author | aura <nw@moneybot.cc> | 2026-07-13 10:15:03 +0200 |
|---|---|---|
| committer | aura <nw@moneybot.cc> | 2026-07-13 10:15:03 +0200 |
| commit | 57d172df4db1451ba3caeeb0ca485d0845a61912 (patch) | |
| tree | ad0be7c8bec79a1eb58b25f2a631bc4b6809e7fd /src/gauges.cpp | |
push source
Diffstat (limited to 'src/gauges.cpp')
| -rw-r--r-- | src/gauges.cpp | 621 |
1 files changed, 621 insertions, 0 deletions
diff --git a/src/gauges.cpp b/src/gauges.cpp new file mode 100644 index 0000000..a15b65c --- /dev/null +++ b/src/gauges.cpp @@ -0,0 +1,621 @@ +#include <cstdio> +#include <math.h> + +#include "gauges.h" + +// 7-seg masks, bit order A B C D E F G; >=10 are letters +const U8 SEG7[G_COUNT] = { + 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, + 0x50, // r + 0x54, // n + 0x40, // - + 0x77, // A + 0x7C, // b + 0x6D, // S + 0x78, // t + 0x39, // C +}; + +F32 gauge_angle( F32 t ) { + const F32 A0 = -90.0f * (F32)M_PI / 180.0f; // south + const F32 A1 = -360.0f * (F32)M_PI / 180.0f; // east, clockwise + if( t < 0.0f ) t = 0.0f; + if( t > 1.0f ) t = 1.0f; + return A0 + ( A1 - A0 ) * t; +} + +GAUGE_RENDERER::GAUGE_RENDERER() { + nverts = 0; + fade = 1.0f; +} + +void GAUGE_RENDERER::clear() { + nverts = 0; + fade = 1.0f; +} + +void GAUGE_RENDERER::set_fade( F32 f ) { + if( f < 0.0f ) f = 0.0f; + if( f > 1.0f ) f = 1.0f; + fade = f; +} + +U32 GAUGE_RENDERER::faded( U32 c ) const { + if( fade >= 0.999f ) + return c; + U32 a = (U32)( ( c >> 24 ) * fade ); + return ( c & 0x00ffffffu ) | ( a << 24 ); +} + +void GAUGE_RENDERER::rect( F32 x, F32 y, F32 w, F32 h, U32 c ) { + c = faded( c ); + if( w <= 0.0f || h <= 0.0f ) + return; + if( nverts + 6 > MAX_VERTS ) + return; + + VERTEX *v = verts + nverts; + v[0].x = x; v[0].y = y; + v[1].x = x + w; v[1].y = y; + v[2].x = x; v[2].y = y + h; + v[3].x = x + w; v[3].y = y; + v[4].x = x + w; v[4].y = y + h; + v[5].x = x; v[5].y = y + h; + for( I32 i = 0; i < 6; i++ ) + v[i].col = c; + nverts += 6; +} + +void GAUGE_RENDERER::line( F32 x0, F32 y0, F32 x1, F32 y1, F32 t, U32 c ) { + c = faded( c ); + F32 dx = x1 - x0, dy = y1 - y0; + F32 len = sqrtf( dx * dx + dy * dy ); + if( len < 1e-3f || nverts + 6 > MAX_VERTS ) + return; + + F32 nx = -dy / len * t * 0.5f; + F32 ny = dx / len * t * 0.5f; + VERTEX *v = verts + nverts; + v[0].x = x0 + nx; v[0].y = y0 + ny; + v[1].x = x1 + nx; v[1].y = y1 + ny; + v[2].x = x0 - nx; v[2].y = y0 - ny; + v[3].x = x1 + nx; v[3].y = y1 + ny; + v[4].x = x1 - nx; v[4].y = y1 - ny; + v[5].x = x0 - nx; v[5].y = y0 - ny; + for( I32 i = 0; i < 6; i++ ) + v[i].col = c; + nverts += 6; +} + +void GAUGE_RENDERER::arc( + F32 cx, F32 cy, F32 r0, F32 r1, + F32 a0, F32 a1, U32 c +) { + c = faded( c ); + F32 span = a1 - a0; + I32 segs = (I32)( fabsf( span ) / 0.05f ) + 1; + if( segs > 256 ) + segs = 256; + F32 step = span / (F32)segs; + + F32 ca = cosf( a0 ), sa = sinf( a0 ); + for( I32 i = 0; i < segs; i++ ) { + if( nverts + 6 > MAX_VERTS ) + return; + + F32 a = a0 + step * (F32)( i + 1 ); + F32 cb = cosf( a ), sb = sinf( a ); + VERTEX *v = verts + nverts; + v[0].x = cx + r0 * ca; v[0].y = cy - r0 * sa; + v[1].x = cx + r1 * ca; v[1].y = cy - r1 * sa; + v[2].x = cx + r0 * cb; v[2].y = cy - r0 * sb; + v[3].x = cx + r1 * ca; v[3].y = cy - r1 * sa; + v[4].x = cx + r1 * cb; v[4].y = cy - r1 * sb; + v[5].x = cx + r0 * cb; v[5].y = cy - r0 * sb; + for( I32 k = 0; k < 6; k++ ) + v[k].col = c; + nverts += 6; + ca = cb; sa = sb; + } +} + +void GAUGE_RENDERER::arc_grad( + F32 cx, F32 cy, F32 r0, F32 r1, + F32 a0, F32 a1, U32 c_in, U32 c_out +) { + c_in = faded( c_in ); + c_out = faded( c_out ); + F32 span = a1 - a0; + I32 segs = (I32)( fabsf( span ) / 0.05f ) + 1; + if( segs > 256 ) + segs = 256; + F32 step = span / (F32)segs; + + F32 ca = cosf( a0 ), sa = sinf( a0 ); + for( I32 i = 0; i < segs; i++ ) { + if( nverts + 6 > MAX_VERTS ) + return; + + F32 a = a0 + step * (F32)( i + 1 ); + F32 cb = cosf( a ), sb = sinf( a ); + VERTEX *v = verts + nverts; + v[0].x = cx + r0 * ca; v[0].y = cy - r0 * sa; v[0].col = c_in; + v[1].x = cx + r1 * ca; v[1].y = cy - r1 * sa; v[1].col = c_out; + v[2].x = cx + r0 * cb; v[2].y = cy - r0 * sb; v[2].col = c_in; + v[3].x = cx + r1 * ca; v[3].y = cy - r1 * sa; v[3].col = c_out; + v[4].x = cx + r1 * cb; v[4].y = cy - r1 * sb; v[4].col = c_out; + v[5].x = cx + r0 * cb; v[5].y = cy - r0 * sb; v[5].col = c_in; + nverts += 6; + ca = cb; sa = sb; + } +} + +void GAUGE_RENDERER::disc( F32 cx, F32 cy, F32 r, U32 c ) { + arc( cx, cy, 0.0f, r, 0.0f, 2.0f * (F32)M_PI, c ); +} + +void GAUGE_RENDERER::disc_grad( F32 cx, F32 cy, F32 r, U32 c_in, U32 c_out ) { + arc_grad( cx, cy, 0.0f, r, 0.0f, 2.0f * (F32)M_PI, c_in, c_out ); +} + +void GAUGE_RENDERER::tick( + F32 cx, F32 cy, F32 a, + F32 rin, F32 rout, + F32 t, U32 c +) { + F32 dx = cosf( a ), dy = -sinf( a ); + line( cx + dx * rin, cy + dy * rin, + cx + dx * rout, cy + dy * rout, t, c ); +} + +void GAUGE_RENDERER::needle( + F32 cx, F32 cy, F32 a, + F32 len, F32 back, + F32 w, U32 c +) { + c = faded( c ); + if( nverts + 6 > MAX_VERTS ) + return; + + F32 dx = cosf( a ), dy = -sinf( a ); + F32 px = -dy, py = dx; + F32 bx = cx - dx * back, by = cy - dy * back; + F32 tx = cx + dx * len, ty = cy + dy * len; + F32 wt = w * 0.18f; + VERTEX *v = verts + nverts; + v[0].x = bx + px * w * 0.5f; v[0].y = by + py * w * 0.5f; + v[1].x = tx + px * wt; v[1].y = ty + py * wt; + v[2].x = bx - px * w * 0.5f; v[2].y = by - py * w * 0.5f; + v[3].x = tx + px * wt; v[3].y = ty + py * wt; + v[4].x = tx - px * wt; v[4].y = ty - py * wt; + v[5].x = bx - px * w * 0.5f; v[5].y = by - py * w * 0.5f; + for( I32 i = 0; i < 6; i++ ) + v[i].col = c; + nverts += 6; +} + +void GAUGE_RENDERER::needle_trail( + F32 cx, F32 cy, + F32 a0, F32 a1, + F32 r0, F32 r1, + U32 c +) { + c = faded( c ); + F32 span = a1 - a0; + if( fabsf( span ) < 1e-3f ) + return; + + I32 segs = (I32)( fabsf( span ) / 0.03f ) + 1; + if( segs > 96 ) + segs = 96; + F32 step = span / (F32)segs; + U32 base_a = c >> 24; + U32 rgb = c & 0x00ffffffu; + + F32 ca = cosf( a0 ), sa = sinf( a0 ); + for( I32 i = 0; i < segs; i++ ) { + if( nverts + 6 > MAX_VERTS ) + return; + + F32 f0 = (F32)i / (F32)segs; + F32 f1 = (F32)( i + 1 ) / (F32)segs; + U32 c0 = rgb | ( (U32)( base_a * f0 * f0 ) << 24 ); + U32 c1 = rgb | ( (U32)( base_a * f1 * f1 ) << 24 ); + + F32 a = a0 + step * (F32)( i + 1 ); + F32 cb = cosf( a ), sb = sinf( a ); + VERTEX *v = verts + nverts; + v[0].x = cx + r0 * ca; v[0].y = cy - r0 * sa; v[0].col = c0; + v[1].x = cx + r1 * ca; v[1].y = cy - r1 * sa; v[1].col = c0; + v[2].x = cx + r0 * cb; v[2].y = cy - r0 * sb; v[2].col = c1; + v[3].x = cx + r1 * ca; v[3].y = cy - r1 * sa; v[3].col = c1; + v[4].x = cx + r1 * cb; v[4].y = cy - r1 * sb; v[4].col = c1; + v[5].x = cx + r0 * cb; v[5].y = cy - r0 * sb; v[5].col = c0; + nverts += 6; + ca = cb; sa = sb; + } +} + +void GAUGE_RENDERER::glyph( F32 x, F32 y, F32 dw, F32 dh, I32 g, U32 c ) { + if( g < 0 || g >= G_COUNT ) + return; + + U32 m = SEG7[g]; + F32 t = dh * 0.13f; + if( t < 1.0f ) + t = 1.0f; + F32 half = ( dh - 3.0f * t ) * 0.5f; + + if( m & 0x01 ) rect( x + t, y, dw - 2 * t, t, c ); + if( m & 0x02 ) rect( x + dw - t, y + t, t, half, c ); + if( m & 0x04 ) rect( x + dw - t, y + 2 * t + half, t, half, c ); + if( m & 0x08 ) rect( x + t, y + dh - t, dw - 2 * t, t, c ); + if( m & 0x10 ) rect( x, y + 2 * t + half, t, half, c ); + if( m & 0x20 ) rect( x, y + t, t, half, c ); + if( m & 0x40 ) rect( x + t, y + ( dh - t ) * 0.5f, dw - 2 * t, t, c ); +} + +void GAUGE_RENDERER::glyph_c( F32 cx, F32 cy, F32 dw, F32 dh, I32 g, U32 c ) { + glyph( cx - dw * 0.5f, cy - dh * 0.5f, dw, dh, g, c ); +} + +void GAUGE_RENDERER::number( + F32 cx, F32 cy, + F32 dw, F32 dh, + I32 val, U32 c +) { + if( val < 0 ) + val = 0; + if( val > 99999 ) + val = 99999; + + I32 nd = 1, v = val; + while( v >= 10 ) { + nd++; + v /= 10; + } + + F32 adv = dw * 1.35f; + F32 x = cx + ( adv * (F32)nd - ( adv - dw ) ) - dw; + v = val; + for( I32 i = 0; i < nd; i++ ) { + glyph( x, cy - dh * 0.5f, dw, dh, v % 10, c ); + v /= 10; + x -= adv; + } +} + +void GAUGE_RENDERER::number_r( + F32 cx, F32 cy, + F32 dw, F32 dh, + I32 val, U32 c +) { + if( val < 0 ) + val = 0; + if( val > 99999 ) + val = 99999; + + I32 nd = 1, v = val; + while( v >= 10 ) { + nd++; + v /= 10; + } + + F32 adv = dw * 1.35f; + F32 x = cx; + v = val; + for( I32 i = 0; i < nd; i++ ) { + glyph( x, cy - dh * 0.5f, dw, dh, v % 10, c ); + v /= 10; + x -= adv; + } +} + +void GAUGE_RENDERER::number_c( + F32 cx, F32 cy, + F32 dw, F32 dh, + I32 val, U32 c +) { + if( val < 0 ) + val = 0; + if( val > 99999 ) + val = 99999; + + I32 nd = 1, v = val; + while( v >= 10 ) { + nd++; + v /= 10; + } + + F32 adv = dw * 1.35f; + F32 x = cx + ( adv * (F32)nd - ( adv - dw ) ) * 0.5f - dw; + v = val; + for( I32 i = 0; i < nd; i++ ) { + glyph( x, cy - dh * 0.5f, dw, dh, v % 10, c ); + v /= 10; + x -= adv; + } +} + +void GAUGE_RENDERER::lamp( F32 cx, F32 cy, F32 h, const I32 g[3], U32 c ) { + F32 dw = h * 0.62f; + F32 adv = dw * 1.35f; + F32 x = cx - adv; + for( I32 i = 0; i < 3; i++ ) { + glyph_c( x, cy, dw, h, g[i], c ); + x += adv; + } +} + + +void GAUGE_RENDERER::build_tach_bg( + F32 cx, F32 cy, F32 r, + F32 rpm_max, F32 red_ang, F32 rpm_off +) { + disc_grad( cx, cy, r * 1.10f, C_HALO_IN, C_HALO_OUT ); + disc_grad( cx, cy, r, C_FACE_MID, C_FACE_EDGE ); + + arc( cx, cy, r * 0.20f, r * 0.54f, + 40.0f * (F32)M_PI / 180.0f, 270.0f * (F32)M_PI / 180.0f, C_SWIRL ); + arc( cx, cy, r - 2.0f, r, 0.0f, 2.0f * (F32)M_PI, C_RIM ); + + if( rpm_off > 0.f ) { + arc( cx, cy, r * 0.84f, r * 0.965f, + gauge_angle( red_ang ), gauge_angle( red_ang + rpm_off ), C_REDLINE2 ); + } + arc( cx, cy, r * 0.84f, r * 0.965f, + gauge_angle( red_ang + rpm_off ), gauge_angle( 1.0f ), C_REDLINE ); + + + I32 kmax = (I32)( rpm_max / 1000.0f + 0.999f ); + for( I32 k1000 = 0; k1000 <= kmax; k1000++ ) { + F32 t = (F32)k1000 * 1000.0f / rpm_max; + if( t > 1.0f ) + break; + + F32 a = gauge_angle( t ); + tick( cx, cy, a, r * 0.85f, r - 2.0f, r * 0.020f, C_TICK ); + F32 lx = cx + cosf( a ) * r * 0.74f; + F32 ly = cy - sinf( a ) * r * 0.74f; + if( k1000 < 10 ) + glyph_c( lx, ly, r * 0.09f, r * 0.15f, k1000, C_LABEL ); + else + number_c( lx, ly, r * 0.075f, r * 0.13f, k1000, C_LABEL ); + } + + for( I32 rr = 250; rr <= (I32)rpm_max; rr += 250 ) { + if( rr % 1000 == 0 ) + continue; + F32 t = (F32)rr / rpm_max; + if( t > 1.0f ) + break; + tick( cx, cy, gauge_angle( t ), + r * 0.87f, r * 0.93f, r * 0.010f, C_TICKMIN ); + } +} + +void GAUGE_RENDERER::build_tach_gear_speed( + F32 cx, F32 cy, F32 r, + F32 rpm, F32 rpm_max, + I32 gear, F32 speed, + F32 red_ang +) { + F32 now = t_nows(); + U8 flash = fmodf( now, 0.2f ) > 0.1f; + + I32 g = gear == 0 ? G_R : ( gear >= 11 ? G_N : gear ); + glyph_c( cx + r * 0.45f, cy - r * 0.11f, r * 0.19f, r * 0.29f, + 0, C_LAMPBG ); + + U32 gearc = C_GEAR; + if( gear != G_N && rpm > rpm_max * red_ang && !flash ) + gearc = rgba( 255, 0, 0, 255 ); + else if( gear == 0 && flash ) + gearc = rgba( 0, 255, 255, 255 ); + + glyph_c( cx + r * 0.45f, cy - r * 0.11f, r * 0.19f, r * 0.29f, + g, gearc ); + I32 spx = cx + r * 0.37f; + I32 spy = cy + r * 0.24f; + for( U32 i = 0; i < 3; ++i ) + number( spx + i * r * 0.13f * 1.35f, spy, r * 0.13f, r * 0.24f, 0, C_LAMPBG ); + number_r( spx + r * 0.13f * 1.35f * 2, spy, r * 0.13f, r * 0.24f, (I32)( speed + 0.5f ), C_SPEED ); +} + +void GAUGE_RENDERER::build_tach( + F32 cx, F32 cy, F32 r, F32 trail, + F32 rpm, F32 rpm_max, F32 red_ang, F32 rpm_off, F32 peak, + I32 gear, F32 speed, U8 have_ext, U8 flash_needle +) { + F32 now = t_nows(); + U8 flash = fmodf( now, 0.2f ) > 0.1f; + if( rpm_max < 100.0f ) + rpm_max = 8000.0f; + + build_tach_bg( cx, cy, r, rpm_max, red_ang, rpm_off ); + + if( have_ext ) { + build_tach_gear_speed( cx, cy, r, rpm, rpm_max, gear, speed, red_ang ); + } + + F32 pt = peak / rpm_max; + if( pt > 0.01f && pt <= 1.0f ) { + tick( cx, cy, gauge_angle( pt ), + r * 0.84f, r * 0.945f, r * 0.016f, C_PEAK ); + } + + U32 trailc = C_TRAIL; + U32 needlec = C_NEEDLE; + if( flash_needle ) { + if( flash && rpm > rpm_max * red_ang ) + needlec = trailc = rgba( 255, 0, 0, 255 ); + else if( !flash && gear == 0 ) + needlec = trailc = C_LAMP; + } + + F32 t = rpm / rpm_max; + if( t < 0.0f ) t = 0.0f; + if( t > 1.0f ) t = 1.0f; + if( fabsf( trail ) > 0.002f ) { + F32 t0 = t - trail; + if( t0 < 0.0f ) t0 = 0.0f; + if( t0 > 1.0f ) t0 = 1.0f; + needle_trail( cx, cy, gauge_angle( t0 ), gauge_angle( t ), + r * 0.10f, r * 0.82f, trailc ); + } + needle( cx, cy, gauge_angle( t ), + r * 0.82f, r * 0.16f, r * 0.05f, needlec ); + disc( cx, cy, r * 0.065f, C_HUB ); + disc( cx, cy, r * 0.026f, C_HUBDOT ); +} + + +void GAUGE_RENDERER::build_boost_bg( F32 cx, F32 cy, F32 r, F32 range ) { + F32 span = range + 1.0f; + + disc_grad( cx, cy, r * 1.12f, C_HALO_IN, C_HALO_OUT ); + disc_grad( cx, cy, r, C_FACE_MID, C_FACE_EDGE ); + arc( cx, cy, r - 2.0f, r, 0.0f, 2.0f * (F32)M_PI, C_RIM ); + + arc( + cx, cy, r * 0.80f, r * 0.92f, + gauge_angle( 0.0f ), gauge_angle( 0.10f / span ), + C_REDLINE + ); + arc( + cx, cy, r * 0.80f, r * 0.92f, + gauge_angle( ( span - 0.25f ) / span ), gauge_angle( 1.0f ), + C_REDLINE + ); + arc( + cx, cy, r * 0.86f, r * 0.90f, + gauge_angle( 0.10f / span ), gauge_angle( 1.0f / span ), + C_VACUUM + ); + + for( I32 q = 0; q <= (I32)( span / 0.25f + 0.5f ); q++ ) { + F32 v = -1.0f + 0.25f * (F32)q; + F32 t = ( v + 1.0f ) / span; + if( t > 1.001f ) + break; + + U8 whole = fabsf( v - roundf( v ) ) < 0.01f; + U8 zero = fabsf( v ) < 0.01f; + tick( cx, cy, gauge_angle( t ), + whole ? r * 0.74f : r * 0.85f, r - 2.0f, + zero ? r * 0.05f : ( whole ? r * 0.03f : r * 0.018f ), + zero ? C_ZERO : ( whole ? C_TICK : C_TICKMIN ) + ); + + if( whole ) { + F32 a = gauge_angle( t ); + F32 lx = cx + cosf( a ) * r * 0.58f; + F32 ly = cy - sinf( a ) * r * 0.58f; + I32 av = (I32)fabsf( roundf( v ) ); + if( v < -0.01f ) { + glyph_c( lx - r * 0.09f, ly, r * 0.09f, r * 0.16f, G_DASH, C_LABEL ); + glyph_c( lx + r * 0.05f, ly, r * 0.09f, r * 0.16f, av, C_LABEL ); + } else { + glyph_c( lx, ly, r * 0.10f, r * 0.17f, av, C_LABEL ); + } + } + } +} + +void GAUGE_RENDERER::build_boost( F32 cx, F32 cy, F32 r, F32 bar, F32 range, F32 trail ) { + build_boost_bg( cx, cy, r, range ); + + F32 span = range + 1.0f; + F32 t = ( bar + 1.0f ) / span; + if( fabsf( trail ) > 0.002f ) { + F32 t0 = t - trail; + if( t0 < 0.0f ) t0 = 0.0f; + if( t0 > 1.0f ) t0 = 1.0f; + needle_trail( cx, cy, gauge_angle( t0 ), gauge_angle( t ), r * 0.12f, r * 0.76f, C_TRAIL ); + } + needle( cx, cy, gauge_angle( t ), r * 0.78f, r * 0.16f, r * 0.06f, C_NEEDLE ); + disc( cx, cy, r * 0.075f, C_HUB ); + disc( cx, cy, r * 0.030f, C_HUBDOT ); +} + +void GAUGE_RENDERER::build_lamps( + F32 cx, F32 cy, F32 r, F32 h, + U8 hb, U8 abs_on, U8 tcs_on, U8 abs_flash, U8 tcs_flash +) { + const I32 ABS[3] = { G_A, G_B, G_S }; + const I32 TCS[3] = { G_T, G_C, G_S }; + + F32 hbx = cx + r * 0.48f; + F32 hby = cy + r * 0.53f; + U32 col = !hb ? C_LAMPBG : rgba( 255, 0, 0, 255 ); + arc( hbx, hby, r * 0.1f, r * 0.117f, 0, M_PI * 2.f, col ); + line( hbx, hby - r * 0.075, hbx, hby + r * 0.04f, r * 0.03, col ); + line( hbx, hby + r * 0.05, hbx, hby + r * 0.085f, r * 0.03, col ); + + if( abs_on ) + lamp( cx + h * 1.6f, cy + r * 0.35f, h, ABS, C_LAMPBG ); + if( abs_flash ) + lamp( cx + h * 1.6f, cy + r * 0.35f, h, ABS, C_LAMP ); + if( tcs_on ) + lamp( cx + h * 1.6f, cy + r * 0.35f + h * 1.1f, h, TCS, C_LAMPBG ); + if( tcs_flash ) + lamp( cx + h * 1.6f, cy + r * 0.35f + h * 1.1f, h, TCS, C_LAMP ); +} + +U32 get_tire_color( F32 temp ) { + U32 a = 200; + temp -= 32.f; + temp /= 1.8f; + if( temp < 30.f ) + return rgba( 0, 0, 255, a ); + if( temp < 45.f ) + return rgba( 0, 255, 255, a ); + if( temp < 75.f ) + return rgba( 0, 255, 0, a ); + if( temp < 90.f ) + return rgba( 0, 170, 0, a ); + if( temp < 120.f ) + return rgba( 255, 170, 0, a ); + if( temp < 150.f ) + return rgba( 255, 100, 0, a ); + return rgba( 255, 0, 0, a ); +} + +void GAUGE_RENDERER::build_tires( F32 cx, F32 cy, F32 h, F32 fl, F32 fr, F32 rl, F32 rr ) { + const F32 tire_w = h * 0.023f; + const F32 tire_h = h * 0.037f; + const F32 rect_w = tire_w * 0.53f; + const F32 rect_h = tire_h * 0.3f; + + line( cx - tire_w, cy - tire_h, cx + tire_w, cy - tire_h, 2, C_TICK ); + line( cx - tire_w, cy + tire_h, cx + tire_w, cy + tire_h, 2, C_TICK ); + line( cx, cy - tire_h, cx, cy + tire_h, 2, C_TICK ); + + // fl + rect( cx - tire_w - rect_w, cy - tire_h - rect_h, rect_w, rect_h * 2.f, get_tire_color( fl ) ); + line( cx - tire_w, cy - tire_h - rect_h, cx - tire_w, cy - tire_h + rect_h, 2, C_TICK ); + line( cx - tire_w, cy - tire_h - rect_h, cx - tire_w - rect_w, cy - tire_h - rect_h, 2, C_TICK ); + line( cx - tire_w, cy - tire_h + rect_h, cx - tire_w - rect_w, cy - tire_h + rect_h, 2, C_TICK ); + line( cx - tire_w - rect_w, cy - tire_h - rect_h, cx - tire_w - rect_w, cy - tire_h + rect_h, 2, C_TICK ); + + // fr + rect( cx + tire_w, cy - tire_h - rect_h, rect_w, rect_h * 2.f, get_tire_color( fr ) ); + line( cx + tire_w, cy - tire_h - rect_h, cx + tire_w, cy - tire_h + rect_h, 2, C_TICK ); + line( cx + tire_w, cy - tire_h - rect_h, cx + tire_w + rect_w, cy - tire_h - rect_h, 2, C_TICK ); + line( cx + tire_w, cy - tire_h + rect_h, cx + tire_w + rect_w, cy - tire_h + rect_h, 2, C_TICK ); + line( cx + tire_w + rect_w, cy - tire_h - rect_h, cx + tire_w + rect_w, cy - tire_h + rect_h, 2, C_TICK ); + + // rl + rect( cx - tire_w - rect_w, cy + tire_h - rect_h, rect_w, rect_h * 2.f, get_tire_color( rl ) ); + line( cx - tire_w, cy + tire_h - rect_h, cx - tire_w, cy + tire_h + rect_h, 2, C_TICK ); + line( cx - tire_w, cy + tire_h - rect_h, cx - tire_w - rect_w, cy + tire_h - rect_h, 2, C_TICK ); + line( cx - tire_w, cy + tire_h + rect_h, cx - tire_w - rect_w, cy + tire_h + rect_h, 2, C_TICK ); + line( cx - tire_w - rect_w, cy + tire_h - rect_h, cx - tire_w - rect_w, cy + tire_h + rect_h, 2, C_TICK ); + + // rr + rect( cx + tire_w, cy + tire_h - rect_h, rect_w, rect_h * 2.f, get_tire_color( rr ) ); + line( cx + tire_w, cy + tire_h - rect_h, cx + tire_w, cy + tire_h + rect_h, 2, C_TICK ); + line( cx + tire_w, cy + tire_h - rect_h, cx + tire_w + rect_w, cy + tire_h - rect_h, 2, C_TICK ); + line( cx + tire_w, cy + tire_h + rect_h, cx + tire_w + rect_w, cy + tire_h + rect_h, 2, C_TICK ); + line( cx + tire_w + rect_w, cy + tire_h - rect_h, cx + tire_w + rect_w, cy + tire_h + rect_h, 2, C_TICK ); +} |
