Rev 18 | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1 | pmbaty | 1 | #include "spark.h" |
| 20 | pmbaty | 2 | #include "brender/brender.h" |
| 1 | pmbaty | 3 | #include "car.h" |
| 4 | #include "depth.h" |
||
| 5 | #include "errors.h" |
||
| 6 | #include "globvars.h" |
||
| 7 | #include "globvrkm.h" |
||
| 8 | #include "graphics.h" |
||
| 9 | #include "harness/hooks.h" |
||
| 10 | #include "harness/trace.h" |
||
| 11 | #include "loading.h" |
||
| 12 | #include "opponent.h" |
||
| 13 | #include "piping.h" |
||
| 14 | #include "replay.h" |
||
| 15 | #include "trig.h" |
||
| 16 | #include "utility.h" |
||
| 17 | #include "world.h" |
||
| 20 | pmbaty | 18 | |
| 1 | pmbaty | 19 | #include <stdlib.h> |
| 20 | |||
| 21 | int gNext_spark; |
||
| 22 | int gSpark_flags; |
||
| 23 | int gNext_shrapnel; |
||
| 24 | int gShrapnel_flags; |
||
| 25 | br_model* gShrapnel_model[2]; |
||
| 26 | int gSmoke_flags; |
||
| 27 | int gSmoke_num; |
||
| 28 | int gOffset = 0; |
||
| 29 | int gColumn_flags; |
||
| 30 | int gNext_column; |
||
| 31 | br_pixelmap* gBlack_smoke_shade_table; |
||
| 32 | br_pixelmap* gDark_smoke_shade_table; |
||
| 33 | br_pixelmap* gGrey_smoke_shade_table; |
||
| 34 | int gSmoke_on = 1; |
||
| 35 | int gNum_splash_types; |
||
| 36 | int gIt_type; |
||
| 37 | br_pixelmap* gIt_shade_table; |
||
| 38 | br_pixelmap** gDust_table = &gShade_list[8]; |
||
| 39 | br_pixelmap* gFlame_map[20]; |
||
| 40 | tBRender_smoke* gBR_smoke_pointers[30]; |
||
| 41 | tSplash gSplash[32]; |
||
| 42 | br_material* gSplash_material[20]; |
||
| 43 | tBRender_smoke gBR_smoke_structs[30]; |
||
| 44 | tSmoke_column gSmoke_column[25]; |
||
| 45 | br_matrix4 gCameraToScreen; |
||
| 46 | tSpark gSparks[32]; |
||
| 47 | br_pixelmap* gShade_list[16]; |
||
| 48 | int gN_BR_smoke_structs; |
||
| 49 | tSmoke gSmoke[25]; |
||
| 50 | tU32 gSplash_flags; |
||
| 51 | tU32 gNext_splash; |
||
| 52 | br_model* gLollipop_model; |
||
| 53 | int gNum_dust_tables; |
||
| 54 | br_model* gSplash_model; |
||
| 55 | int gDust_rotate; |
||
| 56 | br_camera* gSpark_cam; |
||
| 57 | br_material* gBlack_material; |
||
| 58 | tShrapnel gShrapnel[15]; |
||
| 59 | |||
| 60 | // gSmoke_column has 25 elements but all the code just checks the first 5 elements |
||
| 61 | #define MAX_SMOKE_COLUMNS 5 |
||
| 62 | |||
| 63 | // Bugfix: At higher FPS, flame animation runs too quickly, so introduce a new frame timer |
||
| 64 | #define FLAME_ANIMATION_FRAME_INTERVAL 40 |
||
| 65 | |||
| 66 | // Bugfix: At higher FPS, `CreatePuffOfSmoke` is called too often and causes smoke cirlces to be recycled too quickly so assume around 25fps |
||
| 67 | #define SMOKE_COLUMN_NEW_PUFF_INTERVAL 30 |
||
| 68 | |||
| 69 | // IDA: void __cdecl DrawDot(br_scalar z, tU8 *scr_ptr, tU16 *depth_ptr, tU8 *shade_ptr) |
||
| 70 | void DrawDot(br_scalar z, tU8* scr_ptr, tU16* depth_ptr, tU8* shade_ptr) { |
||
| 71 | LOG_TRACE("(%f, %p, %p, %p)", z, scr_ptr, depth_ptr, shade_ptr); |
||
| 72 | |||
| 73 | if (*depth_ptr > (1.0 - z) * 32768.0f) { |
||
| 74 | *depth_ptr = (1.0 - z) * 32768.0f; |
||
| 75 | *scr_ptr = shade_ptr[*scr_ptr]; |
||
| 76 | } |
||
| 77 | } |
||
| 78 | |||
| 79 | // IDA: void __usercall SetWorldToScreen(br_pixelmap *pScreen@<EAX>) |
||
| 80 | void SetWorldToScreen(br_pixelmap* pScreen) { |
||
| 81 | br_matrix4 mat; |
||
| 82 | br_matrix4 mat2; |
||
| 83 | LOG_TRACE("(%p)", pScreen); |
||
| 84 | |||
| 85 | BrMatrix4Perspective(&mat, gSpark_cam->field_of_view, gSpark_cam->aspect, -gSpark_cam->hither_z, -gSpark_cam->yon_z); |
||
| 86 | BrMatrix4Scale(&mat2, pScreen->width / 2, pScreen->height / 2, 1.0f); |
||
| 87 | BrMatrix4Mul(&gCameraToScreen, &mat, &mat2); |
||
| 88 | } |
||
| 89 | |||
| 90 | // IDA: void __usercall DrawLine3DThroughBRender(br_vector3 *pStart@<EAX>, br_vector3 *pEnd@<EDX>) |
||
| 91 | void DrawLine3DThroughBRender(br_vector3* pStart, br_vector3* pEnd) { |
||
| 92 | LOG_TRACE("(%p, %p)", pStart, pEnd); |
||
| 93 | NOT_IMPLEMENTED(); |
||
| 94 | } |
||
| 95 | |||
| 96 | // 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) |
||
| 97 | int DrawLine3D(br_vector3* start, br_vector3* end, br_pixelmap* pScreen, br_pixelmap* pDepth_buffer, br_pixelmap* shade_table) { |
||
| 98 | br_vector3 o; |
||
| 99 | br_vector3 p; |
||
| 100 | //br_vector3 tv; // Pierre-Marie Baty -- unused variable |
||
| 101 | br_vector4 o2; |
||
| 102 | br_vector4 p2; |
||
| 103 | br_scalar ts; |
||
| 104 | LOG_TRACE("(%p, %p, %p, %p, %p)", start, end, pScreen, pDepth_buffer, shade_table); |
||
| 105 | |||
| 106 | o = *start; |
||
| 107 | p = *end; |
||
| 108 | if (-gSpark_cam->hither_z < o.v[2] || -gSpark_cam->hither_z < p.v[2]) { |
||
| 109 | if (-gSpark_cam->hither_z < o.v[2] && -gSpark_cam->hither_z < p.v[2]) { |
||
| 110 | return 0; |
||
| 111 | } |
||
| 112 | ts = (p.v[2] + gSpark_cam->hither_z) / (p.v[2] - o.v[2]); |
||
| 113 | if (-gSpark_cam->hither_z < o.v[2]) { |
||
| 114 | o.v[0] = p.v[0] - (p.v[0] - o.v[0]) * ts; |
||
| 115 | o.v[1] = p.v[1] - (p.v[1] - o.v[1]) * ts; |
||
| 116 | o.v[2] = -gSpark_cam->hither_z; |
||
| 117 | } |
||
| 118 | if (-gSpark_cam->hither_z < p.v[2]) { |
||
| 119 | p.v[0] = p.v[0] - (p.v[0] - o.v[0]) * ts; |
||
| 120 | p.v[1] = p.v[1] - (p.v[1] - o.v[1]) * ts; |
||
| 121 | p.v[2] = -gSpark_cam->hither_z; |
||
| 122 | } |
||
| 123 | } |
||
| 124 | BrMatrix4ApplyP(&o2, &o, &gCameraToScreen); |
||
| 125 | BrMatrix4ApplyP(&p2, &p, &gCameraToScreen); |
||
| 126 | o.v[0] = o2.v[0] / o2.v[3]; |
||
| 127 | o.v[1] = o2.v[1] / o2.v[3]; |
||
| 128 | o.v[2] = o2.v[2] / o2.v[3]; |
||
| 129 | p.v[0] = p2.v[0] / p2.v[3]; |
||
| 130 | p.v[1] = p2.v[1] / p2.v[3]; |
||
| 131 | p.v[2] = p2.v[2] / p2.v[3]; |
||
| 132 | return DrawLine2D(&o, &p, pScreen, pDepth_buffer, 1.0, shade_table); |
||
| 133 | } |
||
| 134 | |||
| 135 | // 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) |
||
| 136 | int DrawLine2D(br_vector3* o, br_vector3* p, br_pixelmap* pScreen, br_pixelmap* pDepth_buffer, br_scalar brightness, br_pixelmap* shade_table) { |
||
| 137 | tU8* scr_ptr; |
||
| 138 | tU16* depth_ptr; |
||
| 139 | tU8* shade_ptr; |
||
| 140 | int x1; |
||
| 141 | int x2; |
||
| 142 | int y1; |
||
| 143 | int y2; |
||
| 144 | int d; |
||
| 145 | int dx; |
||
| 146 | int dy; |
||
| 147 | int ax; |
||
| 148 | int sx; |
||
| 149 | int ay; |
||
| 150 | int sy; |
||
| 151 | int x; |
||
| 152 | int y; |
||
| 153 | br_scalar zbuff; |
||
| 154 | br_scalar zbuff_inc; |
||
| 155 | int darken_count; |
||
| 156 | int darken_init; |
||
| 157 | LOG_TRACE("(%p, %p, %p, %p, %f, %p)", o, p, pScreen, pDepth_buffer, brightness, shade_table); |
||
| 158 | |||
| 159 | scr_ptr = (tU8*)pScreen->pixels + pScreen->base_x + pScreen->base_y * pScreen->row_bytes; |
||
| 160 | depth_ptr = (tU16*)pDepth_buffer->pixels; |
||
| 161 | shade_ptr = (tU8*)shade_table->pixels + shade_table->base_y * shade_table->row_bytes; |
||
| 162 | x1 = pScreen->width / 2 + o->v[0]; |
||
| 163 | x2 = pScreen->width / 2 + p->v[0]; |
||
| 164 | y1 = pScreen->height / 2 - o->v[1]; |
||
| 165 | y2 = pScreen->height / 2 - p->v[1]; |
||
| 166 | if (brightness < 0.001 || brightness > 1.0) { |
||
| 167 | return 0; |
||
| 168 | } |
||
| 169 | if (x1 < 0 || x2 < 0) { |
||
| 170 | if (x1 < 0 && x2 < 0) { |
||
| 171 | return 0; |
||
| 172 | } |
||
| 173 | if (x1 >= 0) { |
||
| 174 | y2 = y1 - x1 * (y1 - y2) / (x1 - x2); |
||
| 175 | p->v[2] = o->v[2] - (o->v[2] - p->v[2]) * (float)x1 / (float)(x1 - x2); |
||
| 176 | x2 = 0; |
||
| 177 | } else { |
||
| 178 | y1 = y2 - x2 * (y2 - y1) / (x2 - x1); |
||
| 179 | o->v[2] = p->v[2] - (p->v[2] - o->v[2]) * (float)x2 / (float)(x2 - x1); |
||
| 180 | x1 = 0; |
||
| 181 | } |
||
| 182 | } |
||
| 183 | if (pScreen->width <= x1 || pScreen->width <= x2) { |
||
| 184 | if (pScreen->width <= x1 && pScreen->width <= x2) { |
||
| 185 | return 0; |
||
| 186 | } |
||
| 187 | if (pScreen->width > x1) { |
||
| 188 | y2 = y1 - (y1 - y2) * (x1 - (pScreen->width - 1)) / (x1 - x2); |
||
| 189 | p->v[2] = o->v[2] - (o->v[2] - p->v[2]) * (x1 - (float)(pScreen->width - 1)) / (float)(x1 - x2); |
||
| 190 | x2 = pScreen->width - 1; |
||
| 191 | } else { |
||
| 192 | y1 = y2 - (y2 - y1) * (x2 - (pScreen->width - 1)) / (x2 - x1); |
||
| 193 | o->v[2] = p->v[2] - (p->v[2] - o->v[2]) * (x2 - (float)(pScreen->width - 1)) / (float)(x2 - x1); |
||
| 194 | x1 = pScreen->width - 1; |
||
| 195 | } |
||
| 196 | } |
||
| 197 | if (y1 < 0 || y2 < 0) { |
||
| 198 | if (y1 < 0 && y2 < 0) { |
||
| 199 | return 0; |
||
| 200 | } |
||
| 201 | if (y1 >= 0) { |
||
| 202 | x2 = x1 - y1 * (x1 - x2) / (y1 - y2); |
||
| 203 | p->v[2] = o->v[2] - (o->v[2] - p->v[2]) * (float)y1 / (float)(y1 - y2); |
||
| 204 | y2 = 0; |
||
| 205 | } else { |
||
| 206 | x1 = x2 - y2 * (x2 - x1) / (y2 - y1); |
||
| 207 | o->v[2] = p->v[2] - (p->v[2] - o->v[2]) * (float)y2 / (float)(y2 - y1); |
||
| 208 | y1 = 0; |
||
| 209 | } |
||
| 210 | } |
||
| 211 | if (pScreen->height <= y1 || pScreen->height <= y2) { |
||
| 212 | if (pScreen->height <= y1 && pScreen->height <= y2) { |
||
| 213 | return 0; |
||
| 214 | } |
||
| 215 | if (pScreen->height > y1) { |
||
| 216 | x2 = x1 - (x1 - x2) * (y1 - (pScreen->height - 1)) / (y1 - y2); |
||
| 217 | p->v[2] = o->v[2] - (o->v[2] - p->v[2]) * (float)(y1 - (pScreen->height - 1)) / (float)(y1 - y2); |
||
| 218 | y2 = pScreen->height - 1; |
||
| 219 | } else { |
||
| 220 | x1 = x2 - (x2 - x1) * (y2 - (pScreen->height - 1)) / (y2 - y1); |
||
| 221 | o->v[2] = p->v[2] - (p->v[2] - o->v[2]) * (float)(y2 - (pScreen->height - 1)) / (float)(y2 - y1); |
||
| 222 | y1 = pScreen->height - 1; |
||
| 223 | } |
||
| 224 | } |
||
| 225 | zbuff = o->v[2]; |
||
| 226 | dx = x2 - x1; |
||
| 227 | dy = y2 - y1; |
||
| 228 | ax = 2 * abs(dx); |
||
| 229 | if (x2 - x1 < 0) { |
||
| 230 | sx = -1; |
||
| 231 | } else { |
||
| 232 | sx = 1; |
||
| 233 | } |
||
| 234 | ay = 2 * abs(dy); |
||
| 235 | if (dy < 0) { |
||
| 236 | sy = -1; |
||
| 237 | } else { |
||
| 238 | sy = 1; |
||
| 239 | } |
||
| 240 | x = x1; |
||
| 241 | y = y1; |
||
| 242 | scr_ptr += x1 + y1 * pScreen->row_bytes; |
||
| 243 | depth_ptr += x1 + y1 * (pDepth_buffer->row_bytes / 2); |
||
| 244 | darken_init = (brightness - 0.001) * (float)shade_table->height; |
||
| 245 | if (ay >= ax) { |
||
| 246 | d = ax - ay / 2; |
||
| 247 | darken_init = 500 * ay / darken_init; |
||
| 248 | darken_count = darken_init; |
||
| 249 | zbuff_inc = (p->v[2] - o->v[2]) * 2.0 / (float)ay; |
||
| 250 | while (1) { |
||
| 251 | DrawDot(zbuff, scr_ptr, depth_ptr, shade_ptr); |
||
| 252 | if (y == y2) { |
||
| 253 | break; |
||
| 254 | } |
||
| 255 | if (d >= 0) { |
||
| 256 | scr_ptr += sx; |
||
| 257 | depth_ptr += sx; |
||
| 258 | d -= ay; |
||
| 259 | } |
||
| 260 | y += sy; |
||
| 261 | d += ax; |
||
| 262 | scr_ptr += sy * pScreen->row_bytes; |
||
| 263 | depth_ptr += sy * (pDepth_buffer->row_bytes / 2); |
||
| 264 | zbuff = zbuff_inc + zbuff; |
||
| 265 | darken_count -= 1000; |
||
| 266 | while (darken_count <= 0) { |
||
| 267 | darken_count += darken_init; |
||
| 268 | shade_ptr += shade_table->row_bytes; |
||
| 269 | } |
||
| 270 | } |
||
| 271 | } else { |
||
| 272 | d = ay - ax / 2; |
||
| 273 | darken_init = 500 * ax / darken_init; |
||
| 274 | darken_count = darken_init; |
||
| 275 | zbuff_inc = (p->v[2] - o->v[2]) * 2.0 / (float)ax; |
||
| 276 | while (1) { |
||
| 277 | DrawDot(zbuff, scr_ptr, depth_ptr, shade_ptr); |
||
| 278 | if (x == x2) { |
||
| 279 | break; |
||
| 280 | } |
||
| 281 | if (d >= 0) { |
||
| 282 | scr_ptr += sy * pScreen->row_bytes; |
||
| 283 | depth_ptr += sy * (pDepth_buffer->row_bytes / 2); |
||
| 284 | d -= ax; |
||
| 285 | } |
||
| 286 | x += sx; |
||
| 287 | scr_ptr += sx; |
||
| 288 | depth_ptr += sx; |
||
| 289 | d += ay; |
||
| 290 | zbuff = zbuff_inc + zbuff; |
||
| 291 | darken_count -= 1000; |
||
| 292 | while (darken_count <= 0) { |
||
| 293 | darken_count += darken_init; |
||
| 294 | shade_ptr += shade_table->row_bytes; |
||
| 295 | } |
||
| 296 | } |
||
| 297 | } |
||
| 298 | return 1; |
||
| 299 | } |
||
| 300 | |||
| 301 | // IDA: void __usercall SetLineModelCols(tU8 pCol@<EAX>) |
||
| 302 | void SetLineModelCols(tU8 pCol) { |
||
| 303 | LOG_TRACE("(%d)", pCol); |
||
| 304 | NOT_IMPLEMENTED(); |
||
| 305 | } |
||
| 306 | |||
| 307 | // IDA: void __usercall ReplaySparks(br_pixelmap *pRender_screen@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, tU32 pTime@<ECX>) |
||
| 308 | void ReplaySparks(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_actor* pCamera, tU32 pTime) { |
||
| 309 | int i; |
||
| 310 | br_vector3 pos; |
||
| 311 | br_vector3 o; |
||
| 312 | br_vector3 p; |
||
| 313 | br_vector3 tv; |
||
| 314 | br_vector3 new_pos; |
||
| 315 | LOG_TRACE("(%p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pTime); |
||
| 316 | |||
| 317 | for (i = 0; i < COUNT_OF(gSparks); i++) { |
||
| 318 | if (gSpark_flags & (1 << i)) { |
||
| 319 | if (gSparks[i].car == NULL) { |
||
| 320 | BrVector3Copy(&pos, &gSparks[i].pos); |
||
| 321 | } else { |
||
| 322 | BrMatrix34ApplyP(&tv, &o, &gSparks[i].car->car_master_actor->t.t.mat); |
||
| 323 | BrVector3Copy(&o, &tv); |
||
| 324 | BrMatrix34ApplyP(&pos, &gSparks[i].pos, &gSparks[i].car->car_master_actor->t.t.mat); |
||
| 325 | } |
||
| 326 | BrVector3Add(&o, &pos, &gSparks[i].length); |
||
| 327 | BrVector3Sub(&tv, &pos, (br_vector3*)gCamera_to_world.m[3]); |
||
| 328 | BrMatrix34TApplyV(&new_pos, &tv, &gCamera_to_world); |
||
| 329 | BrVector3Sub(&tv, &o, (br_vector3*)gCamera_to_world.m[3]); |
||
| 330 | BrMatrix34TApplyV(&p, &tv, &gCamera_to_world); |
||
| 331 | if (gSparks[i].colour) { |
||
| 332 | DrawLine3D(&p, &new_pos, pRender_screen, pDepth_buffer, gFog_shade_table); |
||
| 333 | } else { |
||
| 334 | DrawLine3D(&p, &new_pos, pRender_screen, pDepth_buffer, gAcid_shade_table); |
||
| 335 | } |
||
| 336 | } |
||
| 337 | } |
||
| 338 | } |
||
| 339 | |||
| 340 | // 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) |
||
| 341 | void RenderSparks(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world, tU32 pTime) { |
||
| 342 | int i; |
||
| 343 | int time; |
||
| 344 | br_vector3 tv; |
||
| 345 | br_vector3 o; |
||
| 346 | br_vector3 p; |
||
| 347 | br_vector3 pos; |
||
| 348 | br_vector3 new_pos; |
||
| 349 | br_scalar ts; |
||
| 350 | LOG_TRACE("(%p, %p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pCamera_to_world, pTime); |
||
| 351 | |||
| 352 | gSpark_cam = pCamera->type_data; |
||
| 353 | SetWorldToScreen(pRender_screen); |
||
| 354 | |||
| 355 | if (!gSpark_flags) { |
||
| 356 | return; |
||
| 357 | } |
||
| 358 | |||
| 359 | if (gAction_replay_mode) { |
||
| 360 | ReplaySparks(pRender_screen, pDepth_buffer, pCamera, pTime); |
||
| 361 | return; |
||
| 362 | } |
||
| 363 | StartPipingSession(ePipe_chunk_spark); |
||
| 364 | for (i = 0; i < COUNT_OF(gSparks); i++) { |
||
| 365 | if (((1u << i) & gSpark_flags) == 0) { |
||
| 366 | continue; |
||
| 367 | } |
||
| 368 | if (gSparks[i].count <= 0) { |
||
| 369 | gSparks[i].count = 0; |
||
| 370 | gSpark_flags &= ~(1u << i); |
||
| 371 | } |
||
| 372 | ts = BrVector3Dot(&gSparks[i].normal, &gSparks[i].v); |
||
| 373 | BrVector3Scale(&tv, &gSparks[i].normal, ts); |
||
| 374 | BrVector3Sub(&gSparks[i].v, &gSparks[i].v, &tv); |
||
| 375 | if (gSparks[i].time_sync) { |
||
| 376 | BrVector3Scale(&o, &gSparks[i].v, gSparks[i].time_sync / 1000.0); |
||
| 377 | gSparks[i].count = gSparks[i].time_sync + gSparks[i].count - pTime; |
||
| 378 | gSparks[i].time_sync = 0; |
||
| 379 | } else { |
||
| 380 | BrVector3Scale(&o, &gSparks[i].v, pTime / 1000.0); |
||
| 381 | gSparks[i].count -= pTime; |
||
| 382 | } |
||
| 383 | BrVector3Accumulate(&gSparks[i].pos, &o); |
||
| 384 | time = 1000 - gSparks[i].count; |
||
| 385 | if (time > 150) { |
||
| 386 | time = 150; |
||
| 387 | } |
||
| 388 | ts = -time / 1000.0; |
||
| 389 | if (gSparks[i].colour) { |
||
| 390 | ts = ts / 2.0; |
||
| 391 | } |
||
| 392 | BrVector3Scale(&gSparks[i].length, &gSparks[i].v, ts); |
||
| 393 | ts = pTime * 10.0 / 6900.0; |
||
| 394 | if (gSparks[i].car) { |
||
| 395 | BrMatrix34ApplyV(&tv, &gSparks[i].length, &gSparks[i].car->car_master_actor->t.t.mat); |
||
| 396 | BrVector3Copy(&gSparks[i].length, &tv); |
||
| 397 | BrMatrix34ApplyP(&pos, &gSparks[i].pos, &gSparks[i].car->car_master_actor->t.t.mat); |
||
| 398 | o = tv; |
||
| 399 | gSparks[i].v.v[0] = gSparks[i].v.v[0] - gSparks[i].car->car_master_actor->t.t.mat.m[0][1] * ts; |
||
| 400 | gSparks[i].v.v[1] = gSparks[i].v.v[1] - gSparks[i].car->car_master_actor->t.t.mat.m[1][1] * ts; |
||
| 401 | gSparks[i].v.v[2] = gSparks[i].v.v[2] - gSparks[i].car->car_master_actor->t.t.mat.m[2][1] * ts; |
||
| 402 | } else { |
||
| 403 | BrVector3Copy(&pos, &gSparks[i].pos); |
||
| 404 | gSparks[i].v.v[1] = gSparks[i].v.v[1] - ts; |
||
| 405 | } |
||
| 406 | AddSparkToPipingSession(i + (gSparks[i].colour << 8), &pos, &gSparks[i].length); |
||
| 407 | BrVector3Add(&o, &gSparks[i].length, &pos); |
||
| 408 | BrVector3Sub(&tv, &pos, (br_vector3*)gCamera_to_world.m[3]); |
||
| 409 | BrMatrix34TApplyV(&new_pos, &tv, &gCamera_to_world); |
||
| 410 | BrVector3Sub(&tv, &o, (br_vector3*)gCamera_to_world.m[3]); |
||
| 411 | BrMatrix34TApplyV(&p, &tv, &gCamera_to_world); |
||
| 412 | BrVector3SetFloat(&tv, FRandomBetween(-0.1f, 0.1f), FRandomBetween(-0.1f, 0.1f), FRandomBetween(-0.1f, 0.1f)); |
||
| 413 | BrVector3Accumulate(&gSparks[i].v, &tv); |
||
| 414 | ts = 1.0f - BrVector3Length(&gSparks[i].v) / 1.4f * pTime / 1000.0f; |
||
| 415 | if (ts < 0.1f) { |
||
| 416 | ts = 0.1f; |
||
| 417 | } |
||
| 418 | BrVector3Scale(&gSparks[i].v, &gSparks[i].v, ts); |
||
| 419 | if (gSparks[i].colour) { |
||
| 420 | DrawLine3D(&p, &new_pos, pRender_screen, pDepth_buffer, gFog_shade_table); |
||
| 421 | } else { |
||
| 422 | DrawLine3D(&p, &new_pos, pRender_screen, pDepth_buffer, gAcid_shade_table); |
||
| 423 | } |
||
| 424 | } |
||
| 425 | EndPipingSession(); |
||
| 426 | } |
||
| 427 | |||
| 428 | // IDA: void __usercall CreateSingleSpark(tCar_spec *pCar@<EAX>, br_vector3 *pPos@<EDX>, br_vector3 *pVel@<EBX>) |
||
| 429 | void CreateSingleSpark(tCar_spec* pCar, br_vector3* pPos, br_vector3* pVel) { |
||
| 430 | LOG_TRACE("(%p, %p, %p)", pCar, pPos, pVel); |
||
| 431 | |||
| 432 | BrVector3Copy(&gSparks[gNext_spark].pos, pPos); |
||
| 433 | BrVector3SetFloat(&gSparks[gNext_spark].normal, 0.0f, 0.0f, 0.0f); |
||
| 434 | BrVector3Copy(&gSparks[gNext_spark].v, pVel); |
||
| 435 | gSparks[gNext_spark].count = 500; |
||
| 436 | gSparks[gNext_spark].car = pCar; |
||
| 437 | gSpark_flags |= 1u << gNext_spark; |
||
| 438 | gSparks[gNext_spark].time_sync = 1; |
||
| 439 | gSparks[gNext_spark].colour = 1; |
||
| 440 | gNext_spark++; |
||
| 441 | if (gNext_spark >= COUNT_OF(gSparks)) { |
||
| 442 | gNext_spark = 0; |
||
| 443 | } |
||
| 444 | } |
||
| 445 | |||
| 446 | // IDA: void __usercall CreateSparks(br_vector3 *pos@<EAX>, br_vector3 *v@<EDX>, br_vector3 *pForce@<EBX>, br_scalar sparkiness, tCar_spec *pCar) |
||
| 447 | void CreateSparks(br_vector3* pos, br_vector3* v, br_vector3* pForce, br_scalar sparkiness, tCar_spec* pCar) { |
||
| 448 | br_vector3 norm; |
||
| 449 | br_vector3 normal; |
||
| 450 | br_vector3 tv; |
||
| 451 | br_vector3 tv2; |
||
| 452 | br_vector3 pos2; |
||
| 453 | br_scalar ts; |
||
| 454 | br_scalar ts2; |
||
| 455 | int num; |
||
| 456 | int i; |
||
| 457 | LOG_TRACE("(%p, %p, %p, %f, %p)", pos, v, pForce, sparkiness, pCar); |
||
| 458 | |||
| 459 | ts = BrVector3Length(pForce); |
||
| 460 | BrVector3InvScale(&normal, pForce, ts); |
||
| 461 | ts2 = BrVector3Dot(pForce, v); |
||
| 462 | if (ts2 >= 0) { |
||
| 463 | ts2 = 1.f / (10.f * ts); |
||
| 464 | } else { |
||
| 465 | ts2 = 1.f / (10.f * ts) - ts2 / (ts * ts); |
||
| 466 | } |
||
| 467 | |||
| 468 | BrVector3Scale(&norm, pForce, ts2); |
||
| 469 | BrVector3Accumulate(v, &norm); |
||
| 470 | num = FRandomBetween(0.f, BrVector3Length(v) / 2.f + 0.7f) * sparkiness; |
||
| 471 | |||
| 472 | if (num > 10) { |
||
| 473 | num = 10; |
||
| 474 | } |
||
| 475 | for (i = 0; i < num; i++) { |
||
| 476 | BrVector3Copy(&gSparks[gNext_spark].pos, pos); |
||
| 477 | BrVector3Copy(&gSparks[gNext_spark].normal, &normal); |
||
| 478 | BrVector3Copy(&gSparks[gNext_spark].v, v); |
||
| 479 | gSparks[gNext_spark].v.v[0] *= FRandomBetween(.5f, .9f); |
||
| 480 | gSparks[gNext_spark].v.v[1] *= FRandomBetween(.5f, .9f); |
||
| 481 | gSparks[gNext_spark].v.v[2] *= FRandomBetween(.5f, .9f); |
||
| 482 | gSparks[gNext_spark].count = 1000; |
||
| 483 | gSparks[gNext_spark].car = NULL; |
||
| 484 | gSpark_flags |= 1u << gNext_spark; |
||
| 485 | gSparks[gNext_spark].time_sync = gMechanics_time_sync; |
||
| 486 | gSparks[gNext_spark].colour = 0; |
||
| 487 | gNext_spark++; |
||
| 488 | if (gNext_spark >= COUNT_OF(gSparks)) { |
||
| 489 | gNext_spark = 0; |
||
| 490 | } |
||
| 491 | } |
||
| 492 | if ((ts * sparkiness) >= 10.f) { |
||
| 493 | tv.v[0] = pos->v[0] - pCar->car_master_actor->t.t.translate.t.v[0] / WORLD_SCALE; |
||
| 494 | tv.v[1] = pos->v[1] - pCar->car_master_actor->t.t.translate.t.v[1] / WORLD_SCALE; |
||
| 495 | tv.v[2] = pos->v[2] - pCar->car_master_actor->t.t.translate.t.v[2] / WORLD_SCALE; |
||
| 496 | BrMatrix34TApplyV(&pos2, &tv, &pCar->car_master_actor->t.t.mat); |
||
| 497 | BrMatrix34TApplyV(&norm, &normal, &pCar->car_master_actor->t.t.mat); |
||
| 498 | BrVector3Scale(&tv, &norm, .1f); |
||
| 499 | BrVector3Accumulate(&pos2, &tv); |
||
| 500 | num = (ts * sparkiness / 10.f) + 3; |
||
| 501 | if (num > 10) { |
||
| 502 | num = 10; |
||
| 503 | } |
||
| 504 | for (i = 0; i < num; i++) { |
||
| 505 | BrVector3Copy(&gSparks[gNext_spark].pos, &pos2); |
||
| 506 | BrVector3Copy(&gSparks[gNext_spark].normal, &norm); |
||
| 507 | BrVector3SetFloat(&tv, FRandomBetween(-1.f, 1.f), FRandomBetween(-.2f, 1.f), FRandomBetween(-1.f, 1.f)); |
||
| 508 | ts2 = BrVector3Dot(&norm, &tv); |
||
| 509 | BrVector3Scale(&tv2, &norm, ts2); |
||
| 510 | BrVector3Sub(&gSparks[gNext_spark].v, &tv, &tv2); |
||
| 511 | gSparks[gNext_spark].count = 1000; |
||
| 512 | gSparks[gNext_spark].car = pCar; |
||
| 513 | gSpark_flags |= 1u << gNext_spark; |
||
| 514 | gSparks[gNext_spark].time_sync = gMechanics_time_sync; |
||
| 515 | gSparks[gNext_spark].colour = 0; |
||
| 516 | gNext_spark++; |
||
| 517 | if (gNext_spark >= COUNT_OF(gSparks)) { |
||
| 518 | gNext_spark = 0; |
||
| 519 | } |
||
| 520 | } |
||
| 521 | CreateShrapnelShower(pos, v, &normal, ts, pCar, pCar); |
||
| 522 | } |
||
| 523 | } |
||
| 524 | |||
| 525 | // IDA: void __usercall CreateSparkShower(br_vector3 *pos@<EAX>, br_vector3 *v@<EDX>, br_vector3 *pForce@<EBX>, tCar_spec *pCar1@<ECX>, tCar_spec *pCar2) |
||
| 526 | void CreateSparkShower(br_vector3* pos, br_vector3* v, br_vector3* pForce, tCar_spec* pCar1, tCar_spec* pCar2) { |
||
| 527 | br_scalar ts; |
||
| 528 | br_scalar ts2; |
||
| 529 | int num; |
||
| 530 | int i; |
||
| 531 | tCar_spec* c; |
||
| 532 | br_vector3 tv; |
||
| 533 | //br_vector3 tv2; // Pierre-Marie Baty -- unused variable |
||
| 534 | br_vector3 normal; |
||
| 535 | LOG_TRACE("(%p, %p, %p, %p, %p)", pos, v, pForce, pCar1, pCar2); |
||
| 536 | |||
| 537 | ts = BrVector3Length(pForce); |
||
| 538 | if (pCar1->driver == eDriver_local_human) { |
||
| 539 | c = pCar1; |
||
| 540 | } else { |
||
| 541 | c = pCar2; |
||
| 542 | } |
||
| 543 | BrVector3InvScale(&tv, pForce, ts); |
||
| 544 | if (ts < 10.f) { |
||
| 545 | return; |
||
| 546 | } |
||
| 547 | CreateShrapnelShower(pos, v, &tv, ts, pCar1, pCar2); |
||
| 548 | ts2 = BrVector3Dot(pForce, v) / (ts * ts); |
||
| 549 | BrVector3Scale(v, pForce, ts2); |
||
| 550 | normal.v[0] = pos->v[0] - c->car_master_actor->t.t.translate.t.v[0] / WORLD_SCALE; |
||
| 551 | normal.v[1] = pos->v[1] - c->car_master_actor->t.t.translate.t.v[1] / WORLD_SCALE; |
||
| 552 | normal.v[2] = pos->v[2] - c->car_master_actor->t.t.translate.t.v[2] / WORLD_SCALE; |
||
| 553 | BrMatrix34TApplyV(pos, &normal, &c->car_master_actor->t.t.mat); |
||
| 554 | BrMatrix34TApplyV(&normal, pForce, &c->car_master_actor->t.t.mat); |
||
| 555 | num = (ts / 10.f) + 3; |
||
| 556 | for (i = 0; i < num; i++) { |
||
| 557 | BrVector3Copy(&gSparks[gNext_spark].pos, pos); |
||
| 558 | BrVector3SetFloat(&gSparks[gNext_spark].normal, 0.f, 0.f, 0.f); |
||
| 559 | BrVector3SetFloat(&normal, FRandomBetween(-1.f, 1.f), FRandomBetween(-.2f, 1.f), FRandomBetween(-1.f, 1.f)); |
||
| 560 | ts2 = BrVector3LengthSquared(&normal) / (ts * ts); |
||
| 561 | BrVector3Scale(&tv, &normal, ts2); |
||
| 562 | BrVector3Sub(&gSparks[gNext_spark].v, &normal, &tv); |
||
| 563 | BrVector3Accumulate(&gSparks[gNext_spark].v, v); |
||
| 564 | gSparks[gNext_spark].count = 1000; |
||
| 565 | gSparks[gNext_spark].car = c; |
||
| 566 | gSpark_flags |= 1u << gNext_spark; |
||
| 567 | gSparks[gNext_spark].time_sync = gMechanics_time_sync; |
||
| 568 | gSparks[gNext_spark].colour = 0; |
||
| 569 | gNext_spark++; |
||
| 570 | if (gNext_spark >= COUNT_OF(gSparks)) { |
||
| 571 | gNext_spark = 0; |
||
| 572 | } |
||
| 573 | } |
||
| 574 | } |
||
| 575 | |||
| 576 | // IDA: void __usercall AdjustSpark(int pSpark_num@<EAX>, br_vector3 *pos@<EDX>, br_vector3 *length@<EBX>) |
||
| 577 | void AdjustSpark(int pSpark_num, br_vector3* pos, br_vector3* length) { |
||
| 578 | br_vector3 tv; |
||
| 579 | br_matrix34* mat; |
||
| 580 | int i; |
||
| 581 | LOG_TRACE("(%d, %p, %p)", pSpark_num, pos, length); |
||
| 582 | |||
| 583 | i = pSpark_num & 0xff; |
||
| 584 | gSpark_flags |= 1u << pSpark_num; |
||
| 585 | if (gSparks[i].car != NULL) { |
||
| 586 | mat = &gSparks[i].car->car_master_actor->t.t.mat; |
||
| 587 | tv.v[0] = pos->v[0] - mat->m[3][0]; |
||
| 588 | tv.v[1] = pos->v[0] - mat->m[3][1]; |
||
| 589 | tv.v[2] = pos->v[0] - mat->m[3][2]; |
||
| 590 | BrMatrix34TApplyV(&gSparks[i].pos, &tv, mat); |
||
| 591 | } else { |
||
| 592 | gSparks[i].pos.v[0] = pos->v[0]; |
||
| 593 | gSparks[i].pos.v[1] = pos->v[1]; |
||
| 594 | gSparks[i].pos.v[2] = pos->v[2]; |
||
| 595 | } |
||
| 596 | gSparks[i].length.v[0] = length->v[0]; |
||
| 597 | gSparks[i].length.v[1] = length->v[1]; |
||
| 598 | gSparks[i].length.v[2] = length->v[2]; |
||
| 599 | gSparks[i].colour = pSpark_num >> 8; |
||
| 600 | } |
||
| 601 | |||
| 602 | // IDA: void __usercall AdjustShrapnel(int pShrapnel_num@<EAX>, br_vector3 *pos@<EDX>, tU16 pAge@<EBX>, br_material *pMaterial@<ECX>) |
||
| 603 | void AdjustShrapnel(int pShrapnel_num, br_vector3* pos, tU16 pAge, br_material* pMaterial) { |
||
| 604 | int i; |
||
| 605 | LOG_TRACE("(%d, %p, %d, %p)", pShrapnel_num, pos, pAge, pMaterial); |
||
| 606 | |||
| 607 | i = pShrapnel_num & 0x7fff; |
||
| 608 | if (!(gShrapnel_flags & (1u << i))) { |
||
| 609 | BrActorAdd(gNon_track_actor, gShrapnel[i].actor); |
||
| 610 | } |
||
| 611 | gShrapnel_flags |= 1u << i; |
||
| 612 | gShrapnel[i].actor->t.t.translate.t.v[0] = pos->v[0]; |
||
| 613 | gShrapnel[i].actor->t.t.translate.t.v[1] = pos->v[1]; |
||
| 614 | gShrapnel[i].actor->t.t.translate.t.v[2] = pos->v[2]; |
||
| 615 | if (pShrapnel_num & 0x8000) { |
||
| 616 | gShrapnel[i].age = pAge; |
||
| 617 | gShrapnel[i].actor->material = pMaterial; |
||
| 618 | } |
||
| 619 | } |
||
| 620 | |||
| 621 | // IDA: void __cdecl ResetSparks() |
||
| 622 | void ResetSparks(void) { |
||
| 623 | LOG_TRACE("()"); |
||
| 624 | |||
| 625 | gSpark_flags = 0; |
||
| 626 | } |
||
| 627 | |||
| 628 | // IDA: void __cdecl ResetShrapnel() |
||
| 629 | void ResetShrapnel(void) { |
||
| 630 | int i; |
||
| 631 | LOG_TRACE("()"); |
||
| 632 | |||
| 633 | if (gShrapnel_flags == 0) { |
||
| 634 | return; |
||
| 635 | } |
||
| 636 | for (i = 0; i < COUNT_OF(gShrapnel); i++) { |
||
| 637 | if (gShrapnel_flags & (1u << i)) { |
||
| 638 | BrActorRemove(gShrapnel[i].actor); |
||
| 639 | } |
||
| 640 | } |
||
| 641 | gShrapnel_flags = 0; |
||
| 642 | } |
||
| 643 | |||
| 644 | // 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) |
||
| 645 | void CreateShrapnelShower(br_vector3* pos, br_vector3* v, br_vector3* pNormal, br_scalar pForce, tCar_spec* c1, tCar_spec* c2) { |
||
| 646 | br_scalar ts; |
||
| 647 | br_scalar ts2; |
||
| 648 | br_scalar rnd; |
||
| 649 | int num; |
||
| 650 | int i; |
||
| 651 | tCar_spec* c; |
||
| 652 | br_vector3 tv; |
||
| 653 | br_vector3 tv2; |
||
| 654 | br_vector3 vel; |
||
| 655 | LOG_TRACE("(%p, %p, %p, %f, %p, %p)", pos, v, pNormal, pForce, c1, c2); |
||
| 656 | |||
| 657 | if (pForce < 10.f) { |
||
| 658 | return; |
||
| 659 | } |
||
| 660 | ts = .3f; |
||
| 661 | if (v->v[1] < 0.f) { |
||
| 662 | ts = .3f - v->v[1]; |
||
| 663 | } |
||
| 664 | ts2 = pNormal->v[1] * ts; |
||
| 665 | |||
| 666 | tv.v[0] = v->v[0] - ts2 * pNormal->v[0]; |
||
| 667 | tv.v[1] = v->v[1] + ts - pNormal->v[1] * ts2; |
||
| 668 | tv.v[2] = v->v[2] - pNormal->v[2] * ts2; |
||
| 669 | |||
| 670 | num = (pForce / 10.f) * 3; |
||
| 671 | rnd = ((pForce + 20.f) * 3.f) / 200.f; |
||
| 672 | for (i = 0; i < num; i++) { |
||
| 673 | if ((gShrapnel_flags & (1u << gNext_shrapnel)) == 0) { |
||
| 674 | BrActorAdd(gNon_track_actor, gShrapnel[gNext_shrapnel].actor); |
||
| 675 | } |
||
| 676 | gShrapnel_flags |= 1u << gNext_shrapnel; |
||
| 677 | BrVector3Copy(&gShrapnel[gNext_shrapnel].actor->t.t.translate.t, pos); |
||
| 678 | BrVector3SetFloat(&vel, FRandomBetween(-rnd, rnd), FRandomBetween(0.3f - tv.v[1], rnd), FRandomBetween(-rnd, rnd)); |
||
| 679 | ts2 = BrVector3Dot(pNormal, &vel); |
||
| 680 | BrVector3Scale(&tv2, pNormal, ts2); |
||
| 681 | BrVector3Sub(&gShrapnel[gNext_shrapnel].v, &vel, &tv2); |
||
| 682 | BrVector3Accumulate(&gShrapnel[gNext_shrapnel].v, &tv); |
||
| 683 | gShrapnel[gNext_shrapnel].time_sync = gMechanics_time_sync; |
||
| 684 | gShrapnel[gNext_shrapnel].age = 0; |
||
| 685 | if (IRandomBetween(0, 2) != 0) { |
||
| 686 | c = (IRandomBetween(0, 1) != 0) ? c1 : c2; |
||
| 687 | gShrapnel[gNext_shrapnel].actor->material = c->shrapnel_material[IRandomBetween(0, c->max_shrapnel_material - 1)]; |
||
| 688 | } else { |
||
| 689 | gShrapnel[gNext_shrapnel].actor->material = gBlack_material; |
||
| 690 | } |
||
| 691 | gNext_shrapnel++; |
||
| 692 | if (gNext_shrapnel >= COUNT_OF(gShrapnel)) { |
||
| 693 | gNext_shrapnel = 0; |
||
| 694 | } |
||
| 695 | } |
||
| 696 | } |
||
| 697 | |||
| 698 | // IDA: void __cdecl InitShrapnel() |
||
| 699 | void InitShrapnel(void) { |
||
| 700 | int i; |
||
| 701 | //int j; // Pierre-Marie Baty -- unused variable |
||
| 702 | LOG_TRACE("()"); |
||
| 703 | |||
| 704 | for (i = 0; i < COUNT_OF(gShrapnel); i++) { |
||
| 705 | gShrapnel[i].actor = BrActorAllocate(BR_ACTOR_MODEL, NULL); |
||
| 706 | gShrapnel[i].actor->parent = NULL; |
||
| 707 | gShrapnel[i].actor->model = gShrapnel_model[1]; |
||
| 708 | gShrapnel[i].actor->render_style = BR_RSTYLE_DEFAULT; |
||
| 709 | gShrapnel[i].actor->t.type = BR_TRANSFORM_MATRIX34; |
||
| 710 | gShrapnel[i].actor->material = BrMaterialFind("DEBRIS.MAT"); |
||
| 711 | gShrapnel[i].age = 0; |
||
| 712 | gShrapnel[i].shear1 = FRandomBetween(-2.f, 2.f); |
||
| 713 | gShrapnel[i].shear2 = FRandomBetween(-2.f, 2.f); |
||
| 714 | BrVector3SetFloat(&gShrapnel[i].axis, |
||
| 715 | FRandomBetween(-1.f, 1.f), FRandomBetween(-1.f, 1.f), FRandomBetween(-1.f, 1.f)); |
||
| 716 | BrVector3Normalise(&gShrapnel[i].axis, &gShrapnel[i].axis); |
||
| 717 | } |
||
| 718 | } |
||
| 719 | |||
| 720 | // IDA: void __cdecl LoadInShrapnel() |
||
| 721 | void LoadInShrapnel(void) { |
||
| 722 | LOG_TRACE("()"); |
||
| 723 | |||
| 724 | gShrapnel_model[0] = LoadModel("FRAG4.DAT"); |
||
| 725 | gShrapnel_model[1] = LoadModel("FRAG5.DAT"); |
||
| 726 | BrModelAdd(gShrapnel_model[0]); |
||
| 727 | BrModelAdd(gShrapnel_model[1]); |
||
| 728 | gBlack_material = BrMaterialFind("M14.MAT"); |
||
| 729 | } |
||
| 730 | |||
| 731 | // IDA: void __usercall KillShrapnel(int i@<EAX>) |
||
| 732 | void KillShrapnel(int i) { |
||
| 733 | LOG_TRACE("(%d)", i); |
||
| 734 | |||
| 735 | BrActorRemove(gShrapnel[i].actor); |
||
| 736 | gShrapnel_flags &= ~(1u << i); |
||
| 737 | } |
||
| 738 | |||
| 739 | // IDA: void __cdecl DisposeShrapnel() |
||
| 740 | void DisposeShrapnel(void) { |
||
| 741 | int i; |
||
| 742 | LOG_TRACE("()"); |
||
| 743 | |||
| 744 | for (i = 0; i < COUNT_OF(gShrapnel); i++) { |
||
| 745 | if (gShrapnel_flags & (1u << i)) { |
||
| 746 | BrActorRemove(gShrapnel[i].actor); |
||
| 747 | } |
||
| 748 | BrActorFree(gShrapnel[i].actor); |
||
| 749 | } |
||
| 750 | gShrapnel_flags = 0; |
||
| 751 | for (i = 0; i < COUNT_OF(gShrapnel_model); i++) { |
||
| 752 | BrModelRemove(gShrapnel_model[i]); |
||
| 753 | BrModelFree(gShrapnel_model[i]); |
||
| 754 | } |
||
| 755 | } |
||
| 756 | |||
| 757 | // IDA: void __usercall ReplayShrapnel(tU32 pTime@<EAX>) |
||
| 758 | void ReplayShrapnel(tU32 pTime) { |
||
| 759 | int i; |
||
| 760 | br_matrix34* mat; |
||
| 761 | LOG_TRACE("(%d)", pTime); |
||
| 762 | |||
| 763 | for (i = 0; i < COUNT_OF(gShrapnel); i++) { |
||
| 764 | mat = &gShrapnel[i].actor->t.t.mat; |
||
| 765 | if (gShrapnel_flags & (1 << i)) { |
||
| 766 | gShrapnel[i].age += GetReplayRate() * pTime; |
||
| 767 | DrMatrix34Rotate(mat, gShrapnel[i].age * BrDegreeToAngle(1), &gShrapnel[i].axis); |
||
| 768 | BrMatrix34PreShearX(mat, gShrapnel[i].shear1, gShrapnel[i].shear2); |
||
| 769 | } |
||
| 770 | } |
||
| 771 | } |
||
| 772 | |||
| 773 | // IDA: void __usercall MungeShrapnel(tU32 pTime@<EAX>) |
||
| 774 | void MungeShrapnel(tU32 pTime) { |
||
| 775 | br_vector3 disp; |
||
| 776 | int i; |
||
| 777 | br_matrix34* mat; |
||
| 778 | br_scalar ts; |
||
| 779 | LOG_TRACE("(%d)", pTime); |
||
| 780 | |||
| 781 | MungeSmokeColumn(pTime); |
||
| 782 | MungeSplash(pTime); |
||
| 783 | |||
| 784 | if (gAction_replay_mode) { |
||
| 785 | ReplayShrapnel(pTime); |
||
| 786 | return; |
||
| 787 | } |
||
| 788 | |||
| 789 | StartPipingSession(ePipe_chunk_shrapnel); |
||
| 790 | for (i = 0; i < COUNT_OF(gShrapnel); i++) { |
||
| 791 | mat = &gShrapnel[i].actor->t.t.mat; |
||
| 792 | if (((1u << i) & gShrapnel_flags) == 0) { |
||
| 793 | continue; |
||
| 794 | } |
||
| 795 | if (gShrapnel[i].age == -1) { |
||
| 796 | KillShrapnel(i); |
||
| 797 | } else { |
||
| 798 | if (gShrapnel[i].time_sync) { |
||
| 799 | BrVector3Scale(&disp, &gShrapnel[i].v, gShrapnel[i].time_sync / 1000.0f); |
||
| 800 | gShrapnel[i].time_sync = 0; |
||
| 801 | } else { |
||
| 802 | BrVector3Scale(&disp, &gShrapnel[i].v, pTime / 1000.0f); |
||
| 803 | gShrapnel[i].age += pTime; |
||
| 804 | } |
||
| 805 | mat->m[3][0] = mat->m[3][0] + disp.v[0]; |
||
| 806 | mat->m[3][1] = mat->m[3][1] + disp.v[1]; |
||
| 807 | mat->m[3][2] = mat->m[3][2] + disp.v[2]; |
||
| 808 | gShrapnel[i].v.v[1] -= (10 * pTime) * 0.00014492753f; |
||
| 809 | DrMatrix34Rotate(mat, 182 * gShrapnel[i].age, &gShrapnel[i].axis); |
||
| 810 | BrMatrix34PreShearX(mat, gShrapnel[i].shear1, gShrapnel[i].shear2); |
||
| 811 | // bug: should this be using "&gShrapnel[i].v"?? |
||
| 812 | ts = 1.0 - BrVector3Length(&gSparks[i].v) / 1.4 * pTime / 1000.0; |
||
| 813 | if (ts < 0.1) { |
||
| 814 | ts = (br_scalar) 0.1; // Pierre-Marie Baty -- added type cast |
||
| 815 | } |
||
| 816 | BrVector3Scale(&gShrapnel[i].v, &gShrapnel[i].v, ts); |
||
| 817 | AddShrapnelToPipingSession(i + ((gShrapnel[i].age > 1000 || gShrapnel[i].age < pTime) << 15), (br_vector3*)mat->m[3], gShrapnel[i].age - pTime, gShrapnel[i].actor->material); |
||
| 818 | if (gShrapnel[i].age > 1000) { |
||
| 819 | gShrapnel[i].age = -1; |
||
| 820 | } |
||
| 821 | } |
||
| 822 | } |
||
| 823 | EndPipingSession(); |
||
| 824 | } |
||
| 825 | |||
| 826 | // IDA: void __usercall DrMatrix34Rotate(br_matrix34 *mat@<EAX>, br_angle r@<EDX>, br_vector3 *a@<EBX>) |
||
| 827 | void DrMatrix34Rotate(br_matrix34* mat, br_angle r, br_vector3* a) { |
||
| 828 | br_scalar t; |
||
| 829 | br_scalar s; |
||
| 830 | br_scalar c; |
||
| 831 | br_scalar txy; |
||
| 832 | br_scalar txz; |
||
| 833 | br_scalar tyz; |
||
| 834 | br_scalar sx; |
||
| 835 | br_scalar sy; |
||
| 836 | br_scalar sz; |
||
| 837 | LOG_TRACE("(%p, %d, %p)", mat, r, a); |
||
| 838 | |||
| 839 | s = FastScalarSinAngle(r); |
||
| 840 | c = FastScalarCosAngle(r); |
||
| 841 | t = 1.0f - c; |
||
| 842 | txy = t * a->v[0] * a->v[1]; |
||
| 843 | txz = t * a->v[0] * a->v[2]; |
||
| 844 | tyz = t * a->v[1] * a->v[2]; |
||
| 845 | sx = a->v[0] * s; |
||
| 846 | sy = a->v[1] * s; |
||
| 847 | sz = a->v[2] * s; |
||
| 848 | mat->m[0][0] = a->v[0] * a->v[0] * t + c; |
||
| 849 | mat->m[0][1] = sz + txy; |
||
| 850 | mat->m[0][2] = txz - sy; |
||
| 851 | mat->m[1][0] = txy - sz; |
||
| 852 | mat->m[1][1] = a->v[1] * a->v[1] * t + c; |
||
| 853 | mat->m[1][2] = sx + tyz; |
||
| 854 | mat->m[2][0] = sy + txz; |
||
| 855 | mat->m[2][1] = tyz - sx; |
||
| 856 | mat->m[2][2] = a->v[2] * a->v[2] * t + c; |
||
| 857 | } |
||
| 858 | |||
| 859 | // 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) |
||
| 860 | 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) { |
||
| 861 | int i; |
||
| 862 | int offset; /* Added by dethrace. */ |
||
| 863 | int r_multiplier_int; |
||
| 864 | int shade_offset_int; |
||
| 865 | tU16 z; |
||
| 866 | 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); |
||
| 867 | |||
| 868 | scr_ptr += gOffset; |
||
| 869 | if (gProgram_state.cockpit_on) { |
||
| 870 | depth_ptr += gOffset; |
||
| 871 | } |
||
| 872 | z = (1.f - zbuff) * 32768.0f; |
||
| 873 | r_multiplier_int = r_multiplier * 65536.0f; |
||
| 874 | shade_offset_int = shade_offset * 65536.0f; |
||
| 875 | |||
| 876 | for (i = 0; i < l; i++) { |
||
| 877 | if (*depth_ptr > z) { |
||
| 878 | offset = ((shade_offset_int - r_squared * r_multiplier_int) >> 8) & 0xffffff00; |
||
| 879 | #if defined(DETHRACE_FIX_BUGS) |
||
| 880 | /* Prevent buffer underflows by capping negative offsets. */ |
||
| 881 | offset = MAX(0, offset); |
||
| 882 | #endif |
||
| 883 | *scr_ptr = shade_ptr[*scr_ptr + offset]; |
||
| 884 | } |
||
| 885 | r_multiplier = x + r_squared; |
||
| 886 | scr_ptr++; |
||
| 887 | x++; |
||
| 888 | depth_ptr++; |
||
| 889 | r_squared = x + r_multiplier; |
||
| 890 | } |
||
| 891 | } |
||
| 892 | |||
| 893 | // 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) |
||
| 894 | 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) { |
||
| 895 | tU8* scr_ptr; |
||
| 896 | tU16* depth_ptr; |
||
| 897 | tU8* shade_ptr; |
||
| 898 | tU8* osp; |
||
| 899 | tU16* odp; |
||
| 900 | int ox; |
||
| 901 | int oy; |
||
| 902 | //int i; // Pierre-Marie Baty -- unused variable |
||
| 903 | int r_squared; |
||
| 904 | int max_r_squared; |
||
| 905 | int l; |
||
| 906 | int l2; |
||
| 907 | int x; |
||
| 908 | int x2; |
||
| 909 | //int sx; // Pierre-Marie Baty -- unused variable |
||
| 910 | int y; |
||
| 911 | int inc; |
||
| 912 | int y_limit; |
||
| 913 | int max_x; |
||
| 914 | int min_x; |
||
| 915 | br_scalar shade_offset; |
||
| 916 | br_scalar r_multiplier; |
||
| 917 | br_scalar ry; |
||
| 918 | br_scalar z_multiplier; |
||
| 919 | br_scalar zbuff; |
||
| 920 | br_scalar aspect_squared; |
||
| 921 | void (*line)(int, int, br_scalar, int, tU8*, tU16*, tU8*, br_scalar, br_scalar, br_scalar); |
||
| 922 | LOG_TRACE("(%p, %f, %f, %f, %f, %p, %p, %p)", o, r, extra_z, strength, pAspect, pRender_screen, pDepth_buffer, pShade_table); |
||
| 923 | |||
| 924 | line = SmokeLine; |
||
| 925 | ox = pRender_screen->width / 2 + o->v[0]; |
||
| 926 | oy = pRender_screen->height / 2 + o->v[1]; |
||
| 927 | max_r_squared = r * r; |
||
| 928 | zbuff = o->v[2]; |
||
| 929 | aspect_squared = pAspect * pAspect; |
||
| 930 | if (pRender_screen->width / 4 <= r |
||
| 931 | || pRender_screen->width <= ox - r |
||
| 932 | || ox + r < 0.0f) { |
||
| 933 | return; |
||
| 934 | } |
||
| 935 | shade_ptr = (tU8*)pShade_table->pixels + pShade_table->row_bytes * (pShade_table->base_y + 1); |
||
| 936 | shade_offset = strength * 14.99f; |
||
| 937 | r_multiplier = shade_offset / (double)max_r_squared; |
||
| 938 | z_multiplier = extra_z / (double)max_r_squared; |
||
| 939 | max_x = pRender_screen->width - ox - 1; |
||
| 940 | min_x = -ox; |
||
| 941 | ry = r / pAspect; |
||
| 942 | l = pRender_screen->height - oy - 1; |
||
| 943 | scr_ptr = pRender_screen->pixels; |
||
| 944 | scr_ptr += pRender_screen->base_x + pRender_screen->base_y * pRender_screen->row_bytes + ox + l * pRender_screen->row_bytes; |
||
| 945 | depth_ptr = (tU16*)pDepth_buffer->pixels + ox + l * (pDepth_buffer->row_bytes / 2); |
||
| 946 | osp = scr_ptr; |
||
| 947 | odp = depth_ptr; |
||
| 948 | if (pRender_screen->height > oy && oy + ry >= 0.0) { |
||
| 949 | r_squared = r * r; |
||
| 950 | inc = -r; |
||
| 951 | y = 0; |
||
| 952 | y_limit = ry; |
||
| 953 | if (oy < 0) { |
||
| 954 | y = -oy; |
||
| 955 | r_squared = (y * y) * aspect_squared; |
||
| 956 | scr_ptr += oy * pRender_screen->row_bytes; |
||
| 957 | depth_ptr += oy * (pDepth_buffer->row_bytes / 2); |
||
| 958 | inc = -sqrtf(max_r_squared - r_squared); |
||
| 959 | r_squared += inc * inc; |
||
| 960 | } |
||
| 961 | if (pRender_screen->height < oy + ry) { |
||
| 962 | y_limit = pRender_screen->height - oy - 1; |
||
| 963 | } |
||
| 964 | l = -2 * inc; |
||
| 965 | scr_ptr += inc; |
||
| 966 | depth_ptr += inc; |
||
| 967 | gOffset = 0; |
||
| 968 | while (1) { |
||
| 969 | |||
| 970 | x = inc + gOffset; |
||
| 971 | if (min_x <= inc + gOffset && l + x - 1 <= max_x) { |
||
| 972 | line(l, inc, zbuff, r_squared, scr_ptr, depth_ptr, shade_ptr, r_multiplier, z_multiplier, shade_offset); |
||
| 973 | } else { |
||
| 974 | if (max_x < x || l + x < min_x) { |
||
| 975 | break; |
||
| 976 | } |
||
| 977 | x2 = l; |
||
| 978 | if (l + x - 1 - max_x > 0) { |
||
| 979 | x2 = max_x - (x - 1); |
||
| 980 | } |
||
| 981 | if (min_x - x <= 0) { |
||
| 982 | line(x2, inc, zbuff, r_squared, scr_ptr, depth_ptr, shade_ptr, r_multiplier, z_multiplier, shade_offset); |
||
| 983 | } else { |
||
| 984 | 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); |
||
| 985 | } |
||
| 986 | } |
||
| 987 | if (y_limit <= y) { |
||
| 988 | break; |
||
| 989 | } |
||
| 990 | y++; |
||
| 991 | scr_ptr -= pRender_screen->row_bytes; |
||
| 992 | depth_ptr -= pDepth_buffer->row_bytes / 2; |
||
| 993 | for (r_squared += (2 * y - 1) * aspect_squared; max_r_squared < r_squared && inc < 0; r_squared += 2 * inc - 1) { |
||
| 994 | inc++; |
||
| 995 | scr_ptr++; |
||
| 996 | depth_ptr++; |
||
| 997 | l -= 2; |
||
| 998 | } |
||
| 999 | gOffset += IRandomBetween(-1, 1); |
||
| 1000 | if (gOffset > r / 5.f) { |
||
| 1001 | gOffset = r / 5.f; |
||
| 1002 | } |
||
| 1003 | if (gOffset < -(r / 5.f)) { |
||
| 1004 | gOffset = -(r / 5.f); |
||
| 1005 | } |
||
| 1006 | } |
||
| 1007 | } |
||
| 1008 | if (pAspect < 1.0) { |
||
| 1009 | aspect_squared = 9.f; |
||
| 1010 | ry = r / 3.f; |
||
| 1011 | } |
||
| 1012 | if (oy > 0 && oy <= pRender_screen->height + ry - 2.f) { |
||
| 1013 | r_squared = (r * r); |
||
| 1014 | inc = -r; |
||
| 1015 | y = 0; |
||
| 1016 | scr_ptr = osp; |
||
| 1017 | depth_ptr = odp; |
||
| 1018 | y_limit = ry; |
||
| 1019 | if (pRender_screen->height < oy) { |
||
| 1020 | l2 = oy - pRender_screen->height; |
||
| 1021 | y = pRender_screen->height - oy; |
||
| 1022 | r_squared = y * y * aspect_squared; |
||
| 1023 | scr_ptr = &osp[l2 * pRender_screen->row_bytes]; |
||
| 1024 | depth_ptr = &odp[l2 * (pDepth_buffer->row_bytes / 2)]; |
||
| 1025 | inc = -sqrtf(max_r_squared - r_squared); |
||
| 1026 | r_squared += inc * inc; |
||
| 1027 | } |
||
| 1028 | if (oy - ry < 0.f) { |
||
| 1029 | y_limit = oy; |
||
| 1030 | } |
||
| 1031 | l = -2 * inc; |
||
| 1032 | scr_ptr += inc; |
||
| 1033 | depth_ptr += inc; |
||
| 1034 | gOffset = 0; |
||
| 1035 | do { |
||
| 1036 | y--; |
||
| 1037 | scr_ptr += pRender_screen->row_bytes; |
||
| 1038 | depth_ptr += pDepth_buffer->row_bytes / 2; |
||
| 1039 | for (r_squared -= (2 * y - 1) * aspect_squared; max_r_squared < r_squared && inc < 0; r_squared += 2 * inc - 1) { |
||
| 1040 | inc++; |
||
| 1041 | scr_ptr++; |
||
| 1042 | depth_ptr++; |
||
| 1043 | l -= 2; |
||
| 1044 | } |
||
| 1045 | x = inc + gOffset; |
||
| 1046 | if (min_x <= inc + gOffset && l + x - 1 <= max_x) { |
||
| 1047 | line(l, inc, zbuff, r_squared, scr_ptr, depth_ptr, shade_ptr, r_multiplier, z_multiplier, shade_offset); |
||
| 1048 | } else { |
||
| 1049 | if (max_x < x || l + x < min_x) { |
||
| 1050 | return; |
||
| 1051 | } |
||
| 1052 | x2 = l; |
||
| 1053 | if (l + x - 1 - max_x > 0) { |
||
| 1054 | x2 = max_x - (x - 1); |
||
| 1055 | } |
||
| 1056 | if (min_x - x <= 0) { |
||
| 1057 | line(x2, inc, zbuff, r_squared, scr_ptr, depth_ptr, shade_ptr, r_multiplier, z_multiplier, shade_offset); |
||
| 1058 | } else { |
||
| 1059 | 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); |
||
| 1060 | } |
||
| 1061 | } |
||
| 1062 | gOffset += IRandomBetween(-1, 1); |
||
| 1063 | if (gOffset > r / 5.0) { |
||
| 1064 | gOffset = r / 5.0; |
||
| 1065 | } |
||
| 1066 | if (gOffset < -(r / 5.0)) { |
||
| 1067 | gOffset = -r / 5.0; |
||
| 1068 | } |
||
| 1069 | } while (-y < y_limit); |
||
| 1070 | } |
||
| 1071 | } |
||
| 1072 | |||
| 1073 | // IDA: int __cdecl CmpSmokeZ(void *p1, void *p2) |
||
| 1074 | int CmpSmokeZ(void* p1, void* p2) { |
||
| 1075 | //tBRender_smoke** a; // Pierre-Marie Baty -- unused variable |
||
| 1076 | //tBRender_smoke** b; // Pierre-Marie Baty -- unused variable |
||
| 1077 | LOG_TRACE("(%p, %p)", p1, p2); |
||
| 1078 | NOT_IMPLEMENTED(); |
||
| 1079 | } |
||
| 1080 | |||
| 1081 | // IDA: void __cdecl RenderRecordedSmokeCircles() |
||
| 1082 | void RenderRecordedSmokeCircles(void) { |
||
| 1083 | //int i; // Pierre-Marie Baty -- unused variable |
||
| 1084 | //tBRender_smoke* smoke; // Pierre-Marie Baty -- unused variable |
||
| 1085 | //tU8 red; // Pierre-Marie Baty -- unused variable |
||
| 1086 | //tU8 grn; // Pierre-Marie Baty -- unused variable |
||
| 1087 | //tU8 blu; // Pierre-Marie Baty -- unused variable |
||
| 1088 | LOG_TRACE("()"); |
||
| 1089 | NOT_IMPLEMENTED(); |
||
| 1090 | } |
||
| 1091 | |||
| 1092 | // IDA: void __usercall RecordSmokeCircle(br_vector3 *pCent@<EAX>, br_scalar pR, br_scalar pStrength, br_pixelmap *pShade, br_scalar pAspect) |
||
| 1093 | void RecordSmokeCircle(br_vector3* pCent, br_scalar pR, br_scalar pStrength, br_pixelmap* pShade, br_scalar pAspect) { |
||
| 1094 | //tU8 shade_index; // Pierre-Marie Baty -- unused variable |
||
| 1095 | //br_colour shade_rgb; // Pierre-Marie Baty -- unused variable |
||
| 1096 | LOG_TRACE("(%p, %f, %f, %p, %f)", pCent, pR, pStrength, pShade, pAspect); |
||
| 1097 | NOT_IMPLEMENTED(); |
||
| 1098 | } |
||
| 1099 | |||
| 1100 | // 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) |
||
| 1101 | 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) { |
||
| 1102 | br_vector3 tv; |
||
| 1103 | br_vector3 p; |
||
| 1104 | br_vector4 o2; |
||
| 1105 | br_camera* cam; |
||
| 1106 | int scaled_r; |
||
| 1107 | br_scalar extra_z; |
||
| 1108 | LOG_TRACE("(%p, %f, %f, %f, %p, %p, %p, %p)", o, r, strength, pAspect, pRender_screen, pDepth_buffer, pShade_table, pCam); |
||
| 1109 | |||
| 1110 | cam = pCam->type_data; |
||
| 1111 | srand(o->v[2] * 16777216.0f + o->v[1] * 65536.0f + o->v[0] * 256.0f + r); |
||
| 1112 | BrVector3Sub(&tv, o, (br_vector3*)gCamera_to_world.m[3]); |
||
| 1113 | BrMatrix34TApplyV(&p, &tv, &gCamera_to_world); |
||
| 1114 | |||
| 1115 | if (-p.v[2] >= cam->hither_z && -p.v[2] <= cam->yon_z) { |
||
| 1116 | scaled_r = gCameraToScreen.m[0][0] * r / -p.v[2]; |
||
| 1117 | extra_z = gCameraToScreen.m[3][2] * r / (p.v[2] * p.v[2]); |
||
| 1118 | BrMatrix4ApplyP(&o2, &p, &gCameraToScreen); |
||
| 1119 | BrVector3InvScale(&p, &o2, o2.v[3]); |
||
| 1120 | SmokeCircle(&p, (br_scalar)scaled_r, extra_z, strength, pAspect, pRender_screen, pDepth_buffer, pShade_table); |
||
| 1121 | } |
||
| 1122 | } |
||
| 1123 | |||
| 1124 | // IDA: void __usercall ReplaySmoke(br_pixelmap *pRender_screen@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>) |
||
| 1125 | void ReplaySmoke(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_actor* pCamera) { |
||
| 1126 | br_scalar aspect; |
||
| 1127 | int i; |
||
| 1128 | LOG_TRACE("(%p, %p, %p)", pRender_screen, pDepth_buffer, pCamera); |
||
| 1129 | |||
| 1130 | for (i = 0; i < COUNT_OF(gSmoke_column); i++) { |
||
| 1131 | if (gSmoke_flags & (1 << i)) { |
||
| 1132 | aspect = 1.f + (gSmoke[i].radius - .05f) / .25f * .5f; |
||
| 1133 | if (gSmoke[i].type & 0x10) { |
||
| 1134 | SmokeCircle3D(&gSmoke[i].pos, gSmoke[i].radius / aspect, gSmoke[i].strength, 1.f, |
||
| 1135 | pRender_screen, pDepth_buffer, gShade_list[gSmoke[i].type & 0xf], pCamera); |
||
| 1136 | } else { |
||
| 1137 | SmokeCircle3D(&gSmoke[i].pos, gSmoke[i].radius, gSmoke[i].strength, aspect, |
||
| 1138 | pRender_screen, pDepth_buffer, gShade_list[gSmoke[i].type & 0xf], pCamera); |
||
| 1139 | } |
||
| 1140 | } |
||
| 1141 | } |
||
| 1142 | } |
||
| 1143 | |||
| 1144 | // IDA: void __usercall GenerateContinuousSmoke(tCar_spec *pCar@<EAX>, int wheel@<EDX>, tU32 pTime@<EBX>) |
||
| 1145 | void GenerateContinuousSmoke(tCar_spec* pCar, int wheel, tU32 pTime) { |
||
| 1146 | br_vector3 pos; |
||
| 1147 | br_vector3 v; |
||
| 1148 | br_vector3 vcs; |
||
| 1149 | br_vector3 tv; |
||
| 1150 | br_scalar decay_factor; |
||
| 1151 | br_scalar ts; |
||
| 1152 | br_scalar alpha; |
||
| 1153 | br_scalar beta; |
||
| 1154 | int colour; |
||
| 1155 | LOG_TRACE("(%p, %d, %d)", pCar, wheel, pTime); |
||
| 1156 | |||
| 1157 | if (pCar->dust_time[wheel] > (int) pTime) { // Pierre-Marie Baty -- added type cast |
||
| 1158 | pCar->dust_time[wheel] -= pTime; |
||
| 1159 | return; |
||
| 1160 | } |
||
| 1161 | pCar->dust_time[wheel] += IRandomBetween(200, 400) - pTime; |
||
| 1162 | if (pCar->dust_time[wheel] < 0) { |
||
| 1163 | pCar->dust_time[wheel] = 0; |
||
| 1164 | } |
||
| 1165 | BrVector3Cross(&tv, &pCar->omega, &pCar->wpos[wheel]); |
||
| 1166 | BrVector3Scale(&vcs, &pCar->velocity_car_space, WORLD_SCALE * 1000.0f); |
||
| 1167 | BrVector3Accumulate(&vcs, &tv); |
||
| 1168 | ts = BrVector3LengthSquared(&vcs); |
||
| 1169 | if (ts < 25.0f) { |
||
| 1170 | return; |
||
| 1171 | } |
||
| 1172 | decay_factor = sqrtf(ts) / 25.0f; |
||
| 1173 | if (decay_factor > 1.0f) { |
||
| 1174 | decay_factor = 1.0f; |
||
| 1175 | } |
||
| 1176 | BrVector3InvScale(&tv, &pCar->wpos[wheel], WORLD_SCALE); |
||
| 1177 | tv.v[1] -= pCar->oldd[wheel] / WORLD_SCALE; |
||
| 1178 | |||
| 1179 | alpha = -1000.0f; |
||
| 1180 | if (vcs.v[2] > 0.0f) { |
||
| 1181 | alpha = (pCar->bounds[0].min.v[2] - tv.v[2]) / vcs.v[2]; |
||
| 1182 | } else if (vcs.v[2] < 0.0f) { |
||
| 1183 | alpha = (pCar->bounds[0].max.v[2] - tv.v[2]) / vcs.v[2]; |
||
| 1184 | } |
||
| 1185 | |||
| 1186 | beta = -1000.0f; |
||
| 1187 | if (vcs.v[0] > 0.0f) { |
||
| 1188 | beta = (pCar->bounds[0].min.v[0] - tv.v[0]) / vcs.v[0]; |
||
| 1189 | } else if (vcs.v[0] < 0.0f) { |
||
| 1190 | beta = (pCar->bounds[0].max.v[0] - tv.v[0]) / vcs.v[0]; |
||
| 1191 | } |
||
| 1192 | |||
| 1193 | ts = MAX(alpha, beta); |
||
| 1194 | BrVector3Scale(&pos, &vcs, ts); |
||
| 1195 | BrVector3Accumulate(&tv, &pos); |
||
| 1196 | BrMatrix34ApplyP(&pos, &tv, &pCar->car_master_actor->t.t.mat); |
||
| 1197 | BrMatrix34ApplyV(&v, &vcs, &pCar->car_master_actor->t.t.mat); |
||
| 1198 | |||
| 1199 | colour = gDust_rotate + gCurrent_race.material_modifiers[pCar->material_index[wheel]].smoke_type - 2; |
||
| 1200 | while (colour >= gNum_dust_tables) { |
||
| 1201 | colour -= gNum_dust_tables; |
||
| 1202 | } |
||
| 1203 | CreatePuffOfSmoke(&pos, &v, decay_factor, decay_factor * 2, colour + 8, pCar); |
||
| 1204 | } |
||
| 1205 | |||
| 1206 | // IDA: void __cdecl DustRotate() |
||
| 1207 | void DustRotate(void) { |
||
| 1208 | LOG_TRACE("()"); |
||
| 20 | pmbaty | 1209 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 1210 | } |
| 1211 | |||
| 1212 | // 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) |
||
| 1213 | void RenderSmoke(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world, tU32 pTime) { |
||
| 1214 | int i; |
||
| 1215 | int j; |
||
| 1216 | br_vector3 tv; |
||
| 1217 | br_scalar aspect; |
||
| 1218 | br_scalar ts; |
||
| 1219 | tU32 seed; |
||
| 1220 | tU32 not_lonely; |
||
| 1221 | LOG_TRACE("(%p, %p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pCamera_to_world, pTime); |
||
| 1222 | |||
| 1223 | not_lonely = 0; |
||
| 1224 | DrawTheGlow(pRender_screen, pDepth_buffer, pCamera); |
||
| 1225 | |||
| 1226 | if (gSmoke_flags != 0) { |
||
| 1227 | seed = rand(); |
||
| 1228 | if (gAction_replay_mode) { |
||
| 1229 | ReplaySmoke(pRender_screen, pDepth_buffer, pCamera); |
||
| 1230 | srand(seed); |
||
| 1231 | } else { |
||
| 1232 | StartPipingSession(ePipe_chunk_smoke); |
||
| 1233 | for (i = 0; i < COUNT_OF(gSmoke); i++) { |
||
| 1234 | if ((gSmoke_flags & (1u << i)) != 0) { |
||
| 1235 | if (gSmoke[i].strength > 0.0) { |
||
| 1236 | if (gSmoke[i].time_sync) { |
||
| 1237 | BrVector3Scale(&tv, &gSmoke[i].v, gSmoke[i].time_sync / 1000.0); |
||
| 1238 | gSmoke[i].time_sync = 0; |
||
| 1239 | } else { |
||
| 1240 | BrVector3Scale(&tv, &gSmoke[i].v, pTime / 1000.0); |
||
| 1241 | } |
||
| 1242 | BrVector3Accumulate(&gSmoke[i].pos, &tv); |
||
| 1243 | } else { |
||
| 1244 | gSmoke_flags &= ~(1u << i); |
||
| 1245 | } |
||
| 1246 | } |
||
| 1247 | } |
||
| 1248 | for (i = 0; i < COUNT_OF(gSmoke); i++) { |
||
| 1249 | if ((gSmoke_flags & (1u << i)) != 0) { |
||
| 1250 | if ((gSmoke[i].type & 0xf) == 7) { |
||
| 1251 | not_lonely |= 1u << i; |
||
| 1252 | } else if ((not_lonely & (1u << i)) == 0) { |
||
| 1253 | for (j = i + 1; j < COUNT_OF(gSmoke); j++) { |
||
| 1254 | if ((gSmoke_flags & (1u << j)) != 0) { |
||
| 1255 | BrVector3Sub(&tv, &gSmoke[i].pos, &gSmoke[i].pos); |
||
| 1256 | ts = BrVector3LengthSquared(&tv); |
||
| 1257 | if ((gSmoke[i].radius + gSmoke[j].radius) * (gSmoke[i].radius + gSmoke[j].radius) > ts) { |
||
| 1258 | not_lonely |= (1u << j) | (1u << i); |
||
| 1259 | break; |
||
| 1260 | } |
||
| 1261 | } |
||
| 1262 | } |
||
| 1263 | } |
||
| 1264 | if (((1u << i) & not_lonely) == 0) { |
||
| 1265 | gSmoke[i].strength = gSmoke[i].strength / 2.0; |
||
| 1266 | } |
||
| 1267 | aspect = (gSmoke[i].radius - 0.05f) / 0.25f * 0.5f + 1.0f; |
||
| 1268 | if ((gSmoke[i].type & 0x10) != 0) { |
||
| 1269 | SmokeCircle3D(&gSmoke[i].pos, gSmoke[i].radius / aspect, gSmoke[i].strength, 1.0, pRender_screen, pDepth_buffer, gShade_list[gSmoke[i].type & 0xf], pCamera); |
||
| 1270 | } else { |
||
| 1271 | SmokeCircle3D(&gSmoke[i].pos, gSmoke[i].radius, gSmoke[i].strength, aspect, pRender_screen, pDepth_buffer, gShade_list[gSmoke[i].type & 0xf], pCamera); |
||
| 1272 | } |
||
| 1273 | if (gSmoke[i].pipe_me) { |
||
| 1274 | AddSmokeToPipingSession(i, gSmoke[i].type, &gSmoke[i].pos, gSmoke[i].radius, gSmoke[i].strength); |
||
| 1275 | } |
||
| 1276 | gSmoke[i].radius = (double)pTime / 1000.0 * gSmoke[i].strength * 0.5 + gSmoke[i].radius; |
||
| 1277 | gSmoke[i].strength = gSmoke[i].strength - (double)pTime * gSmoke[i].decay_factor / 1000.0; |
||
| 1278 | if (gSmoke[i].radius > 0.3f) { |
||
| 1279 | gSmoke[i].radius = 0.3f; |
||
| 1280 | } |
||
| 1281 | if (gSmoke[i].strength > 0.0) { |
||
| 1282 | ts = 1.0f - (double)pTime * 0.002f; |
||
| 1283 | if (ts < 0.5f) { |
||
| 1284 | ts = 0.5f; |
||
| 1285 | } |
||
| 1286 | BrVector3Scale(&gSmoke[i].v, &gSmoke[i].v, ts); |
||
| 1287 | if (fabs(gSmoke[i].v.v[1]) < 0.43478259f && (gSmoke[i].type & 0xFu) < 7) { |
||
| 1288 | if (gSmoke[i].v.v[1] >= 0.0) { |
||
| 1289 | gSmoke[i].v.v[1] = 0.43478259f; |
||
| 1290 | } else { |
||
| 1291 | gSmoke[i].v.v[1] += 0.43478259f; |
||
| 1292 | } |
||
| 1293 | } |
||
| 1294 | } else { |
||
| 1295 | gSmoke_flags &= ~(1u << i); |
||
| 1296 | } |
||
| 1297 | } |
||
| 1298 | } |
||
| 1299 | EndPipingSession(); |
||
| 1300 | srand(seed); |
||
| 1301 | } |
||
| 1302 | } |
||
| 1303 | } |
||
| 1304 | |||
| 1305 | // IDA: void __usercall CreatePuffOfSmoke(br_vector3 *pos@<EAX>, br_vector3 *v@<EDX>, br_scalar strength, br_scalar pDecay_factor, int pType, tCar_spec *pC) |
||
| 1306 | void CreatePuffOfSmoke(br_vector3* pos, br_vector3* v, br_scalar strength, br_scalar pDecay_factor, int pType, tCar_spec* pC) { |
||
| 1307 | br_vector3 tv; |
||
| 1308 | //int pipe_me; // Pierre-Marie Baty -- unused variable |
||
| 1309 | LOG_TRACE("(%p, %p, %f, %f, %d, %p)", pos, v, strength, pDecay_factor, pType, pC); |
||
| 1310 | |||
| 1311 | if (!gSmoke_on) { |
||
| 1312 | return; |
||
| 1313 | } |
||
| 1314 | // if we are too far away from the current car... |
||
| 1315 | BrVector3Sub(&tv, pos, &gProgram_state.current_car.pos); |
||
| 1316 | if (BrVector3LengthSquared(&tv) > 625.0) { |
||
| 1317 | // check the distance from the car we are viewing and if it is too far away also, just return |
||
| 1318 | BrVector3Sub(&tv, pos, &gCar_to_view->pos); |
||
| 1319 | if (&gProgram_state.current_car != gCar_to_view && BrVector3LengthSquared(&tv) > 625.0) { |
||
| 1320 | return; |
||
| 1321 | } |
||
| 1322 | } |
||
| 1323 | |||
| 1324 | BrVector3InvScale(&gSmoke[gSmoke_num].v, v, WORLD_SCALE); |
||
| 1325 | gSmoke[gSmoke_num].v.v[1] += (1.0f / WORLD_SCALE); |
||
| 1326 | BrVector3Copy(&gSmoke[gSmoke_num].pos, pos); |
||
| 1327 | gSmoke[gSmoke_num].radius = 0.05f; |
||
| 1328 | if ((pType & 0xF) == 7) { |
||
| 1329 | gSmoke[gSmoke_num].radius *= 2.0f; |
||
| 1330 | } else { |
||
| 1331 | gSmoke[gSmoke_num].pos.v[1] += (br_scalar) 0.04; // Pierre-Marie Baty -- added type cast |
||
| 1332 | } |
||
| 1333 | gSmoke[gSmoke_num].pos.v[1] += (br_scalar) 0.04; // Pierre-Marie Baty -- added type cast |
||
| 1334 | if (strength > 1.0) { |
||
| 1335 | strength = 1.0; |
||
| 1336 | } |
||
| 1337 | gSmoke[gSmoke_num].strength = strength; |
||
| 1338 | gSmoke_flags |= 1u << gSmoke_num; |
||
| 1339 | gSmoke[gSmoke_num].time_sync = gMechanics_time_sync; |
||
| 1340 | gSmoke[gSmoke_num].type = pType; |
||
| 1341 | gSmoke[gSmoke_num].decay_factor = pDecay_factor; |
||
| 1342 | gSmoke[gSmoke_num].pipe_me = 1; |
||
| 1343 | gSmoke_num++; |
||
| 1344 | if (gSmoke_num >= COUNT_OF(gSmoke)) { |
||
| 1345 | gSmoke_num = 0; |
||
| 1346 | } |
||
| 1347 | } |
||
| 1348 | |||
| 1349 | // IDA: void __cdecl ResetSmoke() |
||
| 1350 | void ResetSmoke(void) { |
||
| 1351 | LOG_TRACE("()"); |
||
| 1352 | |||
| 1353 | gSmoke_flags = 0; |
||
| 1354 | ; |
||
| 1355 | } |
||
| 1356 | |||
| 1357 | // IDA: void __usercall AdjustSmoke(int pIndex@<EAX>, tU8 pType@<EDX>, br_vector3 *pPos@<EBX>, br_scalar pRadius, br_scalar pStrength) |
||
| 1358 | void AdjustSmoke(int pIndex, tU8 pType, br_vector3* pPos, br_scalar pRadius, br_scalar pStrength) { |
||
| 1359 | LOG_TRACE("(%d, %d, %p, %f, %f)", pIndex, pType, pPos, pRadius, pStrength); |
||
| 1360 | |||
| 1361 | gSmoke[pIndex].type = pType; |
||
| 1362 | gSmoke[pIndex].radius = pRadius; |
||
| 1363 | gSmoke[pIndex].strength = pStrength; |
||
| 1364 | BrVector3Copy(&gSmoke[pIndex].pos, pPos); |
||
| 1365 | gSmoke_flags |= 1 << pIndex; |
||
| 1366 | } |
||
| 1367 | |||
| 1368 | // IDA: void __cdecl ActorError() |
||
| 1369 | void ActorError(void) { |
||
| 1370 | LOG_TRACE("()"); |
||
| 1371 | } |
||
| 1372 | |||
| 1373 | // IDA: void __usercall AdjustSmokeColumn(int pIndex@<EAX>, tCar_spec *pCar@<EDX>, int pVertex@<EBX>, int pColour@<ECX>) |
||
| 1374 | void AdjustSmokeColumn(int pIndex, tCar_spec* pCar, int pVertex, int pColour) { |
||
| 1375 | int i; |
||
| 1376 | //br_actor* actor; // Pierre-Marie Baty -- unused variable |
||
| 1377 | LOG_TRACE("(%d, %p, %d, %d)", pIndex, pCar, pVertex, pColour); |
||
| 1378 | |||
| 1379 | gColumn_flags ^= 1 << pIndex; |
||
| 1380 | gSmoke_column[pIndex].car = pCar; |
||
| 1381 | gSmoke_column[pIndex].vertex_index = pVertex; |
||
| 1382 | gSmoke_column[pIndex].colour = pColour; |
||
| 1383 | for (i = 0; i < COUNT_OF(gSmoke_column->frame_count); i++) { |
||
| 1384 | gSmoke_column[pIndex].frame_count[i] = 100; |
||
| 1385 | } |
||
| 1386 | if (pColour == 0) { |
||
| 1387 | if ((gColumn_flags & (1 << pIndex)) != 0) { |
||
| 1388 | if (gSmoke_column[pIndex].flame_actor->depth != 0) { |
||
| 1389 | ActorError(); |
||
| 1390 | } |
||
| 1391 | BrActorAdd(gNon_track_actor, gSmoke_column[pIndex].flame_actor); |
||
| 1392 | } else { |
||
| 1393 | if (gSmoke_column[pIndex].flame_actor->depth == 0) { |
||
| 1394 | ActorError(); |
||
| 1395 | } |
||
| 1396 | BrActorRemove(gSmoke_column[pIndex].flame_actor); |
||
| 1397 | } |
||
| 1398 | } |
||
| 1399 | } |
||
| 1400 | |||
| 1401 | // IDA: void __usercall CreateSmokeColumn(tCar_spec *pCar@<EAX>, int pColour@<EDX>, int pVertex_index@<EBX>, tU32 pLifetime@<ECX>) |
||
| 1402 | void CreateSmokeColumn(tCar_spec* pCar, int pColour, int pVertex_index, tU32 pLifetime) { |
||
| 1403 | int i; |
||
| 1404 | br_actor* actor; |
||
| 1405 | tSmoke_column* col; |
||
| 1406 | LOG_TRACE("(%p, %d, %d, %d)", pCar, pColour, pVertex_index, pLifetime); |
||
| 1407 | |||
| 1408 | col = &gSmoke_column[gNext_column]; |
||
| 1409 | if (pCar->last_special_volume != NULL && pCar->last_special_volume->gravity_multiplier < 1.0f) { |
||
| 1410 | return; |
||
| 1411 | } |
||
| 1412 | SmudgeCar(pCar, pVertex_index); |
||
| 1413 | if (pCar->knackered) { |
||
| 1414 | SmudgeCar(pCar, pCar->fire_vertex[IRandomBetween(0, 11)]); |
||
| 1415 | } |
||
| 1416 | if (!gSmoke_on) { |
||
| 1417 | return; |
||
| 1418 | } |
||
| 1419 | if (((1u << gNext_column) & gColumn_flags) != 0) { |
||
| 1420 | if (gSmoke_column[gNext_column].car != NULL) { |
||
| 1421 | gSmoke_column[gNext_column].car->num_smoke_columns--; |
||
| 1422 | } |
||
| 1423 | StartPipingSession(ePipe_chunk_smoke_column); |
||
| 1424 | AddSmokeColumnToPipingSession(gNext_column, gSmoke_column[gNext_column].car, gSmoke_column[gNext_column].vertex_index, gSmoke_column[gNext_column].colour); |
||
| 1425 | EndPipingSession(); |
||
| 1426 | if (gSmoke_column[gNext_column].colour == 0) { |
||
| 1427 | StartPipingSession(ePipe_chunk_flame); |
||
| 1428 | actor = col->flame_actor->children; |
||
| 1429 | for (i = 0; i < 3; i++) { |
||
| 1430 | if (actor->type == BR_ACTOR_MODEL) { |
||
| 1431 | 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]); |
||
| 1432 | } |
||
| 1433 | actor->type = BR_ACTOR_NONE; |
||
| 1434 | actor = actor->next; |
||
| 1435 | } |
||
| 1436 | EndPipingSession(); |
||
| 1437 | } |
||
| 1438 | } |
||
| 1439 | if (pColour == 0 && (((1u << gNext_column) & gColumn_flags) == 0 || gSmoke_column[gNext_column].colour != 0)) { |
||
| 1440 | BrActorAdd(gNon_track_actor, gSmoke_column[gNext_column].flame_actor); |
||
| 1441 | } |
||
| 1442 | if (pColour != 0 && ((1u << gNext_column) & gColumn_flags) != 0 && gSmoke_column[gNext_column].colour == 0) { |
||
| 1443 | BrActorRemove(gSmoke_column[gNext_column].flame_actor); |
||
| 1444 | } |
||
| 1445 | StartPipingSession(ePipe_chunk_smoke_column); |
||
| 1446 | AddSmokeColumnToPipingSession(gNext_column, pCar, pVertex_index, pColour); |
||
| 1447 | EndPipingSession(); |
||
| 1448 | gSmoke_column[gNext_column].car = pCar; |
||
| 1449 | gSmoke_column[gNext_column].colour = pColour; |
||
| 1450 | gSmoke_column[gNext_column].lifetime = pLifetime; |
||
| 1451 | gSmoke_column[gNext_column].time = 0; |
||
| 1452 | gSmoke_column[gNext_column].smudge_timer = 1000; |
||
| 1453 | gSmoke_column[gNext_column].vertex_index = pVertex_index; |
||
| 1454 | gSmoke_column[gNext_column].upright = 1; |
||
| 1455 | gColumn_flags |= 1u << gNext_column; |
||
| 1456 | pCar->num_smoke_columns++; |
||
| 1457 | for (i = 0; i < COUNT_OF(gSmoke_column[gNext_column].frame_count); i++) { |
||
| 1458 | gSmoke_column[gNext_column].frame_count[i] = 100; |
||
| 1459 | } |
||
| 1460 | gNext_column++; |
||
| 1461 | if (gNext_column >= MAX_SMOKE_COLUMNS) { |
||
| 1462 | gNext_column = 0; |
||
| 1463 | } |
||
| 1464 | } |
||
| 1465 | |||
| 1466 | // IDA: void __cdecl GenerateSmokeShades() |
||
| 1467 | void GenerateSmokeShades(void) { |
||
| 1468 | static int rb = 0x00; |
||
| 1469 | static int gb = 0x00; |
||
| 1470 | static int bb = 0x00; |
||
| 1471 | static int rd = 0x40; |
||
| 1472 | static int gd = 0x40; |
||
| 1473 | static int bd = 0x40; |
||
| 1474 | static int rg = 0x80; |
||
| 1475 | static int gg = 0x80; |
||
| 1476 | static int bg = 0x80; |
||
| 1477 | LOG_TRACE("()"); |
||
| 1478 | |||
| 1479 | gBlack_smoke_shade_table = GenerateShadeTable(16, gRender_palette, rb, gb, bb, .25f, .6f, .9f); |
||
| 1480 | gDark_smoke_shade_table = GenerateShadeTable(16, gRender_palette, rd, gd, bd, .25f, .6f, .9f); |
||
| 1481 | gGrey_smoke_shade_table = GenerateShadeTable(16, gRender_palette, rg, gg, bg, .25f, .6f, .9f); |
||
| 1482 | gIt_shade_table = GenerateDarkenedShadeTable(16, gRender_palette, 0, 255, 254, .25f, .5f, .75f, .6f); |
||
| 1483 | |||
| 1484 | gShade_list[0] = gBlack_smoke_shade_table; |
||
| 1485 | gShade_list[1] = gDark_smoke_shade_table; |
||
| 1486 | gShade_list[2] = gGrey_smoke_shade_table; |
||
| 1487 | gShade_list[3] = gFog_shade_table; |
||
| 1488 | gShade_list[4] = gFog_shade_table; |
||
| 1489 | gShade_list[7] = gAcid_shade_table; |
||
| 1490 | } |
||
| 1491 | |||
| 1492 | // IDA: void __cdecl GenerateItFoxShadeTable() |
||
| 1493 | void GenerateItFoxShadeTable(void) { |
||
| 1494 | LOG_TRACE("()"); |
||
| 1495 | |||
| 1496 | if (gIt_shade_table == NULL) { |
||
| 1497 | gIt_shade_table = GenerateDarkenedShadeTable(16, gRender_palette, 0, 255, 254, .25f, .5f, .75f, .6f); |
||
| 1498 | } |
||
| 1499 | } |
||
| 1500 | |||
| 1501 | // 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) |
||
| 1502 | void AdjustFlame(int pIndex, int pFrame_count, br_scalar pScale_x, br_scalar pScale_y, br_scalar pOffset_x, br_scalar pOffset_z) { |
||
| 1503 | int i; |
||
| 1504 | int j; |
||
| 1505 | tSmoke_column* col; |
||
| 1506 | //br_actor* actor; // Pierre-Marie Baty -- unused variable |
||
| 1507 | LOG_TRACE("(%d, %d, %f, %f, %f, %f)", pIndex, pFrame_count, pScale_x, pScale_y, pOffset_x, pOffset_z); |
||
| 1508 | |||
| 1509 | i = pIndex >> 4; |
||
| 1510 | j = pIndex & 0xf; |
||
| 1511 | col = &gSmoke_column[i]; |
||
| 1512 | col->frame_count[j] = pFrame_count; |
||
| 1513 | col->scale_x[j] = pScale_x; |
||
| 1514 | col->scale_y[j] = pScale_y; |
||
| 1515 | col->offset_x[j] = pOffset_x; |
||
| 1516 | col->offset_z[j] = pOffset_z; |
||
| 1517 | } |
||
| 1518 | |||
| 1519 | // IDA: void __usercall ReplayFlame(tSmoke_column *col@<EAX>, br_actor *actor@<EDX>) |
||
| 1520 | void ReplayFlame(tSmoke_column* col, br_actor* actor) { |
||
| 1521 | int i; |
||
| 1522 | LOG_TRACE("(%p, %p)", col, actor); |
||
| 1523 | |||
| 1524 | for (i = 0; i < COUNT_OF(col->frame_count); i++, actor = actor->next) { |
||
| 1525 | col->frame_count[i] += GetReplayRate(); |
||
| 1526 | if (col->frame_count[i] < 0 || col->frame_count[i] >= COUNT_OF(gFlame_map)) { |
||
| 1527 | actor->type = BR_ACTOR_NONE; |
||
| 1528 | } else { |
||
| 1529 | actor->type = BR_ACTOR_MODEL; |
||
| 1530 | actor->material->colour_map = gFlame_map[col->frame_count[i]]; |
||
| 1531 | BrMaterialUpdate(actor->material, BR_MATU_ALL); |
||
| 1532 | BrMatrix34Scale(&actor->t.t.mat, |
||
| 1533 | col->scale_x[i] * gFlame_map[col->frame_count[i]]->width, |
||
| 1534 | col->scale_y[i] * gFlame_map[col->frame_count[i]]->height, |
||
| 1535 | 1.f); |
||
| 1536 | actor->t.t.translate.t.v[0] = col->offset_x[i]; |
||
| 1537 | actor->t.t.translate.t.v[2] = col->offset_z[i]; |
||
| 1538 | } |
||
| 1539 | } |
||
| 1540 | } |
||
| 1541 | |||
| 1542 | // IDA: void __usercall FlameAnimate(int c@<EAX>, br_vector3 *pPos@<EDX>, tU32 pTime@<EBX>) |
||
| 1543 | void FlameAnimate(int c, br_vector3* pPos, tU32 pTime) { |
||
| 1544 | tSmoke_column* col; |
||
| 1545 | br_actor* actor; |
||
| 1546 | int i; |
||
| 1547 | LOG_TRACE("(%d, %p, %d)", c, pPos, pTime); |
||
| 1548 | |||
| 1549 | col = &gSmoke_column[c]; |
||
| 1550 | actor = col->flame_actor; |
||
| 1551 | DRMatrix34RotateY(&actor->t.t.mat, FastScalarArcTan2Angle(gCamera_to_world.m[2][0], gCamera_to_world.m[2][2])); |
||
| 1552 | actor->t.t.translate.t = *pPos; |
||
| 1553 | actor = actor->children; |
||
| 1554 | |||
| 1555 | if (gAction_replay_mode) { |
||
| 1556 | ReplayFlame(col, actor); |
||
| 1557 | return; |
||
| 1558 | } |
||
| 1559 | for (i = 0; i < COUNT_OF(col->frame_count); i++) { |
||
| 1560 | |||
| 1561 | #ifdef DETHRACE_FIX_BUGS |
||
| 1562 | col->frame_time[i] += pTime; |
||
| 1563 | if (col->frame_time[i] > FLAME_ANIMATION_FRAME_INTERVAL) { |
||
| 1564 | col->frame_time[i] = 0; |
||
| 1565 | col->frame_count[i]++; |
||
| 1566 | } |
||
| 1567 | #else |
||
| 1568 | col->frame_count[i]++; |
||
| 1569 | #endif |
||
| 1570 | |||
| 1571 | if (col->frame_count[i] >= COUNT_OF(gFlame_map)) { |
||
| 1572 | StartPipingSession(ePipe_chunk_flame); |
||
| 1573 | 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]); |
||
| 1574 | EndPipingSession(); |
||
| 1575 | col->frame_count[i] = IRandomBetween(-5, -1); |
||
| 1576 | col->scale_x[i] = (2 * IRandomBetween(0, 1) - 1) * SRandomBetween(1.0f, 1.5f) * 0.003f; |
||
| 1577 | col->scale_y[i] = SRandomBetween(0.5f, 1.0f) * 0.003f; |
||
| 1578 | col->offset_x[i] = SRandomPosNeg(0.03f); |
||
| 1579 | col->offset_z[i] = SRandomBetween(-0.03f, 0.0); |
||
| 1580 | actor->type = BR_ACTOR_NONE; |
||
| 1581 | } |
||
| 1582 | if (col->frame_count[i] == 0) { |
||
| 1583 | if (BrVector3LengthSquared(&col->car->v) >= 80.0f || col->lifetime <= 30 * pTime) { |
||
| 1584 | col->frame_count[i] = -5; |
||
| 1585 | } else { |
||
| 1586 | actor->type = BR_ACTOR_MODEL; |
||
| 1587 | StartPipingSession(ePipe_chunk_flame); |
||
| 1588 | 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]); |
||
| 1589 | EndPipingSession(); |
||
| 1590 | } |
||
| 1591 | } |
||
| 1592 | if (col->frame_count[i] >= 0) { |
||
| 1593 | actor->material->colour_map = gFlame_map[col->frame_count[i]]; |
||
| 1594 | BrMaterialUpdate(actor->material, BR_MATU_ALL); |
||
| 1595 | 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); |
||
| 1596 | actor->t.t.mat.m[3][0] = col->offset_x[i]; |
||
| 1597 | actor->t.t.mat.m[3][2] = col->offset_z[i]; |
||
| 1598 | } |
||
| 1599 | actor = actor->next; |
||
| 1600 | } |
||
| 1601 | } |
||
| 1602 | |||
| 1603 | // IDA: void __usercall DoSmokeColumn(int i@<EAX>, tU32 pTime@<EDX>, br_vector3 *pRet_car_pos@<EBX>) |
||
| 1604 | void DoSmokeColumn(int i, tU32 pTime, br_vector3* pRet_car_pos) { |
||
| 1605 | tCar_spec* c; |
||
| 1606 | br_actor* actor; |
||
| 1607 | br_actor* bonny; |
||
| 1608 | //int group; // Pierre-Marie Baty -- unused variable |
||
| 1609 | LOG_TRACE("(%d, %d, %p)", i, pTime, pRet_car_pos); |
||
| 1610 | |||
| 1611 | c = gSmoke_column[i].car; |
||
| 1612 | if (c->car_master_actor->t.t.mat.m[1][1] > 0.1f) { |
||
| 1613 | gSmoke_column[i].upright = 1; |
||
| 1614 | } |
||
| 1615 | if (c->car_master_actor->t.t.mat.m[1][1] < -0.1f) { |
||
| 1616 | gSmoke_column[i].upright = 0; |
||
| 1617 | } |
||
| 1618 | actor = c->car_model_actors[c->principal_car_actor].actor; |
||
| 1619 | bonny = c->car_model_actors[c->car_actor_count - 1].actor; |
||
| 1620 | |||
| 20 | pmbaty | 1621 | BrVector3Add(pRet_car_pos, &V11MODEL(actor->model)->groups->vertices[gSmoke_column[i].vertex_index].p, &actor->t.t.translate.t); |
| 1 | pmbaty | 1622 | if (gProgram_state.cockpit_on && c->driver == eDriver_local_human) { |
| 1623 | if (c->driver_z_offset + 0.2f <= pRet_car_pos->v[2]) { |
||
| 1624 | pRet_car_pos->v[1] -= -0.07f; |
||
| 1625 | } else { |
||
| 20 | pmbaty | 1626 | BrMatrix34ApplyP(pRet_car_pos, &V11MODEL(actor->model)->groups->vertices[gSmoke_column[i].vertex_index].p, &bonny->t.t.mat); |
| 1 | pmbaty | 1627 | } |
| 1628 | } |
||
| 1629 | if (!gSmoke_column[i].upright) { |
||
| 1630 | pRet_car_pos->v[1] = c->bounds[1].min.v[1] / WORLD_SCALE; |
||
| 1631 | } |
||
| 1632 | BrMatrix34ApplyP(&gSmoke_column[i].pos, pRet_car_pos, &c->car_master_actor->t.t.mat); |
||
| 1633 | gSmoke_column[i].pos.v[1] -= 0.03f; |
||
| 1634 | } |
||
| 1635 | |||
| 1636 | // IDA: void __usercall ReplaySmokeColumn(tU32 pTime@<EAX>) |
||
| 1637 | void ReplaySmokeColumn(tU32 pTime) { |
||
| 1638 | int i; |
||
| 1639 | br_vector3 dummy; |
||
| 1640 | LOG_TRACE("(%d)", pTime); |
||
| 1641 | |||
| 1642 | for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { |
||
| 1643 | if ((gColumn_flags & (1 << i)) != 0) { |
||
| 1644 | DoSmokeColumn(i, pTime, &dummy); |
||
| 1645 | if (gSmoke_column[i].colour == 0) { |
||
| 1646 | FlameAnimate(i, &gSmoke_column[i].pos, pTime); |
||
| 1647 | } |
||
| 1648 | } |
||
| 1649 | } |
||
| 1650 | } |
||
| 1651 | |||
| 1652 | // IDA: void __usercall MungeSmokeColumn(tU32 pTime@<EAX>) |
||
| 1653 | void MungeSmokeColumn(tU32 pTime) { |
||
| 1654 | int i; |
||
| 1655 | int plane; |
||
| 1656 | //br_actor* actor; // Pierre-Marie Baty -- unused variable |
||
| 1657 | //br_actor* bonny; // Pierre-Marie Baty -- unused variable |
||
| 1658 | br_vector3 car_pos; |
||
| 1659 | br_vector3 pos; |
||
| 1660 | br_vector3 v; |
||
| 1661 | //br_vector3 up; // Pierre-Marie Baty -- unused variable |
||
| 1662 | //br_vector3 start; // Pierre-Marie Baty -- unused variable |
||
| 1663 | //br_vector3 end; // Pierre-Marie Baty -- unused variable |
||
| 1664 | //br_scalar ts; // Pierre-Marie Baty -- unused variable |
||
| 1665 | br_scalar decay_factor; |
||
| 1666 | tCar_spec* c; |
||
| 1667 | LOG_TRACE("(%d)", pTime); |
||
| 1668 | |||
| 1669 | if (gColumn_flags == 0) { |
||
| 1670 | return; |
||
| 1671 | } |
||
| 1672 | if (gAction_replay_mode) { |
||
| 1673 | ReplaySmokeColumn(pTime); |
||
| 1674 | return; |
||
| 1675 | } |
||
| 1676 | |||
| 1677 | gMechanics_time_sync = 1; |
||
| 1678 | for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { |
||
| 1679 | if (((1u << i) & gColumn_flags) == 0) { |
||
| 1680 | continue; |
||
| 1681 | } |
||
| 1682 | if (gSmoke_column[i].lifetime >= pTime) { |
||
| 1683 | gSmoke_column[i].lifetime -= pTime; |
||
| 1684 | c = gSmoke_column[i].car; |
||
| 1685 | DoSmokeColumn(i, pTime, &car_pos); |
||
| 1686 | if (gSmoke_column[i].colour == 0) { |
||
| 1687 | FlameAnimate(i, &gSmoke_column[i].pos, pTime); |
||
| 1688 | if (gSmoke_column[i].smudge_timer >= pTime) { |
||
| 1689 | gSmoke_column[i].smudge_timer -= pTime; |
||
| 1690 | } else { |
||
| 1691 | gSmoke_column[i].smudge_timer += 2000; |
||
| 1692 | SmudgeCar(gSmoke_column[i].car, gSmoke_column[i].vertex_index); |
||
| 1693 | if (gSmoke_column[i].car->knackered) { |
||
| 1694 | plane = IRandomBetween(0, COUNT_OF(gSmoke_column[i].car->fire_vertex) - 1); |
||
| 1695 | SmudgeCar(gSmoke_column[i].car, gSmoke_column[i].car->fire_vertex[plane]); |
||
| 1696 | } |
||
| 1697 | } |
||
| 1698 | } |
||
| 1699 | gSmoke_column[i].time += pTime; |
||
| 1700 | if (gSmoke_column[i].time > 200) { |
||
| 1701 | #ifdef DETHRACE_FIX_BUGS |
||
| 1702 | gSmoke_column[i].time -= fmaxf(SMOKE_COLUMN_NEW_PUFF_INTERVAL, pTime); |
||
| 1703 | #else |
||
| 1704 | gSmoke_column[i].time -= pTime; |
||
| 1705 | #endif |
||
| 1706 | gSmoke_column[i].count++; |
||
| 1707 | BrVector3Cross(&v, &c->omega, &car_pos); |
||
| 1708 | BrMatrix34ApplyV(&car_pos, &v, &c->car_master_actor->t.t.mat); |
||
| 1709 | BrVector3Add(&v, &c->v, &car_pos); |
||
| 1710 | v.v[1] = v.v[1] + 2.898550724637681f; // 100 / 34.5 ? |
||
| 1711 | pos.v[0] = SRandomBetween(-0.03f, 0.03f) + gSmoke_column[i].pos.v[0]; |
||
| 1712 | pos.v[1] = (gSmoke_column[i].colour == 0) * 0.05f + gSmoke_column[i].pos.v[1]; |
||
| 1713 | pos.v[2] = SRandomBetween(-0.03f, 0.03f) + gSmoke_column[i].pos.v[2]; |
||
| 1714 | if ((gSmoke_column[i].whiter & 2) == 0 || IRandomBetween(0, 3)) { |
||
| 1715 | if (gSmoke_column[i].whiter < 1) { |
||
| 1716 | gSmoke_column[i].whiter = -1; |
||
| 1717 | } else { |
||
| 1718 | gSmoke_column[i].whiter = 2; |
||
| 1719 | } |
||
| 1720 | } else { |
||
| 1721 | gSmoke_column[i].whiter &= 1; |
||
| 1722 | } |
||
| 1723 | decay_factor = ((gSmoke_column[i].whiter > 0) + 1.0f) / 2.0f; |
||
| 1724 | if (gSmoke_column[i].lifetime < 4000) { |
||
| 1725 | decay_factor = gSmoke_column[i].lifetime * decay_factor / 4000.0f; |
||
| 1726 | } |
||
| 1727 | CreatePuffOfSmoke(&pos, &v, decay_factor, decay_factor, gSmoke_column[i].colour + 16, c); |
||
| 1728 | } |
||
| 1729 | } else { |
||
| 1730 | if (gSmoke_column[i].car != NULL) { |
||
| 1731 | StartPipingSession(ePipe_chunk_smoke_column); |
||
| 1732 | AddSmokeColumnToPipingSession(i, gSmoke_column[i].car, gSmoke_column[i].vertex_index, gSmoke_column[i].colour); |
||
| 1733 | EndPipingSession(); |
||
| 1734 | } |
||
| 1735 | gColumn_flags &= ~(1u << i); |
||
| 1736 | if (gSmoke_column[i].colour == 0) { |
||
| 1737 | BrActorRemove(gSmoke_column[i].flame_actor); |
||
| 1738 | } |
||
| 1739 | if (gSmoke_column[i].car != NULL) { |
||
| 1740 | if (gSmoke_column[i].car->num_smoke_columns != 0) { |
||
| 1741 | gSmoke_column[i].car->num_smoke_columns--; |
||
| 1742 | } |
||
| 1743 | } |
||
| 1744 | } |
||
| 1745 | } |
||
| 1746 | } |
||
| 1747 | |||
| 1748 | // IDA: void __cdecl DisposeFlame() |
||
| 1749 | void DisposeFlame(void) { |
||
| 1750 | int i; |
||
| 1751 | int j; |
||
| 1752 | br_actor* actor; |
||
| 1753 | //br_material* material; // Pierre-Marie Baty -- unused variable |
||
| 1754 | LOG_TRACE("()"); |
||
| 1755 | |||
| 1756 | for (i = 0; i < COUNT_OF(gFlame_map); i++) { |
||
| 1757 | BrMapRemove(gFlame_map[i]); |
||
| 1758 | BrPixelmapFree(gFlame_map[i]); |
||
| 1759 | } |
||
| 1760 | |||
| 1761 | for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { |
||
| 1762 | if ((gColumn_flags & (1u << i)) && (gSmoke_column[i].colour == 0)) { |
||
| 1763 | BrActorRemove(gSmoke_column[i].flame_actor); |
||
| 1764 | } |
||
| 1765 | actor = gSmoke_column[i].flame_actor->children; |
||
| 1766 | for (j = 0; j < COUNT_OF(gSmoke_column[0].frame_count); j++) { |
||
| 1767 | BrMaterialRemove(actor->material); |
||
| 1768 | BrMaterialFree(actor->material); |
||
| 1769 | actor = actor->next; |
||
| 1770 | } |
||
| 1771 | BrActorFree(gSmoke_column[i].flame_actor); |
||
| 1772 | } |
||
| 1773 | BrModelRemove(gLollipop_model); |
||
| 1774 | BrModelFree(gLollipop_model); |
||
| 1775 | } |
||
| 1776 | |||
| 1777 | // IDA: void __cdecl InitFlame() |
||
| 1778 | void InitFlame(void) { |
||
| 1779 | int i; |
||
| 1780 | int j; |
||
| 1781 | int num; |
||
| 1782 | char the_path[256]; |
||
| 1783 | br_actor* actor; |
||
| 1784 | br_material* material; |
||
| 1785 | LOG_TRACE("()"); |
||
| 1786 | |||
| 1787 | gColumn_flags = 0; |
||
| 1788 | gLollipop_model = BrModelAllocate("Lollipop", 4, 2); |
||
| 1789 | PathCat(the_path, gApplication_path, "PIXELMAP"); |
||
| 1790 | PathCat(the_path, the_path, "FLAMES.PIX"); |
||
| 1791 | num = DRPixelmapLoadMany(the_path, gFlame_map, COUNT_OF(gFlame_map)); |
||
| 1792 | if (num != COUNT_OF(gFlame_map)) { |
||
| 1793 | FatalError(kFatalError_LoadPixelmapFile_S, the_path); |
||
| 1794 | } |
||
| 1795 | BrMapAddMany(gFlame_map, COUNT_OF(gFlame_map)); |
||
| 1796 | for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { |
||
| 1797 | gSmoke_column[i].flame_actor = BrActorAllocate(BR_ACTOR_NONE, NULL); |
||
| 1798 | for (j = 0; j < COUNT_OF(gSmoke_column[0].frame_count); j++) { |
||
| 1799 | actor = BrActorAllocate(BR_ACTOR_MODEL, NULL); |
||
| 1800 | material = BrMaterialAllocate(NULL); |
||
| 1801 | BrActorAdd(gSmoke_column[i].flame_actor, actor); |
||
| 1802 | actor->model = gLollipop_model; |
||
| 1803 | actor->material = material; |
||
| 1804 | material->flags &= ~BR_MATF_LIGHT; |
||
| 1805 | material->flags |= BR_MATF_ALWAYS_VISIBLE; |
||
| 1806 | material->colour_map = gFlame_map[0]; |
||
| 1807 | BrMaterialAdd(material); |
||
| 1808 | gSmoke_column[i].frame_count[j] = 100; |
||
| 1809 | } |
||
| 1810 | } |
||
| 1811 | gLollipop_model->nvertices = 4; |
||
| 1812 | BrVector3SetFloat(&gLollipop_model->vertices[0].p, -.5f, 0.f, .0f); |
||
| 1813 | BrVector3SetFloat(&gLollipop_model->vertices[1].p, .5f, 0.f, .0f); |
||
| 1814 | BrVector3SetFloat(&gLollipop_model->vertices[2].p, .5f, 1.f, .0f); |
||
| 1815 | BrVector3SetFloat(&gLollipop_model->vertices[3].p, -.5f, 1.f, .0f); |
||
| 1816 | gLollipop_model->vertices[0].map.v[0] = 0.f; |
||
| 1817 | gLollipop_model->vertices[0].map.v[1] = 1.f; |
||
| 1818 | gLollipop_model->vertices[1].map.v[0] = 1.f; |
||
| 1819 | gLollipop_model->vertices[1].map.v[1] = 1.f; |
||
| 1820 | gLollipop_model->vertices[2].map.v[0] = 1.f; |
||
| 1821 | gLollipop_model->vertices[2].map.v[1] = 0.f; |
||
| 1822 | gLollipop_model->vertices[3].map.v[0] = 0.f; |
||
| 1823 | gLollipop_model->vertices[3].map.v[1] = 0.f; |
||
| 1824 | |||
| 1825 | gLollipop_model->nfaces = 2; |
||
| 1826 | gLollipop_model->faces[0].vertices[0] = 0; |
||
| 1827 | gLollipop_model->faces[0].vertices[1] = 1; |
||
| 1828 | gLollipop_model->faces[0].vertices[2] = 2; |
||
| 1829 | gLollipop_model->faces[1].vertices[0] = 0; |
||
| 1830 | gLollipop_model->faces[1].vertices[1] = 2; |
||
| 1831 | gLollipop_model->faces[1].vertices[2] = 3; |
||
| 1832 | gLollipop_model->faces[0].smoothing = 1; |
||
| 1833 | gLollipop_model->faces[1].smoothing = 1; |
||
| 1834 | BrModelAdd(gLollipop_model); |
||
| 1835 | } |
||
| 1836 | |||
| 1837 | // IDA: void __usercall InitSplash(FILE *pF@<EAX>) |
||
| 1838 | void InitSplash(FILE* pF) { |
||
| 1839 | int i; |
||
| 1840 | int num_files; |
||
| 1841 | int num; |
||
| 1842 | br_actor* actor; |
||
| 1843 | char the_path[256]; |
||
| 1844 | char s[256]; |
||
| 1845 | br_pixelmap* splash_maps[20]; |
||
| 1846 | LOG_TRACE("(%p)", pF); |
||
| 1847 | |||
| 1848 | gSplash_flags = 0; |
||
| 1849 | gSplash_model = BrModelAllocate("Splash", 4, 2); |
||
| 1850 | if (pF != NULL) { |
||
| 1851 | num = GetAnInt(pF); |
||
| 1852 | gNum_splash_types = 0; |
||
| 1853 | for (i = 0; num > i; ++i) { |
||
| 1854 | GetAString(pF, s); |
||
| 1855 | PathCat(the_path, gApplication_path, "PIXELMAP"); |
||
| 1856 | PathCat(the_path, the_path, s); |
||
| 1857 | num_files = DRPixelmapLoadMany(the_path, &splash_maps[gNum_splash_types], 20 - gNum_splash_types); |
||
| 1858 | if (num_files == 0) { |
||
| 1859 | FatalError(kFatalError_LoadPixelmapFile_S, the_path); |
||
| 1860 | } |
||
| 1861 | gNum_splash_types += num_files; |
||
| 1862 | } |
||
| 1863 | } else { |
||
| 1864 | PathCat(the_path, gApplication_path, "PIXELMAP"); |
||
| 1865 | PathCat(the_path, the_path, "SPLSHBLU.PIX"); |
||
| 1866 | gNum_splash_types = DRPixelmapLoadMany(the_path, splash_maps, 0x14u); |
||
| 1867 | } |
||
| 1868 | BrMapAddMany(splash_maps, gNum_splash_types); |
||
| 1869 | for (i = 0; i < gNum_splash_types; ++i) { |
||
| 1870 | gSplash_material[i] = BrMaterialAllocate(0); |
||
| 1871 | gSplash_material[i]->flags &= ~(BR_MATF_LIGHT | BR_MATF_PRELIT); |
||
| 1872 | gSplash_material[i]->flags |= BR_MATF_ALWAYS_VISIBLE | BR_MATF_PERSPECTIVE; |
||
| 1873 | gSplash_material[i]->index_blend = LoadSingleShadeTable(&gTrack_storage_space, "BLEND50.TAB"); |
||
| 1874 | gSplash_material[i]->colour_map = splash_maps[i]; |
||
| 1875 | BrMaterialAdd(gSplash_material[i]); |
||
| 1876 | } |
||
| 1877 | gSplash_model->nvertices = 4; |
||
| 1878 | BrVector3SetFloat(&gSplash_model->vertices[0].p, -0.5f, 0.0f, 0.0f); |
||
| 1879 | BrVector3SetFloat(&gSplash_model->vertices[1].p, 0.5f, 0.0f, 0.0f); |
||
| 1880 | BrVector3SetFloat(&gSplash_model->vertices[2].p, 0.5f, 1.0f, 0.0f); |
||
| 1881 | BrVector3SetFloat(&gSplash_model->vertices[3].p, -0.5f, 1.0f, 0.0f); |
||
| 1882 | gSplash_model->vertices[0].map.v[0] = 0.0f; |
||
| 1883 | gSplash_model->vertices[0].map.v[1] = 1.0f; |
||
| 1884 | gSplash_model->vertices[1].map.v[0] = 1.0f; |
||
| 1885 | gSplash_model->vertices[1].map.v[1] = 1.0f; |
||
| 1886 | gSplash_model->vertices[2].map.v[0] = 1.0f; |
||
| 1887 | gSplash_model->vertices[2].map.v[1] = 0.0f; |
||
| 1888 | gSplash_model->vertices[3].map.v[0] = 0.0f; |
||
| 1889 | gSplash_model->vertices[3].map.v[1] = 0.0f; |
||
| 1890 | gSplash_model->nfaces = 2; |
||
| 1891 | gSplash_model->faces[0].vertices[0] = 0; |
||
| 1892 | gSplash_model->faces[0].vertices[1] = 1; |
||
| 1893 | gSplash_model->faces[0].vertices[2] = 2; |
||
| 1894 | gSplash_model->faces[1].vertices[0] = 0; |
||
| 1895 | gSplash_model->faces[1].vertices[1] = 2; |
||
| 1896 | gSplash_model->faces[1].vertices[2] = 3; |
||
| 1897 | gSplash_model->faces[0].smoothing = 1; |
||
| 1898 | gSplash_model->faces[1].smoothing = 1; |
||
| 1899 | BrModelAdd(gSplash_model); |
||
| 1900 | for (i = 0; i < COUNT_OF(gSplash); i++) { |
||
| 1901 | gSplash[i].actor = BrActorAllocate(BR_ACTOR_MODEL, NULL); |
||
| 1902 | actor = gSplash[i].actor; |
||
| 1903 | actor->model = gSplash_model; |
||
| 1904 | if (gNum_splash_types != 0) { |
||
| 1905 | actor->material = gSplash_material[IRandomBetween(0, gNum_splash_types - 1)]; |
||
| 1906 | } else { |
||
| 1907 | actor->material = NULL; |
||
| 1908 | } |
||
| 1909 | gSplash[i].scale_x = SRandomBetween(0.9f, 1.1f) * (2 * IRandomBetween(0, 1) - 1); |
||
| 1910 | } |
||
| 1911 | } |
||
| 1912 | |||
| 1913 | // IDA: void __cdecl DisposeSplash() |
||
| 1914 | void DisposeSplash(void) { |
||
| 1915 | int i; |
||
| 1916 | LOG_TRACE("()"); |
||
| 1917 | |||
| 1918 | for (i = 0; i < gNum_splash_types; i++) { |
||
| 1919 | BrMapRemove(gSplash_material[i]->colour_map); |
||
| 1920 | BrPixelmapFree(gSplash_material[i]->colour_map); |
||
| 1921 | BrMaterialRemove(gSplash_material[i]); |
||
| 1922 | BrMaterialFree(gSplash_material[i]); |
||
| 1923 | } |
||
| 1924 | for (i = 0; i < COUNT_OF(gSplash); i++) { |
||
| 1925 | if (gSplash_flags & (1u << i)) { |
||
| 1926 | BrActorRemove(gSplash[i].actor); |
||
| 1927 | } |
||
| 1928 | BrActorFree(gSplash[i].actor); |
||
| 1929 | } |
||
| 1930 | BrModelRemove(gSplash_model); |
||
| 1931 | BrModelFree(gSplash_model); |
||
| 1932 | } |
||
| 1933 | |||
| 1934 | // IDA: void __usercall DrawTheGlow(br_pixelmap *pRender_screen@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>) |
||
| 1935 | void DrawTheGlow(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_actor* pCamera) { |
||
| 1936 | int i; |
||
| 1937 | br_scalar strength; |
||
| 1938 | br_vector3 tv; |
||
| 1939 | tU32 seed; |
||
| 1940 | LOG_TRACE("(%p, %p, %p)", pRender_screen, pDepth_buffer, pCamera); |
||
| 1941 | |||
| 1942 | if (gColumn_flags) { |
||
| 1943 | seed = rand(); |
||
| 1944 | srand(GetTotalTime()); |
||
| 1945 | for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { |
||
| 1946 | if (((1u << i) & gColumn_flags) != 0 && gSmoke_column[i].colour <= 1) { |
||
| 1947 | strength = 0.5f; |
||
| 1948 | if (gSmoke_column[i].lifetime < 4000) { |
||
| 1949 | strength = gSmoke_column[i].lifetime * 0.5f / 4000.f; |
||
| 1950 | } |
||
| 1951 | BrVector3Set(&tv, gSmoke_column[i].pos.v[0], gSmoke_column[i].pos.v[1] + 0.02f, gSmoke_column[i].pos.v[2]); |
||
| 1952 | SmokeCircle3D(&tv, 0.07f, strength, SRandomBetween(0.5f, 0.99f), pRender_screen, pDepth_buffer, gAcid_shade_table, pCamera); |
||
| 1953 | } |
||
| 1954 | } |
||
| 1955 | srand(seed); |
||
| 1956 | } |
||
| 1957 | } |
||
| 1958 | |||
| 1959 | // IDA: void __usercall PipeInstantUnSmudge(tCar_spec *pCar@<EAX>) |
||
| 1960 | void PipeInstantUnSmudge(tCar_spec* pCar) { |
||
| 1961 | br_model* model; |
||
| 1962 | br_model* b_model; |
||
| 1963 | br_actor* actor; |
||
| 1964 | br_actor* bonny; |
||
| 1965 | int j; |
||
| 1966 | int n; |
||
| 1967 | int v; |
||
| 1968 | int group; |
||
| 1969 | tSmudged_vertex data[1000]; |
||
| 1970 | LOG_TRACE("(%p)", pCar); |
||
| 1971 | |||
| 1972 | if (!gAction_replay_mode) { |
||
| 1973 | return; |
||
| 1974 | } |
||
| 1975 | actor = pCar->car_model_actors[pCar->principal_car_actor].actor; |
||
| 1976 | model = actor->model; |
||
| 1977 | bonny = pCar->car_model_actors[pCar->car_actor_count - 1].actor; |
||
| 1978 | n = 0; |
||
| 1979 | if ((model->flags & BR_MODF_KEEP_ORIGINAL) != 0 || (model->flags & BR_MODF_UPDATEABLE) != 0) { |
||
| 1980 | StartPipingSession(ePipe_chunk_smudge); |
||
| 1981 | j = 0; |
||
| 1982 | for (group = 0; group < V11MODEL(model)->ngroups; group++) { |
||
| 1983 | for (v = 0; v < V11MODEL(model)->groups[group].nvertices; v++) { |
||
| 1984 | if ((V11MODEL(model)->groups[group].vertex_colours[v] >> 24) != 0) { |
||
| 1985 | data[n].vertex_index = j; |
||
| 1986 | data[n].light_index = 0 -(V11MODEL(model)->groups[group].vertex_colours[v] >> 24); // Pierre-Marie Baty -- prefixed 0 to silence signedness warning |
||
| 1987 | n += 1; |
||
| 1988 | V11MODEL(model)->groups[group].vertex_colours[v] = 0; |
||
| 1989 | if ((model->flags & 0x80) != 0) { |
||
| 1990 | model->vertices[V11MODEL(model)->groups[group].vertex_user[v]].index = 0; |
||
| 1991 | } |
||
| 1992 | if (n >= COUNT_OF(data)) { |
||
| 1993 | group = V11MODEL(model)->ngroups; |
||
| 1994 | break; |
||
| 1995 | } |
||
| 1996 | } |
||
| 1997 | j += 1; |
||
| 1998 | } |
||
| 1999 | } |
||
| 2000 | if (n != 0) { |
||
| 2001 | AddSmudgeToPipingSession(pCar->car_ID, pCar->principal_car_actor, n, data); |
||
| 2002 | } |
||
| 2003 | if (bonny != actor) { |
||
| 2004 | b_model = bonny->model; |
||
| 2005 | n = 0; |
||
| 2006 | j = 0; |
||
| 2007 | for (group = 0; group < V11MODEL(model)->ngroups; group++) { |
||
| 2008 | for (v = 0; v < V11MODEL(model)->groups[group].nvertices; v++) { |
||
| 2009 | if ((V11MODEL(model)->groups[group].vertex_colours[v] >> 24) != 0) { |
||
| 2010 | data[n].vertex_index = j; |
||
| 2011 | data[n].light_index = -V11MODEL(model)->groups[group].nvertices; |
||
| 2012 | n += 1; |
||
| 2013 | V11MODEL(model)->groups[group].vertex_colours[v] = 0; |
||
| 2014 | if ((b_model->flags & BR_MODF_UPDATEABLE) != 0) { |
||
| 2015 | b_model->vertices[V11MODEL(model)->groups[group].vertex_user[v]].index = 0; |
||
| 2016 | } |
||
| 2017 | if (n >= COUNT_OF(data)) { |
||
| 2018 | group = V11MODEL(model)->groups[group].nvertices; |
||
| 2019 | break; |
||
| 2020 | } |
||
| 2021 | } |
||
| 2022 | j += 1; |
||
| 2023 | } |
||
| 2024 | } |
||
| 2025 | if (n != 0) { |
||
| 2026 | AddSmudgeToPipingSession(pCar->car_ID, pCar->car_actor_count - 1, n, data); |
||
| 2027 | } |
||
| 2028 | } |
||
| 2029 | EndPipingSession(); |
||
| 2030 | } |
||
| 2031 | } |
||
| 2032 | |||
| 2033 | // IDA: void __usercall SmudgeCar(tCar_spec *pCar@<EAX>, int fire_point@<EDX>) |
||
| 2034 | void SmudgeCar(tCar_spec* pCar, int fire_point) { |
||
| 2035 | int v; |
||
| 2036 | int j; |
||
| 2037 | int real_vertex_number; |
||
| 2038 | br_model* model; |
||
| 2039 | br_model* b_model; |
||
| 2040 | br_actor* actor; |
||
| 2041 | br_actor* bonny; |
||
| 2042 | br_scalar ts; |
||
| 2043 | br_vector3 tv; |
||
| 2044 | br_vector3 bonny_pos; |
||
| 2045 | int group; |
||
| 2046 | br_vector3 point; |
||
| 2047 | tSmudged_vertex data[30]; |
||
| 2048 | int n; |
||
| 2049 | LOG_TRACE("(%p, %d)", pCar, fire_point); |
||
| 2050 | |||
| 2051 | if (gAusterity_mode) { |
||
| 2052 | return; |
||
| 2053 | } |
||
| 2054 | |||
| 2055 | v = fire_point; |
||
| 2056 | group = 0; |
||
| 2057 | actor = pCar->car_model_actors[pCar->principal_car_actor].actor; |
||
| 2058 | model = actor->model; |
||
| 2059 | bonny = pCar->car_model_actors[pCar->car_actor_count - 1].actor; |
||
| 2060 | n = 0; |
||
| 2061 | real_vertex_number = 0; |
||
| 2062 | if ((model->flags & BR_MODF_KEEP_ORIGINAL) != 0 || (model->flags & BR_MODF_UPDATEABLE) != 0) { |
||
| 20 | pmbaty | 2063 | point = V11MODEL(model)->groups[group].vertices[fire_point].p; |
| 1 | pmbaty | 2064 | StartPipingSession(ePipe_chunk_smudge); |
| 2065 | for (group = 0; group < V11MODEL(model)->ngroups; group++) { |
||
| 2066 | for (j = 0; j < V11MODEL(model)->groups[group].nvertices; j++) { |
||
| 20 | pmbaty | 2067 | BrVector3Sub(&tv, &V11MODEL(model)->groups[group].vertices[j].p, &point); |
| 1 | pmbaty | 2068 | ts = (.0144f - BrVector3LengthSquared(&tv) / SRandomBetween(.5f, 1.f)) / .0144f * 127.f; |
| 2069 | if (ts > 0.f) { |
||
| 2070 | ts += BR_ALPHA(V11MODEL(model)->groups[group].vertex_colours[j]); |
||
| 2071 | if (ts > 255.f) { |
||
| 2072 | ts = 255.f; |
||
| 2073 | } |
||
| 2074 | if (BR_ALPHA(V11MODEL(model)->groups[group].vertex_colours[j]) != (int)ts) { |
||
| 2075 | data[n].vertex_index = real_vertex_number; |
||
| 2076 | data[n].light_index = (int)ts - BR_ALPHA(V11MODEL(model)->groups[group].vertex_colours[j]); |
||
| 2077 | V11MODEL(model)->groups[group].vertex_colours[j] = (int)ts << 24; |
||
| 2078 | if ((model->flags & BR_MODF_UPDATEABLE) != 0) { |
||
| 2079 | model->vertices[V11MODEL(model)->groups[group].vertex_user[j]].index = (int)ts; |
||
| 2080 | } |
||
| 2081 | n++; |
||
| 2082 | if (n >= COUNT_OF(data)) { |
||
| 2083 | break; |
||
| 2084 | } |
||
| 2085 | } |
||
| 2086 | } |
||
| 2087 | real_vertex_number++; |
||
| 2088 | } |
||
| 2089 | if (n >= COUNT_OF(data)) { |
||
| 2090 | break; |
||
| 2091 | } |
||
| 2092 | } |
||
| 2093 | if (n > 0) { |
||
| 2094 | AddSmudgeToPipingSession(pCar->car_ID, pCar->principal_car_actor, n, data); |
||
| 2095 | // Added by dethrace to update gpu-buffered vertices |
||
| 20 | pmbaty | 2096 | model->flags |= BR_MODF_DETHRACE_FORCE_BUFFER_UPDATE; |
| 1 | pmbaty | 2097 | } |
| 2098 | |||
| 2099 | n = 0; |
||
| 2100 | real_vertex_number = 0; |
||
| 2101 | if (actor != bonny) { |
||
| 2102 | b_model = bonny->model; |
||
| 2103 | BrVector3Add(&tv, &actor->t.t.translate.t, &point); |
||
| 2104 | BrVector3Accumulate(&tv, &bonny->t.t.translate.t); |
||
| 2105 | BrMatrix34TApplyV(&bonny_pos, &tv, &bonny->t.t.mat); |
||
| 2106 | for (group = 0; group < V11MODEL(b_model)->ngroups; group++) { |
||
| 2107 | j = 0; |
||
| 2108 | for (j = 0; j < V11MODEL(b_model)->groups[group].nvertices; j++) { |
||
| 20 | pmbaty | 2109 | BrVector3Sub(&tv, &V11MODEL(b_model)->groups[group].vertices[j].p, &bonny_pos); |
| 1 | pmbaty | 2110 | ts = (.0144f - BrVector3LengthSquared(&tv) / SRandomBetween(.5f, 1.f)) / .0144f * 127.f; |
| 2111 | if (ts > 0.f) { |
||
| 2112 | ts += BR_ALPHA(V11MODEL(b_model)->groups[group].vertex_colours[j]); |
||
| 2113 | if (ts > 255.f) { |
||
| 2114 | ts = 255.f; |
||
| 2115 | } |
||
| 2116 | if (BR_ALPHA(V11MODEL(b_model)->groups[group].vertex_colours[j]) != (int)ts) { |
||
| 2117 | data[n].vertex_index = real_vertex_number; |
||
| 2118 | data[n].light_index = (int)ts - BR_ALPHA(V11MODEL(b_model)->groups[group].vertex_colours[j]); |
||
| 2119 | V11MODEL(b_model)->groups[group].vertex_colours[j] = (int)ts << 24; |
||
| 2120 | if ((b_model->flags & BR_MODF_UPDATEABLE) != 0) { |
||
| 2121 | b_model->vertices[V11MODEL(b_model)->groups[group].vertex_user[j]].index = (int)ts; |
||
| 2122 | } |
||
| 2123 | n++; |
||
| 2124 | if (n >= COUNT_OF(data)) { |
||
| 2125 | break; |
||
| 2126 | } |
||
| 2127 | } |
||
| 2128 | } |
||
| 2129 | real_vertex_number++; |
||
| 2130 | } |
||
| 2131 | if (n >= COUNT_OF(data)) { |
||
| 2132 | break; |
||
| 2133 | } |
||
| 2134 | } |
||
| 2135 | if (n > 0) { |
||
| 2136 | AddSmudgeToPipingSession(pCar->car_ID, pCar->car_actor_count - 1, n, data); |
||
| 20 | pmbaty | 2137 | |
| 1 | pmbaty | 2138 | // Added by dethrace to update gpu-buffered vertices |
| 20 | pmbaty | 2139 | b_model->flags |= BR_MODF_DETHRACE_FORCE_BUFFER_UPDATE; |
| 1 | pmbaty | 2140 | } |
| 2141 | } |
||
| 2142 | EndPipingSession(); |
||
| 2143 | } |
||
| 2144 | } |
||
| 2145 | |||
| 2146 | // IDA: void __cdecl ResetSmokeColumns() |
||
| 2147 | void ResetSmokeColumns(void) { |
||
| 20 | pmbaty | 2148 | //int i; // Pierre-Marie Baty -- unused variable |
| 1 | pmbaty | 2149 | LOG_TRACE("()"); |
| 20 | pmbaty | 2150 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 2151 | } |
| 2152 | |||
| 2153 | // IDA: void __usercall SetSmokeOn(int pSmoke_on@<EAX>) |
||
| 2154 | void SetSmokeOn(int pSmoke_on) { |
||
| 2155 | LOG_TRACE("(%d)", pSmoke_on); |
||
| 2156 | |||
| 2157 | gSmoke_on = pSmoke_on; |
||
| 2158 | } |
||
| 2159 | |||
| 2160 | // IDA: void __usercall ReallySetSmokeOn(int pSmoke_on@<EAX>) |
||
| 2161 | void ReallySetSmokeOn(int pSmoke_on) { |
||
| 2162 | LOG_TRACE("(%d)", pSmoke_on); |
||
| 20 | pmbaty | 2163 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 2164 | } |
| 2165 | |||
| 2166 | // IDA: void __usercall SetSmoke(int pSmoke_on@<EAX>) |
||
| 2167 | void SetSmoke(int pSmoke_on) { |
||
| 2168 | LOG_TRACE("(%d)", pSmoke_on); |
||
| 2169 | |||
| 2170 | ReallySetSmokeOn(pSmoke_on); |
||
| 2171 | SetSmokeOn(pSmoke_on); |
||
| 2172 | } |
||
| 2173 | |||
| 2174 | // IDA: int __cdecl GetSmokeOn() |
||
| 2175 | int GetSmokeOn(void) { |
||
| 2176 | LOG_TRACE("()"); |
||
| 2177 | |||
| 2178 | return gSmoke_on; |
||
| 2179 | } |
||
| 2180 | |||
| 2181 | // IDA: void __usercall StopCarSmoking(tCar_spec *pCar@<EAX>) |
||
| 2182 | void StopCarSmoking(tCar_spec* pCar) { |
||
| 2183 | int i; |
||
| 2184 | LOG_TRACE("(%p)", pCar); |
||
| 2185 | |||
| 2186 | for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { |
||
| 2187 | if (gSmoke_column[i].car == pCar && gSmoke_column[i].lifetime > 2000) { |
||
| 2188 | gSmoke_column[i].lifetime = 2000; |
||
| 2189 | } |
||
| 2190 | } |
||
| 2191 | } |
||
| 2192 | |||
| 2193 | // IDA: void __usercall StopCarSmokingInstantly(tCar_spec *pCar@<EAX>) |
||
| 2194 | void StopCarSmokingInstantly(tCar_spec* pCar) { |
||
| 2195 | int i; |
||
| 2196 | LOG_TRACE("(%p)", pCar); |
||
| 2197 | |||
| 2198 | for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { |
||
| 2199 | if (gSmoke_column[i].car == pCar) { |
||
| 2200 | gSmoke_column[i].lifetime = 0; |
||
| 2201 | } |
||
| 2202 | } |
||
| 2203 | } |
||
| 2204 | |||
| 2205 | // IDA: void __usercall ConditionalSmokeColumn(tCar_spec *pCar@<EAX>, int pDamage_index@<EDX>, int pColour@<EBX>) |
||
| 2206 | void ConditionalSmokeColumn(tCar_spec* pCar, int pDamage_index, int pColour) { |
||
| 2207 | int i; |
||
| 2208 | LOG_TRACE("(%p, %d, %d)", pCar, pDamage_index, pColour); |
||
| 2209 | |||
| 2210 | if (!pColour) { |
||
| 2211 | pColour = pCar->driver < eDriver_net_human; |
||
| 2212 | } |
||
| 2213 | if (pCar->num_smoke_columns != 0) { |
||
| 2214 | for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { |
||
| 2215 | if (gSmoke_column[i].car == pCar) { |
||
| 2216 | if (((1u << i) & gColumn_flags) != 0 && gSmoke_column[i].colour <= pColour && gSmoke_column[i].lifetime) { |
||
| 2217 | return; |
||
| 2218 | } |
||
| 2219 | gSmoke_column[i].lifetime = 2000; |
||
| 2220 | } |
||
| 2221 | } |
||
| 2222 | } |
||
| 2223 | CreateSmokeColumn(pCar, pColour, pCar->fire_vertex[pDamage_index], 10000000u); |
||
| 2224 | } |
||
| 2225 | |||
| 2226 | // IDA: void __usercall SingleSplash(tCar_spec *pCar@<EAX>, br_vector3 *sp@<EDX>, br_vector3 *normal@<EBX>, tU32 pTime@<ECX>) |
||
| 2227 | void SingleSplash(tCar_spec* pCar, br_vector3* sp, br_vector3* normal, tU32 pTime) { |
||
| 2228 | br_matrix34* mat; |
||
| 2229 | br_matrix34* c_mat; |
||
| 2230 | br_vector3 tv; |
||
| 2231 | br_vector3 vel; |
||
| 2232 | br_scalar size; |
||
| 2233 | br_scalar speed; |
||
| 2234 | br_scalar ts; |
||
| 2235 | LOG_TRACE("(%p, %p, %p, %d)", pCar, sp, normal, pTime); |
||
| 2236 | |||
| 2237 | mat = &gSplash[gNext_splash].actor->t.t.mat; |
||
| 2238 | c_mat = &pCar->car_master_actor->t.t.mat; |
||
| 2239 | BrMatrix34ApplyP(&gSplash[gNext_splash].actor->t.t.euler.t, sp, c_mat); |
||
| 2240 | tv.v[0] = sp->v[2] * pCar->omega.v[1] - pCar->omega.v[2] * sp->v[1]; |
||
| 2241 | tv.v[1] = pCar->omega.v[2] * sp->v[0] - sp->v[2] * pCar->omega.v[0]; |
||
| 2242 | tv.v[2] = sp->v[1] * pCar->omega.v[0] - pCar->omega.v[1] * sp->v[0]; |
||
| 2243 | BrMatrix34ApplyV(&vel, &tv, c_mat); |
||
| 2244 | BrVector3Accumulate(&vel, &pCar->v); |
||
| 2245 | ts = BrVector3Length(&vel); |
||
| 2246 | size = (fabs(BrVector3Dot(normal, &vel)) * 5.0 + ts) / 150.0 + 0.047826085; |
||
| 2247 | if (size > 0.5) { |
||
| 2248 | size = 0.5; |
||
| 2249 | } |
||
| 2250 | if (BrVector3Dot(&pCar->velocity_car_space, sp) < 0.0) { |
||
| 2251 | size = size / 2.0; |
||
| 2252 | } |
||
| 2253 | |||
| 2254 | gSplash[gNext_splash].size = SRandomBetween(size / 2.0, size); |
||
| 2255 | if (((1u << gNext_splash) & gSplash_flags) == 0) { |
||
| 2256 | BrActorAdd(gDont_render_actor, gSplash[gNext_splash].actor); |
||
| 2257 | } |
||
| 2258 | gSplash_flags |= 1u << gNext_splash; |
||
| 2259 | gSplash[gNext_splash].just_done = 1; |
||
| 2260 | if ((double)pTime * 0.003 > SRandomBetween(0.0, 1.0) && !gAction_replay_mode) { |
||
| 2261 | BrVector3InvScale(&vel, &vel, WORLD_SCALE); |
||
| 2262 | BrVector3Scale(&tv, &vel, 0.1f); |
||
| 2263 | speed = sqrt(ts / 70.0) * 15.0; |
||
| 2264 | if (speed > 15.0f) { |
||
| 2265 | speed = 15.0f; |
||
| 2266 | } |
||
| 2267 | tv.v[1] += SRandomBetween(5.0, speed) / WORLD_SCALE; |
||
| 2268 | BrMatrix34TApplyV(&vel, &tv, &pCar->car_master_actor->t.t.mat); |
||
| 2269 | |||
| 2270 | BrVector3Cross(&tv, &vel, &pCar->water_normal); |
||
| 2271 | BrVector3Scale(&tv, &tv, 0.5f); |
||
| 2272 | if (BrVector3Dot(sp, &tv) <= 0.0) { |
||
| 2273 | BrVector3Sub(&vel, &vel, &tv); |
||
| 2274 | } else { |
||
| 2275 | BrVector3Accumulate(&vel, &tv); |
||
| 2276 | } |
||
| 2277 | CreateSingleSpark(pCar, sp, &vel); |
||
| 2278 | } |
||
| 2279 | gNext_splash++; |
||
| 2280 | if (gNext_splash >= COUNT_OF(gSplash)) { |
||
| 2281 | gNext_splash = 0; |
||
| 2282 | } |
||
| 2283 | } |
||
| 2284 | |||
| 2285 | // IDA: void __usercall CreateSplash(tCar_spec *pCar@<EAX>, tU32 pTime@<EDX>) |
||
| 2286 | void CreateSplash(tCar_spec* pCar, tU32 pTime) { |
||
| 2287 | br_vector3 normal_car_space; |
||
| 2288 | br_vector3 pos2; |
||
| 2289 | br_vector3 v_plane; |
||
| 2290 | br_vector3 p; |
||
| 2291 | br_vector3 tv; |
||
| 2292 | br_vector3 tv2; |
||
| 2293 | br_vector3 cm; |
||
| 2294 | int i; |
||
| 2295 | int j; |
||
| 2296 | int mask; |
||
| 2297 | int axis1; |
||
| 2298 | int axis2; |
||
| 2299 | int axis3; |
||
| 2300 | //br_bounds bnds; // Pierre-Marie Baty -- unused variable |
||
| 2301 | br_scalar min; |
||
| 2302 | br_scalar max; |
||
| 2303 | br_scalar d; |
||
| 2304 | //br_scalar d2; // Pierre-Marie Baty -- unused variable |
||
| 2305 | br_scalar dist; |
||
| 2306 | br_scalar dist2; |
||
| 2307 | br_scalar ts; |
||
| 2308 | br_vector3 back_point[2]; |
||
| 2309 | br_scalar back_val[2]; |
||
| 2310 | LOG_TRACE("(%p, %d)", pCar, pTime); |
||
| 2311 | |||
| 2312 | back_val[0] = 0.0; |
||
| 2313 | back_val[1] = 0.0; |
||
| 2314 | #ifdef DETHRACE_FIX_BUGS |
||
| 2315 | BrVector3Set(&p, 0.f, 0.f, 0.f); |
||
| 2316 | #endif |
||
| 2317 | 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) { |
||
| 2318 | BrMatrix34TApplyV(&normal_car_space, &pCar->water_normal, &pCar->car_master_actor->t.t.mat); |
||
| 2319 | BrMatrix34ApplyP(&tv, &pCar->bounds[0].min, &pCar->car_master_actor->t.t.mat); |
||
| 2320 | min = BrVector3Dot(&pCar->water_normal, &tv) - pCar->water_d; |
||
| 2321 | max = min; |
||
| 2322 | for (i = 0; i < 3; ++i) { |
||
| 2323 | if (normal_car_space.v[i] <= 0.0) { |
||
| 2324 | max = (pCar->bounds[0].max.v[i] - pCar->bounds[0].min.v[i]) * normal_car_space.v[i] + max; |
||
| 2325 | } else { |
||
| 2326 | min = (pCar->bounds[0].max.v[i] - pCar->bounds[0].min.v[i]) * normal_car_space.v[i] + min; |
||
| 2327 | } |
||
| 2328 | } |
||
| 2329 | if (min * max <= 0.0) { |
||
| 2330 | BrVector3InvScale(&back_point[0], &pCar->bounds[1].min, WORLD_SCALE); |
||
| 2331 | BrVector3InvScale(&back_point[1], &pCar->bounds[1].max, WORLD_SCALE); |
||
| 2332 | back_point[0].v[1] = (br_scalar) 0.01; // Pierre-Marie Baty -- added type cast |
||
| 2333 | ts = BrVector3Dot(&pCar->velocity_car_space, &normal_car_space); |
||
| 2334 | BrVector3Scale(&tv, &normal_car_space, ts); |
||
| 2335 | BrVector3Sub(&v_plane, &pCar->velocity_car_space, &tv); |
||
| 2336 | d = pCar->water_d |
||
| 2337 | - (pCar->car_master_actor->t.t.mat.m[3][1] * pCar->water_normal.v[1] |
||
| 2338 | + pCar->car_master_actor->t.t.mat.m[3][2] * pCar->water_normal.v[2] |
||
| 2339 | + pCar->car_master_actor->t.t.mat.m[3][0] * pCar->water_normal.v[0]); |
||
| 2340 | mask = IRandomBetween(0, 3); |
||
| 2341 | axis2 = 2; |
||
| 2342 | for (axis1 = 0; axis1 < 3; ++axis1) { |
||
| 2343 | axis3 = 3 - axis1 - axis2; |
||
| 2344 | for (j = 0; j < 4; ++j) { |
||
| 2345 | i = j ^ mask; |
||
| 2346 | if (((j ^ mask) & 1) != 0) { |
||
| 2347 | tv2.v[axis3] = back_point[0].v[axis3]; |
||
| 2348 | } else { |
||
| 2349 | tv2.v[axis3] = back_point[1].v[axis3]; |
||
| 2350 | } |
||
| 2351 | if (((j ^ mask) & 1) != 0) { |
||
| 2352 | tv2.v[axis2] = back_point[0].v[axis2]; |
||
| 2353 | } else { |
||
| 2354 | tv2.v[axis2] = back_point[1].v[axis2]; |
||
| 2355 | } |
||
| 2356 | |||
| 2357 | ts = d - tv2.v[axis3] * normal_car_space.v[axis3] - tv2.v[axis2] * normal_car_space.v[axis2]; |
||
| 2358 | ts = ts / normal_car_space.v[axis1]; |
||
| 2359 | if (ts >= back_point[0].v[axis1] && back_point[1].v[axis1] >= ts) { |
||
| 2360 | tv2.v[axis1] = ts; |
||
| 2361 | ts = BrVector3Dot(&pCar->velocity_car_space, &tv2); |
||
| 2362 | if (ts >= back_val[0]) { |
||
| 2363 | if (back_val[1] <= ts) { |
||
| 2364 | SingleSplash(pCar, &tv2, &normal_car_space, pTime); |
||
| 2365 | } else { |
||
| 2366 | if (back_val[1] < 0.0) { |
||
| 2367 | SingleSplash(pCar, &pos2, &normal_car_space, pTime); |
||
| 2368 | } |
||
| 2369 | back_val[1] = ts; |
||
| 2370 | pos2 = tv2; |
||
| 2371 | } |
||
| 2372 | } else { |
||
| 2373 | if (back_val[1] < 0.0) { |
||
| 2374 | SingleSplash(pCar, &pos2, &normal_car_space, pTime); |
||
| 2375 | } |
||
| 2376 | back_val[1] = back_val[0]; |
||
| 2377 | back_val[0] = ts; |
||
| 2378 | pos2 = p; |
||
| 2379 | p = tv2; |
||
| 2380 | } |
||
| 2381 | } |
||
| 2382 | } |
||
| 2383 | axis2 = axis1; |
||
| 2384 | } |
||
| 2385 | if (back_val[1] >= 0.0) { |
||
| 2386 | if (back_val[0] < 0.0) { |
||
| 2387 | SingleSplash(pCar, &p, &normal_car_space, pTime); |
||
| 2388 | } |
||
| 2389 | } else { |
||
| 2390 | tv.v[0] = pos2.v[0] - p.v[0]; |
||
| 2391 | tv.v[1] = pos2.v[1] - p.v[1]; |
||
| 2392 | tv.v[2] = pos2.v[2] - p.v[2]; |
||
| 2393 | BrVector3Sub(&tv, &pos2, &p); |
||
| 2394 | ts = SRandomBetween((br_scalar) 0.4, (br_scalar) 0.6); // Pierre-Marie Baty -- added type casts |
||
| 2395 | BrVector3Scale(&tv2, &tv, ts); |
||
| 2396 | BrVector3Accumulate(&tv2, &p); |
||
| 2397 | ts = SRandomBetween((br_scalar) 0.2, (br_scalar) 0.3); // Pierre-Marie Baty -- added type casts |
||
| 2398 | BrVector3Scale(&cm, &tv, ts); |
||
| 2399 | BrVector3Accumulate(&p, &cm); |
||
| 2400 | ts = -SRandomBetween((br_scalar) 0.2, (br_scalar) 0.3); // Pierre-Marie Baty -- added type casts |
||
| 2401 | BrVector3Scale(&cm, &tv, ts); |
||
| 2402 | BrVector3Accumulate(&pos2, &cm); |
||
| 2403 | ts = BrVector3Dot(&pCar->velocity_car_space, &normal_car_space); |
||
| 2404 | BrVector3Scale(&tv, &normal_car_space, -ts); |
||
| 2405 | BrVector3Add(&v_plane, &pCar->velocity_car_space, &tv); |
||
| 2406 | BrVector3Normalise(&tv, &v_plane); |
||
| 2407 | BrVector3Scale(&tv, &tv, -0.028985508f); |
||
| 2408 | BrVector3Accumulate(&tv2, &tv); |
||
| 2409 | BrVector3Scale(&tv, &tv, 0.5f); |
||
| 2410 | BrVector3Accumulate(&p, &tv); |
||
| 2411 | BrVector3Accumulate(&pos2, &tv); |
||
| 2412 | SingleSplash(pCar, &tv2, &normal_car_space, pTime); |
||
| 2413 | SingleSplash(pCar, &p, &normal_car_space, pTime); |
||
| 2414 | SingleSplash(pCar, &pos2, &normal_car_space, pTime); |
||
| 2415 | } |
||
| 2416 | d = d * WORLD_SCALE; |
||
| 2417 | dist = d - BrVector3Dot(&pCar->cmpos, &normal_car_space); |
||
| 2418 | for (i = 0; pCar->extra_point_num > i; ++i) { |
||
| 2419 | dist2 = d |
||
| 2420 | - (pCar->extra_points[i].v[1] * normal_car_space.v[1] |
||
| 2421 | + pCar->extra_points[i].v[2] * normal_car_space.v[2] |
||
| 2422 | + pCar->extra_points[i].v[0] * normal_car_space.v[0]); |
||
| 2423 | if ((dist > 0.0) != (dist2 > 0.0)) { |
||
| 2424 | ts = dist / (dist - dist2); |
||
| 2425 | BrVector3Sub(&tv, &pCar->extra_points[i], &pCar->cmpos); |
||
| 2426 | BrVector3Scale(&tv, &tv, ts); |
||
| 2427 | BrVector3Accumulate(&tv, &pCar->cmpos); |
||
| 2428 | if (pCar->bounds[1].max.v[1] - 0.028985508 > tv.v[1] |
||
| 2429 | || pCar->bounds[1].min.v[0] > tv.v[0] |
||
| 2430 | || pCar->bounds[1].max.v[0] < tv.v[1] |
||
| 2431 | || pCar->bounds[1].min.v[2] > tv.v[2] |
||
| 2432 | || pCar->bounds[1].max.v[2] < tv.v[2]) { |
||
| 2433 | BrVector3InvScale(&tv, &tv, WORLD_SCALE); |
||
| 2434 | SingleSplash(pCar, &tv, &normal_car_space, pTime); |
||
| 2435 | } |
||
| 2436 | } |
||
| 2437 | } |
||
| 2438 | for (i = 0; i < 4; ++i) { |
||
| 2439 | if ((i & 1) != 0) { |
||
| 2440 | tv.v[0] = pCar->bounds[1].max.v[0]; |
||
| 2441 | } else { |
||
| 2442 | tv.v[0] = pCar->bounds[1].min.v[0]; |
||
| 2443 | } |
||
| 2444 | tv.v[1] = pCar->bounds[1].max.v[1]; |
||
| 2445 | tv.v[2] = pCar->wpos[i].v[2]; |
||
| 2446 | dist = d - BrVector3Dot(&tv, &normal_car_space); |
||
| 2447 | dist2 = (pCar->bounds[1].max.v[1] - 0.01) * normal_car_space.v[1] + dist; |
||
| 2448 | if ((dist > 0.0) != (dist2 > 0.0)) { |
||
| 2449 | ts = dist / (dist - dist2); |
||
| 2450 | tv.v[1] -= (pCar->bounds[1].max.v[1] - 0.01) * ts; |
||
| 2451 | BrVector3InvScale(&tv, &tv, WORLD_SCALE); |
||
| 2452 | SingleSplash(pCar, &tv, &normal_car_space, pTime); |
||
| 2453 | } |
||
| 2454 | } |
||
| 2455 | } else { |
||
| 2456 | min = min + 1.0; |
||
| 2457 | } |
||
| 2458 | } |
||
| 2459 | } |
||
| 2460 | |||
| 2461 | // IDA: void __usercall MungeSplash(tU32 pTime@<EAX>) |
||
| 2462 | void MungeSplash(tU32 pTime) { |
||
| 2463 | int i; |
||
| 2464 | //br_vector3 tv; // Pierre-Marie Baty -- unused variable |
||
| 2465 | br_scalar dt; |
||
| 2466 | br_scalar ts; |
||
| 2467 | tCar_spec* car; |
||
| 2468 | tVehicle_type type; |
||
| 2469 | LOG_TRACE("(%d)", pTime); |
||
| 2470 | |||
| 2471 | if (gNum_splash_types == 0) { |
||
| 2472 | return; |
||
| 2473 | } |
||
| 2474 | if (!gAction_replay_mode || GetReplayRate() == 0.0) { |
||
| 2475 | if (!gAction_replay_mode) { |
||
| 2476 | for (i = 0; i < gNum_cars_and_non_cars; i++) { |
||
| 2477 | if (gActive_car_list[i]->water_d != 10000.0 && gActive_car_list[i]->driver != eDriver_local_human) { |
||
| 2478 | CreateSplash(gActive_car_list[i], pTime); |
||
| 2479 | } |
||
| 2480 | } |
||
| 2481 | if (gProgram_state.current_car.water_d != 10000.0) { |
||
| 2482 | CreateSplash(&gProgram_state.current_car, 100); |
||
| 2483 | } |
||
| 2484 | } |
||
| 2485 | } else { |
||
| 2486 | for (type = eVehicle_net_player; type <= eVehicle_rozzer; type++) { |
||
| 2487 | for (i = 0;; i++) { |
||
| 2488 | if (i >= type ? GetCarCount(type) : 1) { |
||
| 2489 | break; |
||
| 2490 | } |
||
| 2491 | if (type) { |
||
| 2492 | car = GetCarSpec(type, i); |
||
| 2493 | } else { |
||
| 2494 | car = &gProgram_state.current_car; |
||
| 2495 | } |
||
| 2496 | if (car->water_d != 10000.0 && car->driver != eDriver_local_human) { |
||
| 2497 | CreateSplash(car, pTime); |
||
| 2498 | } |
||
| 2499 | } |
||
| 2500 | } |
||
| 2501 | if (gProgram_state.current_car.water_d != 10000.0) { |
||
| 2502 | CreateSplash(&gProgram_state.current_car, 0x64u); |
||
| 2503 | } |
||
| 2504 | } |
||
| 2505 | if (!gSplash_flags) { |
||
| 2506 | return; |
||
| 2507 | } |
||
| 2508 | for (i = 0; i < COUNT_OF(gSplash); i++) { |
||
| 2509 | if (((1u << i) & gSplash_flags) == 0) { |
||
| 2510 | continue; |
||
| 2511 | } |
||
| 2512 | if (gSplash[i].just_done || (gAction_replay_mode && GetReplayRate() == 0.0f)) { |
||
| 2513 | dt = gSplash[i].size * gSplash[i].scale_x; |
||
| 2514 | gSplash[i].actor->t.t.mat.m[0][0] = gCamera_to_world.m[0][0] * dt; |
||
| 2515 | gSplash[i].actor->t.t.mat.m[0][1] = gCamera_to_world.m[0][1] * dt; |
||
| 2516 | gSplash[i].actor->t.t.mat.m[0][2] = gCamera_to_world.m[0][2] * dt; |
||
| 2517 | gSplash[i].actor->t.t.mat.m[1][0] = gSplash[i].size * gCamera_to_world.m[1][0]; |
||
| 2518 | gSplash[i].actor->t.t.mat.m[1][1] = gSplash[i].size * gCamera_to_world.m[1][1]; |
||
| 2519 | gSplash[i].actor->t.t.mat.m[1][2] = gSplash[i].size * gCamera_to_world.m[1][2]; |
||
| 2520 | gSplash[i].actor->t.t.mat.m[2][0] = gSplash[i].size * gCamera_to_world.m[2][0]; |
||
| 2521 | gSplash[i].actor->t.t.mat.m[2][1] = gSplash[i].size * gCamera_to_world.m[2][1]; |
||
| 2522 | gSplash[i].actor->t.t.mat.m[2][2] = gSplash[i].size * gCamera_to_world.m[2][2]; |
||
| 2523 | if (gProgram_state.cockpit_on) { |
||
| 2524 | 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]); |
||
| 2525 | DRMatrix34PreRotateZ(&gSplash[i].actor->t.t.mat, -FastScalarArcTan2Angle(gCamera_to_world.m[0][1], ts)); |
||
| 2526 | } |
||
| 2527 | gSplash[i].just_done = 0; |
||
| 2528 | } else { |
||
| 2529 | gSplash_flags &= ~(1u << i); |
||
| 2530 | BrActorRemove(gSplash[i].actor); |
||
| 2531 | } |
||
| 2532 | } |
||
| 2533 | } |
||
| 2534 | |||
| 2535 | // IDA: void __cdecl RenderSplashes() |
||
| 2536 | void RenderSplashes(void) { |
||
| 2537 | int i; |
||
| 2538 | LOG_TRACE("()"); |
||
| 2539 | |||
| 2540 | for (i = 0; i < COUNT_OF(gSplash); i++) { |
||
| 2541 | if (gSplash_flags & (1u << i)) { |
||
| 2542 | BrActorRelink(gNon_track_actor, gSplash[i].actor); |
||
| 2543 | BrZbSceneRenderAdd(gSplash[i].actor); |
||
| 2544 | BrActorRelink(gDont_render_actor, gSplash[i].actor); |
||
| 2545 | } |
||
| 2546 | } |
||
| 2547 | } |
||
| 2548 | |||
| 2549 | // IDA: void __usercall GetSmokeShadeTables(FILE *f@<EAX>) |
||
| 2550 | void GetSmokeShadeTables(FILE* f) { |
||
| 2551 | int i; |
||
| 2552 | int red; |
||
| 2553 | int green; |
||
| 2554 | int blue; |
||
| 2555 | br_scalar quarter; |
||
| 2556 | br_scalar half; |
||
| 2557 | br_scalar three_quarter; |
||
| 2558 | LOG_TRACE("(%p)", f); |
||
| 2559 | |||
| 2560 | gNum_dust_tables = GetAnInt(f); |
||
| 2561 | if (gNum_dust_tables > 8) { |
||
| 2562 | gNum_dust_tables = 8; |
||
| 2563 | } |
||
| 2564 | for (i = 0; gNum_dust_tables > i; ++i) { |
||
| 2565 | PossibleService(); |
||
| 2566 | GetThreeInts(f, &red, &green, &blue); |
||
| 2567 | GetThreeScalars(f, &quarter, &half, &three_quarter); |
||
| 2568 | gDust_table[i] = GenerateShadeTable(16, gRender_palette, red, green, blue, quarter, half, three_quarter); |
||
| 2569 | } |
||
| 2570 | } |
||
| 2571 | |||
| 2572 | // IDA: void __cdecl FreeSmokeShadeTables() |
||
| 2573 | void FreeSmokeShadeTables(void) { |
||
| 2574 | int i; |
||
| 2575 | LOG_TRACE("()"); |
||
| 2576 | |||
| 2577 | for (i = 0; i < gNum_dust_tables; i++) { |
||
| 2578 | PossibleService(); |
||
| 2579 | BrTableRemove(gDust_table[i]); |
||
| 2580 | BrPixelmapFree(gDust_table[i]); |
||
| 2581 | } |
||
| 2582 | } |
||
| 2583 | |||
| 2584 | // IDA: void __usercall LoadInKevStuff(FILE *pF@<EAX>) |
||
| 2585 | void LoadInKevStuff(FILE* pF) { |
||
| 2586 | LOG_TRACE("(%p)", pF); |
||
| 2587 | |||
| 2588 | PossibleService(); |
||
| 2589 | LoadInShrapnel(); |
||
| 2590 | PossibleService(); |
||
| 2591 | InitShrapnel(); |
||
| 2592 | PossibleService(); |
||
| 2593 | InitFlame(); |
||
| 2594 | PossibleService(); |
||
| 2595 | InitSplash(pF); |
||
| 2596 | } |
||
| 2597 | |||
| 2598 | // IDA: void __cdecl DisposeKevStuff() |
||
| 2599 | void DisposeKevStuff(void) { |
||
| 2600 | LOG_TRACE("()"); |
||
| 2601 | |||
| 2602 | DisposeShrapnel(); |
||
| 2603 | DisposeFlame(); |
||
| 2604 | DisposeSplash(); |
||
| 2605 | } |
||
| 2606 | |||
| 2607 | // IDA: void __usercall DisposeKevStuffCar(tCar_spec *pCar@<EAX>) |
||
| 2608 | void DisposeKevStuffCar(tCar_spec* pCar) { |
||
| 2609 | int i; |
||
| 2610 | LOG_TRACE("(%p)", pCar); |
||
| 2611 | |||
| 2612 | for (i = 0; i < MAX_SMOKE_COLUMNS; i++) { |
||
| 2613 | if (gSmoke_column[i].car == pCar) { |
||
| 2614 | gSmoke_column[i].lifetime = 0; |
||
| 2615 | gSmoke_column[i].car = NULL; |
||
| 2616 | } |
||
| 2617 | } |
||
| 2618 | for (i = 0; i < COUNT_OF(gSparks); i++) { |
||
| 2619 | if ((gSpark_flags & (1u << i)) && gSparks[i].car == pCar) { |
||
| 2620 | gSparks[i].count = 0; |
||
| 2621 | gSpark_flags &= ~(1u << i); |
||
| 2622 | } |
||
| 2623 | if (gCar_to_view == pCar) { |
||
| 2624 | gCamera_yaw = 0; |
||
| 2625 | gCar_to_view = &gProgram_state.current_car; |
||
| 2626 | InitialiseExternalCamera(); |
||
| 2627 | PositionExternalCamera(gCar_to_view, 200); |
||
| 2628 | gCar_to_view = &gProgram_state.current_car; |
||
| 2629 | } |
||
| 2630 | } |
||
| 2631 | } |
||
| 2632 | |||
| 2633 | // IDA: void __cdecl DoTrueColModelThing(br_actor *actor, br_model *pModel, br_material *material, void *render_data, br_uint_8 style, int on_screen) |
||
| 2634 | void DoTrueColModelThing(br_actor* actor, br_model* pModel, br_material* material, void* render_data, br_uint_8 style, int on_screen) { |
||
| 20 | pmbaty | 2635 | //int group; // Pierre-Marie Baty -- unused variable |
| 2636 | //int j; // Pierre-Marie Baty -- unused variable |
||
| 2637 | //int val; // Pierre-Marie Baty -- unused variable |
||
| 1 | pmbaty | 2638 | LOG_TRACE("(%p, %p, %p, %p, %d, %d)", actor, pModel, material, render_data, style, on_screen); |
| 2639 | NOT_IMPLEMENTED(); |
||
| 2640 | } |
||
| 2641 | |||
| 2642 | // IDA: void __cdecl DoModelThing(br_actor *actor, br_model *pModel, br_material *material, void *render_data, br_uint_8 style, int on_screen) |
||
| 2643 | void DoModelThing(br_actor* actor, br_model* pModel, br_material* material, void* render_data, br_uint_8 style, int on_screen) { |
||
| 20 | pmbaty | 2644 | //int j; // Pierre-Marie Baty -- unused variable |
| 2645 | //int i; // Pierre-Marie Baty -- unused variable |
||
| 2646 | //int group; // Pierre-Marie Baty -- unused variable |
||
| 2647 | //tU32 t; // Pierre-Marie Baty -- unused variable |
||
| 2648 | //int val; // Pierre-Marie Baty -- unused variable |
||
| 1 | pmbaty | 2649 | LOG_TRACE("(%p, %p, %p, %p, %d, %d)", actor, pModel, material, render_data, style, on_screen); |
| 20 | pmbaty | 2650 | NOT_IMPLEMENTED(); |
| 1 | pmbaty | 2651 | } |
| 2652 | |||
| 2653 | // IDA: void __usercall SetModelShade(br_actor *pActor@<EAX>, br_pixelmap *pShade@<EDX>) |
||
| 2654 | void SetModelShade(br_actor* pActor, br_pixelmap* pShade) { |
||
| 2655 | int i; |
||
| 2656 | br_material* material; |
||
| 2657 | br_model* model; |
||
| 2658 | LOG_TRACE("(%p, %p)", pActor, pShade); |
||
| 2659 | |||
| 2660 | model = pActor->model; |
||
| 2661 | if (pActor->material != NULL && pActor->material->index_shade != pShade) { |
||
| 2662 | pActor->material->index_shade = pShade; |
||
| 2663 | BrMaterialUpdate(pActor->material, BR_MATU_ALL); |
||
| 2664 | } |
||
| 2665 | for (i = 0; i < model->nfaces; i++) { |
||
| 2666 | material = model->faces[i].material; |
||
| 2667 | if (material != NULL && material->index_shade != pShade) { |
||
| 2668 | material->index_shade = pShade; |
||
| 2669 | BrMaterialUpdate(material, BR_MATU_ALL); |
||
| 2670 | } |
||
| 2671 | } |
||
| 2672 | } |
||
| 2673 | |||
| 2674 | // IDA: void __usercall MakeCarIt(tCar_spec *pCar@<EAX>) |
||
| 2675 | void MakeCarIt(tCar_spec* pCar) { |
||
| 2676 | br_actor* actor; |
||
| 2677 | br_actor* bonny; |
||
| 2678 | br_pixelmap* shade[6]; |
||
| 2679 | static int shade_num = 0; |
||
| 2680 | //int i; // Pierre-Marie Baty -- unused variable |
||
| 2681 | LOG_TRACE("(%p)", pCar); |
||
| 2682 | |||
| 20 | pmbaty | 2683 | STUB(); |
| 2684 | return; |
||
| 2685 | |||
| 1 | pmbaty | 2686 | shade[0] = gIt_shade_table; |
| 2687 | shade[1] = gFog_shade_table; |
||
| 2688 | shade[2] = gShade_list[0]; |
||
| 2689 | shade[3] = gShade_list[1]; |
||
| 2690 | shade[4] = gShade_list[2]; |
||
| 2691 | shade[5] = NULL; |
||
| 2692 | |||
| 2693 | actor = pCar->car_model_actors[pCar->principal_car_actor].actor; |
||
| 2694 | bonny = pCar->car_model_actors[pCar->car_actor_count - 1].actor; |
||
| 20 | pmbaty | 2695 | if (((actor->model->flags & BR_MODF_CUSTOM) == 0) || actor->model->custom != DoTrueColModelThing) { |
| 1 | pmbaty | 2696 | SetModelShade(actor, shade[shade_num]); |
| 20 | pmbaty | 2697 | actor->model->user = DoTrueColModelThing; |
| 2698 | actor->model->custom = DoTrueColModelThing; |
||
| 1 | pmbaty | 2699 | actor->model->flags |= BR_MODF_CUSTOM; |
| 2700 | if (bonny != actor) { |
||
| 20 | pmbaty | 2701 | bonny->model->user = DoTrueColModelThing; |
| 2702 | bonny->model->custom = DoTrueColModelThing; |
||
| 1 | pmbaty | 2703 | bonny->model->flags |= BR_MODF_CUSTOM; |
| 2704 | SetModelShade(bonny, shade[shade_num]); |
||
| 2705 | } |
||
| 2706 | } |
||
| 2707 | } |
||
| 2708 | |||
| 2709 | // IDA: void __usercall StopCarBeingIt(tCar_spec *pCar@<EAX>) |
||
| 2710 | void StopCarBeingIt(tCar_spec* pCar) { |
||
| 20 | pmbaty | 2711 | //int i; // Pierre-Marie Baty -- unused variable |
| 2712 | //int group; // Pierre-Marie Baty -- unused variable |
||
| 2713 | //br_actor* actor; // Pierre-Marie Baty -- unused variable |
||
| 2714 | //br_actor* bonny; // Pierre-Marie Baty -- unused variable |
||
| 1 | pmbaty | 2715 | LOG_TRACE("(%p)", pCar); |
| 20 | pmbaty | 2716 | STUB(); |
| 1 | pmbaty | 2717 | } |