- #include "spark.h" 
- #include "brender.h" 
- #include "car.h" 
- #include "crush.h" 
- #include "depth.h" 
- #include "displays.h" 
- #include "errors.h" 
- #include "formats.h" 
- #include "globvars.h" 
- #include "globvrkm.h" 
- #include "graphics.h" 
- #include "harness/hooks.h" 
- #include "harness/trace.h" 
- #include "loading.h" 
- #include "opponent.h" 
- #include "piping.h" 
- #include "replay.h" 
- #include "trig.h" 
- #include "utility.h" 
- #include "world.h" 
- #include <math.h> 
- #include <stdlib.h> 
-   
- int gNext_spark; 
- int gSpark_flags; 
- int gNext_shrapnel; 
- int gShrapnel_flags; 
- br_model* gShrapnel_model[2]; 
- int gSmoke_flags; 
- int gSmoke_num; 
- int gOffset = 0; 
- int gColumn_flags; 
- int gNext_column; 
- br_pixelmap* gBlack_smoke_shade_table; 
- br_pixelmap* gDark_smoke_shade_table; 
- br_pixelmap* gGrey_smoke_shade_table; 
- int gSmoke_on = 1; 
- int gNum_splash_types; 
- int gIt_type; 
- br_pixelmap* gIt_shade_table; 
- br_pixelmap** gDust_table = &gShade_list[8]; 
- br_pixelmap* gFlame_map[20]; 
- tBRender_smoke* gBR_smoke_pointers[30]; 
- tSplash gSplash[32]; 
- br_material* gSplash_material[20]; 
- tBRender_smoke gBR_smoke_structs[30]; 
- tSmoke_column gSmoke_column[25]; 
- br_matrix4 gCameraToScreen; 
- tSpark gSparks[32]; 
- br_pixelmap* gShade_list[16]; 
- int gN_BR_smoke_structs; 
- tSmoke gSmoke[25]; 
- tU32 gSplash_flags; 
- tU32 gNext_splash; 
- br_model* gLollipop_model; 
- int gNum_dust_tables; 
- br_model* gSplash_model; 
- int gDust_rotate; 
- br_camera* gSpark_cam; 
- br_material* gBlack_material; 
- tShrapnel gShrapnel[15]; 
-   
- // gSmoke_column has 25 elements but all the code just checks the first 5 elements 
- #define MAX_SMOKE_COLUMNS 5 
-   
- // Bugfix: At higher FPS, flame animation runs too quickly, so introduce a new frame timer 
- #define FLAME_ANIMATION_FRAME_INTERVAL 40 
-   
- // Bugfix: At higher FPS, `CreatePuffOfSmoke` is called too often and causes smoke cirlces to be recycled too quickly so assume around 25fps 
- #define SMOKE_COLUMN_NEW_PUFF_INTERVAL 30 
-   
- // IDA: void __cdecl DrawDot(br_scalar z, tU8 *scr_ptr, tU16 *depth_ptr, tU8 *shade_ptr) 
- void DrawDot(br_scalar z, tU8* scr_ptr, tU16* depth_ptr, tU8* shade_ptr) { 
-     LOG_TRACE("(%f, %p, %p, %p)", z, scr_ptr, depth_ptr, shade_ptr); 
-   
-     if (*depth_ptr > (1.0 - z) * 32768.0f) { 
-         *depth_ptr = (1.0 - z) * 32768.0f; 
-         *scr_ptr = shade_ptr[*scr_ptr]; 
-     } 
- } 
-   
- // IDA: void __usercall SetWorldToScreen(br_pixelmap *pScreen@<EAX>) 
- void SetWorldToScreen(br_pixelmap* pScreen) { 
-     br_matrix4 mat; 
-     br_matrix4 mat2; 
-     LOG_TRACE("(%p)", pScreen); 
-   
-     BrMatrix4Perspective(&mat, gSpark_cam->field_of_view, gSpark_cam->aspect, -gSpark_cam->hither_z, -gSpark_cam->yon_z); 
-     BrMatrix4Scale(&mat2, pScreen->width / 2, pScreen->height / 2, 1.0f); 
-     BrMatrix4Mul(&gCameraToScreen, &mat, &mat2); 
- } 
-   
- // IDA: void __usercall DrawLine3DThroughBRender(br_vector3 *pStart@<EAX>, br_vector3 *pEnd@<EDX>) 
- void DrawLine3DThroughBRender(br_vector3* pStart, br_vector3* pEnd) { 
-     LOG_TRACE("(%p, %p)", pStart, pEnd); 
-     NOT_IMPLEMENTED(); 
- } 
-   
- // IDA: int __usercall DrawLine3D@<EAX>(br_vector3 *start@<EAX>, br_vector3 *end@<EDX>, br_pixelmap *pScreen@<EBX>, br_pixelmap *pDepth_buffer@<ECX>, br_pixelmap *shade_table) 
- int DrawLine3D(br_vector3* start, br_vector3* end, br_pixelmap* pScreen, br_pixelmap* pDepth_buffer, br_pixelmap* shade_table) { 
-     br_vector3 o; 
-     br_vector3 p; 
-     //br_vector3 tv; // Pierre-Marie Baty -- unused variable 
-     br_vector4 o2; 
-     br_vector4 p2; 
-     br_scalar ts; 
-     LOG_TRACE("(%p, %p, %p, %p, %p)", start, end, pScreen, pDepth_buffer, shade_table); 
-   
-     o = *start; 
-     p = *end; 
-     if (-gSpark_cam->hither_z < o.v[2] || -gSpark_cam->hither_z < p.v[2]) { 
-         if (-gSpark_cam->hither_z < o.v[2] && -gSpark_cam->hither_z < p.v[2]) { 
-             return 0; 
-         } 
-         ts = (p.v[2] + gSpark_cam->hither_z) / (p.v[2] - o.v[2]); 
-         if (-gSpark_cam->hither_z < o.v[2]) { 
-             o.v[0] = p.v[0] - (p.v[0] - o.v[0]) * ts; 
-             o.v[1] = p.v[1] - (p.v[1] - o.v[1]) * ts; 
-             o.v[2] = -gSpark_cam->hither_z; 
-         } 
-         if (-gSpark_cam->hither_z < p.v[2]) { 
-             p.v[0] = p.v[0] - (p.v[0] - o.v[0]) * ts; 
-             p.v[1] = p.v[1] - (p.v[1] - o.v[1]) * ts; 
-             p.v[2] = -gSpark_cam->hither_z; 
-         } 
-     } 
-     BrMatrix4ApplyP(&o2, &o, &gCameraToScreen); 
-     BrMatrix4ApplyP(&p2, &p, &gCameraToScreen); 
-     o.v[0] = o2.v[0] / o2.v[3]; 
-     o.v[1] = o2.v[1] / o2.v[3]; 
-     o.v[2] = o2.v[2] / o2.v[3]; 
-     p.v[0] = p2.v[0] / p2.v[3]; 
-     p.v[1] = p2.v[1] / p2.v[3]; 
-     p.v[2] = p2.v[2] / p2.v[3]; 
-     return DrawLine2D(&o, &p, pScreen, pDepth_buffer, 1.0, shade_table); 
- } 
-   
- // IDA: int __usercall DrawLine2D@<EAX>(br_vector3 *o@<EAX>, br_vector3 *p@<EDX>, br_pixelmap *pScreen@<EBX>, br_pixelmap *pDepth_buffer@<ECX>, br_scalar brightness, br_pixelmap *shade_table) 
- int DrawLine2D(br_vector3* o, br_vector3* p, br_pixelmap* pScreen, br_pixelmap* pDepth_buffer, br_scalar brightness, br_pixelmap* shade_table) { 
-     tU8* scr_ptr; 
-     tU16* depth_ptr; 
-     tU8* shade_ptr; 
-     int x1; 
-     int x2; 
-     int y1; 
-     int y2; 
-     int d; 
-     int dx; 
-     int dy; 
-     int ax; 
-     int sx; 
-     int ay; 
-     int sy; 
-     int x; 
-     int y; 
-     br_scalar zbuff; 
-     br_scalar zbuff_inc; 
-     int darken_count; 
-     int darken_init; 
-     LOG_TRACE("(%p, %p, %p, %p, %f, %p)", o, p, pScreen, pDepth_buffer, brightness, shade_table); 
-   
-     scr_ptr = (tU8*)pScreen->pixels + pScreen->base_x + pScreen->base_y * pScreen->row_bytes; 
-     depth_ptr = (tU16*)pDepth_buffer->pixels; 
-     shade_ptr = (tU8*)shade_table->pixels + shade_table->base_y * shade_table->row_bytes; 
-     x1 = pScreen->width / 2 + o->v[0]; 
-     x2 = pScreen->width / 2 + p->v[0]; 
-     y1 = pScreen->height / 2 - o->v[1]; 
-     y2 = pScreen->height / 2 - p->v[1]; 
-     if (brightness < 0.001 || brightness > 1.0) { 
-         return 0; 
-     } 
-     if (x1 < 0 || x2 < 0) { 
-         if (x1 < 0 && x2 < 0) { 
-             return 0; 
-         } 
-         if (x1 >= 0) { 
-             y2 = y1 - x1 * (y1 - y2) / (x1 - x2); 
-             p->v[2] = o->v[2] - (o->v[2] - p->v[2]) * (float)x1 / (float)(x1 - x2); 
-             x2 = 0; 
-         } else { 
-             y1 = y2 - x2 * (y2 - y1) / (x2 - x1); 
-             o->v[2] = p->v[2] - (p->v[2] - o->v[2]) * (float)x2 / (float)(x2 - x1); 
-             x1 = 0; 
-         } 
-     } 
-     if (pScreen->width <= x1 || pScreen->width <= x2) { 
-         if (pScreen->width <= x1 && pScreen->width <= x2) { 
-             return 0; 
-         } 
-         if (pScreen->width > x1) { 
-             y2 = y1 - (y1 - y2) * (x1 - (pScreen->width - 1)) / (x1 - x2); 
-             p->v[2] = o->v[2] - (o->v[2] - p->v[2]) * (x1 - (float)(pScreen->width - 1)) / (float)(x1 - x2); 
-             x2 = pScreen->width - 1; 
-         } else { 
-             y1 = y2 - (y2 - y1) * (x2 - (pScreen->width - 1)) / (x2 - x1); 
-             o->v[2] = p->v[2] - (p->v[2] - o->v[2]) * (x2 - (float)(pScreen->width - 1)) / (float)(x2 - x1); 
-             x1 = pScreen->width - 1; 
-         } 
-     } 
-     if (y1 < 0 || y2 < 0) { 
-         if (y1 < 0 && y2 < 0) { 
-             return 0; 
-         } 
-         if (y1 >= 0) { 
-             x2 = x1 - y1 * (x1 - x2) / (y1 - y2); 
-             p->v[2] = o->v[2] - (o->v[2] - p->v[2]) * (float)y1 / (float)(y1 - y2); 
-             y2 = 0; 
-         } else { 
-             x1 = x2 - y2 * (x2 - x1) / (y2 - y1); 
-             o->v[2] = p->v[2] - (p->v[2] - o->v[2]) * (float)y2 / (float)(y2 - y1); 
-             y1 = 0; 
-         } 
-     } 
-     if (pScreen->height <= y1 || pScreen->height <= y2) { 
-         if (pScreen->height <= y1 && pScreen->height <= y2) { 
-             return 0; 
-         } 
-         if (pScreen->height > y1) { 
-             x2 = x1 - (x1 - x2) * (y1 - (pScreen->height - 1)) / (y1 - y2); 
-             p->v[2] = o->v[2] - (o->v[2] - p->v[2]) * (float)(y1 - (pScreen->height - 1)) / (float)(y1 - y2); 
-             y2 = pScreen->height - 1; 
-         } else { 
-             x1 = x2 - (x2 - x1) * (y2 - (pScreen->height - 1)) / (y2 - y1); 
-             o->v[2] = p->v[2] - (p->v[2] - o->v[2]) * (float)(y2 - (pScreen->height - 1)) / (float)(y2 - y1); 
-             y1 = pScreen->height - 1; 
-         } 
-     } 
-     zbuff = o->v[2]; 
-     dx = x2 - x1; 
-     dy = y2 - y1; 
-     if (x2 - x1 < 0) { 
-         sx = -1; 
-     } else { 
-         sx = 1; 
-     } 
-     if (dy < 0) { 
-         sy = -1; 
-     } else { 
-         sy = 1; 
-     } 
-     x = x1; 
-     y = y1; 
-     scr_ptr += x1 + y1 * pScreen->row_bytes; 
-     depth_ptr += x1 + y1 * (pDepth_buffer->row_bytes / 2); 
-     darken_init = (brightness - 0.001) * (float)shade_table->height; 
-     if (ay >= ax) { 
-         d = ax - ay / 2; 
-         darken_init = 500 * ay / darken_init; 
-         darken_count = darken_init; 
-         zbuff_inc = (p->v[2] - o->v[2]) * 2.0 / (float)ay; 
-         while (1) { 
-             DrawDot(zbuff, scr_ptr, depth_ptr, shade_ptr); 
-             if (y == y2) { 
-                 break; 
-             } 
-             if (d >= 0) { 
-                 scr_ptr += sx; 
-                 depth_ptr += sx; 
-                 d -= ay; 
-             } 
-             y += sy; 
-             d += ax; 
-             scr_ptr += sy * pScreen->row_bytes; 
-             depth_ptr += sy * (pDepth_buffer->row_bytes / 2); 
-             zbuff = zbuff_inc + zbuff; 
-             darken_count -= 1000; 
-             while (darken_count <= 0) { 
-                 darken_count += darken_init; 
-                 shade_ptr += shade_table->row_bytes; 
-             } 
-         } 
-     } else { 
-         d = ay - ax / 2; 
-         darken_init = 500 * ax / darken_init; 
-         darken_count = darken_init; 
-         zbuff_inc = (p->v[2] - o->v[2]) * 2.0 / (float)ax; 
-         while (1) { 
-             DrawDot(zbuff, scr_ptr, depth_ptr, shade_ptr); 
-             if (x == x2) { 
-                 break; 
-             } 
-             if (d >= 0) { 
-                 scr_ptr += sy * pScreen->row_bytes; 
-                 depth_ptr += sy * (pDepth_buffer->row_bytes / 2); 
-                 d -= ax; 
-             } 
-             x += sx; 
-             scr_ptr += sx; 
-             depth_ptr += sx; 
-             d += ay; 
-             zbuff = zbuff_inc + zbuff; 
-             darken_count -= 1000; 
-             while (darken_count <= 0) { 
-                 darken_count += darken_init; 
-                 shade_ptr += shade_table->row_bytes; 
-             } 
-         } 
-     } 
-     return 1; 
- } 
-   
- // IDA: void __usercall SetLineModelCols(tU8 pCol@<EAX>) 
- void SetLineModelCols(tU8 pCol) { 
-     LOG_TRACE("(%d)", pCol); 
-     NOT_IMPLEMENTED(); 
- } 
-   
- // IDA: void __usercall ReplaySparks(br_pixelmap *pRender_screen@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, tU32 pTime@<ECX>) 
- void ReplaySparks(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_actor* pCamera, tU32 pTime) { 
-     int i; 
-     br_vector3 pos; 
-     br_vector3 o; 
-     br_vector3 p; 
-     br_vector3 tv; 
-     br_vector3 new_pos; 
-     LOG_TRACE("(%p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pTime); 
-   
-     for (i = 0; i < COUNT_OF(gSparks); i++) { 
-         if (gSpark_flags & (1 << i)) { 
-             if (gSparks[i].car == NULL) { 
-                 BrVector3Copy(&pos, &gSparks[i].pos); 
-             } else { 
-                 BrMatrix34ApplyP(&tv, &o, &gSparks[i].car->car_master_actor->t.t.mat); 
-                 BrVector3Copy(&o, &tv); 
-                 BrMatrix34ApplyP(&pos, &gSparks[i].pos, &gSparks[i].car->car_master_actor->t.t.mat); 
-             } 
-             BrVector3Add(&o, &pos, &gSparks[i].length); 
-             BrVector3Sub(&tv, &pos, (br_vector3*)gCamera_to_world.m[3]); 
-             BrMatrix34TApplyV(&new_pos, &tv, &gCamera_to_world); 
-             BrVector3Sub(&tv, &o, (br_vector3*)gCamera_to_world.m[3]); 
-             BrMatrix34TApplyV(&p, &tv, &gCamera_to_world); 
-             if (gSparks[i].colour) { 
-                 DrawLine3D(&p, &new_pos, pRender_screen, pDepth_buffer, gFog_shade_table); 
-             } else { 
-                 DrawLine3D(&p, &new_pos, pRender_screen, pDepth_buffer, gAcid_shade_table); 
-             } 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall RenderSparks(br_pixelmap *pRender_screen@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>, tU32 pTime) 
- void RenderSparks(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world, tU32 pTime) { 
-     int i; 
-     br_vector3 tv; 
-     br_vector3 o; 
-     br_vector3 p; 
-     br_vector3 pos; 
-     br_vector3 new_pos; 
-     br_scalar ts; 
-     LOG_TRACE("(%p, %p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pCamera_to_world, pTime); 
-   
-     gSpark_cam = pCamera->type_data; 
-     SetWorldToScreen(pRender_screen); 
-   
-     if (!gSpark_flags) { 
-         return; 
-     } 
-   
-     if (gAction_replay_mode) { 
-         ReplaySparks(pRender_screen, pDepth_buffer, pCamera, pTime); 
-         return; 
-     } 
-     StartPipingSession(ePipe_chunk_spark); 
-     for (i = 0; i < COUNT_OF(gSparks); i++) { 
-         if (((1u << i) & gSpark_flags) == 0) { 
-             continue; 
-         } 
-         if (gSparks[i].count <= 0) { 
-             gSparks[i].count = 0; 
-             gSpark_flags &= ~(1u << i); 
-         } 
-         ts = BrVector3Dot(&gSparks[i].normal, &gSparks[i].v); 
-         BrVector3Scale(&tv, &gSparks[i].normal, ts); 
-         BrVector3Sub(&gSparks[i].v, &gSparks[i].v, &tv); 
-         if (gSparks[i].time_sync) { 
-             BrVector3Scale(&o, &gSparks[i].v, gSparks[i].time_sync / 1000.0); 
-             gSparks[i].count = gSparks[i].time_sync + gSparks[i].count - pTime; 
-             gSparks[i].time_sync = 0; 
-         } else { 
-             BrVector3Scale(&o, &gSparks[i].v, pTime / 1000.0); 
-             gSparks[i].count -= pTime; 
-         } 
-         BrVector3Accumulate(&gSparks[i].pos, &o); 
-         time = 1000 --  gSparks [- i ]- . count;
 
-         } 
-         if (gSparks[i].colour) { 
-             ts = ts / 2.0; 
-         } 
-         BrVector3Scale(&gSparks[i].length, &gSparks[i].v, ts); 
-         ts = pTime * 10.0 / 6900.0; 
-         if (gSparks[i].car) { 
-             BrMatrix34ApplyV(&tv, &gSparks[i].length, &gSparks[i].car->car_master_actor->t.t.mat); 
-             BrVector3Copy(&gSparks[i].length, &tv); 
-             BrMatrix34ApplyP(&pos, &gSparks[i].pos, &gSparks[i].car->car_master_actor->t.t.mat); 
-             o = tv; 
-             gSparks[i].v.v[0] = gSparks[i].v.v[0] - gSparks[i].car->car_master_actor->t.t.mat.m[0][1] * ts; 
-             gSparks[i].v.v[1] = gSparks[i].v.v[1] - gSparks[i].car->car_master_actor->t.t.mat.m[1][1] * ts; 
-             gSparks[i].v.v[2] = gSparks[i].v.v[2] - gSparks[i].car->car_master_actor->t.t.mat.m[2][1] * ts; 
-         } else { 
-             BrVector3Copy(&pos, &gSparks[i].pos); 
-             gSparks[i].v.v[1] = gSparks[i].v.v[1] - ts; 
-         } 
-         AddSparkToPipingSession(i + (gSparks[i].colour << 8), &pos, &gSparks[i].length); 
-         BrVector3Add(&o, &gSparks[i].length, &pos); 
-         BrVector3Sub(&tv, &pos, (br_vector3*)gCamera_to_world.m[3]); 
-         BrMatrix34TApplyV(&new_pos, &tv, &gCamera_to_world); 
-         BrVector3Sub(&tv, &o, (br_vector3*)gCamera_to_world.m[3]); 
-         BrMatrix34TApplyV(&p, &tv, &gCamera_to_world); 
-         BrVector3SetFloat(&tv, FRandomBetween(-0.1f, 0.1f), FRandomBetween(-0.1f, 0.1f), FRandomBetween(-0.1f, 0.1f)); 
-         BrVector3Accumulate(&gSparks[i].v, &tv); 
-         ts = 1.0f - BrVector3Length(&gSparks[i].v) / 1.4f * pTime / 1000.0f; 
-         if (ts < 0.1f) { 
-             ts = 0.1f; 
-         } 
-         BrVector3Scale(&gSparks[i].v, &gSparks[i].v, ts); 
-         if (gSparks[i].colour) { 
-             DrawLine3D(&p, &new_pos, pRender_screen, pDepth_buffer, gFog_shade_table); 
-         } else { 
-             DrawLine3D(&p, &new_pos, pRender_screen, pDepth_buffer, gAcid_shade_table); 
-         } 
-     } 
-     EndPipingSession(); 
- } 
-   
- // IDA: void __usercall CreateSingleSpark(tCar_spec *pCar@<EAX>, br_vector3 *pPos@<EDX>, br_vector3 *pVel@<EBX>) 
- void CreateSingleSpark(tCar_spec* pCar, br_vector3* pPos, br_vector3* pVel) { 
-     LOG_TRACE("(%p, %p, %p)", pCar, pPos, pVel); 
-   
-     BrVector3Copy(&gSparks[gNext_spark].pos, pPos); 
-     BrVector3SetFloat(&gSparks[gNext_spark].normal, 0.0f, 0.0f, 0.0f); 
-     BrVector3Copy(&gSparks[gNext_spark].v, pVel); 
-     gSparks[gNext_spark].count = 500; 
-     gSparks[gNext_spark].car = pCar; 
-     gSpark_flags |= 1u << gNext_spark; 
-     gSparks[gNext_spark].time_sync = 1; 
-     gSparks[gNext_spark].colour = 1; 
-     gNext_spark++; 
-     if (gNext_spark >= COUNT_OF(gSparks)) { 
-         gNext_spark = 0; 
-     } 
- } 
-   
- // IDA: void __usercall CreateSparks(br_vector3 *pos@<EAX>, br_vector3 *v@<EDX>, br_vector3 *pForce@<EBX>, br_scalar sparkiness, tCar_spec *pCar) 
- void CreateSparks(br_vector3* pos, br_vector3* v, br_vector3* pForce, br_scalar sparkiness, tCar_spec* pCar) { 
-     br_vector3 norm; 
-     br_vector3 normal; 
-     br_vector3 tv; 
-     br_vector3 tv2; 
-     br_vector3 pos2; 
-     br_scalar ts; 
-     br_scalar ts2; 
-     int num; 
-     int i; 
-     LOG_TRACE("(%p, %p, %p, %f, %p)", pos, v, pForce, sparkiness, pCar); 
-   
-     ts = BrVector3Length(pForce); 
-     BrVector3InvScale(&normal, pForce, ts); 
-     ts2 = BrVector3Dot(pForce, v); 
-     if (ts2 >= 0) { 
-         ts2 = 1.f / (10.f * ts); 
-     } else { 
-         ts2 = 1.f / (10.f * ts) - ts2 / (ts * ts); 
-     } 
-   
-     BrVector3Scale(&norm, pForce, ts2); 
-     BrVector3Accumulate(v, &norm); 
-     num = FRandomBetween(0.f, BrVector3Length(v) / 2.f + 0.7f) * sparkiness; 
-   
-     if (num > 10) { 
-         num = 10; 
-     } 
-     for (i = 0; i < num; i++) { 
-         BrVector3Copy(&gSparks[gNext_spark].pos, pos); 
-         BrVector3Copy(&gSparks[gNext_spark].normal, &normal); 
-         BrVector3Copy(&gSparks[gNext_spark].v, v); 
-         gSparks[gNext_spark].v.v[0] *= FRandomBetween(.5f, .9f); 
-         gSparks[gNext_spark].v.v[1] *= FRandomBetween(.5f, .9f); 
-         gSparks[gNext_spark].v.v[2] *= FRandomBetween(.5f, .9f); 
-         gSparks[gNext_spark].count = 1000; 
-         gSparks[gNext_spark].car = NULL; 
-         gSpark_flags |= 1u << gNext_spark; 
-         gSparks[gNext_spark].time_sync = gMechanics_time_sync; 
-         gSparks[gNext_spark].colour = 0; 
-         gNext_spark++; 
-         if (gNext_spark >= COUNT_OF(gSparks)) { 
-             gNext_spark = 0; 
-         } 
-     } 
-     if ((ts * sparkiness) >= 10.f) { 
-         tv.v[0] = pos->v[0] - pCar->car_master_actor->t.t.translate.t.v[0] / WORLD_SCALE; 
-         tv.v[1] = pos->v[1] - pCar->car_master_actor->t.t.translate.t.v[1] / WORLD_SCALE; 
-         tv.v[2] = pos->v[2] - pCar->car_master_actor->t.t.translate.t.v[2] / WORLD_SCALE; 
-         BrMatrix34TApplyV(&pos2, &tv, &pCar->car_master_actor->t.t.mat); 
-         BrMatrix34TApplyV(&norm, &normal, &pCar->car_master_actor->t.t.mat); 
-         BrVector3Scale(&tv, &norm, .1f); 
-         BrVector3Accumulate(&pos2, &tv); 
-         num = (ts * sparkiness / 10.f) + 3; 
-         if (num > 10) { 
-             num = 10; 
-         } 
-         for (i = 0; i < num; i++) { 
-             BrVector3Copy(&gSparks[gNext_spark].pos, &pos2); 
-             BrVector3Copy(&gSparks[gNext_spark].normal, &norm); 
-             BrVector3SetFloat(&tv, FRandomBetween(-1.f, 1.f), FRandomBetween(-.2f, 1.f), FRandomBetween(-1.f, 1.f)); 
-             ts2 = BrVector3Dot(&norm, &tv); 
-             BrVector3Scale(&tv2, &norm, ts2); 
-             BrVector3Sub(&gSparks[gNext_spark].v, &tv, &tv2); 
-             gSparks[gNext_spark].count = 1000; 
-             gSparks[gNext_spark].car = pCar; 
-             gSpark_flags |= 1u << gNext_spark; 
-             gSparks[gNext_spark].time_sync = gMechanics_time_sync; 
-             gSparks[gNext_spark].colour = 0; 
-             gNext_spark++; 
-             if (gNext_spark >= COUNT_OF(gSparks)) { 
-                 gNext_spark = 0; 
-             } 
-         } 
-         CreateShrapnelShower(pos, v, &normal, ts, pCar, pCar); 
-     } 
- } 
-   
- // IDA: void __usercall CreateSparkShower(br_vector3 *pos@<EAX>, br_vector3 *v@<EDX>, br_vector3 *pForce@<EBX>, tCar_spec *pCar1@<ECX>, tCar_spec *pCar2) 
- void CreateSparkShower(br_vector3* pos, br_vector3* v, br_vector3* pForce, tCar_spec* pCar1, tCar_spec* pCar2) { 
-     br_scalar ts; 
-     br_scalar ts2; 
-     int num; 
-     int i; 
-     tCar_spec* c; 
-     br_vector3 tv; 
-     //br_vector3 tv2; // Pierre-Marie Baty -- unused variable 
-     br_vector3 normal; 
-     LOG_TRACE("(%p, %p, %p, %p, %p)", pos, v, pForce, pCar1, pCar2); 
-   
-     ts = BrVector3Length(pForce); 
-     if (pCar1->driver == eDriver_local_human) { 
-         c = pCar1; 
-     } else { 
-         c = pCar2; 
-     } 
-     BrVector3InvScale(&tv, pForce, ts); 
-     if (ts < 10.f) { 
-         return; 
-     } 
-     CreateShrapnelShower(pos, v, &tv, ts, pCar1, pCar2); 
-     ts2 = BrVector3Dot(pForce, v) / (ts * ts); 
-     BrVector3Scale(v, pForce, ts2); 
-     normal.v[0] = pos->v[0] - c->car_master_actor->t.t.translate.t.v[0] / WORLD_SCALE; 
-     normal.v[1] = pos->v[1] - c->car_master_actor->t.t.translate.t.v[1] / WORLD_SCALE; 
-     normal.v[2] = pos->v[2] - c->car_master_actor->t.t.translate.t.v[2] / WORLD_SCALE; 
-     BrMatrix34TApplyV(pos, &normal, &c->car_master_actor->t.t.mat); 
-     BrMatrix34TApplyV(&normal, pForce, &c->car_master_actor->t.t.mat); 
-     num = (ts / 10.f) + 3; 
-     for (i = 0; i < num; i++) { 
-         BrVector3Copy(&gSparks[gNext_spark].pos, pos); 
-         BrVector3SetFloat(&gSparks[gNext_spark].normal, 0.f, 0.f, 0.f); 
-         BrVector3SetFloat(&normal, FRandomBetween(-1.f, 1.f), FRandomBetween(-.2f, 1.f), FRandomBetween(-1.f, 1.f)); 
-         ts2 = BrVector3LengthSquared(&normal) / (ts * ts); 
-         BrVector3Scale(&tv, &normal, ts2); 
-         BrVector3Sub(&gSparks[gNext_spark].v, &normal, &tv); 
-         BrVector3Accumulate(&gSparks[gNext_spark].v, v); 
-         gSparks[gNext_spark].count = 1000; 
-         gSparks[gNext_spark].car = c; 
-         gSpark_flags |= 1u << gNext_spark; 
-         gSparks[gNext_spark].time_sync = gMechanics_time_sync; 
-         gSparks[gNext_spark].colour = 0; 
-         gNext_spark++; 
-         if (gNext_spark >= COUNT_OF(gSparks)) { 
-             gNext_spark = 0; 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall AdjustSpark(int pSpark_num@<EAX>, br_vector3 *pos@<EDX>, br_vector3 *length@<EBX>) 
- void AdjustSpark(int pSpark_num, br_vector3* pos, br_vector3* length) { 
-     br_vector3 tv; 
-     br_matrix34* mat; 
-     int i; 
-     LOG_TRACE("(%d, %p, %p)", pSpark_num, pos, length); 
-   
-     i = pSpark_num & 0xff; 
-     gSpark_flags |= 1u << pSpark_num; 
-     if (gSparks[i].car != NULL) { 
-         mat = &gSparks[i].car->car_master_actor->t.t.mat; 
-         tv.v[0] = pos->v[0] - mat->m[3][0]; 
-         tv.v[1] = pos->v[0] - mat->m[3][1]; 
-         tv.v[2] = pos->v[0] - mat->m[3][2]; 
-         BrMatrix34TApplyV(&gSparks[i].pos, &tv, mat); 
-     } else { 
-         gSparks[i].pos.v[0] = pos->v[0]; 
-         gSparks[i].pos.v[1] = pos->v[1]; 
-         gSparks[i].pos.v[2] = pos->v[2]; 
-     } 
-     gSparks[i].length.v[0] = length->v[0]; 
-     gSparks[i].length.v[1] = length->v[1]; 
-     gSparks[i].length.v[2] = length->v[2]; 
-     gSparks[i].colour = pSpark_num >> 8; 
- } 
-   
- // IDA: void __usercall AdjustShrapnel(int pShrapnel_num@<EAX>, br_vector3 *pos@<EDX>, tU16 pAge@<EBX>, br_material *pMaterial@<ECX>) 
- void AdjustShrapnel(int pShrapnel_num, br_vector3* pos, tU16 pAge, br_material* pMaterial) { 
-     int i; 
-     LOG_TRACE("(%d, %p, %d, %p)", pShrapnel_num, pos, pAge, pMaterial); 
-   
-     i = pShrapnel_num & 0x7fff; 
-     if (!(gShrapnel_flags & (1u << i))) { 
-         BrActorAdd(gNon_track_actor, gShrapnel[i].actor); 
-     } 
-     gShrapnel_flags |= 1u << i; 
-     gShrapnel[i].actor->t.t.translate.t.v[0] = pos->v[0]; 
-     gShrapnel[i].actor->t.t.translate.t.v[1] = pos->v[1]; 
-     gShrapnel[i].actor->t.t.translate.t.v[2] = pos->v[2]; 
-     if (pShrapnel_num & 0x8000) { 
-         gShrapnel[i].age = pAge; 
-         gShrapnel[i].actor->material = pMaterial; 
-     } 
- } 
-   
- // IDA: void __cdecl ResetSparks() 
- void ResetSparks(void) { 
-     LOG_TRACE("()"); 
-   
-     gSpark_flags = 0; 
- } 
-   
- // IDA: void __cdecl ResetShrapnel() 
- void ResetShrapnel(void) { 
-     int i; 
-     LOG_TRACE("()"); 
-   
-     if (gShrapnel_flags == 0) { 
-         return; 
-     } 
-     for (i = 0; i < COUNT_OF(gShrapnel); i++) { 
-         if (gShrapnel_flags & (1u << i)) { 
-             BrActorRemove(gShrapnel[i].actor); 
-         } 
-     } 
-     gShrapnel_flags = 0; 
- } 
-   
- // IDA: void __usercall CreateShrapnelShower(br_vector3 *pos@<EAX>, br_vector3 *v@<EDX>, br_vector3 *pNormal@<EBX>, br_scalar pForce, tCar_spec *c1, tCar_spec *c2) 
- void CreateShrapnelShower(br_vector3* pos, br_vector3* v, br_vector3* pNormal, br_scalar pForce, tCar_spec* c1, tCar_spec* c2) { 
-     br_scalar ts; 
-     br_scalar ts2; 
-     br_scalar rnd; 
-     int num; 
-     int i; 
-     tCar_spec* c; 
-     br_vector3 tv; 
-     br_vector3 tv2; 
-     br_vector3 vel; 
-     LOG_TRACE("(%p, %p, %p, %f, %p, %p)", pos, v, pNormal, pForce, c1, c2); 
-   
-     if (pForce < 10.f) { 
-         return; 
-     } 
-     ts = .3f; 
-     if (v->v[1] < 0.f) { 
-         ts = .3f - v->v[1]; 
-     } 
-     ts2 = pNormal->v[1] * ts; 
-   
-     tv.v[0] = v->v[0] - ts2 * pNormal->v[0]; 
-     tv.v[1] = v->v[1] + ts - pNormal->v[1] * ts2; 
-     tv.v[2] = v->v[2] - pNormal->v[2] * ts2; 
-   
-     num = (pForce / 10.f) * 3; 
-     rnd = ((pForce + 20.f) * 3.f) / 200.f; 
-     for (i = 0; i < num; i++) { 
-         if ((gShrapnel_flags & (1u << gNext_shrapnel)) == 0) { 
-             BrActorAdd(gNon_track_actor, gShrapnel[gNext_shrapnel].actor); 
-         } 
-         gShrapnel_flags |= 1u << gNext_shrapnel; 
-         BrVector3Copy(&gShrapnel[gNext_shrapnel].actor->t.t.translate.t, pos); 
-         BrVector3SetFloat(&vel, FRandomBetween(-rnd, rnd), FRandomBetween(0.3f - tv.v[1], rnd), FRandomBetween(-rnd, rnd)); 
-         ts2 = BrVector3Dot(pNormal, &vel); 
-         BrVector3Scale(&tv2, pNormal, ts2); 
-         BrVector3Sub(&gShrapnel[gNext_shrapnel].v, &vel, &tv2); 
-         BrVector3Accumulate(&gShrapnel[gNext_shrapnel].v, &tv); 
-         gShrapnel[gNext_shrapnel].time_sync = gMechanics_time_sync; 
-         gShrapnel[gNext_shrapnel].age = 0; 
-         if (IRandomBetween(0, 2) != 0) { 
-             c = (IRandomBetween(0, 1) != 0) ? c1 : c2; 
-             gShrapnel[gNext_shrapnel].actor->material = c->shrapnel_material[IRandomBetween(0, c->max_shrapnel_material - 1)]; 
-         } else { 
-             gShrapnel[gNext_shrapnel].actor->material = gBlack_material; 
-         } 
-         gNext_shrapnel++; 
-         if (gNext_shrapnel >= COUNT_OF(gShrapnel)) { 
-             gNext_shrapnel = 0; 
-         } 
-     } 
- } 
-   
- // IDA: void __cdecl InitShrapnel() 
- void InitShrapnel(void) { 
-     int i; 
-     //int j; // Pierre-Marie Baty -- unused variable 
-     LOG_TRACE("()"); 
-   
-     for (i = 0; i < COUNT_OF(gShrapnel); i++) { 
-         gShrapnel[i].actor = BrActorAllocate(BR_ACTOR_MODEL, NULL); 
-         gShrapnel[i].actor->parent = NULL; 
-         gShrapnel[i].actor->model = gShrapnel_model[1]; 
-         gShrapnel[i].actor->render_style = BR_RSTYLE_DEFAULT; 
-         gShrapnel[i].actor->t.type = BR_TRANSFORM_MATRIX34; 
-         gShrapnel[i].actor->material = BrMaterialFind("DEBRIS.MAT"); 
-         gShrapnel[i].age = 0; 
-         gShrapnel[i].shear1 = FRandomBetween(-2.f, 2.f); 
-         gShrapnel[i].shear2 = FRandomBetween(-2.f, 2.f); 
-         BrVector3SetFloat(&gShrapnel[i].axis, 
-             FRandomBetween(-1.f, 1.f), FRandomBetween(-1.f, 1.f), FRandomBetween(-1.f, 1.f)); 
-         BrVector3Normalise(&gShrapnel[i].axis, &gShrapnel[i].axis); 
-     } 
- } 
-   
- // IDA: void __cdecl LoadInShrapnel() 
- void LoadInShrapnel(void) { 
-     LOG_TRACE("()"); 
-   
-     gShrapnel_model[0] = LoadModel("FRAG4.DAT"); 
-     gShrapnel_model[1] = LoadModel("FRAG5.DAT"); 
-     BrModelAdd(gShrapnel_model[0]); 
-     BrModelAdd(gShrapnel_model[1]); 
-     gBlack_material = BrMaterialFind("M14.MAT"); 
- } 
-   
- // IDA: void __usercall KillShrapnel(int i@<EAX>) 
- void KillShrapnel(int i) { 
-     LOG_TRACE("(%d)", i); 
-   
-     BrActorRemove(gShrapnel[i].actor); 
-     gShrapnel_flags &= ~(1u << i); 
- } 
-   
- // IDA: void __cdecl DisposeShrapnel() 
- void DisposeShrapnel(void) { 
-     int i; 
-     LOG_TRACE("()"); 
-   
-     for (i = 0; i < COUNT_OF(gShrapnel); i++) { 
-         if (gShrapnel_flags & (1u << i)) { 
-             BrActorRemove(gShrapnel[i].actor); 
-         } 
-         BrActorFree(gShrapnel[i].actor); 
-     } 
-     gShrapnel_flags = 0; 
-     for (i = 0; i < COUNT_OF(gShrapnel_model); i++) { 
-         BrModelRemove(gShrapnel_model[i]); 
-         BrModelFree(gShrapnel_model[i]); 
-     } 
- } 
-   
- // IDA: void __usercall ReplayShrapnel(tU32 pTime@<EAX>) 
- void ReplayShrapnel(tU32 pTime) { 
-     int i; 
-     br_matrix34* mat; 
-     LOG_TRACE("(%d)", pTime); 
-   
-     for (i = 0; i < COUNT_OF(gShrapnel); i++) { 
-         mat = &gShrapnel[i].actor->t.t.mat; 
-         if (gShrapnel_flags & (1 << i)) { 
-             gShrapnel[i].age += GetReplayRate() * pTime; 
-             DrMatrix34Rotate(mat, gShrapnel[i].age * BrDegreeToAngle(1), &gShrapnel[i].axis); 
-             BrMatrix34PreShearX(mat, gShrapnel[i].shear1, gShrapnel[i].shear2); 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall MungeShrapnel(tU32 pTime@<EAX>) 
- void MungeShrapnel(tU32 pTime) { 
-     br_vector3 disp; 
-     int i; 
-     br_matrix34* mat; 
-     br_scalar ts; 
-     LOG_TRACE("(%d)", pTime); 
-   
-     MungeSmokeColumn(pTime); 
-     MungeSplash(pTime); 
-   
-     if (gAction_replay_mode) { 
-         ReplayShrapnel(pTime); 
-         return; 
-     } 
-   
-     StartPipingSession(ePipe_chunk_shrapnel); 
-     for (i = 0; i < COUNT_OF(gShrapnel); i++) { 
-         mat = &gShrapnel[i].actor->t.t.mat; 
-         if (((1u << i) & gShrapnel_flags) == 0) { 
-             continue; 
-         } 
-         if (gShrapnel[i].age == -1) { 
-             KillShrapnel(i); 
-         } else { 
-             if (gShrapnel[i].time_sync) { 
-                 BrVector3Scale(&disp, &gShrapnel[i].v, gShrapnel[i].time_sync / 1000.0f); 
-                 gShrapnel[i].time_sync = 0; 
-             } else { 
-                 BrVector3Scale(&disp, &gShrapnel[i].v, pTime / 1000.0f); 
-                 gShrapnel[i].age += pTime; 
-             } 
-             mat->m[3][0] = mat->m[3][0] + disp.v[0]; 
-             mat->m[3][1] = mat->m[3][1] + disp.v[1]; 
-             mat->m[3][2] = mat->m[3][2] + disp.v[2]; 
-             gShrapnel[i].v.v[1] -= (10 * pTime) * 0.00014492753f; 
-             DrMatrix34Rotate(mat, 182 * gShrapnel[i].age, &gShrapnel[i].axis); 
-             BrMatrix34PreShearX(mat, gShrapnel[i].shear1, gShrapnel[i].shear2); 
-             // bug: should this be using "&gShrapnel[i].v"?? 
-             ts = 1.0 - BrVector3Length(&gSparks[i].v) / 1.4 * pTime / 1000.0; 
-             if (ts < 0.1) { 
-                 ts = (br_scalar) 0.1; // Pierre-Marie Baty -- added type cast 
-             } 
-             BrVector3Scale(&gShrapnel[i].v, &gShrapnel[i].v, ts); 
-             AddShrapnelToPipingSession(i + ((gShrapnel[i].age > 1000 || gShrapnel[i].age < pTime) << 15), (br_vector3*)mat->m[3], gShrapnel[i].age - pTime, gShrapnel[i].actor->material); 
-             if (gShrapnel[i].age > 1000) { 
-                 gShrapnel[i].age = -1; 
-             } 
-         } 
-     } 
-     EndPipingSession(); 
- } 
-   
- // IDA: void __usercall DrMatrix34Rotate(br_matrix34 *mat@<EAX>, br_angle r@<EDX>, br_vector3 *a@<EBX>) 
- void DrMatrix34Rotate(br_matrix34* mat, br_angle r, br_vector3* a) { 
-     br_scalar t; 
-     br_scalar s; 
-     br_scalar c; 
-     br_scalar txy; 
-     br_scalar txz; 
-     br_scalar tyz; 
-     br_scalar sx; 
-     br_scalar sy; 
-     br_scalar sz; 
-     LOG_TRACE("(%p, %d, %p)", mat, r, a); 
-   
-     s = FastScalarSinAngle(r); 
-     c = FastScalarCosAngle(r); 
-     t = 1.0f - c; 
-     txy = t * a->v[0] * a->v[1]; 
-     txz = t * a->v[0] * a->v[2]; 
-     tyz = t * a->v[1] * a->v[2]; 
-     sx = a->v[0] * s; 
-     sy = a->v[1] * s; 
-     sz = a->v[2] * s; 
-     mat->m[0][0] = a->v[0] * a->v[0] * t + c; 
-     mat->m[0][1] = sz + txy; 
-     mat->m[0][2] = txz - sy; 
-     mat->m[1][0] = txy - sz; 
-     mat->m[1][1] = a->v[1] * a->v[1] * t + c; 
-     mat->m[1][2] = sx + tyz; 
-     mat->m[2][0] = sy + txz; 
-     mat->m[2][1] = tyz - sx; 
-     mat->m[2][2] = a->v[2] * a->v[2] * t + c; 
- } 
-   
- // IDA: void __usercall SmokeLine(int l@<EAX>, int x@<EDX>, br_scalar zbuff, int r_squared, tU8 *scr_ptr, tU16 *depth_ptr, tU8 *shade_ptr, br_scalar r_multiplier, br_scalar z_multiplier, br_scalar shade_offset) 
- void SmokeLine(int l, int x, br_scalar zbuff, int r_squared, tU8* scr_ptr, tU16* depth_ptr, tU8* shade_ptr, br_scalar r_multiplier, br_scalar z_multiplier, br_scalar shade_offset) { 
-     int i; 
-     int offset; /* Added by dethrace. */ 
-     int r_multiplier_int; 
-     int shade_offset_int; 
-     tU16 z; 
-     LOG_TRACE("(%d, %d, %f, %d, %p, %p, %p, %f, %f, %f)", l, x, zbuff, r_squared, scr_ptr, depth_ptr, shade_ptr, r_multiplier, z_multiplier, shade_offset); 
-   
-     scr_ptr += gOffset; 
-     if (gProgram_state.cockpit_on) { 
-         depth_ptr += gOffset; 
-     } 
-     z = (1.f - zbuff) * 32768.0f; 
-     r_multiplier_int = r_multiplier * 65536.0f; 
-     shade_offset_int = shade_offset * 65536.0f; 
-   
-     for (i = 0; i < l; i++) { 
-         if (*depth_ptr > z) { 
-             offset = ((shade_offset_int - r_squared * r_multiplier_int) >> 8) & 0xffffff00; 
- #if defined(DETHRACE_FIX_BUGS) 
-             /* Prevent buffer underflows by capping negative offsets. */ 
-             offset = MAX(0, offset); 
- #endif 
-             *scr_ptr = shade_ptr[*scr_ptr + offset]; 
-         } 
-         r_multiplier = x + r_squared; 
-         scr_ptr++; 
-         x++; 
-         depth_ptr++; 
-         r_squared = x + r_multiplier; 
-     } 
- } 
-   
- // IDA: void __usercall SmokeCircle(br_vector3 *o@<EAX>, br_scalar r, br_scalar extra_z, br_scalar strength, br_scalar pAspect, br_pixelmap *pRender_screen, br_pixelmap *pDepth_buffer, br_pixelmap *pShade_table) 
- void SmokeCircle(br_vector3* o, br_scalar r, br_scalar extra_z, br_scalar strength, br_scalar pAspect, br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_pixelmap* pShade_table) { 
-     tU8* scr_ptr; 
-     tU16* depth_ptr; 
-     tU8* shade_ptr; 
-     tU8* osp; 
-     tU16* odp; 
-     int ox; 
-     int oy; 
-     //int i; // Pierre-Marie Baty -- unused variable 
-     int r_squared; 
-     int max_r_squared; 
-     int l; 
-     int l2; 
-     int x; 
-     int x2; 
-     //int sx; // Pierre-Marie Baty -- unused variable 
-     int y; 
-     int inc; 
-     int y_limit; 
-     int max_x; 
-     int min_x; 
-     br_scalar shade_offset; 
-     br_scalar r_multiplier; 
-     br_scalar ry; 
-     br_scalar z_multiplier; 
-     br_scalar zbuff; 
-     br_scalar aspect_squared; 
-     void (*line)(int, int, br_scalar, int, tU8*, tU16*, tU8*, br_scalar, br_scalar, br_scalar); 
-     LOG_TRACE("(%p, %f, %f, %f, %f, %p, %p, %p)", o, r, extra_z, strength, pAspect, pRender_screen, pDepth_buffer, pShade_table); 
-   
-     line = SmokeLine; 
-     ox = pRender_screen->width / 2 + o->v[0]; 
-     oy = pRender_screen->height / 2 + o->v[1]; 
-     max_r_squared = r * r; 
-     zbuff = o->v[2]; 
-     aspect_squared = pAspect * pAspect; 
-     if (pRender_screen->width / 4 <= r 
-         || pRender_screen->width <= ox - r 
-         || ox + r < 0.0f) { 
-         return; 
-     } 
-     shade_ptr = (tU8*)pShade_table->pixels + pShade_table->row_bytes * (pShade_table->base_y + 1); 
-     shade_offset = strength * 14.99f; 
-     r_multiplier = shade_offset / (double)max_r_squared; 
-     z_multiplier = extra_z / (double)max_r_squared; 
-     max_x = pRender_screen->width - ox - 1; 
-     min_x = -ox; 
-     ry = r / pAspect; 
-     l = pRender_screen->height - oy - 1; 
-     scr_ptr = pRender_screen->pixels; 
-     scr_ptr += pRender_screen->base_x + pRender_screen->base_y * pRender_screen->row_bytes + ox + l * pRender_screen->row_bytes; 
-     depth_ptr = (tU16*)pDepth_buffer->pixels + ox + l * (pDepth_buffer->row_bytes / 2); 
-     osp = scr_ptr; 
-     odp = depth_ptr; 
-     if (pRender_screen->height > oy && oy + ry >= 0.0) { 
-         r_squared = r * r; 
-         inc = -r; 
-         y = 0; 
-         y_limit = ry; 
-         if (oy < 0) { 
-             y = -oy; 
-             r_squared = (y * y) * aspect_squared; 
-             scr_ptr += oy * pRender_screen->row_bytes; 
-             depth_ptr += oy * (pDepth_buffer->row_bytes / 2); 
-             inc = -sqrtf(max_r_squared - r_squared); 
-             r_squared += inc * inc; 
-         } 
-         if (pRender_screen->height < oy + ry) { 
-             y_limit = pRender_screen->height - oy - 1; 
-         } 
-         l = -2 * inc; 
-         scr_ptr += inc; 
-         depth_ptr += inc; 
-         gOffset = 0; 
-         while (1) { 
-   
-             x = inc + gOffset; 
-             if (min_x <= inc + gOffset && l + x - 1 <= max_x) { 
-                 line(l, inc, zbuff, r_squared, scr_ptr, depth_ptr, shade_ptr, r_multiplier, z_multiplier, shade_offset); 
-             } else { 
-                 if (max_x < x || l + x < min_x) { 
-                     break; 
-                 } 
-                 x2 = l; 
-                 if (l + x - 1 - max_x > 0) { 
-                     x2 = max_x - (x - 1); 
-                 } 
-                 if (min_x - x <= 0) { 
-                     line(x2, inc, zbuff, r_squared, scr_ptr, depth_ptr, shade_ptr, r_multiplier, z_multiplier, shade_offset); 
-                 } else { 
-                     line(x2 - (min_x - x), min_x - x + inc, zbuff, y * y + (min_x - x + inc) * (min_x - x + inc), &scr_ptr[min_x - x], &depth_ptr[min_x - x], shade_ptr, r_multiplier, z_multiplier, shade_offset); 
-                 } 
-             } 
-             if (y_limit <= y) { 
-                 break; 
-             } 
-             y++; 
-             scr_ptr -= pRender_screen->row_bytes; 
-             depth_ptr -= pDepth_buffer->row_bytes / 2; 
-             for (r_squared += (2 * y - 1) * aspect_squared; max_r_squared < r_squared && inc < 0; r_squared += 2 * inc - 1) { 
-                 inc++; 
-                 scr_ptr++; 
-                 depth_ptr++; 
-                 l -= 2; 
-             } 
-             gOffset += IRandomBetween(-1, 1); 
-             if (gOffset > r / 5.f) { 
-                 gOffset = r / 5.f; 
-             } 
-             if (gOffset < -(r / 5.f)) { 
-                 gOffset = -(r / 5.f); 
-             } 
-         } 
-     } 
-     if (pAspect < 1.0) { 
-         aspect_squared = 9.f; 
-         ry = r / 3.f; 
-     } 
-     if (oy > 0 && oy <= pRender_screen->height + ry - 2.f) { 
-         r_squared = (r * r); 
-         inc = -r; 
-         y = 0; 
-         scr_ptr = osp; 
-         depth_ptr = odp; 
-         y_limit = ry; 
-         if (pRender_screen->height < oy) { 
-             l2 = oy - pRender_screen->height; 
-             y = pRender_screen->height - oy; 
-             r_squared = y * y * aspect_squared; 
-             scr_ptr = &osp[l2 * pRender_screen->row_bytes]; 
-             depth_ptr = &odp[l2 * (pDepth_buffer->row_bytes / 2)]; 
-             inc = -sqrtf(max_r_squared - r_squared); 
-             r_squared += inc * inc; 
-         } 
-         if (oy - ry < 0.f) { 
-             y_limit = oy; 
-         } 
-         l = -2 * inc; 
-         scr_ptr += inc; 
-         depth_ptr += inc; 
-         gOffset = 0; 
-         do { 
-             y--; 
-             scr_ptr += pRender_screen->row_bytes; 
-             depth_ptr += pDepth_buffer->row_bytes / 2; 
-             for (r_squared -= (2 * y - 1) * aspect_squared; max_r_squared < r_squared && inc < 0; r_squared += 2 * inc - 1) { 
-                 inc++; 
-                 scr_ptr++; 
-                 depth_ptr++; 
-                 l -= 2; 
-             } 
-             x = inc + gOffset; 
-             if (min_x <= inc + gOffset && l + x - 1 <= max_x) { 
-                 line(l, inc, zbuff, r_squared, scr_ptr, depth_ptr, shade_ptr, r_multiplier, z_multiplier, shade_offset); 
-             } else { 
-                 if (max_x < x || l + x < min_x) { 
-                     return; 
-                 } 
-                 x2 = l; 
-                 if (l + x - 1 - max_x > 0) { 
-                     x2 = max_x - (x - 1); 
-                 } 
-                 if (min_x - x <= 0) { 
-                     line(x2, inc, zbuff, r_squared, scr_ptr, depth_ptr, shade_ptr, r_multiplier, z_multiplier, shade_offset); 
-                 } else { 
-                     line(x2 - (min_x - x), min_x - x + inc, zbuff, y * y + (min_x - x + inc) * (min_x - x + inc), &scr_ptr[min_x - x], &depth_ptr[min_x - x], shade_ptr, r_multiplier, z_multiplier, shade_offset); 
-                 } 
-             } 
-             gOffset += IRandomBetween(-1, 1); 
-             if (gOffset > r / 5.0) { 
-                 gOffset = r / 5.0; 
-             } 
-             if (gOffset < -(r / 5.0)) { 
-                 gOffset = -r / 5.0; 
-             } 
-         } while (-y < y_limit); 
-     } 
- } 
-   
- // IDA: int __cdecl CmpSmokeZ(void *p1, void *p2) 
- int CmpSmokeZ(void* p1, void* p2) { 
-     //tBRender_smoke** a; // Pierre-Marie Baty -- unused variable 
-     //tBRender_smoke** b; // Pierre-Marie Baty -- unused variable 
-     LOG_TRACE("(%p, %p)", p1, p2); 
-     NOT_IMPLEMENTED(); 
- } 
-   
- // IDA: void __cdecl RenderRecordedSmokeCircles() 
- void RenderRecordedSmokeCircles(void) { 
-     //int i; // Pierre-Marie Baty -- unused variable 
-     //tBRender_smoke* smoke; // Pierre-Marie Baty -- unused variable 
-     //tU8 red; // Pierre-Marie Baty -- unused variable 
-     //tU8 grn; // Pierre-Marie Baty -- unused variable 
-     //tU8 blu; // Pierre-Marie Baty -- unused variable 
-     LOG_TRACE("()"); 
-     NOT_IMPLEMENTED(); 
- } 
-   
- // IDA: void __usercall RecordSmokeCircle(br_vector3 *pCent@<EAX>, br_scalar pR, br_scalar pStrength, br_pixelmap *pShade, br_scalar pAspect) 
- void RecordSmokeCircle(br_vector3* pCent, br_scalar pR, br_scalar pStrength, br_pixelmap* pShade, br_scalar pAspect) { 
-     //tU8 shade_index; // Pierre-Marie Baty -- unused variable 
-     //br_colour shade_rgb; // Pierre-Marie Baty -- unused variable 
-     LOG_TRACE("(%p, %f, %f, %p, %f)", pCent, pR, pStrength, pShade, pAspect); 
-     NOT_IMPLEMENTED(); 
- } 
-   
- // IDA: void __usercall SmokeCircle3D(br_vector3 *o@<EAX>, br_scalar r, br_scalar strength, br_scalar pAspect, br_pixelmap *pRender_screen, br_pixelmap *pDepth_buffer, br_pixelmap *pShade_table, br_actor *pCam) 
- void SmokeCircle3D(br_vector3* o, br_scalar r, br_scalar strength, br_scalar pAspect, br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_pixelmap* pShade_table, br_actor* pCam) { 
-     br_vector3 tv; 
-     br_vector3 p; 
-     br_vector4 o2; 
-     br_camera* cam; 
-     int scaled_r; 
-     br_scalar extra_z; 
-     LOG_TRACE("(%p, %f, %f, %f, %p, %p, %p, %p)", o, r, strength, pAspect, pRender_screen, pDepth_buffer, pShade_table, pCam); 
-   
-     cam = pCam->type_data; 
-     srand(- o ->- v [2] * 16777216.0f +-  o ->- v [1] * 65536.0f +-  o ->- v [0] * 256.0f +-  r );
 
-     BrVector3Sub(&tv, o, (br_vector3*)gCamera_to_world.m[3]); 
-     BrMatrix34TApplyV(&p, &tv, &gCamera_to_world); 
-   
-     if (-p.v[2] >= cam->hither_z && -p.v[2] <= cam->yon_z) { 
-         scaled_r = gCameraToScreen.m[0][0] * r / -p.v[2]; 
-         extra_z = gCameraToScreen.m[3][2] * r / (p.v[2] * p.v[2]); 
-         BrMatrix4ApplyP(&o2, &p, &gCameraToScreen); 
-         BrVector3InvScale(&p, &o2, o2.v[3]); 
-         SmokeCircle(&p, (br_scalar)scaled_r, extra_z, strength, pAspect, pRender_screen, pDepth_buffer, pShade_table); 
-     } 
- } 
-   
- // IDA: void __usercall ReplaySmoke(br_pixelmap *pRender_screen@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>) 
- void ReplaySmoke(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_actor* pCamera) { 
-     br_scalar aspect; 
-     int i; 
-     LOG_TRACE("(%p, %p, %p)", pRender_screen, pDepth_buffer, pCamera); 
-   
-     for (i = 0; i < COUNT_OF(gSmoke_column); i++) { 
-         if (gSmoke_flags & (1 << i)) { 
-             aspect = 1.f + (gSmoke[i].radius - .05f) / .25f * .5f; 
-             if (gSmoke[i].type & 0x10) { 
-                 SmokeCircle3D(&gSmoke[i].pos, gSmoke[i].radius / aspect, gSmoke[i].strength, 1.f, 
-                     pRender_screen, pDepth_buffer, gShade_list[gSmoke[i].type & 0xf], pCamera); 
-             } else { 
-                 SmokeCircle3D(&gSmoke[i].pos, gSmoke[i].radius, gSmoke[i].strength, aspect, 
-                     pRender_screen, pDepth_buffer, gShade_list[gSmoke[i].type & 0xf], pCamera); 
-             } 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall GenerateContinuousSmoke(tCar_spec *pCar@<EAX>, int wheel@<EDX>, tU32 pTime@<EBX>) 
- void GenerateContinuousSmoke(tCar_spec* pCar, int wheel, tU32 pTime) { 
-     br_vector3 pos; 
-     br_vector3 v; 
-     br_vector3 vcs; 
-     br_vector3 tv; 
-     br_scalar decay_factor; 
-     br_scalar ts; 
-     br_scalar alpha; 
-     br_scalar beta; 
-     int colour; 
-     LOG_TRACE("(%p, %d, %d)", pCar, wheel, pTime); 
-   
-     if (pCar->dust_time[wheel] > (int) pTime) { // Pierre-Marie Baty -- added type cast 
-         pCar->dust_time[wheel] -= pTime; 
-         return; 
-     } 
-     pCar->dust_time[wheel] += IRandomBetween(200, 400) - pTime; 
-     if (pCar->dust_time[wheel] < 0) { 
-         pCar->dust_time[wheel] = 0; 
-     } 
-     BrVector3Cross(&tv, &pCar->omega, &pCar->wpos[wheel]); 
-     BrVector3Scale(&vcs, &pCar->velocity_car_space, WORLD_SCALE * 1000.0f); 
-     BrVector3Accumulate(&vcs, &tv); 
-     ts = BrVector3LengthSquared(&vcs); 
-     if (ts < 25.0f) { 
-         return; 
-     } 
-     decay_factor = sqrtf(ts) / 25.0f; 
-     if (decay_factor > 1.0f) { 
-         decay_factor = 1.0f; 
-     } 
-     BrVector3InvScale(&tv, &pCar->wpos[wheel], WORLD_SCALE); 
-     tv.v[1] -= pCar->oldd[wheel] / WORLD_SCALE; 
-   
-     alpha = -1000.0f; 
-     if (vcs.v[2] > 0.0f) { 
-         alpha = (pCar->bounds[0].min.v[2] - tv.v[2]) / vcs.v[2]; 
-     } else if (vcs.v[2] < 0.0f) { 
-         alpha = (pCar->bounds[0].max.v[2] - tv.v[2]) / vcs.v[2]; 
-     } 
-   
-     beta = -1000.0f; 
-     if (vcs.v[0] > 0.0f) { 
-         beta = (pCar->bounds[0].min.v[0] - tv.v[0]) / vcs.v[0]; 
-     } else if (vcs.v[0] < 0.0f) { 
-         beta = (pCar->bounds[0].max.v[0] - tv.v[0]) / vcs.v[0]; 
-     } 
-   
-     ts = MAX(alpha, beta); 
-     BrVector3Scale(&pos, &vcs, ts); 
-     BrVector3Accumulate(&tv, &pos); 
-     BrMatrix34ApplyP(&pos, &tv, &pCar->car_master_actor->t.t.mat); 
-     BrMatrix34ApplyV(&v, &vcs, &pCar->car_master_actor->t.t.mat); 
-   
-     colour = gDust_rotate + gCurrent_race.material_modifiers[pCar->material_index[wheel]].smoke_type - 2; 
-     while (colour >= gNum_dust_tables) { 
-         colour -= gNum_dust_tables; 
-     } 
-     CreatePuffOfSmoke(&pos, &v, decay_factor, decay_factor * 2, colour + 8, pCar); 
- } 
-   
- // IDA: void __cdecl DustRotate() 
- void DustRotate(void) { 
-     LOG_TRACE("()"); 
-   
-     gDust_rotate += 1; 
-     if (gDust_rotate >= gNum_dust_tables) { 
-         gDust_rotate = 0; 
-     } 
-     NewTextHeadupSlot(4, 0, 1000, -4, "Dust colour rotated"); 
- } 
-   
- // IDA: void __usercall RenderSmoke(br_pixelmap *pRender_screen@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>, tU32 pTime) 
- void RenderSmoke(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world, tU32 pTime) { 
-     int i; 
-     int j; 
-     br_vector3 tv; 
-     br_scalar aspect; 
-     br_scalar ts; 
-     tU32 seed; 
-     tU32 not_lonely; 
-     LOG_TRACE("(%p, %p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pCamera_to_world, pTime); 
-   
-     not_lonely = 0; 
-     DrawTheGlow(pRender_screen, pDepth_buffer, pCamera); 
-   
-     if (gSmoke_flags != 0) { 
-         if (gAction_replay_mode) { 
-             ReplaySmoke(pRender_screen, pDepth_buffer, pCamera); 
-         } else { 
-             StartPipingSession(ePipe_chunk_smoke); 
-             for (i = 0; i < COUNT_OF(gSmoke); i++) { 
-                 if ((gSmoke_flags & (1u << i)) != 0) { 
-                     if (gSmoke[i].strength > 0.0) { 
-                         if (gSmoke[i].time_sync) { 
-                             BrVector3Scale(&tv, &gSmoke[i].v, gSmoke[i].time_sync / 1000.0); 
-                             gSmoke[i].time_sync = 0; 
-                         } else { 
-                             BrVector3Scale(&tv, &gSmoke[i].v, pTime / 1000.0); 
-                         } 
-                         BrVector3Accumulate(&gSmoke[i].pos, &tv); 
-                     } else { 
-                         gSmoke_flags &= ~(1u << i); 
-                     } 
-                 } 
-             } 
-             for (i = 0; i < COUNT_OF(gSmoke); i++) { 
-                 if ((gSmoke_flags & (1u << i)) != 0) { 
-                     if ((gSmoke[i].type & 0xf) == 7) { 
-                         not_lonely |= 1u << i; 
-                     } else if ((not_lonely & (1u << i)) == 0) { 
-                         for (j = i + 1; j < COUNT_OF(gSmoke); j++) { 
-                             if ((gSmoke_flags & (1u << j)) != 0) { 
-                                 BrVector3Sub(&tv, &gSmoke[i].pos, &gSmoke[i].pos); 
-                                 ts = BrVector3LengthSquared(&tv); 
-                                 if ((gSmoke[i].radius + gSmoke[j].radius) * (gSmoke[i].radius + gSmoke[j].radius) > ts) { 
-                                     not_lonely |= (1u << j) | (1u << i); 
-                                     break; 
-                                 } 
-                             } 
-                         } 
-                     } 
-                     if (((1u << i) & not_lonely) == 0) { 
-                         gSmoke[i].strength = gSmoke[i].strength / 2.0; 
-                     } 
-                     aspect = (gSmoke[i].radius - 0.05f) / 0.25f * 0.5f + 1.0f; 
-                     if ((gSmoke[i].type & 0x10) != 0) { 
-                         SmokeCircle3D(&gSmoke[i].pos, gSmoke[i].radius / aspect, gSmoke[i].strength, 1.0, pRender_screen, pDepth_buffer, gShade_list[gSmoke[i].type & 0xf], pCamera); 
-                     } else { 
-                         SmokeCircle3D(&gSmoke[i].pos, gSmoke[i].radius, gSmoke[i].strength, aspect, pRender_screen, pDepth_buffer, gShade_list[gSmoke[i].type & 0xf], pCamera); 
-                     } 
-                     if (gSmoke[i].pipe_me) { 
-                         AddSmokeToPipingSession(i, gSmoke[i].type, &gSmoke[i].pos, gSmoke[i].radius, gSmoke[i].strength); 
-                     } 
-                     gSmoke[i].radius = (double)pTime / 1000.0 * gSmoke[i].strength * 0.5 + gSmoke[i].radius; 
-                     gSmoke[i].strength = gSmoke[i].strength - (double)pTime * gSmoke[i].decay_factor / 1000.0; 
-                     if (gSmoke[i].radius > 0.3f) { 
-                         gSmoke[i].radius = 0.3f; 
-                     } 
-                     if (gSmoke[i].strength > 0.0) { 
-                         ts = 1.0f - (double)pTime * 0.002f; 
-                         if (ts < 0.5f) { 
-                             ts = 0.5f; 
-                         } 
-                         BrVector3Scale(&gSmoke[i].v, &gSmoke[i].v, ts); 
-                         if (fabs(- gSmoke [- i ]- . v- . v[1]) < 0.43478259f && (- gSmoke [- i ]- . type &-  0xFu ) < 7) {
 
-                             if (gSmoke[i].v.v[1] >= 0.0) { 
-                                 gSmoke[i].v.v[1] = 0.43478259f; 
-                             } else { 
-                                 gSmoke[i].v.v[1] += 0.43478259f; 
-                             } 
-                         } 
-                     } else { 
-                         gSmoke_flags &= ~(1u << i); 
-                     } 
-                 } 
-             } 
-             EndPipingSession(); 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall CreatePuffOfSmoke(br_vector3 *pos@<EAX>, br_vector3 *v@<EDX>, br_scalar strength, br_scalar pDecay_factor, int pType, tCar_spec *pC) 
- void CreatePuffOfSmoke(br_vector3* pos, br_vector3* v, br_scalar strength, br_scalar pDecay_factor, int pType, tCar_spec* pC) { 
-     br_vector3 tv; 
-     //int pipe_me; // Pierre-Marie Baty -- unused variable 
-     LOG_TRACE("(%p, %p, %f, %f, %d, %p)", pos, v, strength, pDecay_factor, pType, pC); 
-   
-     if (!gSmoke_on) { 
-         return; 
-     } 
-     // if we are too far away from the current car... 
-     BrVector3Sub(&tv, pos, &gProgram_state.current_car.pos); 
-     if (BrVector3LengthSquared(&tv) > 625.0) { 
-         // check the distance from the car we are viewing and if it is too far away also, just return 
-         BrVector3Sub(&tv, pos, &gCar_to_view->pos); 
-         if (&gProgram_state.current_car != gCar_to_view && BrVector3LengthSquared(&tv) > 625.0) { 
-             return; 
-         } 
-     } 
-   
-     BrVector3InvScale(&gSmoke[gSmoke_num].v, v, WORLD_SCALE); 
-     gSmoke[gSmoke_num].v.v[1] += (1.0f / WORLD_SCALE); 
-     BrVector3Copy(&gSmoke[gSmoke_num].pos, pos); 
-     gSmoke[gSmoke_num].radius = 0.05f; 
-     if ((pType & 0xF) == 7) { 
-         gSmoke[gSmoke_num].radius *= 2.0f; 
-     } else { 
-         gSmoke[gSmoke_num].pos.v[1] += (br_scalar) 0.04; // Pierre-Marie Baty -- added type cast 
-     } 
-     gSmoke[gSmoke_num].pos.v[1] += (br_scalar) 0.04; // Pierre-Marie Baty -- added type cast 
-     if (strength > 1.0) { 
-         strength = 1.0; 
-     } 
-     gSmoke[gSmoke_num].strength = strength; 
-     gSmoke_flags |= 1u << gSmoke_num; 
-     gSmoke[gSmoke_num].time_sync = gMechanics_time_sync; 
-     gSmoke[gSmoke_num].type = pType; 
-     gSmoke[gSmoke_num].decay_factor = pDecay_factor; 
-     gSmoke[gSmoke_num].pipe_me = 1; 
-     gSmoke_num++; 
-     if (gSmoke_num >= COUNT_OF(gSmoke)) { 
-         gSmoke_num = 0; 
-     } 
- } 
-   
- // IDA: void __cdecl ResetSmoke() 
- void ResetSmoke(void) { 
-     LOG_TRACE("()"); 
-   
-     gSmoke_flags = 0; 
-     ; 
- } 
-   
- // IDA: void __usercall AdjustSmoke(int pIndex@<EAX>, tU8 pType@<EDX>, br_vector3 *pPos@<EBX>, br_scalar pRadius, br_scalar pStrength) 
- void AdjustSmoke(int pIndex, tU8 pType, br_vector3* pPos, br_scalar pRadius, br_scalar pStrength) { 
-     LOG_TRACE("(%d, %d, %p, %f, %f)", pIndex, pType, pPos, pRadius, pStrength); 
-   
-     gSmoke[pIndex].type = pType; 
-     gSmoke[pIndex].radius = pRadius; 
-     gSmoke[pIndex].strength = pStrength; 
-     BrVector3Copy(&gSmoke[pIndex].pos, pPos); 
-     gSmoke_flags |= 1 << pIndex; 
- } 
-   
- // IDA: void __cdecl ActorError() 
- void ActorError(void) { 
-     LOG_TRACE("()"); 
- } 
-   
- // IDA: void __usercall AdjustSmokeColumn(int pIndex@<EAX>, tCar_spec *pCar@<EDX>, int pVertex@<EBX>, int pColour@<ECX>) 
- void AdjustSmokeColumn(int pIndex, tCar_spec* pCar, int pVertex, int pColour) { 
-     int i; 
-     //br_actor* actor; // Pierre-Marie Baty -- unused variable 
-     LOG_TRACE("(%d, %p, %d, %d)", pIndex, pCar, pVertex, pColour); 
-   
-     gColumn_flags ^= 1 << pIndex; 
-     gSmoke_column[pIndex].car = pCar; 
-     gSmoke_column[pIndex].vertex_index = pVertex; 
-     gSmoke_column[pIndex].colour = pColour; 
-     for (i = 0; i < COUNT_OF(gSmoke_column->frame_count); i++) { 
-         gSmoke_column[pIndex].frame_count[i] = 100; 
-     } 
-     if (pColour == 0) { 
-         if ((gColumn_flags & (1 << pIndex)) != 0) { 
-             if (gSmoke_column[pIndex].flame_actor->depth != 0) { 
-                 ActorError(); 
-             } 
-             BrActorAdd(gNon_track_actor, gSmoke_column[pIndex].flame_actor); 
-         } else { 
-             if (gSmoke_column[pIndex].flame_actor->depth == 0) { 
-                 ActorError(); 
-             } 
-             BrActorRemove(gSmoke_column[pIndex].flame_actor); 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall CreateSmokeColumn(tCar_spec *pCar@<EAX>, int pColour@<EDX>, int pVertex_index@<EBX>, tU32 pLifetime@<ECX>) 
- void CreateSmokeColumn(tCar_spec* pCar, int pColour, int pVertex_index, tU32 pLifetime) { 
-     int i; 
-     br_actor* actor; 
-     tSmoke_column* col; 
-     LOG_TRACE("(%p, %d, %d, %d)", pCar, pColour, pVertex_index, pLifetime); 
-   
-     col = &gSmoke_column[gNext_column]; 
-     if (pCar->last_special_volume != NULL && pCar->last_special_volume->gravity_multiplier < 1.0f) { 
-         return; 
-     } 
-     SmudgeCar(pCar, pVertex_index); 
-     if (pCar->knackered) { 
-         SmudgeCar(pCar, pCar->fire_vertex[IRandomBetween(0, 11)]); 
-     } 
-     if (!gSmoke_on) { 
-         return; 
-     } 
-     if (((1u << gNext_column) & gColumn_flags) != 0) { 
-         if (gSmoke_column[gNext_column].car != NULL) { 
-             gSmoke_column[gNext_column].car->num_smoke_columns--; 
-         } 
-         StartPipingSession(ePipe_chunk_smoke_column); 
-         AddSmokeColumnToPipingSession(gNext_column, gSmoke_column[gNext_column].car, gSmoke_column[gNext_column].vertex_index, gSmoke_column[gNext_column].colour); 
-         EndPipingSession(); 
-         if (gSmoke_column[gNext_column].colour == 0) { 
-             StartPipingSession(ePipe_chunk_flame); 
-             actor = col->flame_actor->children; 
-             for (i = 0; i < 3; i++) { 
-                 if (actor->type == BR_ACTOR_MODEL) { 
-                     AddFlameToPipingSession(i + 16 * gNext_column, col->frame_count[i], col->scale_x[i], col->scale_y[i], col->offset_x[i], col->offset_z[i]); 
-                 } 
-                 actor->type = BR_ACTOR_NONE; 
-                 actor = actor->next; 
-             } 
-             EndPipingSession(); 
-         } 
-     } 
-     if (pColour == 0 && (((1u << gNext_column) & gColumn_flags) == 0 || gSmoke_column[gNext_column].colour != 0)) { 
-         BrActorAdd(gNon_track_actor, gSmoke_column[gNext_column].flame_actor); 
-     } 
-     if (pColour != 0 && ((1u << gNext_column) & gColumn_flags) != 0 && gSmoke_column[gNext_column].colour == 0) { 
-         BrActorRemove(gSmoke_column[gNext_column].flame_actor); 
-     } 
-     StartPipingSession(ePipe_chunk_smoke_column); 
-     AddSmokeColumnToPipingSession(gNext_column, pCar, pVertex_index, pColour); 
-     EndPipingSession(); 
-     gSmoke_column[gNext_column].car = pCar; 
-     gSmoke_column[gNext_column].colour = pColour; 
-     gSmoke_column[gNext_column].lifetime = pLifetime; 
-     gSmoke_column [- gNext_column ]- . time = 0;
-     gSmoke_column[gNext_column].smudge_timer = 1000; 
-     gSmoke_column[gNext_column].vertex_index = pVertex_index; 
-     gSmoke_column[gNext_column].upright = 1; 
-     gColumn_flags |= 1u << gNext_column; 
-     pCar->num_smoke_columns++; 
-     for (i = 0; i < COUNT_OF(gSmoke_column[gNext_column].frame_count); i++) { 
-         gSmoke_column[gNext_column].frame_count[i] = 100; 
-     } 
-     gNext_column++; 
-     if (gNext_column >= MAX_SMOKE_COLUMNS) { 
-         gNext_column = 0; 
-     } 
- } 
-   
- // IDA: void __cdecl GenerateSmokeShades() 
- void GenerateSmokeShades(void) { 
-     static int rb = 0x00; 
-     static int gb = 0x00; 
-     static int bb = 0x00; 
-     static int rd = 0x40; 
-     static int gd = 0x40; 
-     static int bd = 0x40; 
-     static int rg = 0x80; 
-     static int gg = 0x80; 
-     static int bg = 0x80; 
-     LOG_TRACE("()"); 
-   
-     gBlack_smoke_shade_table = GenerateShadeTable(16, gRender_palette, rb, gb, bb, .25f, .6f, .9f); 
-     gDark_smoke_shade_table = GenerateShadeTable(16, gRender_palette, rd, gd, bd, .25f, .6f, .9f); 
-     gGrey_smoke_shade_table = GenerateShadeTable(16, gRender_palette, rg, gg, bg, .25f, .6f, .9f); 
-     gIt_shade_table = GenerateDarkenedShadeTable(16, gRender_palette, 0, 255, 254, .25f, .5f, .75f, .6f); 
-   
-     gShade_list[0] = gBlack_smoke_shade_table; 
-     gShade_list[1] = gDark_smoke_shade_table; 
-     gShade_list[2] = gGrey_smoke_shade_table; 
-     gShade_list[3] = gFog_shade_table; 
-     gShade_list[4] = gFog_shade_table; 
-     gShade_list[7] = gAcid_shade_table; 
- } 
-   
- // IDA: void __cdecl GenerateItFoxShadeTable() 
- void GenerateItFoxShadeTable(void) { 
-     LOG_TRACE("()"); 
-   
-     if (gIt_shade_table == NULL) { 
-         gIt_shade_table = GenerateDarkenedShadeTable(16, gRender_palette, 0, 255, 254, .25f, .5f, .75f, .6f); 
-     } 
- } 
-   
- // IDA: void __usercall AdjustFlame(int pIndex@<EAX>, int pFrame_count@<EDX>, br_scalar pScale_x, br_scalar pScale_y, br_scalar pOffset_x, br_scalar pOffset_z) 
- void AdjustFlame(int pIndex, int pFrame_count, br_scalar pScale_x, br_scalar pScale_y, br_scalar pOffset_x, br_scalar pOffset_z) { 
-     int i; 
-     int j; 
-     tSmoke_column* col; 
-     //br_actor* actor; // Pierre-Marie Baty -- unused variable 
-     LOG_TRACE("(%d, %d, %f, %f, %f, %f)", pIndex, pFrame_count, pScale_x, pScale_y, pOffset_x, pOffset_z); 
-   
-     i = pIndex >> 4; 
-     j = pIndex & 0xf; 
-     col = &gSmoke_column[i]; 
-     col->frame_count[j] = pFrame_count; 
-     col->scale_x[j] = pScale_x; 
-     col->scale_y[j] = pScale_y; 
-     col->offset_x[j] = pOffset_x; 
-     col->offset_z[j] = pOffset_z; 
- } 
-   
- // IDA: void __usercall ReplayFlame(tSmoke_column *col@<EAX>, br_actor *actor@<EDX>) 
- void ReplayFlame(tSmoke_column* col, br_actor* actor) { 
-     int i; 
-     LOG_TRACE("(%p, %p)", col, actor); 
-   
-     for (i = 0; i < COUNT_OF(col->frame_count); i++, actor = actor->next) { 
-         col->frame_count[i] += GetReplayRate(); 
-         if (col->frame_count[i] < 0 || col->frame_count[i] >= COUNT_OF(gFlame_map)) { 
-             actor->type = BR_ACTOR_NONE; 
-         } else { 
-             actor->type = BR_ACTOR_MODEL; 
-             actor->material->colour_map = gFlame_map[col->frame_count[i]]; 
-             BrMaterialUpdate(actor->material, BR_MATU_ALL); 
-             BrMatrix34Scale(&actor->t.t.mat, 
-                 col->scale_x[i] * gFlame_map[col->frame_count[i]]->width, 
-                 col->scale_y[i] * gFlame_map[col->frame_count[i]]->height, 
-                 1.f); 
-             actor->t.t.translate.t.v[0] = col->offset_x[i]; 
-             actor->t.t.translate.t.v[2] = col->offset_z[i]; 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall FlameAnimate(int c@<EAX>, br_vector3 *pPos@<EDX>, tU32 pTime@<EBX>) 
- void FlameAnimate(int c, br_vector3* pPos, tU32 pTime) { 
-     tSmoke_column* col; 
-     br_actor* actor; 
-     int i; 
-     LOG_TRACE("(%d, %p, %d)", c, pPos, pTime); 
-   
-     col = &gSmoke_column[c]; 
-     actor = col->flame_actor; 
-     DRMatrix34RotateY(&actor->t.t.mat, FastScalarArcTan2Angle(gCamera_to_world.m[2][0], gCamera_to_world.m[2][2])); 
-     actor->t.t.translate.t = *pPos; 
-     actor = actor->children; 
-   
-     if (gAction_replay_mode) { 
-         ReplayFlame(col, actor); 
-         return; 
-     } 
-     for (i = 0; i < COUNT_OF(col->frame_count); i++) { 
-   
- #ifdef DETHRACE_FIX_BUGS 
-         col->frame_time[i] += pTime; 
-         if (col->frame_time[i] > FLAME_ANIMATION_FRAME_INTERVAL) { 
-             col->frame_time[i] = 0; 
-             col->frame_count[i]++; 
-         } 
- #else 
-         col->frame_count[i]++; 
- #endif 
-   
-         if (col->frame_count[i] >= COUNT_OF(gFlame_map)) { 
-             StartPipingSession(ePipe_chunk_flame); 
-             AddFlameToPipingSession(i + 16 * c, col->frame_count[i] + 1, col->scale_x[i], col->scale_y[i], col->offset_x[i], col->offset_z[i]); 
-             EndPipingSession(); 
-             col->frame_count[i] = IRandomBetween(-5, -1); 
-             col->scale_x[i] = (2 * IRandomBetween(0, 1) - 1) * SRandomBetween(1.0f, 1.5f) * 0.003f; 
-             col->scale_y[i] = SRandomBetween(0.5f, 1.0f) * 0.003f; 
-             col->offset_x[i] = SRandomPosNeg(0.03f); 
-             col->offset_z[i] = SRandomBetween(-0.03f, 0.0); 
-             actor->type = BR_ACTOR_NONE; 
-         } 
-         if (col->frame_count[i] == 0) { 
-             if (BrVector3LengthSquared(&col->car->v) >= 80.0f || col->lifetime <= 30 * pTime) { 
-                 col->frame_count[i] = -5; 
-             } else { 
-                 actor->type = BR_ACTOR_MODEL; 
-                 StartPipingSession(ePipe_chunk_flame); 
-                 AddFlameToPipingSession(i + 16 * c, col->frame_count[i] - 1, col->scale_x[i], col->scale_y[i], col->offset_x[i], col->offset_z[i]); 
-                 EndPipingSession(); 
-             } 
-         } 
-         if (col->frame_count[i] >= 0) { 
-             actor->material->colour_map = gFlame_map[col->frame_count[i]]; 
-             BrMaterialUpdate(actor->material, BR_MATU_ALL); 
-             BrMatrix34Scale(&actor->t.t.mat, gFlame_map[col->frame_count[i]]->width * col->scale_x[i], gFlame_map[col->frame_count[i]]->height * col->scale_y[i], 1.0); 
-             actor->t.t.mat.m[3][0] = col->offset_x[i]; 
-             actor->t.t.mat.m[3][2] = col->offset_z[i]; 
-         } 
-         actor = actor->next; 
-     } 
- } 
-   
- // IDA: void __usercall DoSmokeColumn(int i@<EAX>, tU32 pTime@<EDX>, br_vector3 *pRet_car_pos@<EBX>) 
- void DoSmokeColumn(int i, tU32 pTime, br_vector3* pRet_car_pos) { 
-     tCar_spec* c; 
-     br_actor* actor; 
-     br_actor* bonny; 
-     //int group; // Pierre-Marie Baty -- unused variable 
-     LOG_TRACE("(%d, %d, %p)", i, pTime, pRet_car_pos); 
-   
-     c = gSmoke_column[i].car; 
-     if (c->car_master_actor->t.t.mat.m[1][1] > 0.1f) { 
-         gSmoke_column[i].upright = 1; 
-     } 
-     if (c->car_master_actor->t.t.mat.m[1][1] < -0.1f) { 
-         gSmoke_column[i].upright = 0; 
-     } 
-     actor = c->car_model_actors[c->principal_car_actor].actor; 
-     bonny = c->car_model_actors[c->car_actor_count - 1].actor; 
-   
-     BrVector3Add(pRet_car_pos, &V11MODEL(actor->model)->groups[0].position[gSmoke_column[i].vertex_index], &actor->t.t.translate.t); 
-     if (gProgram_state.cockpit_on && c->driver == eDriver_local_human) { 
-         if (c->driver_z_offset + 0.2f <= pRet_car_pos->v[2]) { 
-             pRet_car_pos->v[1] -= -0.07f; 
-         } else { 
-             BrMatrix34ApplyP(pRet_car_pos, &V11MODEL(actor->model)->groups[0].position[gSmoke_column[i].vertex_index], &bonny->t.t.mat); 
-         } 
-     } 
-     if (!gSmoke_column[i].upright) { 
-         pRet_car_pos->v[1] = c->bounds[1].min.v[1] / WORLD_SCALE; 
-     } 
-     BrMatrix34ApplyP(&gSmoke_column[i].pos, pRet_car_pos, &c->car_master_actor->t.t.mat); 
-     gSmoke_column[i].pos.v[1] -= 0.03f; 
- } 
-   
- // IDA: void __usercall ReplaySmokeColumn(tU32 pTime@<EAX>) 
- void ReplaySmokeColumn(tU32 pTime) { 
-     int i; 
-     br_vector3 dummy; 
-     LOG_TRACE("(%d)", pTime); 
-   
-     for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { 
-         if ((gColumn_flags & (1 << i)) != 0) { 
-             DoSmokeColumn(i, pTime, &dummy); 
-             if (gSmoke_column[i].colour == 0) { 
-                 FlameAnimate(i, &gSmoke_column[i].pos, pTime); 
-             } 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall MungeSmokeColumn(tU32 pTime@<EAX>) 
- void MungeSmokeColumn(tU32 pTime) { 
-     int i; 
-     int plane; 
-     //br_actor* actor; // Pierre-Marie Baty -- unused variable 
-     //br_actor* bonny; // Pierre-Marie Baty -- unused variable 
-     br_vector3 car_pos; 
-     br_vector3 pos; 
-     br_vector3 v; 
-     //br_vector3 up; // Pierre-Marie Baty -- unused variable 
-     //br_vector3 start; // Pierre-Marie Baty -- unused variable 
-     //br_vector3 end; // Pierre-Marie Baty -- unused variable 
-     //br_scalar ts; // Pierre-Marie Baty -- unused variable 
-     br_scalar decay_factor; 
-     tCar_spec* c; 
-     LOG_TRACE("(%d)", pTime); 
-   
-     if (gColumn_flags == 0) { 
-         return; 
-     } 
-     if (gAction_replay_mode) { 
-         ReplaySmokeColumn(pTime); 
-         return; 
-     } 
-   
-     gMechanics_time_sync = 1; 
-     for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { 
-         if (((1u << i) & gColumn_flags) == 0) { 
-             continue; 
-         } 
-         if (gSmoke_column[i].lifetime >= pTime) { 
-             gSmoke_column[i].lifetime -= pTime; 
-             c = gSmoke_column[i].car; 
-             DoSmokeColumn(i, pTime, &car_pos); 
-             if (gSmoke_column[i].colour == 0) { 
-                 FlameAnimate(i, &gSmoke_column[i].pos, pTime); 
-                 if (gSmoke_column[i].smudge_timer >= pTime) { 
-                     gSmoke_column[i].smudge_timer -= pTime; 
-                 } else { 
-                     gSmoke_column[i].smudge_timer += 2000; 
-                     SmudgeCar(gSmoke_column[i].car, gSmoke_column[i].vertex_index); 
-                     if (gSmoke_column[i].car->knackered) { 
-                         plane = IRandomBetween(0, COUNT_OF(gSmoke_column[i].car->fire_vertex) - 1); 
-                         SmudgeCar(gSmoke_column[i].car, gSmoke_column[i].car->fire_vertex[plane]); 
-                     } 
-                 } 
-             } 
-             gSmoke_column [- i ]- . time +=-  pTime ;
-             if (- gSmoke_column [- i ]- . time > 200) {
 
- #ifdef DETHRACE_FIX_BUGS 
-                 gSmoke_column [- i ]- . time -=-  fmaxf (- SMOKE_COLUMN_NEW_PUFF_INTERVAL ,-  pTime );
- #else 
-                 gSmoke_column [- i ]- . time -=-  pTime ;
- #endif 
-                 gSmoke_column[i].count++; 
-                 BrVector3Cross(&v, &c->omega, &car_pos); 
-                 BrMatrix34ApplyV(&car_pos, &v, &c->car_master_actor->t.t.mat); 
-                 BrVector3Add(&v, &c->v, &car_pos); 
-                 v.v[1] = v.v[1] + 2.898550724637681f; // 100 / 34.5 ? 
-                 pos.v[0] = SRandomBetween(-0.03f, 0.03f) + gSmoke_column[i].pos.v[0]; 
-                 pos.v[1] = (gSmoke_column[i].colour == 0) * 0.05f + gSmoke_column[i].pos.v[1]; 
-                 pos.v[2] = SRandomBetween(-0.03f, 0.03f) + gSmoke_column[i].pos.v[2]; 
-                 if ((gSmoke_column[i].whiter & 2) == 0 || IRandomBetween(0, 3)) { 
-                     if (gSmoke_column[i].whiter < 1) { 
-                         gSmoke_column[i].whiter = -1; 
-                     } else { 
-                         gSmoke_column[i].whiter = 2; 
-                     } 
-                 } else { 
-                     gSmoke_column[i].whiter &= 1; 
-                 } 
-                 decay_factor = ((gSmoke_column[i].whiter > 0) + 1.0f) / 2.0f; 
-                 if (gSmoke_column[i].lifetime < 4000) { 
-                     decay_factor = gSmoke_column[i].lifetime * decay_factor / 4000.0f; 
-                 } 
-                 CreatePuffOfSmoke(&pos, &v, decay_factor, decay_factor, gSmoke_column[i].colour + 16, c); 
-             } 
-         } else { 
-             if (gSmoke_column[i].car != NULL) { 
-                 StartPipingSession(ePipe_chunk_smoke_column); 
-                 AddSmokeColumnToPipingSession(i, gSmoke_column[i].car, gSmoke_column[i].vertex_index, gSmoke_column[i].colour); 
-                 EndPipingSession(); 
-             } 
-             gColumn_flags &= ~(1u << i); 
-             if (gSmoke_column[i].colour == 0) { 
-                 BrActorRemove(gSmoke_column[i].flame_actor); 
-             } 
-             if (gSmoke_column[i].car != NULL) { 
-                 if (gSmoke_column[i].car->num_smoke_columns != 0) { 
-                     gSmoke_column[i].car->num_smoke_columns--; 
-                 } 
-             } 
-         } 
-     } 
- } 
-   
- // IDA: void __cdecl DisposeFlame() 
- void DisposeFlame(void) { 
-     int i; 
-     int j; 
-     br_actor* actor; 
-     //br_material* material; // Pierre-Marie Baty -- unused variable 
-     LOG_TRACE("()"); 
-   
-     for (i = 0; i < COUNT_OF(gFlame_map); i++) { 
-         BrMapRemove(gFlame_map[i]); 
-         BrPixelmapFree(gFlame_map[i]); 
-     } 
-   
-     for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { 
-         if ((gColumn_flags & (1u << i)) && (gSmoke_column[i].colour == 0)) { 
-             BrActorRemove(gSmoke_column[i].flame_actor); 
-         } 
-         actor = gSmoke_column[i].flame_actor->children; 
-         for (j = 0; j < COUNT_OF(gSmoke_column[0].frame_count); j++) { 
-             BrMaterialRemove(actor->material); 
-             BrMaterialFree(actor->material); 
-             actor = actor->next; 
-         } 
-         BrActorFree(gSmoke_column[i].flame_actor); 
-     } 
-     BrModelRemove(gLollipop_model); 
-     BrModelFree(gLollipop_model); 
- } 
-   
- // IDA: void __cdecl InitFlame() 
- void InitFlame(void) { 
-     int i; 
-     int j; 
-     int num; 
-     char the_path[256]; 
-     br_actor* actor; 
-     br_material* material; 
-     LOG_TRACE("()"); 
-   
-     gColumn_flags = 0; 
-     gLollipop_model = BrModelAllocate("Lollipop", 4, 2); 
-     PathCat(the_path, gApplication_path, "PIXELMAP"); 
-     PathCat(the_path, the_path, "FLAMES.PIX"); 
-     num = DRPixelmapLoadMany(the_path, gFlame_map, COUNT_OF(gFlame_map)); 
-     if (num != COUNT_OF(gFlame_map)) { 
-         FatalError(kFatalError_LoadPixelmapFile_S, the_path); 
-     } 
-     BrMapAddMany(gFlame_map, COUNT_OF(gFlame_map)); 
-     for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { 
-         gSmoke_column[i].flame_actor = BrActorAllocate(BR_ACTOR_NONE, NULL); 
-         for (j = 0; j < COUNT_OF(gSmoke_column[0].frame_count); j++) { 
-             actor = BrActorAllocate(BR_ACTOR_MODEL, NULL); 
-             material = BrMaterialAllocate(NULL); 
-             BrActorAdd(gSmoke_column[i].flame_actor, actor); 
-             actor->model = gLollipop_model; 
-             actor->material = material; 
-             material->flags &= ~BR_MATF_LIGHT; 
-             material->flags |= BR_MATF_ALWAYS_VISIBLE; 
-             material->colour_map = gFlame_map[0]; 
-             BrMaterialAdd(material); 
-             gSmoke_column[i].frame_count[j] = 100; 
-         } 
-     } 
-     gLollipop_model->nvertices = 4; 
-     BrVector3SetFloat(&gLollipop_model->vertices[0].p, -.5f, 0.f, .0f); 
-     BrVector3SetFloat(&gLollipop_model->vertices[1].p, .5f, 0.f, .0f); 
-     BrVector3SetFloat(&gLollipop_model->vertices[2].p, .5f, 1.f, .0f); 
-     BrVector3SetFloat(&gLollipop_model->vertices[3].p, -.5f, 1.f, .0f); 
-     gLollipop_model->vertices[0].map.v[0] = 0.f; 
-     gLollipop_model->vertices[0].map.v[1] = 1.f; 
-     gLollipop_model->vertices[1].map.v[0] = 1.f; 
-     gLollipop_model->vertices[1].map.v[1] = 1.f; 
-     gLollipop_model->vertices[2].map.v[0] = 1.f; 
-     gLollipop_model->vertices[2].map.v[1] = 0.f; 
-     gLollipop_model->vertices[3].map.v[0] = 0.f; 
-     gLollipop_model->vertices[3].map.v[1] = 0.f; 
-   
-     gLollipop_model->nfaces = 2; 
-     gLollipop_model->faces[0].vertices[0] = 0; 
-     gLollipop_model->faces[0].vertices[1] = 1; 
-     gLollipop_model->faces[0].vertices[2] = 2; 
-     gLollipop_model->faces[1].vertices[0] = 0; 
-     gLollipop_model->faces[1].vertices[1] = 2; 
-     gLollipop_model->faces[1].vertices[2] = 3; 
-     gLollipop_model->faces[0].smoothing = 1; 
-     gLollipop_model->faces[1].smoothing = 1; 
-     BrModelAdd(gLollipop_model); 
- } 
-   
- // IDA: void __usercall InitSplash(FILE *pF@<EAX>) 
- void InitSplash(FILE* pF) { 
-     int i; 
-     int num_files; 
-     int num; 
-     br_actor* actor; 
-     char the_path[256]; 
-     char s[256]; 
-     br_pixelmap* splash_maps[20]; 
-     LOG_TRACE("(%p)", pF); 
-   
-     gSplash_flags = 0; 
-     gSplash_model = BrModelAllocate("Splash", 4, 2); 
-     if (pF != NULL) { 
-         num = GetAnInt(pF); 
-         gNum_splash_types = 0; 
-         for (i = 0; num > i; ++i) { 
-             GetAString(pF, s); 
-             PathCat(the_path, gApplication_path, "PIXELMAP"); 
-             PathCat(the_path, the_path, s); 
-             num_files = DRPixelmapLoadMany(the_path, &splash_maps[gNum_splash_types], 20 - gNum_splash_types); 
-             if (num_files == 0) { 
-                 FatalError(kFatalError_LoadPixelmapFile_S, the_path); 
-             } 
-             gNum_splash_types += num_files; 
-         } 
-     } else { 
-         PathCat(the_path, gApplication_path, "PIXELMAP"); 
-         PathCat(the_path, the_path, "SPLSHBLU.PIX"); 
-         gNum_splash_types = DRPixelmapLoadMany(the_path, splash_maps, 0x14u); 
-     } 
-     BrMapAddMany(splash_maps, gNum_splash_types); 
-     for (i = 0; i < gNum_splash_types; ++i) { 
-         gSplash_material[i] = BrMaterialAllocate(0); 
-         gSplash_material[i]->flags &= ~(BR_MATF_LIGHT | BR_MATF_PRELIT); 
-         gSplash_material[i]->flags |= BR_MATF_ALWAYS_VISIBLE | BR_MATF_PERSPECTIVE; 
-         gSplash_material[i]->index_blend = LoadSingleShadeTable(&gTrack_storage_space, "BLEND50.TAB"); 
-         gSplash_material[i]->colour_map = splash_maps[i]; 
-         BrMaterialAdd(gSplash_material[i]); 
-     } 
-     gSplash_model->nvertices = 4; 
-     BrVector3SetFloat(&gSplash_model->vertices[0].p, -0.5f, 0.0f, 0.0f); 
-     BrVector3SetFloat(&gSplash_model->vertices[1].p, 0.5f, 0.0f, 0.0f); 
-     BrVector3SetFloat(&gSplash_model->vertices[2].p, 0.5f, 1.0f, 0.0f); 
-     BrVector3SetFloat(&gSplash_model->vertices[3].p, -0.5f, 1.0f, 0.0f); 
-     gSplash_model->vertices[0].map.v[0] = 0.0f; 
-     gSplash_model->vertices[0].map.v[1] = 1.0f; 
-     gSplash_model->vertices[1].map.v[0] = 1.0f; 
-     gSplash_model->vertices[1].map.v[1] = 1.0f; 
-     gSplash_model->vertices[2].map.v[0] = 1.0f; 
-     gSplash_model->vertices[2].map.v[1] = 0.0f; 
-     gSplash_model->vertices[3].map.v[0] = 0.0f; 
-     gSplash_model->vertices[3].map.v[1] = 0.0f; 
-     gSplash_model->nfaces = 2; 
-     gSplash_model->faces[0].vertices[0] = 0; 
-     gSplash_model->faces[0].vertices[1] = 1; 
-     gSplash_model->faces[0].vertices[2] = 2; 
-     gSplash_model->faces[1].vertices[0] = 0; 
-     gSplash_model->faces[1].vertices[1] = 2; 
-     gSplash_model->faces[1].vertices[2] = 3; 
-     gSplash_model->faces[0].smoothing = 1; 
-     gSplash_model->faces[1].smoothing = 1; 
-     BrModelAdd(gSplash_model); 
-     for (i = 0; i < COUNT_OF(gSplash); i++) { 
-         gSplash[i].actor = BrActorAllocate(BR_ACTOR_MODEL, NULL); 
-         actor = gSplash[i].actor; 
-         actor->model = gSplash_model; 
-         if (gNum_splash_types != 0) { 
-             actor->material = gSplash_material[IRandomBetween(0, gNum_splash_types - 1)]; 
-         } else { 
-             actor->material = NULL; 
-         } 
-         gSplash[i].scale_x = SRandomBetween(0.9f, 1.1f) * (2 * IRandomBetween(0, 1) - 1); 
-     } 
- } 
-   
- // IDA: void __cdecl DisposeSplash() 
- void DisposeSplash(void) { 
-     int i; 
-     LOG_TRACE("()"); 
-   
-     for (i = 0; i < gNum_splash_types; i++) { 
-         BrMapRemove(gSplash_material[i]->colour_map); 
-         BrPixelmapFree(gSplash_material[i]->colour_map); 
-         BrMaterialRemove(gSplash_material[i]); 
-         BrMaterialFree(gSplash_material[i]); 
-     } 
-     for (i = 0; i < COUNT_OF(gSplash); i++) { 
-         if (gSplash_flags & (1u << i)) { 
-             BrActorRemove(gSplash[i].actor); 
-         } 
-         BrActorFree(gSplash[i].actor); 
-     } 
-     BrModelRemove(gSplash_model); 
-     BrModelFree(gSplash_model); 
- } 
-   
- // IDA: void __usercall DrawTheGlow(br_pixelmap *pRender_screen@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>) 
- void DrawTheGlow(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_actor* pCamera) { 
-     int i; 
-     br_scalar strength; 
-     br_vector3 tv; 
-     tU32 seed; 
-     LOG_TRACE("(%p, %p, %p)", pRender_screen, pDepth_buffer, pCamera); 
-   
-     if (gColumn_flags) { 
-         for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { 
-             if (((1u << i) & gColumn_flags) != 0 && gSmoke_column[i].colour <= 1) { 
-                 strength = 0.5f; 
-                 if (gSmoke_column[i].lifetime < 4000) { 
-                     strength = gSmoke_column[i].lifetime * 0.5f / 4000.f; 
-                 } 
-                 BrVector3Set(&tv, gSmoke_column[i].pos.v[0], gSmoke_column[i].pos.v[1] + 0.02f, gSmoke_column[i].pos.v[2]); 
-                 SmokeCircle3D(&tv, 0.07f, strength, SRandomBetween(0.5f, 0.99f), pRender_screen, pDepth_buffer, gAcid_shade_table, pCamera); 
-             } 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall PipeInstantUnSmudge(tCar_spec *pCar@<EAX>) 
- void PipeInstantUnSmudge(tCar_spec* pCar) { 
-     br_model* model; 
-     br_model* b_model; 
-     br_actor* actor; 
-     br_actor* bonny; 
-     int j; 
-     int n; 
-     int v; 
-     int group; 
-     tSmudged_vertex data[1000]; 
-     LOG_TRACE("(%p)", pCar); 
-   
-     if (!gAction_replay_mode) { 
-         return; 
-     } 
-     actor = pCar->car_model_actors[pCar->principal_car_actor].actor; 
-     model = actor->model; 
-     bonny = pCar->car_model_actors[pCar->car_actor_count - 1].actor; 
-     n = 0; 
-     if ((model->flags & BR_MODF_KEEP_ORIGINAL) != 0 || (model->flags & BR_MODF_UPDATEABLE) != 0) { 
-         StartPipingSession(ePipe_chunk_smudge); 
-         j = 0; 
-         for (group = 0; group < V11MODEL(model)->ngroups; group++) { 
-             for (v = 0; v < V11MODEL(model)->groups[group].nvertices; v++) { 
-                 if ((V11MODEL(model)->groups[group].vertex_colours[v] >> 24) != 0) { 
-                     data[n].vertex_index = j; 
-                     data[n].light_index = 0 -(V11MODEL(model)->groups[group].vertex_colours[v] >> 24); // Pierre-Marie Baty -- prefixed 0 to silence signedness warning 
-                     n += 1; 
-                     V11MODEL(model)->groups[group].vertex_colours[v] = 0; 
-                     if ((model->flags & 0x80) != 0) { 
-                         model->vertices[V11MODEL(model)->groups[group].vertex_user[v]].index = 0; 
-                     } 
-                     if (n >= COUNT_OF(data)) { 
-                         group = V11MODEL(model)->ngroups; 
-                         break; 
-                     } 
-                 } 
-                 j += 1; 
-             } 
-         } 
-         if (n != 0) { 
-             AddSmudgeToPipingSession(pCar->car_ID, pCar->principal_car_actor, n, data); 
-         } 
-         if (bonny != actor) { 
-             b_model = bonny->model; 
-             n = 0; 
-             j = 0; 
-             for (group = 0; group < V11MODEL(model)->ngroups; group++) { 
-                 for (v = 0; v < V11MODEL(model)->groups[group].nvertices; v++) { 
-                     if ((V11MODEL(model)->groups[group].vertex_colours[v] >> 24) != 0) { 
-                         data[n].vertex_index = j; 
-                         data[n].light_index = -V11MODEL(model)->groups[group].nvertices; 
-                         n += 1; 
-                         V11MODEL(model)->groups[group].vertex_colours[v] = 0; 
-                         if ((b_model->flags & BR_MODF_UPDATEABLE) != 0) { 
-                             b_model->vertices[V11MODEL(model)->groups[group].vertex_user[v]].index = 0; 
-                         } 
-                         if (n >= COUNT_OF(data)) { 
-                             group = V11MODEL(model)->groups[group].nvertices; 
-                             break; 
-                         } 
-                     } 
-                     j += 1; 
-                 } 
-             } 
-             if (n != 0) { 
-                 AddSmudgeToPipingSession(pCar->car_ID, pCar->car_actor_count - 1, n, data); 
-             } 
-         } 
-         EndPipingSession(); 
-     } 
- } 
-   
- // IDA: void __usercall SmudgeCar(tCar_spec *pCar@<EAX>, int fire_point@<EDX>) 
- void SmudgeCar(tCar_spec* pCar, int fire_point) { 
-     int v; 
-     int j; 
-     int real_vertex_number; 
-     br_model* model; 
-     br_model* b_model; 
-     br_actor* actor; 
-     br_actor* bonny; 
-     br_scalar ts; 
-     br_vector3 tv; 
-     br_vector3 bonny_pos; 
-     int group; 
-     br_vector3 point; 
-     tSmudged_vertex data[30]; 
-     int n; 
-     LOG_TRACE("(%p, %d)", pCar, fire_point); 
-   
-     if (gAusterity_mode) { 
-         return; 
-     } 
-   
-     v = fire_point; 
-     group = 0; 
-     actor = pCar->car_model_actors[pCar->principal_car_actor].actor; 
-     model = actor->model; 
-     bonny = pCar->car_model_actors[pCar->car_actor_count - 1].actor; 
-     n = 0; 
-     real_vertex_number = 0; 
-     if ((model->flags & BR_MODF_KEEP_ORIGINAL) != 0 || (model->flags & BR_MODF_UPDATEABLE) != 0) { 
-         point = V11MODEL(model)->groups[group].position[fire_point]; 
-         StartPipingSession(ePipe_chunk_smudge); 
-         for (group = 0; group < V11MODEL(model)->ngroups; group++) { 
-             for (j = 0; j < V11MODEL(model)->groups[group].nvertices; j++) { 
-                 BrVector3Sub(&tv, &V11MODEL(model)->groups[group].position[j], &point); 
-                 ts = (.0144f - BrVector3LengthSquared(&tv) / SRandomBetween(.5f, 1.f)) / .0144f * 127.f; 
-                 if (ts > 0.f) { 
-                     ts += BR_ALPHA(V11MODEL(model)->groups[group].vertex_colours[j]); 
-                     if (ts > 255.f) { 
-                         ts = 255.f; 
-                     } 
-                     if (BR_ALPHA(V11MODEL(model)->groups[group].vertex_colours[j]) != (int)ts) { 
-                         data[n].vertex_index = real_vertex_number; 
-                         data[n].light_index = (int)ts - BR_ALPHA(V11MODEL(model)->groups[group].vertex_colours[j]); 
-                         V11MODEL(model)->groups[group].vertex_colours[j] = (int)ts << 24; 
-                         if ((model->flags & BR_MODF_UPDATEABLE) != 0) { 
-                             model->vertices[V11MODEL(model)->groups[group].vertex_user[j]].index = (int)ts; 
-                         } 
-                         n++; 
-                         if (n >= COUNT_OF(data)) { 
-                             break; 
-                         } 
-                     } 
-                 } 
-                 real_vertex_number++; 
-             } 
-             if (n >= COUNT_OF(data)) { 
-                 break; 
-             } 
-         } 
-         if (n > 0) { 
-             AddSmudgeToPipingSession(pCar->car_ID, pCar->principal_car_actor, n, data); 
-             // FIXME? 
-             // Added by dethrace to update gpu-buffered vertices 
-             // model->flags |= BR_MODF_DETHRACE_FORCE_BUFFER_UPDATE; 
-         } 
-   
-         n = 0; 
-         real_vertex_number = 0; 
-         if (actor != bonny) { 
-             b_model = bonny->model; 
-             BrVector3Add(&tv, &actor->t.t.translate.t, &point); 
-             BrVector3Accumulate(&tv, &bonny->t.t.translate.t); 
-             BrMatrix34TApplyV(&bonny_pos, &tv, &bonny->t.t.mat); 
-             for (group = 0; group < V11MODEL(b_model)->ngroups; group++) { 
-                 j = 0; 
-                 for (j = 0; j < V11MODEL(b_model)->groups[group].nvertices; j++) { 
-                     BrVector3Sub(&tv, &V11MODEL(b_model)->groups[group].position[j], &bonny_pos); 
-                     ts = (.0144f - BrVector3LengthSquared(&tv) / SRandomBetween(.5f, 1.f)) / .0144f * 127.f; 
-                     if (ts > 0.f) { 
-                         ts += BR_ALPHA(V11MODEL(b_model)->groups[group].vertex_colours[j]); 
-                         if (ts > 255.f) { 
-                             ts = 255.f; 
-                         } 
-                         if (BR_ALPHA(V11MODEL(b_model)->groups[group].vertex_colours[j]) != (int)ts) { 
-                             data[n].vertex_index = real_vertex_number; 
-                             data[n].light_index = (int)ts - BR_ALPHA(V11MODEL(b_model)->groups[group].vertex_colours[j]); 
-                             V11MODEL(b_model)->groups[group].vertex_colours[j] = (int)ts << 24; 
-                             if ((b_model->flags & BR_MODF_UPDATEABLE) != 0) { 
-                                 b_model->vertices[V11MODEL(b_model)->groups[group].vertex_user[j]].index = (int)ts; 
-                             } 
-                             n++; 
-                             if (n >= COUNT_OF(data)) { 
-                                 break; 
-                             } 
-                         } 
-                     } 
-                     real_vertex_number++; 
-                 } 
-                 if (n >= COUNT_OF(data)) { 
-                     break; 
-                 } 
-             } 
-             if (n > 0) { 
-                 AddSmudgeToPipingSession(pCar->car_ID, pCar->car_actor_count - 1, n, data); 
-                 // FIXME? 
-                 // Added by dethrace to update gpu-buffered vertices 
-                 // b_model->flags |= BR_MODF_DETHRACE_FORCE_BUFFER_UPDATE; 
-             } 
-         } 
-         EndPipingSession(); 
-     } 
- } 
-   
- // IDA: void __cdecl ResetSmokeColumns() 
- void ResetSmokeColumns(void) { 
-     int i; 
-     LOG_TRACE("()"); 
-   
-     for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { 
-         if (gColumn_flags & (1 << i)) { 
-             BrActorRemove(gSmoke_column[i].flame_actor); 
-         } 
-     } 
-     gColumn_flags = 0; 
- } 
-   
- // IDA: void __usercall SetSmokeOn(int pSmoke_on@<EAX>) 
- void SetSmokeOn(int pSmoke_on) { 
-     LOG_TRACE("(%d)", pSmoke_on); 
-   
-     gSmoke_on = pSmoke_on; 
- } 
-   
- // IDA: void __usercall ReallySetSmokeOn(int pSmoke_on@<EAX>) 
- void ReallySetSmokeOn(int pSmoke_on) { 
-     LOG_TRACE("(%d)", pSmoke_on); 
-   
-     ResetSmoke(); 
-     ResetSmokeColumns(); 
- } 
-   
- // IDA: void __usercall SetSmoke(int pSmoke_on@<EAX>) 
- void SetSmoke(int pSmoke_on) { 
-     LOG_TRACE("(%d)", pSmoke_on); 
-   
-     ReallySetSmokeOn(pSmoke_on); 
-     SetSmokeOn(pSmoke_on); 
- } 
-   
- // IDA: int __cdecl GetSmokeOn() 
- int GetSmokeOn(void) { 
-     LOG_TRACE("()"); 
-   
-     return gSmoke_on; 
- } 
-   
- // IDA: void __usercall StopCarSmoking(tCar_spec *pCar@<EAX>) 
- void StopCarSmoking(tCar_spec* pCar) { 
-     int i; 
-     LOG_TRACE("(%p)", pCar); 
-   
-     for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { 
-         if (gSmoke_column[i].car == pCar && gSmoke_column[i].lifetime > 2000) { 
-             gSmoke_column[i].lifetime = 2000; 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall StopCarSmokingInstantly(tCar_spec *pCar@<EAX>) 
- void StopCarSmokingInstantly(tCar_spec* pCar) { 
-     int i; 
-     LOG_TRACE("(%p)", pCar); 
-   
-     for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { 
-         if (gSmoke_column[i].car == pCar) { 
-             gSmoke_column[i].lifetime = 0; 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall ConditionalSmokeColumn(tCar_spec *pCar@<EAX>, int pDamage_index@<EDX>, int pColour@<EBX>) 
- void ConditionalSmokeColumn(tCar_spec* pCar, int pDamage_index, int pColour) { 
-     int i; 
-     LOG_TRACE("(%p, %d, %d)", pCar, pDamage_index, pColour); 
-   
-     if (!pColour) { 
-         pColour = pCar->driver < eDriver_net_human; 
-     } 
-     if (pCar->num_smoke_columns != 0) { 
-         for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { 
-             if (gSmoke_column[i].car == pCar) { 
-                 if (((1u << i) & gColumn_flags) != 0 && gSmoke_column[i].colour <= pColour && gSmoke_column[i].lifetime) { 
-                     return; 
-                 } 
-                 gSmoke_column[i].lifetime = 2000; 
-             } 
-         } 
-     } 
-     CreateSmokeColumn(pCar, pColour, pCar->fire_vertex[pDamage_index], 10000000u); 
- } 
-   
- // IDA: void __usercall SingleSplash(tCar_spec *pCar@<EAX>, br_vector3 *sp@<EDX>, br_vector3 *normal@<EBX>, tU32 pTime@<ECX>) 
- void SingleSplash(tCar_spec* pCar, br_vector3* sp, br_vector3* normal, tU32 pTime) { 
-     br_matrix34* mat; 
-     br_matrix34* c_mat; 
-     br_vector3 tv; 
-     br_vector3 vel; 
-     br_scalar size; 
-     br_scalar speed; 
-     br_scalar ts; 
-     LOG_TRACE("(%p, %p, %p, %d)", pCar, sp, normal, pTime); 
-   
-     mat = &gSplash[gNext_splash].actor->t.t.mat; 
-     c_mat = &pCar->car_master_actor->t.t.mat; 
-     BrMatrix34ApplyP(&gSplash[gNext_splash].actor->t.t.euler.t, sp, c_mat); 
-     tv.v[0] = sp->v[2] * pCar->omega.v[1] - pCar->omega.v[2] * sp->v[1]; 
-     tv.v[1] = pCar->omega.v[2] * sp->v[0] - sp->v[2] * pCar->omega.v[0]; 
-     tv.v[2] = sp->v[1] * pCar->omega.v[0] - pCar->omega.v[1] * sp->v[0]; 
-     BrMatrix34ApplyV(&vel, &tv, c_mat); 
-     BrVector3Accumulate(&vel, &pCar->v); 
-     ts = BrVector3Length(&vel); 
-     size  = (fabs(- BrVector3Dot (- normal , &- vel )) * 5.0 +-  ts ) / 150.0 + 0.047826085;
-     if (size > 0.5) { 
-         size = 0.5; 
-     } 
-     if (BrVector3Dot(&pCar->velocity_car_space, sp) < 0.0) { 
-         size = size / 2.0; 
-     } 
-   
-     gSplash[gNext_splash].size = SRandomBetween(size / 2.0, size); 
-     if (((1u << gNext_splash) & gSplash_flags) == 0) { 
-         BrActorAdd(gDont_render_actor, gSplash[gNext_splash].actor); 
-     } 
-     gSplash_flags |= 1u << gNext_splash; 
-     gSplash[gNext_splash].just_done = 1; 
-     if ((double)pTime * 0.003 > SRandomBetween(0.0, 1.0) && !gAction_replay_mode) { 
-         BrVector3InvScale(&vel, &vel, WORLD_SCALE); 
-         BrVector3Scale(&tv, &vel, 0.1f); 
-         speed  = sqrt(- ts  / 70.0) * 15.0;
-         if (speed > 15.0f) { 
-             speed = 15.0f; 
-         } 
-         tv.v[1] += SRandomBetween(5.0, speed) / WORLD_SCALE; 
-         BrMatrix34TApplyV(&vel, &tv, &pCar->car_master_actor->t.t.mat); 
-   
-         BrVector3Cross(&tv, &vel, &pCar->water_normal); 
-         BrVector3Scale(&tv, &tv, 0.5f); 
-         if (BrVector3Dot(sp, &tv) <= 0.0) { 
-             BrVector3Sub(&vel, &vel, &tv); 
-         } else { 
-             BrVector3Accumulate(&vel, &tv); 
-         } 
-         CreateSingleSpark(pCar, sp, &vel); 
-     } 
-     gNext_splash++; 
-     if (gNext_splash >= COUNT_OF(gSplash)) { 
-         gNext_splash = 0; 
-     } 
- } 
-   
- // IDA: void __usercall CreateSplash(tCar_spec *pCar@<EAX>, tU32 pTime@<EDX>) 
- void CreateSplash(tCar_spec* pCar, tU32 pTime) { 
-     br_vector3 normal_car_space; 
-     br_vector3 pos2; 
-     br_vector3 v_plane; 
-     br_vector3 p; 
-     br_vector3 tv; 
-     br_vector3 tv2; 
-     br_vector3 cm; 
-     int i; 
-     int j; 
-     int mask; 
-     int axis1; 
-     int axis2; 
-     int axis3; 
-     //br_bounds bnds; // Pierre-Marie Baty -- unused variable 
-     br_scalar min; 
-     br_scalar max; 
-     br_scalar d; 
-     //br_scalar d2; // Pierre-Marie Baty -- unused variable 
-     br_scalar dist; 
-     br_scalar dist2; 
-     br_scalar ts; 
-     br_vector3 back_point[2]; 
-     br_scalar back_val[2]; 
-     LOG_TRACE("(%p, %d)", pCar, pTime); 
-   
-     back_val[0] = 0.0; 
-     back_val[1] = 0.0; 
- #ifdef DETHRACE_FIX_BUGS 
-     BrVector3Set(&p, 0.f, 0.f, 0.f); 
- #endif 
-     if (pCar->v.v[2] * pCar->v.v[2] + pCar->v.v[1] * pCar->v.v[1] + pCar->v.v[0] * pCar->v.v[0] >= 1.0) { 
-         BrMatrix34TApplyV(&normal_car_space, &pCar->water_normal, &pCar->car_master_actor->t.t.mat); 
-         BrMatrix34ApplyP(&tv, &pCar->bounds[0].min, &pCar->car_master_actor->t.t.mat); 
-         min = BrVector3Dot(&pCar->water_normal, &tv) - pCar->water_d; 
-         max = min; 
-         for (i = 0; i < 3; ++i) { 
-             if (normal_car_space.v[i] <= 0.0) { 
-                 max = (pCar->bounds[0].max.v[i] - pCar->bounds[0].min.v[i]) * normal_car_space.v[i] + max; 
-             } else { 
-                 min = (pCar->bounds[0].max.v[i] - pCar->bounds[0].min.v[i]) * normal_car_space.v[i] + min; 
-             } 
-         } 
-         if (min * max <= 0.0) { 
-             BrVector3InvScale(&back_point[0], &pCar->bounds[1].min, WORLD_SCALE); 
-             BrVector3InvScale(&back_point[1], &pCar->bounds[1].max, WORLD_SCALE); 
-             back_point[0].v[1] = (br_scalar) 0.01; // Pierre-Marie Baty -- added type cast 
-             ts = BrVector3Dot(&pCar->velocity_car_space, &normal_car_space); 
-             BrVector3Scale(&tv, &normal_car_space, ts); 
-             BrVector3Sub(&v_plane, &pCar->velocity_car_space, &tv); 
-             d = pCar->water_d 
-                 - (pCar->car_master_actor->t.t.mat.m[3][1] * pCar->water_normal.v[1] 
-                     + pCar->car_master_actor->t.t.mat.m[3][2] * pCar->water_normal.v[2] 
-                     + pCar->car_master_actor->t.t.mat.m[3][0] * pCar->water_normal.v[0]); 
-             mask = IRandomBetween(0, 3); 
-             axis2 = 2; 
-             for (axis1 = 0; axis1 < 3; ++axis1) { 
-                 axis3 = 3 - axis1 - axis2; 
-                 for (j = 0; j < 4; ++j) { 
-                     i = j ^ mask; 
-                     if (((j ^ mask) & 1) != 0) { 
-                         tv2.v[axis3] = back_point[0].v[axis3]; 
-                     } else { 
-                         tv2.v[axis3] = back_point[1].v[axis3]; 
-                     } 
-                     if (((j ^ mask) & 1) != 0) { 
-                         tv2.v[axis2] = back_point[0].v[axis2]; 
-                     } else { 
-                         tv2.v[axis2] = back_point[1].v[axis2]; 
-                     } 
-   
-                     ts = d - tv2.v[axis3] * normal_car_space.v[axis3] - tv2.v[axis2] * normal_car_space.v[axis2]; 
-                     ts = ts / normal_car_space.v[axis1]; 
-                     if (ts >= back_point[0].v[axis1] && back_point[1].v[axis1] >= ts) { 
-                         tv2.v[axis1] = ts; 
-                         ts = BrVector3Dot(&pCar->velocity_car_space, &tv2); 
-                         if (ts >= back_val[0]) { 
-                             if (back_val[1] <= ts) { 
-                                 SingleSplash(pCar, &tv2, &normal_car_space, pTime); 
-                             } else { 
-                                 if (back_val[1] < 0.0) { 
-                                     SingleSplash(pCar, &pos2, &normal_car_space, pTime); 
-                                 } 
-                                 back_val[1] = ts; 
-                                 pos2 = tv2; 
-                             } 
-                         } else { 
-                             if (back_val[1] < 0.0) { 
-                                 SingleSplash(pCar, &pos2, &normal_car_space, pTime); 
-                             } 
-                             back_val[1] = back_val[0]; 
-                             back_val[0] = ts; 
-                             pos2 = p; 
-                             p = tv2; 
-                         } 
-                     } 
-                 } 
-                 axis2 = axis1; 
-             } 
-             if (back_val[1] >= 0.0) { 
-                 if (back_val[0] < 0.0) { 
-                     SingleSplash(pCar, &p, &normal_car_space, pTime); 
-                 } 
-             } else { 
-                 tv.v[0] = pos2.v[0] - p.v[0]; 
-                 tv.v[1] = pos2.v[1] - p.v[1]; 
-                 tv.v[2] = pos2.v[2] - p.v[2]; 
-                 BrVector3Sub(&tv, &pos2, &p); 
-                 ts = SRandomBetween((br_scalar) 0.4, (br_scalar) 0.6); // Pierre-Marie Baty -- added type casts 
-                 BrVector3Scale(&tv2, &tv, ts); 
-                 BrVector3Accumulate(&tv2, &p); 
-                 ts = SRandomBetween((br_scalar) 0.2, (br_scalar) 0.3); // Pierre-Marie Baty -- added type casts 
-                 BrVector3Scale(&cm, &tv, ts); 
-                 BrVector3Accumulate(&p, &cm); 
-                 ts = -SRandomBetween((br_scalar) 0.2, (br_scalar) 0.3); // Pierre-Marie Baty -- added type casts 
-                 BrVector3Scale(&cm, &tv, ts); 
-                 BrVector3Accumulate(&pos2, &cm); 
-                 ts = BrVector3Dot(&pCar->velocity_car_space, &normal_car_space); 
-                 BrVector3Scale(&tv, &normal_car_space, -ts); 
-                 BrVector3Add(&v_plane, &pCar->velocity_car_space, &tv); 
-                 BrVector3Normalise(&tv, &v_plane); 
-                 BrVector3Scale(&tv, &tv, -0.028985508f); 
-                 BrVector3Accumulate(&tv2, &tv); 
-                 BrVector3Scale(&tv, &tv, 0.5f); 
-                 BrVector3Accumulate(&p, &tv); 
-                 BrVector3Accumulate(&pos2, &tv); 
-                 SingleSplash(pCar, &tv2, &normal_car_space, pTime); 
-                 SingleSplash(pCar, &p, &normal_car_space, pTime); 
-                 SingleSplash(pCar, &pos2, &normal_car_space, pTime); 
-             } 
-             d = d * WORLD_SCALE; 
-             dist = d - BrVector3Dot(&pCar->cmpos, &normal_car_space); 
-             for (i = 0; pCar->extra_point_num > i; ++i) { 
-                 dist2 = d 
-                     - (pCar->extra_points[i].v[1] * normal_car_space.v[1] 
-                         + pCar->extra_points[i].v[2] * normal_car_space.v[2] 
-                         + pCar->extra_points[i].v[0] * normal_car_space.v[0]); 
-                 if ((dist > 0.0) != (dist2 > 0.0)) { 
-                     ts = dist / (dist - dist2); 
-                     BrVector3Sub(&tv, &pCar->extra_points[i], &pCar->cmpos); 
-                     BrVector3Scale(&tv, &tv, ts); 
-                     BrVector3Accumulate(&tv, &pCar->cmpos); 
-                     if (pCar->bounds[1].max.v[1] - 0.028985508 > tv.v[1] 
-                         || pCar->bounds[1].min.v[0] > tv.v[0] 
-                         || pCar->bounds[1].max.v[0] < tv.v[1] 
-                         || pCar->bounds[1].min.v[2] > tv.v[2] 
-                         || pCar->bounds[1].max.v[2] < tv.v[2]) { 
-                         BrVector3InvScale(&tv, &tv, WORLD_SCALE); 
-                         SingleSplash(pCar, &tv, &normal_car_space, pTime); 
-                     } 
-                 } 
-             } 
-             for (i = 0; i < 4; ++i) { 
-                 if ((i & 1) != 0) { 
-                     tv.v[0] = pCar->bounds[1].max.v[0]; 
-                 } else { 
-                     tv.v[0] = pCar->bounds[1].min.v[0]; 
-                 } 
-                 tv.v[1] = pCar->bounds[1].max.v[1]; 
-                 tv.v[2] = pCar->wpos[i].v[2]; 
-                 dist = d - BrVector3Dot(&tv, &normal_car_space); 
-                 dist2 = (pCar->bounds[1].max.v[1] - 0.01) * normal_car_space.v[1] + dist; 
-                 if ((dist > 0.0) != (dist2 > 0.0)) { 
-                     ts = dist / (dist - dist2); 
-                     tv.v[1] -= (pCar->bounds[1].max.v[1] - 0.01) * ts; 
-                     BrVector3InvScale(&tv, &tv, WORLD_SCALE); 
-                     SingleSplash(pCar, &tv, &normal_car_space, pTime); 
-                 } 
-             } 
-         } else { 
-             min = min + 1.0; 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall MungeSplash(tU32 pTime@<EAX>) 
- void MungeSplash(tU32 pTime) { 
-     int i; 
-     //br_vector3 tv; // Pierre-Marie Baty -- unused variable 
-     br_scalar dt; 
-     br_scalar ts; 
-     tCar_spec* car; 
-     tVehicle_type type; 
-     LOG_TRACE("(%d)", pTime); 
-   
-     if (gNum_splash_types == 0) { 
-         return; 
-     } 
-     if (!gAction_replay_mode || GetReplayRate() == 0.0) { 
-         if (!gAction_replay_mode) { 
-             for (i = 0; i < gNum_cars_and_non_cars; i++) { 
-                 if (gActive_car_list[i]->water_d != 10000.0 && gActive_car_list[i]->driver != eDriver_local_human) { 
-                     CreateSplash(gActive_car_list[i], pTime); 
-                 } 
-             } 
-             if (gProgram_state.current_car.water_d != 10000.0) { 
-                 CreateSplash(&gProgram_state.current_car, 100); 
-             } 
-         } 
-     } else { 
-         for (type = eVehicle_net_player; type <= eVehicle_rozzer; type++) { 
-             for (i = 0;; i++) { 
-                 if (i >= type ? GetCarCount(type) : 1) { 
-                     break; 
-                 } 
-                 if (type) { 
-                     car = GetCarSpec(type, i); 
-                 } else { 
-                     car = &gProgram_state.current_car; 
-                 } 
-                 if (car->water_d != 10000.0 && car->driver != eDriver_local_human) { 
-                     CreateSplash(car, pTime); 
-                 } 
-             } 
-         } 
-         if (gProgram_state.current_car.water_d != 10000.0) { 
-             CreateSplash(&gProgram_state.current_car, 0x64u); 
-         } 
-     } 
-     if (!gSplash_flags) { 
-         return; 
-     } 
-     for (i = 0; i < COUNT_OF(gSplash); i++) { 
-         if (((1u << i) & gSplash_flags) == 0) { 
-             continue; 
-         } 
-         if (gSplash[i].just_done || (gAction_replay_mode && GetReplayRate() == 0.0f)) { 
-             dt = gSplash[i].size * gSplash[i].scale_x; 
-             gSplash[i].actor->t.t.mat.m[0][0] = gCamera_to_world.m[0][0] * dt; 
-             gSplash[i].actor->t.t.mat.m[0][1] = gCamera_to_world.m[0][1] * dt; 
-             gSplash[i].actor->t.t.mat.m[0][2] = gCamera_to_world.m[0][2] * dt; 
-             gSplash[i].actor->t.t.mat.m[1][0] = gSplash[i].size * gCamera_to_world.m[1][0]; 
-             gSplash[i].actor->t.t.mat.m[1][1] = gSplash[i].size * gCamera_to_world.m[1][1]; 
-             gSplash[i].actor->t.t.mat.m[1][2] = gSplash[i].size * gCamera_to_world.m[1][2]; 
-             gSplash[i].actor->t.t.mat.m[2][0] = gSplash[i].size * gCamera_to_world.m[2][0]; 
-             gSplash[i].actor->t.t.mat.m[2][1] = gSplash[i].size * gCamera_to_world.m[2][1]; 
-             gSplash[i].actor->t.t.mat.m[2][2] = gSplash[i].size * gCamera_to_world.m[2][2]; 
-             if (gProgram_state.cockpit_on) { 
-                 ts  = sqrt(- gCamera_to_world. m[0][2] *-  gCamera_to_world. m[0][2] +-  gCamera_to_world. m[0][0] *-  gCamera_to_world. m[0][0]);
-                 DRMatrix34PreRotateZ(&gSplash[i].actor->t.t.mat, -FastScalarArcTan2Angle(gCamera_to_world.m[0][1], ts)); 
-             } 
-             gSplash[i].just_done = 0; 
-         } else { 
-             gSplash_flags &= ~(1u << i); 
-             BrActorRemove(gSplash[i].actor); 
-         } 
-     } 
- } 
-   
- // IDA: void __cdecl RenderSplashes() 
- void RenderSplashes(void) { 
-     int i; 
-     LOG_TRACE("()"); 
-   
-     for (i = 0; i < COUNT_OF(gSplash); i++) { 
-         if (gSplash_flags & (1u << i)) { 
-             BrActorRelink(gNon_track_actor, gSplash[i].actor); 
-             BrZbSceneRenderAdd(gSplash[i].actor); 
-             BrActorRelink(gDont_render_actor, gSplash[i].actor); 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall GetSmokeShadeTables(FILE *f@<EAX>) 
- void GetSmokeShadeTables(FILE* f) { 
-     int i; 
-     int red; 
-     int green; 
-     int blue; 
-     br_scalar quarter; 
-     br_scalar half; 
-     br_scalar three_quarter; 
-     LOG_TRACE("(%p)", f); 
-   
-     gNum_dust_tables = GetAnInt(f); 
-     if (gNum_dust_tables > 8) { 
-         gNum_dust_tables = 8; 
-     } 
-     for (i = 0; gNum_dust_tables > i; ++i) { 
-         PossibleService(); 
-         GetThreeInts(f, &red, &green, &blue); 
-         GetThreeScalars(f, &quarter, &half, &three_quarter); 
-         gDust_table[i] = GenerateShadeTable(16, gRender_palette, red, green, blue, quarter, half, three_quarter); 
-     } 
- } 
-   
- // IDA: void __cdecl FreeSmokeShadeTables() 
- void FreeSmokeShadeTables(void) { 
-     int i; 
-     LOG_TRACE("()"); 
-   
-     for (i = 0; i < gNum_dust_tables; i++) { 
-         PossibleService(); 
-         BrTableRemove(gDust_table[i]); 
-         BrPixelmapFree(gDust_table[i]); 
-     } 
- } 
-   
- // IDA: void __usercall LoadInKevStuff(FILE *pF@<EAX>) 
- void LoadInKevStuff(FILE* pF) { 
-     LOG_TRACE("(%p)", pF); 
-   
-     PossibleService(); 
-     LoadInShrapnel(); 
-     PossibleService(); 
-     InitShrapnel(); 
-     PossibleService(); 
-     InitFlame(); 
-     PossibleService(); 
-     InitSplash(pF); 
- } 
-   
- // IDA: void __cdecl DisposeKevStuff() 
- void DisposeKevStuff(void) { 
-     LOG_TRACE("()"); 
-   
-     DisposeShrapnel(); 
-     DisposeFlame(); 
-     DisposeSplash(); 
- } 
-   
- // IDA: void __usercall DisposeKevStuffCar(tCar_spec *pCar@<EAX>) 
- void DisposeKevStuffCar(tCar_spec* pCar) { 
-     int i; 
-     LOG_TRACE("(%p)", pCar); 
-   
-     for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { 
-         if (gSmoke_column[i].car == pCar) { 
-             gSmoke_column[i].lifetime = 0; 
-             gSmoke_column[i].car = NULL; 
-         } 
-     } 
-     for (i = 0; i < COUNT_OF(gSparks); i++) { 
-         if ((gSpark_flags & (1u << i)) && gSparks[i].car == pCar) { 
-             gSparks[i].count = 0; 
-             gSpark_flags &= ~(1u << i); 
-         } 
-         if (gCar_to_view == pCar) { 
-             gCamera_yaw = 0; 
-             gCar_to_view = &gProgram_state.current_car; 
-             InitialiseExternalCamera(); 
-             PositionExternalCamera(gCar_to_view, 200); 
-             gCar_to_view = &gProgram_state.current_car; 
-         } 
-     } 
- } 
-   
- // IDA: void __cdecl DoTrueColModelThing(br_actor *actor, br_model *pModel, br_material *material, void *render_data, br_uint_8 style, int on_screen) 
- void DoTrueColModelThing(br_actor* actor, br_model* pModel, br_material* material, void* render_data, br_uint_8 style, int on_screen) { 
-     int group; 
-     int j; 
-     int val; 
-     LOG_TRACE("(%p, %p, %p, %p, %d, %d)", actor, pModel, material, render_data, style, on_screen); 
-     NOT_IMPLEMENTED(); 
- } 
-   
- // IDA: void __cdecl DoModelThing(br_actor *actor, br_model *pModel, br_material *material, void *render_data, br_uint_8 style, int on_screen) 
- void DoModelThing(br_actor* actor, br_model* pModel, br_material* material, void* render_data, br_uint_8 style, int on_screen) { 
-     int j; 
-     int i; 
-     int group; 
-     tU32 t; 
-     int val; 
-     LOG_TRACE("(%p, %p, %p, %p, %d, %d)", actor, pModel, material, render_data, style, on_screen); 
-   
-     GetRaceTime(); 
-     for (group = 0; group < V11MODEL(pModel)->ngroups; group++) { 
-         for (j = 0; j < V11MODEL(pModel)->groups[group].nvertices; j++) { 
-             if (!(((V11MODEL(pModel)->groups[group].vertex_colours[j]) >> 24) & 1)) { 
-                 if (((V11MODEL(pModel)->groups[group].vertex_colours[j]) >> 24) < 0xc9) { 
-                     val = ((V11MODEL(pModel)->groups[group].vertex_colours[j]) >> 24) + 2 * IRandomBetween(5, 10); 
-                     V11MODEL(pModel)->groups[group].vertex_colours[j] = BR_COLOUR_RGBA(0, 0, 0, val); 
-                     if (pModel->flags & BR_MODF_UPDATEABLE) { 
-                         pModel->vertices[V11MODEL(pModel)->groups[group].vertex_user[j]].index = val; 
-                     } 
-                 } else { 
-                     V11MODEL(pModel)->groups[group].vertex_colours[j] = BR_COLOUR_RGBA(0, 0, 0, 0xc9); 
-                     if (pModel->flags & BR_MODF_UPDATEABLE) { 
-                         pModel->vertices[V11MODEL(pModel)->groups[group].vertex_user[j]].index = 0xc9; 
-                     } 
-                 } 
-             } else if ((V11MODEL(pModel)->groups[group].vertex_colours[j] >> 24) < 20) { 
-                 V11MODEL(pModel)->groups[group].vertex_colours[j] = 0; 
-                 if (pModel->flags & BR_MODF_UPDATEABLE) { 
-                     pModel->vertices[V11MODEL(pModel)->groups[group].vertex_user[j]].index = 0; 
-                 } 
-             } else { 
-                 val = ((V11MODEL(pModel)->groups[group].vertex_colours[j] >> 24) - 2 * IRandomBetween(5, 10)) << 24; 
-                 V11MODEL(pModel)->groups[group].vertex_colours[j] = BR_COLOUR_RGBA(0, 0, 0, val); 
-                 if (pModel->flags & BR_MODF_UPDATEABLE) { 
-                     pModel->vertices[V11MODEL(pModel)->groups[group].vertex_user[j]].index = val; 
-                 } 
-             } 
-         } 
-     } 
-     if ((pModel->flags & BR_MODF_UPDATEABLE) && pModel->user != NULL) { 
-         BrModelUpdate(pModel, BR_MODU_VERTEX_POSITIONS); 
-     } 
-     pModel->user = NULL; 
-     BrZbModelRender(actor, pModel, material, style, BrOnScreenCheck(&pModel->bounds), 0); 
- } 
-   
- // IDA: void __usercall SetModelShade(br_actor *pActor@<EAX>, br_pixelmap *pShade@<EDX>) 
- void SetModelShade(br_actor* pActor, br_pixelmap* pShade) { 
-     int i; 
-     br_material* material; 
-     br_model* model; 
-     LOG_TRACE("(%p, %p)", pActor, pShade); 
-   
-     model = pActor->model; 
-     if (pActor->material != NULL && pActor->material->index_shade != pShade) { 
-         pActor->material->index_shade = pShade; 
-         BrMaterialUpdate(pActor->material, BR_MATU_ALL); 
-     } 
-     for (i = 0; i < model->nfaces; i++) { 
-         material = model->faces[i].material; 
-         if (material != NULL && material->index_shade != pShade) { 
-             material->index_shade = pShade; 
-             BrMaterialUpdate(material, BR_MATU_ALL); 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall MakeCarIt(tCar_spec *pCar@<EAX>) 
- void MakeCarIt(tCar_spec* pCar) { 
-     br_actor* actor; 
-     br_actor* bonny; 
-     br_pixelmap* shade[6]; 
-     static int shade_num = 0; 
-     //int i; // Pierre-Marie Baty -- unused variable 
-     LOG_TRACE("(%p)", pCar); 
-   
-     shade[0] = gIt_shade_table; 
-     shade[1] = gFog_shade_table; 
-     shade[2] = gShade_list[0]; 
-     shade[3] = gShade_list[1]; 
-     shade[4] = gShade_list[2]; 
-     shade[5] = NULL; 
-   
-     actor = pCar->car_model_actors[pCar->principal_car_actor].actor; 
-     bonny = pCar->car_model_actors[pCar->car_actor_count - 1].actor; 
-     if (!(actor->model->flags & BR_MODF_CUSTOM) || actor->model->custom != DoModelThing) { 
-         SetModelShade(actor, shade[shade_num]); 
-         actor->model->user = DoModelThing; 
-         actor->model->custom = DoModelThing; 
-         actor->model->flags |= BR_MODF_CUSTOM; 
-         if (bonny != actor) { 
-             bonny->model->user = DoModelThing; 
-             bonny->model->custom = DoModelThing; 
-             bonny->model->flags |= BR_MODF_CUSTOM; 
-             SetModelShade(bonny, shade[shade_num]); 
-         } 
-     } 
- } 
-   
- // IDA: void __usercall StopCarBeingIt(tCar_spec *pCar@<EAX>) 
- void StopCarBeingIt(tCar_spec* pCar) { 
-     int i; 
-     int group; 
-     br_actor* actor; 
-     br_actor* bonny; 
-     LOG_TRACE("(%p)", pCar); 
-   
-     actor = pCar->car_model_actors[pCar->principal_car_actor].actor; 
-     bonny = pCar->car_model_actors[pCar->car_actor_count - 1].actor; 
-     if (actor->model->custom == DoModelThing) { 
-         actor->model->flags &= ~BR_MODF_CUSTOM; 
-         SetModelShade(actor, gShade_list[0]); 
-         for (group = 0; group < V11MODEL(actor->model)->ngroups; group++) { 
-             for (i = 0; i < V11MODEL(actor->model)->groups[group].nvertices; i++) { 
-                 V11MODEL(actor->model)->groups[group].vertex_colours[i] = 0; 
-                 if (actor->model->flags & BR_MODF_UPDATEABLE) { 
-                     actor->model->vertices[V11MODEL(actor->model)->groups[group].vertex_user[i]].index = 0; 
-                 } 
-             } 
-         } 
-         SetModelForUpdate(actor->model, pCar, 0); 
-         if (bonny != actor) { 
-             bonny->model->flags &= ~BR_MODF_CUSTOM; 
-             SetModelShade(bonny, gShade_list[0]); 
-             for (group = 0; group < V11MODEL(bonny->model)->ngroups; group++) { 
-                 for (i = 0; i < V11MODEL(bonny->model)->groups[group].nvertices; i++) { 
-                     V11MODEL(bonny->model)->groups[group].vertex_colours[i] = 0; 
-                     if (bonny->model->flags & BR_MODF_UPDATEABLE) { 
-                         bonny->model->vertices[V11MODEL(bonny->model)->groups[group].vertex_user[i]].index = 0; 
-                     } 
-                 } 
-             } 
-             SetModelForUpdate(bonny->model, pCar, 0); 
-         } 
-     } 
- } 
-