From 4608bdd8ca0594fe89287b8f51fefcec9ed43ee0 Mon Sep 17 00:00:00 2001 From: Jeff Harris Date: Tue, 21 Sep 2021 13:09:18 +1200 Subject: [PATCH] Feature/collision detection (#60) * most functions implemented, car disappears on collision? * implements friction from collision, car no longer disappears * removes -Werror compiler flag for DETHRACE directory --- src/BRSRC13/CORE/MATH/matrix4.c | 124 +++- src/BRSRC13/CORE/STD/brstdlib.c | 17 +- src/BRSRC13/CORE/V1DB/prepmap.c | 2 +- src/BRSRC13/brender.h | 7 +- src/DETHRACE/CMakeLists.txt | 2 - src/DETHRACE/common/car.c | 1162 +++++++++++++++++++++++++++++-- src/DETHRACE/common/controls.c | 10 +- src/DETHRACE/common/crush.c | 8 +- src/DETHRACE/common/depth.c | 8 +- src/DETHRACE/common/displays.c | 10 +- src/DETHRACE/common/finteray.c | 129 +++- src/DETHRACE/common/graphics.c | 19 +- src/DETHRACE/common/loading.c | 2 - src/DETHRACE/common/netgame.c | 6 +- src/DETHRACE/common/network.c | 6 +- src/DETHRACE/common/oil.c | 2 +- src/DETHRACE/common/opponent.c | 2 +- src/DETHRACE/common/pedestrn.c | 6 +- src/DETHRACE/common/piping.c | 12 +- src/DETHRACE/common/powerup.c | 4 +- src/DETHRACE/common/pratcam.c | 8 +- src/DETHRACE/common/racestrt.c | 5 +- src/DETHRACE/common/replay.c | 8 +- src/DETHRACE/common/skidmark.c | 4 +- src/DETHRACE/common/sound.c | 7 +- src/DETHRACE/common/spark.c | 12 +- src/DETHRACE/common/structur.c | 2 +- src/DETHRACE/common/world.c | 2 +- src/DETHRACE/constants.h | 6 + src/harness/harness_trace.h | 8 +- 30 files changed, 1442 insertions(+), 158 deletions(-) diff --git a/src/BRSRC13/CORE/MATH/matrix4.c b/src/BRSRC13/CORE/MATH/matrix4.c index f36480de..450aaf53 100644 --- a/src/BRSRC13/CORE/MATH/matrix4.c +++ b/src/BRSRC13/CORE/MATH/matrix4.c @@ -1,10 +1,36 @@ #include "matrix4.h" #include "harness_trace.h" +#include + +#define A(x, y) A->m[x][y] +#define B(x, y) B->m[x][y] +#define C(x, y) C->m[x][y] +#define M(x, y) mat->m[x][y] + +#define BR_MAC2(a, b, c, d) ((a) * (b) + (c) * (d)) +#define BR_MAC3(a, b, c, d, e, f) ((a) * (b) + (c) * (d) + (e) * (f)) +#define BR_MAC4(a, b, c, d, e, f, g, h) ((a) * (b) + (c) * (d) + (e) * (f) + (g) * (h)) // IDA: void __cdecl BrMatrix4Copy(br_matrix4 *A, br_matrix4 *B) void BrMatrix4Copy(br_matrix4* A, br_matrix4* B) { LOG_TRACE("(%p, %p)", A, B); - NOT_IMPLEMENTED(); + + A(0, 0) = B(0, 0); + A(0, 1) = B(0, 1); + A(0, 2) = B(0, 2); + A(0, 3) = B(0, 3); + A(1, 0) = B(1, 0); + A(1, 1) = B(1, 1); + A(1, 2) = B(1, 2); + A(1, 3) = B(1, 3); + A(2, 0) = B(2, 0); + A(2, 1) = B(2, 1); + A(2, 2) = B(2, 2); + A(2, 3) = B(2, 3); + A(3, 0) = B(3, 0); + A(3, 1) = B(3, 1); + A(3, 2) = B(3, 2); + A(3, 3) = B(3, 3); } // IDA: void __cdecl BrMatrix4Mul(br_matrix4 *A, br_matrix4 *B, br_matrix4 *C) @@ -32,13 +58,30 @@ br_scalar BrMatrix4Inverse(br_matrix4* A, br_matrix4* B) { br_scalar det; br_scalar idet; LOG_TRACE("(%p, %p)", A, B); - NOT_IMPLEMENTED(); + + BrMatrix4Adjoint(A, B); + det = BrMatrix4Determinant(B); + + if (fabs(det) < BR_SCALAR_EPSILON * 2) + return 0; + + idet = 1.0 / det; + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + A(i, j) = A(i, j) * idet; + } + } + + return det; } // IDA: br_scalar __cdecl Determinant3(br_scalar a1, br_scalar a2, br_scalar a3, br_scalar b1, br_scalar b2, br_scalar b3, br_scalar c1, br_scalar c2, br_scalar c3) br_scalar Determinant3(br_scalar a1, br_scalar a2, br_scalar a3, br_scalar b1, br_scalar b2, br_scalar b3, br_scalar c1, br_scalar c2, br_scalar c3) { LOG_TRACE("(%f, %f, %f, %f, %f, %f, %f, %f, %f)", a1, a2, a3, b1, b2, b3, c1, c2, c3); - NOT_IMPLEMENTED(); + + return BR_MAC3(a1, BR_MAC2(b2, c3, -b3, c2), + -b1, BR_MAC2(a2, c3, -a3, c2), + c1, BR_MAC2(a2, b3, -a3, b2)); } // IDA: br_scalar __cdecl BrMatrix4Determinant(br_matrix4 *mat) @@ -60,7 +103,31 @@ br_scalar BrMatrix4Determinant(br_matrix4* mat) { br_scalar d3; br_scalar d4; LOG_TRACE("(%p)", mat); - NOT_IMPLEMENTED(); + + a1 = M(0, 0); + b1 = M(0, 1); + c1 = M(0, 2); + d1 = M(0, 3); + + a2 = M(1, 0); + b2 = M(1, 1); + c2 = M(1, 2); + d2 = M(1, 3); + + a3 = M(2, 0); + b3 = M(2, 1); + c3 = M(2, 2); + d3 = M(2, 3); + + a4 = M(3, 0); + b4 = M(3, 1); + c4 = M(3, 2); + d4 = M(3, 3); + + return BR_MAC4(a1, Determinant3(b2, b3, b4, c2, c3, c4, d2, d3, d4), + -b1, Determinant3(a2, a3, a4, c2, c3, c4, d2, d3, d4), + c1, Determinant3(a2, a3, a4, b2, b3, b4, d2, d3, d4), + -d1, Determinant3(a2, a3, a4, b2, b3, b4, c2, c3, c4)); } // IDA: void __cdecl BrMatrix4Adjoint(br_matrix4 *A, br_matrix4 *B) @@ -82,7 +149,48 @@ void BrMatrix4Adjoint(br_matrix4* A, br_matrix4* B) { br_scalar d3; br_scalar d4; LOG_TRACE("(%p, %p)", A, B); - NOT_IMPLEMENTED(); + + a1 = B(0, 0); + b1 = B(0, 1); + c1 = B(0, 2); + d1 = B(0, 3); + + a2 = B(1, 0); + b2 = B(1, 1); + c2 = B(1, 2); + d2 = B(1, 3); + + a3 = B(2, 0); + b3 = B(2, 1); + c3 = B(2, 2); + d3 = B(2, 3); + + a4 = B(3, 0); + b4 = B(3, 1); + c4 = B(3, 2); + d4 = B(3, 3); + + /* row column labeling reversed since we transpose rows & columns */ + + A(0, 0) = Determinant3(b2, b3, b4, c2, c3, c4, d2, d3, d4); + A(1, 0) = -Determinant3(a2, a3, a4, c2, c3, c4, d2, d3, d4); + A(2, 0) = Determinant3(a2, a3, a4, b2, b3, b4, d2, d3, d4); + A(3, 0) = -Determinant3(a2, a3, a4, b2, b3, b4, c2, c3, c4); + + A(0, 1) = -Determinant3(b1, b3, b4, c1, c3, c4, d1, d3, d4); + A(1, 1) = Determinant3(a1, a3, a4, c1, c3, c4, d1, d3, d4); + A(2, 1) = -Determinant3(a1, a3, a4, b1, b3, b4, d1, d3, d4); + A(3, 1) = Determinant3(a1, a3, a4, b1, b3, b4, c1, c3, c4); + + A(0, 2) = Determinant3(b1, b2, b4, c1, c2, c4, d1, d2, d4); + A(1, 2) = -Determinant3(a1, a2, a4, c1, c2, c4, d1, d2, d4); + A(2, 2) = Determinant3(a1, a2, a4, b1, b2, b4, d1, d2, d4); + A(3, 2) = -Determinant3(a1, a2, a4, b1, b2, b4, c1, c2, c4); + + A(0, 3) = -Determinant3(b1, b2, b3, c1, c2, c3, d1, d2, d3); + A(1, 3) = Determinant3(a1, a2, a3, c1, c2, c3, d1, d2, d3); + A(2, 3) = -Determinant3(a1, a2, a3, b1, b2, b3, d1, d2, d3); + A(3, 3) = Determinant3(a1, a2, a3, b1, b2, b3, c1, c2, c3); } // IDA: void __cdecl BrMatrix4Perspective(br_matrix4 *mat, br_angle field_of_view, br_scalar aspect, br_scalar hither, br_scalar yon) @@ -113,7 +221,11 @@ void BrMatrix4ApplyV(br_vector4* A, br_vector3* B, br_matrix4* C) { // IDA: void __cdecl BrMatrix4TApply(br_vector4 *A, br_vector4 *B, br_matrix4 *C) void BrMatrix4TApply(br_vector4* A, br_vector4* B, br_matrix4* C) { LOG_TRACE("(%p, %p, %p)", A, B, C); - NOT_IMPLEMENTED(); + + A->v[0] = BR_MAC4(B->v[0], C(0, 0), B->v[1], C(0, 1), B->v[2], C(0, 2), B->v[3], C(0, 3)); + A->v[1] = BR_MAC4(B->v[0], C(1, 0), B->v[1], C(1, 1), B->v[2], C(1, 2), B->v[3], C(1, 3)); + A->v[2] = BR_MAC4(B->v[0], C(2, 0), B->v[1], C(2, 1), B->v[2], C(2, 2), B->v[3], C(2, 3)); + A->v[3] = BR_MAC4(B->v[0], C(3, 0), B->v[1], C(3, 1), B->v[2], C(3, 2), B->v[3], C(3, 3)); } // IDA: void __cdecl BrMatrix4TApplyP(br_vector4 *A, br_vector3 *B, br_matrix4 *C) diff --git a/src/BRSRC13/CORE/STD/brstdlib.c b/src/BRSRC13/CORE/STD/brstdlib.c index 91e79322..b990acaa 100644 --- a/src/BRSRC13/CORE/STD/brstdlib.c +++ b/src/BRSRC13/CORE/STD/brstdlib.c @@ -14,11 +14,11 @@ int BrMemCmp(void* s1, void* s2, size_t n) { } void* BrMemCpy(void* s1, void* s2, size_t n) { - memcpy(s1, s2, n); + return memcpy(s1, s2, n); } void* BrMemSet(void* s, int c, size_t n) { - memset(s, c, n); + return memset(s, c, n); } char* BrStrCat(char* s1, char* s2) { @@ -65,62 +65,50 @@ char* BrStrNCpy(char* s1, char* s2, size_t n) { char* BrStrRChr(char* s1, char c) { return strrchr(s1, c); - NOT_IMPLEMENTED(); } void BrAbort(void) { abort(); - NOT_IMPLEMENTED(); } char* BrGetEnv(char* name) { return getenv(name); - NOT_IMPLEMENTED(); } float BrStrToF(char* nptr, char** endptr) { return strtof(nptr, endptr); - NOT_IMPLEMENTED(); } double BrStrToD(char* nptr, char** endptr) { return strtod(nptr, endptr); - NOT_IMPLEMENTED(); } long BrStrToL(char* nptr, char** endptr, int base) { return strtol(nptr, endptr, base); - NOT_IMPLEMENTED(); } unsigned long BrStrToUL(char* nptr, char** endptr, int base) { return strtoul(nptr, endptr, base); - NOT_IMPLEMENTED(); } br_boolean BrIsAlpha(int c) { return isalpha(c); - NOT_IMPLEMENTED(); } br_boolean BrIsDigit(int c) { return isdigit(c); - NOT_IMPLEMENTED(); } br_boolean BrIsSpace(int c) { return isspace(c); - NOT_IMPLEMENTED(); } br_boolean BrIsPrint(int c) { return isprint(c); - NOT_IMPLEMENTED(); } br_int_32 BrVSprintf(char* buf, const char* fmt, va_list args) { return vsprintf(buf, fmt, args); - NOT_IMPLEMENTED(); } br_int_32 BrVSprintfN(char* buf, br_size_t buf_size, const char* fmt, va_list args) { @@ -140,5 +128,4 @@ br_int_32 BrVSprintfN(char* buf, br_size_t buf_size, const char* fmt, va_list ar br_int_32 BrVSScanf(char* buf, const char* fmt, va_list args) { return vsscanf(buf, fmt, args); - NOT_IMPLEMENTED(); } diff --git a/src/BRSRC13/CORE/V1DB/prepmap.c b/src/BRSRC13/CORE/V1DB/prepmap.c index 6b21c012..e1bc2293 100644 --- a/src/BRSRC13/CORE/V1DB/prepmap.c +++ b/src/BRSRC13/CORE/V1DB/prepmap.c @@ -17,5 +17,5 @@ void BrBufferUpdate(br_pixelmap* pm, br_token use, br_uint_16 flags) { void BrBufferClear(br_pixelmap* pm) { LOG_TRACE("(%p)", pm); - SILENT_STUB(); + STUB_ONCE(); } diff --git a/src/BRSRC13/brender.h b/src/BRSRC13/brender.h index e25995a8..ef69cc47 100644 --- a/src/BRSRC13/brender.h +++ b/src/BRSRC13/brender.h @@ -53,7 +53,7 @@ void BrMaterialFree(br_material* m); br_uint_32 BrMaterialAddMany(br_material** items, int n); br_uint_32 BrMaterialEnum(char* pattern, br_material_enum_cbfn* callback, void* arg); -// BrMatrix +// BrMatrix34 void BrMatrix23Identity(br_matrix23* mat); void BrMatrix34Identity(br_matrix34* mat); @@ -81,6 +81,11 @@ void BrMatrix34PostShearX(br_matrix34* mat, br_scalar sy, br_scalar sz); void BrMatrix34PostShearY(br_matrix34* mat, br_scalar sx, br_scalar sz); void BrMatrix34PostShearZ(br_matrix34* mat, br_scalar sx, br_scalar sy); +// BrMatrix4 +void BrMatrix4Copy(br_matrix4* A, br_matrix4* B); +br_scalar BrMatrix4Inverse(br_matrix4* A, br_matrix4* B); +void BrMatrix4TApply(br_vector4* A, br_vector4* B, br_matrix4* C); + // BrMem void BrMemFree(void* block); void* BrMemAllocate(br_size_t size, br_uint_8 type); diff --git a/src/DETHRACE/CMakeLists.txt b/src/DETHRACE/CMakeLists.txt index ae899664..f690ab19 100644 --- a/src/DETHRACE/CMakeLists.txt +++ b/src/DETHRACE/CMakeLists.txt @@ -17,7 +17,6 @@ if (CMAKE_C_COMPILER_ID MATCHES "Clang") target_compile_options(dethrace_obj PRIVATE -g -Wall - -Werror -Wno-return-type -Wno-unused-variable -Wno-unused-parameter @@ -28,7 +27,6 @@ elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(dethrace_obj PRIVATE -g -Wall - -Werror -Wno-return-type -Wno-unused-variable -Wno-unused-parameter diff --git a/src/DETHRACE/common/car.c b/src/DETHRACE/common/car.c index 370b85a0..1c5dd122 100644 --- a/src/DETHRACE/common/car.c +++ b/src/DETHRACE/common/car.c @@ -1,5 +1,6 @@ #include "car.h" #include "brender.h" +#include "car.h" #include "constants.h" #include "controls.h" #include "crush.h" @@ -17,6 +18,7 @@ #include "raycast.h" #include "replay.h" #include "skidmark.h" +#include "sound.h" #include "spark.h" #include "trig.h" #include "utility.h" @@ -705,7 +707,7 @@ void RememberSafePosition(tCar_spec* car, tU32 pTime) { br_scalar ts; LOG_TRACE("(%p, %d)", car, pTime); - STUB(); + STUB_ONCE(); } // IDA: void __usercall ControlOurCar(tU32 pTime_difference@) @@ -1195,7 +1197,7 @@ void MungeSpecialVolume(tCollision_info* pCar) { tCar_spec* car; LOG_TRACE("(%p)", pCar); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall ResetCarSpecialVolume(tCollision_info *pCar@) @@ -1229,7 +1231,7 @@ void TestAutoSpecialVolume(tCollision_info* pCar) { int i; LOG_TRACE("(%p)", pCar); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall MoveAndCollideCar(tCar_spec *car@, br_scalar dt) @@ -1658,7 +1660,7 @@ void DoBumpiness(tCar_spec* c, br_vector3* wheel_pos, br_vector3* norm, br_scala tMaterial_modifiers* mat_list; LOG_TRACE("(%p, %p, %p, %p, %d)", c, wheel_pos, norm, d, n); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall CalcForce(tCar_spec *c@, br_scalar dt) @@ -2429,39 +2431,30 @@ void DoRevs(tCar_spec* c, br_scalar dt) { if (c->target_revs < 0.0) { c->target_revs = 0.0; c->gear = 0; - LOG_DEBUG("changedown2"); } if (!c->number_of_wheels_on_ground || ((c->wheel_slip & 2) + 1) != 0 || !c->gear) { if (c->number_of_wheels_on_ground) { - //LOG_DEBUG("spin1"); wheel_spin_force = c->force_torque_ratio * c->torque - (double)c->gear * c->acc_force; } else { wheel_spin_force = c->force_torque_ratio * c->torque; - LOG_DEBUG("spin2"); } if (c->gear) { if (c->gear < 2 && (c->keys.dec || c->joystick.dec > 0) && fabs(ts) < 1.0 && c->revs > 1000.0) { - LOG_DEBUG("something 2"); c->gear = -c->gear; } } else { if (c->revs > 1000.0 && !c->keys.brake && (c->keys.acc || c->joystick.acc > 0) && !gCountdown) { if (c->keys.backwards) { - LOG_DEBUG("change_down3"); c->gear = -1; } else { - LOG_DEBUG("change_up2"); c->gear = 1; } } wheel_spin_force = c->force_torque_ratio * c->torque; } - //LOG_DEBUG("setting revs %f. torque %f", wheel_spin_force, c->torque); - //printf("revs 0 %f, torque %f acc_force %f\n", c->revs, c->torque, c->acc_force); c->revs = wheel_spin_force / c->force_torque_ratio * dt / 0.0002 + c->revs; - //printf("revs 1 %f\n", c->revs); + if (c->traction_control && wheel_spin_force > 0.0 && c->revs > c->target_revs && c->gear && c->target_revs > 1000.0) { - LOG_DEBUG("revs = target_revs"); c->revs = c->target_revs; } if (c->revs <= 0.0) { @@ -2470,7 +2463,6 @@ void DoRevs(tCar_spec* c, br_scalar dt) { } if ((c->wheel_slip & 2) == 0 && c->target_revs > 6000.0 && c->revs > 6000.0 && c->gear < c->max_gear && c->gear > 0 && !c->just_changed_gear) { c->gear++; - LOG_DEBUG("gear_up"); } if (c->gear > 1 && c->target_revs < 3000.0 && !c->just_changed_gear) { c->gear--; @@ -2484,14 +2476,6 @@ void DoRevs(tCar_spec* c, br_scalar dt) { if (c->revs >= 6000.0 && (c->keys.acc || c->joystick.acc > 0)) { c->just_changed_gear = 0; } - - //LOG_DEBUG("target_revs %f, %f, ac %d", c->target_revs, c->revs, c->keys.acc); - - // if (c->driver == eDriver_local_human) { - // char s[256]; - // sprintf(s, "gear %d, speed %f, rpm: %f", c->gear, c->speed, c->revs); - // ChangeHeadupText(gProgram_state.frame_rate_headup, s); - // } } // IDA: void __usercall ApplyTorque(tCar_spec *c@, br_vector3 *tdt@) @@ -2574,8 +2558,479 @@ int CollCheck(tCollision_info* c, br_scalar dt) { br_matrix34 message_mat; LOG_TRACE("(%p, %f)", c, dt); - SILENT_STUB(); - return 0; + tCar_spec* car_spec; // added for readability + + // v34 = 0; + // v35 = 0; + // v36 = 0x3F800000; + // v48 = 0x3F800347; + car_spec = (tCar_spec*)c; + mat = &c->car_master_actor->t.t.mat; + oldmat = &c->oldmat; + k = 0; + gMaterial_index = 0; + if (c->dt >= 0.0 && gNet_mode == eNet_mode_host) { + oldmat = &message_mat; + GetExpandedMatrix(&message_mat, &c->message.mat); + } + if (dt < 0.0) { + mat = oldmat; + } + BrMatrix34LPInverse(&tm, mat); + BrMatrix34Mul(&oldmat_to_mat, oldmat, &tm); + oldmat_to_mat.m[3][0] = oldmat_to_mat.m[3][0] / WORLD_SCALE; + oldmat_to_mat.m[3][1] = oldmat_to_mat.m[3][1] / WORLD_SCALE; + oldmat_to_mat.m[3][2] = oldmat_to_mat.m[3][2] / WORLD_SCALE; + GetNewBoundingBox(&bnds, &c->bounds[2], &oldmat_to_mat); + for (i = 0; i < 3; ++i) { + if (c->bounds[2].min.v[i] < bnds.min.v[i]) { + bnds.min.v[i] = c->bounds[2].min.v[i]; + } + if (c->bounds[2].max.v[i] > bnds.max.v[i]) { + bnds.max.v[i] = c->bounds[2].max.v[i]; + } + } + a1.v[0] = mat->m[3][0] / WORLD_SCALE; + a1.v[1] = mat->m[3][1] / WORLD_SCALE; + a1.v[2] = mat->m[3][2] / WORLD_SCALE; + BrMatrix34ApplyV(&aa, &bnds.min, mat); + aa.v[0] = a1.v[0] + aa.v[0]; + aa.v[1] = a1.v[1] + aa.v[1]; + aa.v[2] = a1.v[2] + aa.v[2]; + for (j = 0; j < 3; ++j) { + edges[j].v[0] = (bnds.max.v[j] - bnds.min.v[j]) * mat->m[j][0]; + edges[j].v[1] = (bnds.max.v[j] - bnds.min.v[j]) * mat->m[j][1]; + edges[j].v[2] = (bnds.max.v[j] - bnds.min.v[j]) * mat->m[j][2]; + } + i = 0; + f_ref = &gFace_list__car[c->box_face_start]; + while (c->box_face_end - c->box_face_start > i && i < 50) { + bb.v[0] = aa.v[0] - f_ref->v[0].v[0]; + bb.v[1] = aa.v[1] - f_ref->v[0].v[1]; + bb.v[2] = aa.v[2] - f_ref->v[0].v[2]; + max = bb.v[1] * f_ref->normal.v[1] + f_ref->normal.v[2] * bb.v[2] + f_ref->normal.v[0] * bb.v[0]; + min = max; + for (j = 0; j < 3; ++j) { + ts = edges[j].v[2] * f_ref->normal.v[2] + edges[j].v[1] * f_ref->normal.v[1] + edges[j].v[0] * f_ref->normal.v[0]; + if (ts >= 0) { + max = max + ts; + } else { + min = min + ts; + } + } + if ((max <= 0.001 || min <= 0.001) && (max >= -0.001 || min >= -0.001)) { + f_ref->flags &= ~0x80u; + k++; + } else { + f_ref->flags |= 0x80u; + } + i++; + f_ref++; + } + if (!k) { + return 0; + } + k = 0; + BrMatrix34LPInverse(&tm, oldmat); + BrMatrix34Mul(&mat_to_oldmat, mat, &tm); + gEliminate_faces = 1; + for (i = 0; i < c->extra_point_num + 8; i++) { + if (i >= 8) { + tv.v[0] = c->bounds[1].min.v[3 * i]; + tv.v[1] = c->bounds[1].min.v[3 * i + 1]; + tv.v[2] = c->bounds[1].min.v[3 * i + 2]; + } else { + tv.v[0] = ((i & 2) == 0) * c->bounds[1].min.v[0] + ((i & 2) >> 1) * c->bounds[1].max.v[0]; + tv.v[1] = ((i & 1) == 0) * c->bounds[1].min.v[1] + (i & 1) * c->bounds[1].max.v[1]; + tv.v[2] = ((i & 4) == 0) * c->bounds[1].max.v[2] + ((i & 4) >> 2) * c->bounds[1].min.v[2]; + } + BrMatrix34ApplyP(&dir, &tv, mat); + if (dt >= 0.0) { + BrMatrix34ApplyP(&a, &tv, oldmat); + } else { + a.v[0] = c->pos.v[0] * 6.9000001; + a.v[1] = c->pos.v[1] * 6.9000001; + a.v[2] = c->pos.v[2] * 6.9000001; + } + dir.v[0] = dir.v[0] - a.v[0]; + dir.v[1] = dir.v[1] - a.v[1]; + dir.v[2] = dir.v[2] - a.v[2]; + ts = sqrt(dir.v[2] * dir.v[2] + dir.v[1] * dir.v[1] + dir.v[0] * dir.v[0]); + if (ts <= 2.38419e-07) { + normal_force.v[0] = 1.0; + normal_force.v[1] = 0.0; + normal_force.v[2] = 0.0; + } else { + ts = 1.0 / ts; + normal_force.v[0] = dir.v[0] * ts; + normal_force.v[1] = dir.v[1] * ts; + normal_force.v[2] = dir.v[2] * ts; + } + normal_force.v[0] = normal_force.v[0] * 0.0072463769; + normal_force.v[1] = normal_force.v[1] * 0.0072463769; + normal_force.v[2] = normal_force.v[2] * 0.0072463769; + dir.v[0] = dir.v[0] + normal_force.v[0]; + dir.v[1] = dir.v[1] + normal_force.v[1]; + dir.v[2] = dir.v[2] + normal_force.v[2]; + material = FindFloorInBoxM2(&a, &dir, &norm, &dist, c); + if (dist >= 0.0 && dist < 1.0001) { + cc.v[0] = c->pos.v[0] * 6.9000001; + cc.v[1] = c->pos.v[1] * 6.9000001; + cc.v[2] = c->pos.v[2] * 6.9000001; + cc.v[0] = cc.v[0] - a.v[0]; + cc.v[1] = cc.v[1] - a.v[1]; + cc.v[2] = cc.v[2] - a.v[2]; + FindFloorInBoxM(&a, &cc, &bb, &ts, c); + if (i < 8 || ts > 1.0) { + BrMatrix34TApplyV(&a, &norm, oldmat); + AddCollPoint(dist, &tv, &a, r, n, &dir, k, c); + k++; + if (!gMaterial_index) { + gMaterial_index = material; + } + } + } + } + gEliminate_faces = 0; + if (k < 1) { + k += BoxFaceIntersect(&c->bounds[1], mat, &mat_to_oldmat, &r[k], &n[k], &d[k], 8 - k, c); + } + if (k > 4) { + k = 4; + } + for (i = 0; i < k; i++) { + if (fabs(r[i].v[1]) + fabs(r[i].v[2]) + fabs(r[i].v[0]) > 500.0) { + for (j = i + 1; j < k; j++) { + if (fabs(r[j].v[1]) + fabs(r[j].v[2]) + fabs(r[j].v[0]) < 500.0) { + r[i].v[0] = r[j].v[0]; + r[i].v[1] = r[j].v[1]; + r[i].v[2] = r[j].v[2]; + n[i].v[0] = n[j].v[0]; + n[i].v[1] = n[j].v[1]; + n[i].v[2] = n[j].v[2]; + i++; + } + } + k = i; + break; + } + } + if (dt >= 0.0) { + if (k > 0 && c->collision_flag && k < 4 + && (fabs(r[0].v[0] - c->old_point.v[0]) > 0.05 + || fabs(r[0].v[1] - c->old_point.v[1]) > 0.05 + || fabs(r[0].v[2] - c->old_point.v[2]) > 0.05)) { + r[k].v[0] = c->old_point.v[0]; + r[k].v[1] = c->old_point.v[1]; + r[k].v[2] = c->old_point.v[2]; + n[k].v[0] = c->old_norm.v[0]; + n[k].v[1] = c->old_norm.v[1]; + n[k].v[2] = c->old_norm.v[2]; + k++; + } + if (k > 0) { + c->old_point = r[0]; + c->old_norm = n[0]; + BrMatrix34Copy(mat, oldmat); + c->omega = c->oldomega; + BrMatrix34TApplyV(&c->velocity_car_space, &c->v, mat); + memset(&norm, 0, sizeof(norm)); + collision = 0; + for (i = 0; i < k; i++) { + tau[i].v[0] = r[i].v[1] * n[i].v[2] - r[i].v[2] * n[i].v[1]; + tau[i].v[1] = r[i].v[2] * n[i].v[0] - r[i].v[0] * n[i].v[2]; + tau[i].v[2] = r[i].v[0] * n[i].v[1] - r[i].v[1] * n[i].v[0]; + tau[i].v[0] = tau[i].v[0] / c->I.v[0]; + tau[i].v[1] = tau[i].v[1] / c->I.v[1]; + tau[i].v[2] = tau[i].v[2] / c->I.v[2]; + normal_force.v[0] = r[i].v[2] * c->omega.v[1] - r[i].v[1] * c->omega.v[2]; + normal_force.v[1] = r[i].v[0] * c->omega.v[2] - r[i].v[2] * c->omega.v[0]; + normal_force.v[2] = r[i].v[1] * c->omega.v[0] - r[i].v[0] * c->omega.v[1]; + normal_force.v[0] = c->velocity_car_space.v[0] + normal_force.v[0]; + normal_force.v[1] = c->velocity_car_space.v[1] + normal_force.v[1]; + normal_force.v[2] = c->velocity_car_space.v[2] + normal_force.v[2]; + d[i] = -(n[i].v[2] * normal_force.v[2] + n[i].v[1] * normal_force.v[1] + n[i].v[0] * normal_force.v[0]); + normal_force.v[0] = r[i].v[0] + c->cmpos.v[0]; + normal_force.v[1] = r[i].v[1] + c->cmpos.v[1]; + normal_force.v[2] = r[i].v[2] + c->cmpos.v[2]; + BrMatrix34ApplyP(&dir, &normal_force, &mat_to_oldmat); + dir.v[0] = dir.v[0] - normal_force.v[0]; + dir.v[1] = dir.v[1] - normal_force.v[1]; + dir.v[2] = dir.v[2] - normal_force.v[2]; + ts = -((n[i].v[1] * dir.v[1] + n[i].v[2] * dir.v[2] + n[i].v[0] * dir.v[0]) / dt); + if (ts > d[i]) { + d[i] = ts; + } + if (d[i] > 0.0) { + collision = 1; + } + } + if (!collision) { + d[0] = 0.5; + } + for (i = 0; k > i; ++i) { + for (j = 0; k > j; ++j) { + normal_force.v[0] = r[i].v[2] * tau[j].v[1] - r[i].v[1] * tau[j].v[2]; + normal_force.v[1] = r[i].v[0] * tau[j].v[2] - r[i].v[2] * tau[j].v[0]; + normal_force.v[2] = r[i].v[1] * tau[j].v[0] - tau[j].v[1] * r[i].v[0]; + norm.v[0] = n[j].v[0] / c->M; + norm.v[1] = n[j].v[1] / c->M; + norm.v[2] = n[j].v[2] / c->M; + normal_force.v[0] = norm.v[0] + normal_force.v[0]; + normal_force.v[1] = norm.v[1] + normal_force.v[1]; + normal_force.v[2] = norm.v[2] + normal_force.v[2]; + M.m[0][4 * i + j] = n[i].v[2] * normal_force.v[2] + n[i].v[1] * normal_force.v[1] + n[i].v[0] * normal_force.v[0]; + } + } + switch (k) { + case 1: + ts = SinglePointColl(f, &M, d); + break; + case 2: + ts = TwoPointColl(f, &M, d, tau, n); + break; + case 3: + d[3] = 0.0; + ts = ThreePointCollRec(f, &M, d, tau, n, c); + break; + case 4: + ts = FourPointColl(f, &M, d, tau, n, c); + break; + default: + break; + } + if (k > 3) { + k = 3; + } + // if (f[0] > 10.0 || f[1] > 10.0 || f[2] > 10.0) { + // v31 = 0; + // } + if (fabs(ts) <= 0.000001) { + c->v.v[0] = 0.0; + c->v.v[1] = 0.0; + c->v.v[2] = 0.0; + c->omega.v[0] = 0.0; + c->omega.v[1] = 0.0; + c->omega.v[2] = 0.0; + c->oldomega.v[0] = 0.0; + c->oldomega.v[1] = 0.0; + c->oldomega.v[2] = 0.0; + return k; + } + + memset(&p_vel, 0, sizeof(p_vel)); + memset(&dir, 0, sizeof(dir)); + memset(&friction_force, 0, sizeof(friction_force)); + total_force = 0.0; + for (i = 0; k > i; ++i) { + if (f[i] < 0.001) { + f[i] = 0.001; + } + f[i] = f[i] * 1.001; + tau[i].v[0] = tau[i].v[0] * f[i]; + tau[i].v[1] = tau[i].v[1] * f[i]; + tau[i].v[2] = tau[i].v[2] * f[i]; + c->omega.v[0] = tau[i].v[0] + c->omega.v[0]; + c->omega.v[1] = tau[i].v[1] + c->omega.v[1]; + c->omega.v[2] = tau[i].v[2] + c->omega.v[2]; + f[i] = f[i] / c->M; + n[i].v[0] = n[i].v[0] * f[i]; + n[i].v[1] = n[i].v[1] * f[i]; + n[i].v[2] = n[i].v[2] * f[i]; + p_vel.v[0] = n[i].v[0] + p_vel.v[0]; + p_vel.v[1] = n[i].v[1] + p_vel.v[1]; + p_vel.v[2] = n[i].v[2] + p_vel.v[2]; + bb.v[0] = r[i].v[0] + c->cmpos.v[0]; + bb.v[1] = r[i].v[1] + c->cmpos.v[1]; + bb.v[2] = r[i].v[2] + c->cmpos.v[2]; + bb.v[0] = f[i] * bb.v[0]; + bb.v[1] = f[i] * bb.v[1]; + bb.v[2] = f[i] * bb.v[2]; + dir.v[0] = dir.v[0] + bb.v[0]; + dir.v[1] = dir.v[1] + bb.v[1]; + dir.v[2] = dir.v[2] + bb.v[2]; + total_force = f[i] + total_force; + } + if (gPinball_factor != 0.0) { + p_vel.v[0] = p_vel.v[0] * gPinball_factor; + p_vel.v[1] = p_vel.v[1] * gPinball_factor; + p_vel.v[2] = p_vel.v[2] * gPinball_factor; + point_vel = p_vel.v[2] * p_vel.v[2] + p_vel.v[1] * p_vel.v[1] + p_vel.v[0] * p_vel.v[0]; + if (point_vel > 10.0) { + noise_defeat = 1; + if (c->driver == eDriver_local_human) { + DRS3StartSound(gIndexed_outlets[1], 9011); + } else { + DRS3StartSound3D( + gIndexed_outlets[1], + 9011, + &c->pos, + &gZero_v__car, + 1, + 255, + 0x10000, + 0x10000); + } + if (point_vel > 10000.0) { + ts = sqrt(p_vel.v[2] * p_vel.v[2] + p_vel.v[1] * p_vel.v[1] + p_vel.v[0] * p_vel.v[0]); + if (ts <= 2.3841858e-7) { + p_vel.v[0] = 1.0; + p_vel.v[1] = 0.0; + p_vel.v[2] = 0.0; + } else { + ts = 1.0 / ts; + p_vel.v[0] = p_vel.v[0] * ts; + p_vel.v[1] = p_vel.v[1] * ts; + p_vel.v[2] = p_vel.v[2] * ts; + } + p_vel.v[0] = p_vel.v[0] * 100.0; + p_vel.v[1] = p_vel.v[1] * 100.0; + p_vel.v[2] = p_vel.v[2] * 100.0; + } + } + } + c->velocity_car_space.v[0] = c->velocity_car_space.v[0] + p_vel.v[0]; + c->velocity_car_space.v[1] = c->velocity_car_space.v[1] + p_vel.v[1]; + c->velocity_car_space.v[2] = c->velocity_car_space.v[2] + p_vel.v[2]; + dir.v[0] = dir.v[0] / total_force; + dir.v[1] = dir.v[1] / total_force; + dir.v[2] = dir.v[2] / total_force; + tv.v[0] = c->omega.v[1] * dir.v[2] - c->omega.v[2] * dir.v[1]; + tv.v[1] = c->omega.v[2] * dir.v[0] - c->omega.v[0] * dir.v[2]; + tv.v[2] = c->omega.v[0] * dir.v[1] - c->omega.v[1] * dir.v[0]; + tv.v[0] = c->velocity_car_space.v[0] + tv.v[0]; + tv.v[1] = c->velocity_car_space.v[1] + tv.v[1]; + tv.v[2] = c->velocity_car_space.v[2] + tv.v[2]; + batwick_length = sqrt(tv.v[2] * tv.v[2] + tv.v[1] * tv.v[1] + tv.v[0] * tv.v[0]); + if (!c->collision_flag || (c->collision_flag == 1 && oldk < k)) { + for (i = 0; k > i; ++i) { + vel.v[0] = r[i].v[2] * c->omega.v[1] - r[i].v[1] * c->omega.v[2]; + vel.v[1] = r[i].v[0] * c->omega.v[2] - r[i].v[2] * c->omega.v[0]; + vel.v[2] = r[i].v[1] * c->omega.v[0] - r[i].v[0] * c->omega.v[1]; + vel.v[0] = c->velocity_car_space.v[0] + vel.v[0]; + vel.v[1] = c->velocity_car_space.v[1] + vel.v[1]; + vel.v[2] = c->velocity_car_space.v[2] + vel.v[2]; + AddFriction(c, &vel, &n[i], &r[i], f[i], &max_friction); + friction_force.v[0] = friction_force.v[0] + max_friction.v[0]; + friction_force.v[1] = friction_force.v[1] + max_friction.v[1]; + friction_force.v[2] = friction_force.v[2] + max_friction.v[2]; + c->velocity_car_space.v[0] = c->velocity_car_space.v[0] + max_friction.v[0]; + c->velocity_car_space.v[1] = c->velocity_car_space.v[1] + max_friction.v[1]; + c->velocity_car_space.v[2] = c->velocity_car_space.v[2] + max_friction.v[2]; + } + } + oldk = k; + BrMatrix34ApplyP(&pos, &dir, &c->car_master_actor->t.t.mat); + pos.v[0] = pos.v[0] / 6.9000001; + pos.v[1] = pos.v[1] / 6.9000001; + pos.v[2] = pos.v[2] / 6.9000001; + noise_defeat = 0; + normal_force.v[0] = friction_force.v[0] + p_vel.v[0]; + normal_force.v[1] = friction_force.v[1] + p_vel.v[1]; + normal_force.v[2] = friction_force.v[2] + p_vel.v[2]; + BrMatrix34ApplyV(&norm, &normal_force, mat); + min = dt * 90.0 / 10.0; + max = dt * 110.0 / 10.0; + if (c->last_special_volume) { + min = c->last_special_volume->gravity_multiplier * min; + max = c->last_special_volume->gravity_multiplier * max; + } + if (c->velocity_car_space.v[2] * c->velocity_car_space.v[2] + c->velocity_car_space.v[1] * c->velocity_car_space.v[1] + c->velocity_car_space.v[0] * c->velocity_car_space.v[0] < 0.050000001 + && total_force * 0.1 > c->omega.v[2] * tv.v[2] + c->omega.v[1] * tv.v[1] + c->omega.v[0] * tv.v[0] + && k >= 3 + && norm.v[1] > min + && norm.v[1] < max) { + if (c->driver <= eDriver_non_car || fabs(normal_force.v[2]) <= total_force * 0.89999998) { + c->v.v[0] = 0.0; + c->v.v[1] = 0.0; + c->v.v[2] = 0.0; + memset(&norm, 0, sizeof(norm)); + memset(&normal_force, 0, sizeof(normal_force)); + c->omega.v[0] = 0.0; + c->omega.v[1] = 0.0; + c->omega.v[2] = 0.0; + c->oldomega.v[0] = 0.0; + c->oldomega.v[1] = 0.0; + c->oldomega.v[2] = 0.0; + if (c->driver <= eDriver_non_car || car_spec->max_force_rear == 0.0) { + if (c->driver <= eDriver_non_car) { + PipeSingleNonCar(c); + } + c->doing_nothing_flag = 1; + } + } else { + BrVector3SetFloat(&tv2, 0.0, -1.0, 0.0); + bb.v[0] = mat->m[1][2] * tv2.v[1] - mat->m[1][1] * tv2.v[2]; + bb.v[1] = mat->m[1][0] * tv2.v[2] - mat->m[1][2] * tv2.v[0]; + bb.v[2] = mat->m[1][1] * tv2.v[0] - mat->m[1][0] * tv2.v[1]; + if (mat->m[0][1] * bb.v[1] + mat->m[0][2] * bb.v[2] + mat->m[0][0] * bb.v[0] <= 0.0) { + c->omega.v[0] = -0.5; + } else { + c->omega.v[0] = 0.5; + } + } + } + c->v.v[0] = c->v.v[0] + norm.v[0]; + c->v.v[1] = c->v.v[1] + norm.v[1]; + c->v.v[2] = c->v.v[2] + norm.v[2]; + if (c->driver >= eDriver_net_human) { + normal_force.v[0] = gDefensive_powerup_factor[car_spec->power_up_levels[0]] * normal_force.v[0]; + normal_force.v[1] = gDefensive_powerup_factor[car_spec->power_up_levels[0]] * normal_force.v[1]; + normal_force.v[2] = gDefensive_powerup_factor[car_spec->power_up_levels[0]] * normal_force.v[2]; + } + if (c->driver < eDriver_net_human) { + normal_force.v[0] = normal_force.v[0] * 0.0099999998; + normal_force.v[1] = normal_force.v[1] * 0.0099999998; + normal_force.v[2] = normal_force.v[2] * 0.0099999998; + } else { + normal_force.v[0] = normal_force.v[0] * 0.75; + normal_force.v[1] = normal_force.v[1] * 0.75; + normal_force.v[2] = normal_force.v[2] * 0.75; + } + v_diff = (car_spec->pre_car_col_velocity.v[1] - c->v.v[1]) * gDefensive_powerup_factor[car_spec->power_up_levels[0]]; + if (car_spec->invulnerable + || (c->driver < eDriver_net_human && (c->driver != eDriver_oppo || PointOutOfSight(&c->pos, 150.0))) + || (v_diff >= -20.0) + || car_spec->number_of_wheels_on_ground >= 3) { + CrushAndDamageCar(car_spec, &dir, &normal_force, NULL); + } else { + if (c->driver == eDriver_oppo && c->index == 4 && v_diff < -40.0) { + KnackerThisCar(car_spec); + StealCar(car_spec); + v_diff = v_diff * 5.0; + } + for (i = 0; i < ((tCar_spec*)c)->car_actor_count; i++) { + ts2 = (v_diff + 20.0) * -0.01; + TotallySpamTheModel( + car_spec, + i, + car_spec->car_model_actors[i].actor, + &car_spec->car_model_actors[i].crush_data, + ts2); + } + for (i = 0; i < 12; i++) { + DamageUnit(car_spec, i, IRandomPosNeg(5) + (v_diff + 20.0) * -1.5); + } + } + if (!noise_defeat) { + CrashNoise(&norm, &pos, gMaterial_index); + ScrapeNoise(batwick_length, &pos, gMaterial_index); + } + tv.v[0] = tv.v[0] / 6.9000001; + tv.v[1] = tv.v[1] / 6.9000001; + tv.v[2] = tv.v[2] / 6.9000001; + BrMatrix34ApplyV(&bb, &tv, &c->car_master_actor->t.t.mat); + BrMatrix34ApplyV(&norm, &p_vel, &c->car_master_actor->t.t.mat); + CreateSparks(&pos, &bb, &norm, gCurrent_race.material_modifiers[gMaterial_index].sparkiness, car_spec); + } + return k; + } else { + if (k) { + c->old_point = r[0]; + c->old_norm = n[0]; + } + return k; + } } // IDA: br_scalar __usercall AddFriction@(tCollision_info *c@, br_vector3 *vel@, br_vector3 *normal_force@, br_vector3 *pos@, br_scalar total_force, br_vector3 *max_friction) @@ -2586,7 +3041,62 @@ br_scalar AddFriction(tCollision_info* c, br_vector3* vel, br_vector3* normal_fo br_scalar ts; br_scalar point_vel; LOG_TRACE("(%p, %p, %p, %p, %f, %p)", c, vel, normal_force, pos, total_force, max_friction); - NOT_IMPLEMENTED(); + + ts = (normal_force->v[1] * vel->v[1] + normal_force->v[2] * vel->v[2] + normal_force->v[0] * vel->v[0]) + / (normal_force->v[1] * normal_force->v[1] + + normal_force->v[2] * normal_force->v[2] + + normal_force->v[0] * normal_force->v[0]); + tv.v[0] = normal_force->v[0] * ts; + tv.v[1] = normal_force->v[1] * ts; + tv.v[2] = normal_force->v[2] * ts; + vel->v[0] = vel->v[0] - tv.v[0]; + vel->v[1] = vel->v[1] - tv.v[1]; + vel->v[2] = vel->v[2] - tv.v[2]; + point_vel = total_force * 0.34999999 * gCurrent_race.material_modifiers[gMaterial_index].car_wall_friction; + ts = sqrt(vel->v[1] * vel->v[1] + vel->v[2] * vel->v[2] + vel->v[0] * vel->v[0]); + if (ts < 0.000099999997) { + max_friction->v[0] = 0.0; + max_friction->v[1] = 0.0; + max_friction->v[2] = 0.0; + return 0.0; + } + ts = 1.0 / -ts; + max_friction->v[0] = vel->v[0] * ts; + max_friction->v[1] = vel->v[1] * ts; + max_friction->v[2] = vel->v[2] * ts; + ftau.v[0] = pos->v[1] * max_friction->v[2] - pos->v[2] * max_friction->v[1]; + ftau.v[1] = pos->v[2] * max_friction->v[0] - pos->v[0] * max_friction->v[2]; + ftau.v[2] = pos->v[0] * max_friction->v[1] - pos->v[1] * max_friction->v[0]; + ftau.v[0] = c->M * ftau.v[0]; + ftau.v[1] = c->M * ftau.v[1]; + ftau.v[2] = c->M * ftau.v[2]; + ftau.v[0] = ftau.v[0] / c->I.v[0]; + ftau.v[1] = ftau.v[1] / c->I.v[1]; + ftau.v[2] = ftau.v[2] / c->I.v[2]; + ts = 1.0 / c->M; + norm.v[0] = pos->v[2] * ftau.v[1] - pos->v[1] * ftau.v[2]; + norm.v[1] = pos->v[0] * ftau.v[2] - pos->v[2] * ftau.v[0]; + norm.v[2] = pos->v[1] * ftau.v[0] - pos->v[0] * ftau.v[1]; + ts = max_friction->v[0] * norm.v[0] + max_friction->v[1] * norm.v[1] + max_friction->v[2] * norm.v[2] + ts; + if (fabs(ts) <= 0.000099999997) { + ts = 0.0; + } else { + ts = -((max_friction->v[1] * vel->v[1] + max_friction->v[2] * vel->v[2] + max_friction->v[0] * vel->v[0]) / ts); + } + if (ts > point_vel) { + ts = point_vel; + } + max_friction->v[0] = max_friction->v[0] * ts; + max_friction->v[1] = max_friction->v[1] * ts; + max_friction->v[2] = max_friction->v[2] * ts; + tv.v[0] = pos->v[1] * max_friction->v[2] - pos->v[2] * max_friction->v[1]; + tv.v[1] = pos->v[2] * max_friction->v[0] - pos->v[0] * max_friction->v[2]; + tv.v[2] = pos->v[0] * max_friction->v[1] - pos->v[1] * max_friction->v[0]; + tv.v[0] = c->M * tv.v[0]; + tv.v[1] = c->M * tv.v[1]; + tv.v[2] = c->M * tv.v[2]; + ApplyTorque((tCar_spec*)c, &tv); + return point_vel; } // IDA: void __usercall AddFrictionCarToCar(tCollision_info *car1@, tCollision_info *car2@, br_vector3 *vel1@, br_vector3 *vel2@, br_vector3 *normal_force1, br_vector3 *pos1, br_vector3 *pos2, br_scalar total_force, br_vector3 *max_friction) @@ -2616,7 +3126,7 @@ void ScrapeNoise(br_scalar vel, br_vector3* position, int material) { br_vector3 velocity; br_vector3 position_in_br; LOG_TRACE("(%f, %p, %d)", vel, position, material); - NOT_IMPLEMENTED(); + STUB(); } // IDA: void __usercall SkidNoise(tCar_spec *pC@, int pWheel_num@, br_scalar pV, int material) @@ -2630,14 +3140,14 @@ void SkidNoise(tCar_spec* pC, int pWheel_num, br_scalar pV, int material) { int i; LOG_TRACE("(%p, %d, %f, %d)", pC, pWheel_num, pV, material); - STUB(); + STUB_ONCE(); } // IDA: void __usercall StopSkid(tCar_spec *pC@) void StopSkid(tCar_spec* pC) { LOG_TRACE("(%p)", pC); - STUB(); + STUB_ONCE(); } // IDA: void __usercall CrashNoise(br_vector3 *pForce@, br_vector3 *position@, int material@) @@ -2647,7 +3157,7 @@ void CrashNoise(br_vector3* pForce, br_vector3* position, int material) { tS3_volume vol; br_vector3 velocity; LOG_TRACE("(%p, %p, %d)", pForce, position, material); - NOT_IMPLEMENTED(); + STUB(); } // IDA: void __usercall CrushAndDamageCar(tCar_spec *c@, br_vector3 *pPosition@, br_vector3 *pForce_car_space@, tCar_spec *car2@) @@ -2663,7 +3173,7 @@ void CrushAndDamageCar(tCar_spec* c, br_vector3* pPosition, br_vector3* pForce_c br_matrix34 m; br_scalar fudge_multiplier; LOG_TRACE("(%p, %p, %p, %p)", c, pPosition, pForce_car_space, car2); - NOT_IMPLEMENTED(); + STUB(); } // IDA: int __usercall ExpandBoundingBox@(tCar_spec *c@) @@ -2695,26 +3205,73 @@ void AddCollPoint(br_scalar dist, br_vector3* p, br_vector3* norm, br_vector3* r int i; int furthest; LOG_TRACE("(%f, %p, %p, %p, %p, %p, %d, %p)", dist, p, norm, r, n, dir, num, c); - NOT_IMPLEMENTED(); + + if (num < 4) { + d[num] = dist; + n[num] = *norm; + r[num].v[0] = p->v[0] - c->cmpos.v[0]; + r[num].v[1] = p->v[1] - c->cmpos.v[1]; + r[num].v[2] = p->v[2] - c->cmpos.v[2]; + return; + } + furthest = 0; + for (i = 1; i < 4; i++) { + if (d[furthest] < d[i]) { + furthest = i; + } + } + if (d[furthest] >= dist) { + num = furthest; + d[num] = dist; + n[num] = *norm; + r[num].v[0] = p->v[0] - c->cmpos.v[0]; + r[num].v[1] = p->v[1] - c->cmpos.v[1]; + r[num].v[2] = p->v[2] - c->cmpos.v[2]; + } } // IDA: br_scalar __usercall SinglePointColl@(br_scalar *f@, br_matrix4 *m@, br_scalar *d@) br_scalar SinglePointColl(br_scalar* f, br_matrix4* m, br_scalar* d) { LOG_TRACE("(%p, %p, %p)", f, m, d); - NOT_IMPLEMENTED(); + + *f = *d / m->m[0][0]; + if (*f < 0.0) { + *f = 0.0; + } + return fabs(m->m[0][0]); } // IDA: br_scalar __usercall TwoPointColl@(br_scalar *f@, br_matrix4 *m@, br_scalar *d@, br_vector3 *tau@, br_vector3 *n) br_scalar TwoPointColl(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* tau, br_vector3* n) { br_scalar ts; LOG_TRACE("(%p, %p, %p, %p, %p)", f, m, d, tau, n); - NOT_IMPLEMENTED(); + + ts = m->m[1][1] * m->m[0][0] - m->m[0][1] * m->m[1][0]; + if (fabs(ts) >= 0.000001) { + *f = (m->m[1][1] * *d - m->m[0][1] * d[1]) / ts; + f[1] = (m->m[1][0] * *d - m->m[0][0] * d[1]) / -ts; + } + if (f[1] >= 0.0 && fabs(ts) >= 0.000001) { + if (*f < 0.0) { + m->m[0][0] = m->m[1][1]; + *tau = tau[1]; + *n = n[1]; + *d = d[1]; + ts = SinglePointColl(f, m, d); + f[1] = 0.0; + } + } else { + ts = SinglePointColl(f, m, d); + f[1] = 0.0; + } + return fabs(ts); } // IDA: br_scalar __usercall DrMatrix4Inverse@(br_matrix4 *mi@, br_matrix4 *mc@) br_scalar DrMatrix4Inverse(br_matrix4* mi, br_matrix4* mc) { LOG_TRACE("(%p, %p)", mi, mc); - NOT_IMPLEMENTED(); + + return BrMatrix4Inverse(mi, mc); } // IDA: br_scalar __usercall ThreePointColl@(br_scalar *f@, br_matrix4 *m@, br_scalar *d@) @@ -2723,7 +3280,16 @@ br_scalar ThreePointColl(br_scalar* f, br_matrix4* m, br_scalar* d) { br_matrix4 mi; br_scalar ts; LOG_TRACE("(%p, %p, %p)", f, m, d); - NOT_IMPLEMENTED(); + + BrMatrix4Copy(&mc, m); + memset(&mc.m[2][3], 0, 16); + mc.m[1][3] = 0.0; + mc.m[0][3] = 0.0; + mc.m[3][3] = 1.0; + ts = DrMatrix4Inverse(&mi, &mc); + BrMatrix4TApply((br_vector4*)f, (br_vector4*)d, &mi); + f[3] = 0.0; + return fabs(ts); } // IDA: br_scalar __usercall ThreePointCollRec@(br_scalar *f@, br_matrix4 *m@, br_scalar *d@, br_vector3 *tau@, br_vector3 *n, tCollision_info *c) @@ -2732,7 +3298,45 @@ br_scalar ThreePointCollRec(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector int j; br_scalar ts; LOG_TRACE("(%p, %p, %p, %p, %p, %p)", f, m, d, tau, n, c); - NOT_IMPLEMENTED(); + + ts = ThreePointColl(f, m, d); + if (*f >= 0.0 && f[1] >= 0.0 && f[2] >= 0.0 && ts >= 0.000001) { + c->infinite_mass = 256; + return ts; + } + if (ts >= 0.000001) { + if (*f >= 0.0) { + if (f[1] >= 0.0) { + if (f[2] >= 0.0) { + return 0.0; + } + i = 0; + j = 1; + } else { + i = 0; + j = 2; + } + } else { + i = 1; + j = 2; + } + } else { + i = 0; + j = 1; + } + m->m[0][0] = m->m[0][5 * i]; + m->m[1][0] = m->m[j][i]; + m->m[0][1] = m->m[i][j]; + m->m[1][1] = m->m[0][5 * j]; + *tau = tau[i]; + tau[1] = tau[j]; + *n = n[i]; + n[1] = n[j]; + *d = d[i]; + d[1] = d[j]; + ts = TwoPointColl(f, m, d, tau, n); + f[2] = 0.0; + return ts; } // IDA: br_scalar __usercall FourPointColl@(br_scalar *f@, br_matrix4 *m@, br_scalar *d@, br_vector3 *tau@, br_vector3 *n, tCollision_info *c) @@ -2742,7 +3346,41 @@ br_scalar FourPointColl(br_scalar* f, br_matrix4* m, br_scalar* d, br_vector3* t int l; br_scalar ts; LOG_TRACE("(%p, %p, %p, %p, %p, %p)", f, m, d, tau, n, c); - NOT_IMPLEMENTED(); + + ts = ThreePointColl(f, m, d); + if (*f < 0.0 || f[1] < 0.0 || f[2] < 0.0 || ts < 0.000001) { + if (ts >= 0.000001) { + if (*f >= 0.0) { + if (f[1] >= 0.0) { + j = 2; + } else { + j = 1; + } + } else { + j = 0; + } + } else { + j = 3; + } + for (i = j; i < 3; ++i) { + for (l = 0; l < 4; ++l) { + m->m[i][l] = m->m[i + 1][l]; + } + d[i] = d[i + 1]; + tau[i] = tau[i + 1]; + n[i] = n[i + 1]; + d[i] = d[i + 1]; + } + for (i = j; i < 3; ++i) { + for (l = 0; l < 3; ++l) { + m->m[l][i] = m->m[l][i + 1]; + } + } + return ThreePointCollRec(f, m, d, tau, n, c); + } else { + c->infinite_mass = 256; + return ts; + } } // IDA: void __usercall MultiFindFloorInBoxM(int pNum_rays@, br_vector3 *a@, br_vector3 *b@, br_vector3 *nor@, br_scalar *d, tCar_spec *c, int *mat_ref) @@ -2776,7 +3414,7 @@ void MultiFindFloorInBoxBU(int pNum_rays, br_vector3* a, br_vector3* b, br_vecto for (i = 0; i < c->box_face_end; i++) { face_ref = &gFace_list__car[i]; - if (!gEliminate_faces || (face_ref->flags & 0x80) == 0) { + if (!gEliminate_faces || SLOBYTE(face_ref->flags) == 0) { MultiRayCheckSingleFace(pNum_rays, face_ref, a, b, &nor2, dist); for (j = 0; j < pNum_rays; ++j) { if (d[j] > dist[j]) { @@ -2813,7 +3451,14 @@ int FindFloorInBoxM(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d, br_vector3 aa; br_vector3 bb; LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); - NOT_IMPLEMENTED(); + + aa.v[0] = a->v[0] / 6.9000001; + aa.v[1] = a->v[1] / 6.9000001; + aa.v[2] = a->v[2] / 6.9000001; + bb.v[0] = b->v[0] / 6.9000001; + bb.v[1] = b->v[1] / 6.9000001; + bb.v[2] = b->v[2] / 6.9000001; + return FindFloorInBoxBU(&aa, &bb, nor, d, c); } // IDA: int __usercall FindFloorInBoxBU@(br_vector3 *a@, br_vector3 *b@, br_vector3 *nor@, br_scalar *d@, tCollision_info *c) @@ -2824,7 +3469,29 @@ int FindFloorInBoxBU(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d br_scalar dist; tFace_ref* face_ref; LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); - NOT_IMPLEMENTED(); + + j = 0; // added to keep compiler happy + *d = 2.0; + for (i = c->box_face_start; i < c->box_face_end; i++) { + face_ref = &gFace_list__car[i]; + if (!gEliminate_faces || SLOBYTE(face_ref->flags) >= 0) { + CheckSingleFace(face_ref, a, b, &nor2, &dist); + if (*d > dist) { + *d = dist; + j = i; + *nor = nor2; + } + } + } + if (*d >= 2.0) { + return 0; + } + i = *gFace_list__car[j].material->identifier - '/'; + if (i < 0 || i >= 11) { + return 0; + } else { + return *gFace_list__car[j].material->identifier - '/'; + } } // IDA: int __usercall FindFloorInBoxBU2@(br_vector3 *a@, br_vector3 *b@, br_vector3 *nor@, br_scalar *d@, tCollision_info *c) @@ -2836,7 +3503,41 @@ int FindFloorInBoxBU2(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* br_scalar dist; tFace_ref* face_ref; LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); - NOT_IMPLEMENTED(); + + j = 0; // added to keep compiler happy + *d = 2.0; + for (i = c->box_face_start; i < c->box_face_end; i++) { + face_ref = &gFace_list__car[i]; + if (!gEliminate_faces || SLOBYTE(face_ref->flags) >= 0) { + CheckSingleFace(face_ref, a, b, &nor2, &dist); + if (*d > dist) { + if (face_ref->material->colour_map_1 == DOUBLESIDED_FLAG_COLOR_MAP || (face_ref->material->flags & 0x1800) != 0) { + tv.v[0] = c->pos.v[0] - a->v[0]; + tv.v[1] = c->pos.v[1] - a->v[1]; + tv.v[2] = c->pos.v[2] - a->v[2]; + if (tv.v[2] * nor2.v[2] + tv.v[1] * nor2.v[1] + tv.v[0] * nor2.v[0] >= 0.0) { + *d = dist; + j = i; + *nor = nor2; + } + } else { + *d = dist; + j = i; + *nor = nor2; + } + } + } + face_ref++; + } + if (*d >= 2.0) { + return 0; + } + i = *gFace_list__car[j].material->identifier - '/'; + if (i < 0 || i >= 11) { + return 0; + } else { + return *gFace_list__car[j].material->identifier - '/'; + } } // IDA: int __usercall FindFloorInBoxM2@(br_vector3 *a@, br_vector3 *b@, br_vector3 *nor@, br_scalar *d@, tCollision_info *c) @@ -2844,7 +3545,14 @@ int FindFloorInBoxM2(br_vector3* a, br_vector3* b, br_vector3* nor, br_scalar* d br_vector3 aa; br_vector3 bb; LOG_TRACE("(%p, %p, %p, %p, %p)", a, b, nor, d, c); - NOT_IMPLEMENTED(); + + aa.v[0] = a->v[0] / 6.9000001; + aa.v[1] = a->v[1] / 6.9000001; + aa.v[2] = a->v[2] / 6.9000001; + bb.v[0] = b->v[0] / 6.9000001; + bb.v[1] = b->v[1] / 6.9000001; + bb.v[2] = b->v[2] / 6.9000001; + return FindFloorInBoxBU2(&aa, &bb, nor, d, c); } // IDA: int __usercall BoxFaceIntersect@(br_bounds *pB@, br_matrix34 *pM@, br_matrix34 *pMold@, br_vector3 *pPoint_list@, br_vector3 *pNorm_list, br_scalar *pDist_list, int pMax_pnts, tCollision_info *c) @@ -2861,7 +3569,93 @@ int BoxFaceIntersect(br_bounds* pB, br_matrix34* pM, br_matrix34* pMold, br_vect tFace_ref* f_ref; br_face* face; LOG_TRACE("(%p, %p, %p, %p, %p, %p, %d, %p)", pB, pM, pMold, pPoint_list, pNorm_list, pDist_list, pMax_pnts, c); - NOT_IMPLEMENTED(); + + n = 0; + bnds.min.v[0] = pB->min.v[0] * 0.14492753; + bnds.min.v[1] = pB->min.v[1] * 0.14492753; + bnds.min.v[2] = pB->min.v[2] * 0.14492753; + bnds.max.v[0] = pB->max.v[0] * 0.14492753; + bnds.max.v[1] = pB->max.v[1] * 0.14492753; + bnds.max.v[2] = pB->max.v[2] * 0.14492753; + pos.v[0] = pM->m[3][0] * 0.14492753; + pos.v[1] = pM->m[3][1] * 0.14492753; + pos.v[2] = pM->m[3][2] * 0.14492753; + pMold->m[3][0] = pMold->m[3][0] * 0.14492753; + pMold->m[3][1] = pMold->m[3][1] * 0.14492753; + pMold->m[3][2] = pMold->m[3][2] * 0.14492753; + + for (i = c->box_face_start; i < c->box_face_end && i < c->box_face_start + 50; i++) { + f_ref = &gFace_list__car[i]; + if (SLOBYTE(f_ref->flags) >= 0 && *f_ref->material->identifier != '!') { + tv.v[0] = f_ref->v[0].v[0] - pos.v[0]; + tv.v[1] = f_ref->v[0].v[1] - pos.v[1]; + tv.v[2] = f_ref->v[0].v[2] - pos.v[2]; + BrMatrix34TApplyV(p, &tv, pM); + tv.v[0] = f_ref->v[1].v[0] - pos.v[0]; + tv.v[1] = f_ref->v[1].v[1] - pos.v[1]; + tv.v[2] = f_ref->v[1].v[2] - pos.v[2]; + BrMatrix34TApplyV(&p[1], &tv, pM); + tv.v[0] = f_ref->v[2].v[0] - pos.v[0]; + tv.v[1] = f_ref->v[2].v[1] - pos.v[1]; + tv.v[2] = f_ref->v[2].v[2] - pos.v[2]; + BrMatrix34TApplyV(&p[2], &tv, pM); + j = n; + if ((f_ref->flags & 1) == 0) { + n += AddEdgeCollPoints(p, &p[1], &bnds, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); + } + if ((f_ref->flags & 2) == 0) { + n += AddEdgeCollPoints(&p[1], &p[2], &bnds, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); + } + if ((f_ref->flags & 4) == 0) { + n += AddEdgeCollPoints(&p[2], p, &bnds, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); + } + if (n > j) { + if (!gMaterial_index) { + m = *f_ref->material->identifier - '/'; + if (m > 0 && m < 11) { + gMaterial_index = m; + } + } + while (n > j) { + pPoint_list[j].v[0] = pPoint_list[j].v[0] * 6.9000001; + pPoint_list[j].v[1] = pPoint_list[j].v[1] * 6.9000001; + pPoint_list[j].v[2] = pPoint_list[j].v[2] * 6.9000001; + pPoint_list[j].v[0] = pPoint_list[j].v[0] - c->cmpos.v[0]; + pPoint_list[j].v[1] = pPoint_list[j].v[1] - c->cmpos.v[1]; + pPoint_list[j].v[2] = pPoint_list[j].v[2] - c->cmpos.v[2]; + ++j; + } + } + } + } + if (n) { + m = 0; + for (i = 0; i < n - 1; i++) { + flag = 1; + for (j = i + 1; j < n; j++) { + if (fabs(pPoint_list[i].v[0] - pPoint_list[j].v[0]) <= 0.001 + && fabs(pPoint_list[i].v[1] - pPoint_list[j].v[1]) <= 0.001 + && fabs(pPoint_list[i].v[2] - pPoint_list[j].v[2]) <= 0.001) { + flag = 0; + break; + } + } + if (flag) { + pPoint_list[m].v[0] = pPoint_list[i].v[0]; + pPoint_list[m].v[1] = pPoint_list[i].v[1]; + pPoint_list[m].v[2] = pPoint_list[i].v[2]; + m++; + } + } + pPoint_list[m].v[0] = pPoint_list[n - 1].v[0]; + pPoint_list[m].v[1] = pPoint_list[n - 1].v[1]; + pPoint_list[m].v[2] = pPoint_list[n - 1].v[2]; + n = m + 1; + } + pMold->m[3][0] = pMold->m[3][0] * 6.9000001; + pMold->m[3][1] = pMold->m[3][1] * 6.9000001; + pMold->m[3][2] = pMold->m[3][2] * 6.9000001; + return n; } // IDA: int __usercall AddEdgeCollPoints@(br_vector3 *p1@, br_vector3 *p2@, br_bounds *pB@, br_matrix34 *pMold@, br_vector3 *pPoint_list, br_vector3 *pNorm_list, int n, int pMax_pnts, tCollision_info *c) @@ -2879,14 +3673,243 @@ int AddEdgeCollPoints(br_vector3* p1, br_vector3* p2, br_bounds* pB, br_matrix34 int plane3; int d; LOG_TRACE("(%p, %p, %p, %p, %p, %p, %d, %d, %p)", p1, p2, pB, pMold, pPoint_list, pNorm_list, n, pMax_pnts, c); - NOT_IMPLEMENTED(); + + float scale; + + plane1 = LineBoxColl(p1, p2, pB, &hp1); + if (!plane1) { + return 0; + } + if (n + 2 > pMax_pnts) { + return 0; + } + plane2 = LineBoxColl(p2, p1, pB, &hp2); + if (!plane2) { + return 0; + } + if (plane1 == 8 || plane2 == 8 || (plane1 ^ plane2) != 4) { + if (plane1 != 8 || plane2 == 8) { + if (plane2 != 8 || plane1 == 8) { + if (plane1 == 8 || plane2 == 8) { + if (plane1 == 8 && plane2 == 8) { + BrMatrix34ApplyP(&op1, p1, pMold); + plane3 = LineBoxColl(&op1, p1, pB, &pPoint_list[n]); + GetPlaneNormal(&pNorm_list[n], plane3); + d = n + (plane3 != 8); + BrMatrix34ApplyP(&op1, p2, pMold); + plane3 = LineBoxColl(&op1, p2, pB, &pPoint_list[d]); + GetPlaneNormal(&pNorm_list[d], plane3); + return (n != d) + (plane3 != 8); + } else { + return 0; + } + } else { + op1.v[0] = hp2.v[0] + hp1.v[0]; + op1.v[1] = hp2.v[1] + hp1.v[1]; + op1.v[2] = hp2.v[2] + hp1.v[2]; + op1.v[0] = op1.v[0] * 0.5; + op1.v[1] = op1.v[1] * 0.5; + op1.v[2] = op1.v[2] * 0.5; + BrMatrix34ApplyP(&op2, &op1, pMold); + plane3 = LineBoxColl(&op2, &op1, pB, &hp3); + if (plane3 != 8 && plane3) { + if (plane1 == plane3 || plane2 == plane3) { + GetBoundsEdge( + &pPoint_list[n], + &edge, + pB, + plane1, + plane2, + &op2, + &hp1, + &hp2, + c->collision_flag); + op1.v[0] = hp1.v[0] - hp2.v[0]; + op1.v[1] = hp1.v[1] - hp2.v[1]; + op1.v[2] = hp1.v[2] - hp2.v[2]; + op2.v[0] = edge.v[1] * op1.v[2] - op1.v[1] * edge.v[2]; + op2.v[1] = edge.v[2] * op1.v[0] - op1.v[2] * edge.v[0]; + op2.v[2] = op1.v[1] * edge.v[0] - edge.v[1] * op1.v[0]; + scale = sqrt(op2.v[1] * op2.v[1] + op2.v[2] * op2.v[2] + op2.v[0] * op2.v[0]); + if (scale <= 2.3841858e-7) { + pNorm_list[n].v[0] = 1.0; + pNorm_list[n].v[1] = 0.0; + pNorm_list[n].v[2] = 0.0; + } else { + scale = 1.0 / scale; + pNorm_list[n].v[0] = op2.v[0] * scale; + pNorm_list[n].v[1] = op2.v[1] * scale; + pNorm_list[n].v[2] = op2.v[2] * scale; + } + op1.v[0] = pB->max.v[0] + pB->min.v[0]; + op1.v[1] = pB->min.v[1] + pB->max.v[1]; + op1.v[2] = pB->max.v[2] + pB->min.v[2]; + op1.v[0] = op1.v[0] * 0.5; + op1.v[1] = op1.v[1] * 0.5; + op1.v[2] = op1.v[2] * 0.5; + op1.v[0] = pPoint_list[n].v[0] - op1.v[0]; + op1.v[1] = pPoint_list[n].v[1] - op1.v[1]; + op1.v[2] = pPoint_list[n].v[2] - op1.v[2]; + if (pNorm_list[n].v[1] * op1.v[1] + pNorm_list[n].v[2] * op1.v[2] + pNorm_list[n].v[0] * op1.v[0] > 0.0) { + pNorm_list[n].v[0] = -pNorm_list[n].v[0]; + pNorm_list[n].v[1] = -pNorm_list[n].v[1]; + pNorm_list[n].v[2] = -pNorm_list[n].v[2]; + } + op1 = pNorm_list[n]; + BrMatrix34ApplyV(&pNorm_list[n], &op1, pMold); + return 1; + } else { + GetBoundsEdge( + &pPoint_list[n], + &edge, + pB, + plane1, + plane3, + &hp3, + &hp1, + &hp2, + c->collision_flag); + GetBoundsEdge( + &pPoint_list[n + 1], + &edge, + pB, + plane2, + plane3, + &hp3, + &hp1, + &hp2, + c->collision_flag); + GetPlaneNormal(&pNorm_list[n], plane3); + pNorm_list[n + 1] = pNorm_list[n]; + return 2; + } + } else { + return 0; + } + } + } else { + BrMatrix34ApplyP(&b, p2, pMold); + plane3 = LineBoxColl(&b, p2, pB, &hp3); + if (plane3 == 8) { + return 0; + } else { + pPoint_list[n] = hp3; + GetPlaneNormal(&pNorm_list[n], plane1); + if (plane1 == plane3 || (plane3 ^ plane1) == 4) { + return 1; + } else { + GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane1, plane3, p2, &hp1, &hp3, c->collision_flag); + op1.v[0] = p1->v[0] - p2->v[0]; + op1.v[1] = p1->v[1] - p2->v[1]; + op1.v[2] = p1->v[2] - p2->v[2]; + pNorm_list[n + 1].v[0] = edge.v[1] * op1.v[2] - op1.v[1] * edge.v[2]; + pNorm_list[n + 1].v[1] = edge.v[2] * op1.v[0] - op1.v[2] * edge.v[0]; + pNorm_list[n + 1].v[2] = op1.v[1] * edge.v[0] - edge.v[1] * op1.v[0]; + scale = sqrt( + pNorm_list[n + 1].v[0] * pNorm_list[n + 1].v[0] + + pNorm_list[n + 1].v[1] * pNorm_list[n + 1].v[1] + + pNorm_list[n + 1].v[2] * pNorm_list[n + 1].v[2]); + if (scale <= 2.3841858e-7) { + pNorm_list[n + 1].v[0] = 1.0; + pNorm_list[n + 1].v[1] = 0.0; + pNorm_list[n + 1].v[2] = 0.0; + } else { + scale = 1.0 / scale; + pNorm_list[n + 1].v[0] = pNorm_list[n + 1].v[0] * scale; + pNorm_list[n + 1].v[1] = pNorm_list[n + 1].v[1] * scale; + pNorm_list[n + 1].v[2] = pNorm_list[n + 1].v[2] * scale; + } + d = (plane1 - 1) & 3; + if ((pNorm_list[n + 1].v[d] < 0.0) == (plane1 & 4) >> 2) { + pNorm_list[n + 1].v[0] = -pNorm_list[n + 1].v[0]; + pNorm_list[n + 1].v[1] = -pNorm_list[n + 1].v[1]; + pNorm_list[n + 1].v[2] = -pNorm_list[n + 1].v[2]; + } + op1 = pNorm_list[n + 1]; + BrMatrix34ApplyV(&pNorm_list[n + 1], &op1, pMold); + return 2; + } + } + } + } else { + BrMatrix34ApplyP(&a, p1, pMold); + plane3 = LineBoxColl(&a, p1, pB, &hp3); + if (plane3 == 8) { + return 0; + } else { + pPoint_list[n] = hp3; + GetPlaneNormal(&pNorm_list[n], plane2); + if (plane2 == plane3 || (plane3 ^ plane2) == 4) { + return 1; + } else { + GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane2, plane3, p1, &hp2, &hp3, c->collision_flag); + op1.v[0] = p1->v[0] - p2->v[0]; + op1.v[1] = p1->v[1] - p2->v[1]; + op1.v[2] = p1->v[2] - p2->v[2]; + pNorm_list[n + 1].v[0] = edge.v[1] * op1.v[2] - op1.v[1] * edge.v[2]; + pNorm_list[n + 1].v[1] = edge.v[2] * op1.v[0] - op1.v[2] * edge.v[0]; + pNorm_list[n + 1].v[2] = op1.v[1] * edge.v[0] - edge.v[1] * op1.v[0]; + scale = sqrt( + pNorm_list[n + 1].v[0] * pNorm_list[n + 1].v[0] + + pNorm_list[n + 1].v[1] * pNorm_list[n + 1].v[1] + + pNorm_list[n + 1].v[2] * pNorm_list[n + 1].v[2]); + if (scale <= 2.3841858e-7) { + pNorm_list[n + 1].v[0] = 1.0; + pNorm_list[n + 1].v[1] = 0.0; + pNorm_list[n + 1].v[2] = 0.0; + } else { + scale = 1.0 / scale; + pNorm_list[n + 1].v[0] = pNorm_list[n + 1].v[0] * scale; + pNorm_list[n + 1].v[1] = pNorm_list[n + 1].v[1] * scale; + pNorm_list[n + 1].v[2] = pNorm_list[n + 1].v[2] * scale; + } + d = (plane2 - 1) & 3; + if ((pNorm_list[n + 1].v[d] < 0.0) == (plane2 & 4) >> 2) { + pNorm_list[n + 1].v[0] = -pNorm_list[n + 1].v[0]; + pNorm_list[n + 1].v[1] = -pNorm_list[n + 1].v[1]; + pNorm_list[n + 1].v[2] = -pNorm_list[n + 1].v[2]; + } + op1 = pNorm_list[n + 1]; + BrMatrix34ApplyV(&pNorm_list[n + 1], &op1, pMold); + return 2; + } + } + } + } else { + op1.v[0] = hp2.v[0] + hp1.v[0]; + op1.v[1] = hp2.v[1] + hp1.v[1]; + op1.v[2] = hp2.v[2] + hp1.v[2]; + op1.v[0] = op1.v[0] * 0.5; + op1.v[1] = op1.v[1] * 0.5; + op1.v[2] = op1.v[2] * 0.5; + BrMatrix34ApplyP(&op2, &op1, pMold); + plane3 = LineBoxColl(&op2, &op1, pB, &hp3); + if (plane3 == 8) { + return 0; + } else { + GetBoundsEdge(&pPoint_list[n], &edge, pB, plane1, plane3, &op2, &hp1, &hp2, c->collision_flag); + GetBoundsEdge(&pPoint_list[n + 1], &edge, pB, plane2, plane3, &op2, &hp1, &hp2, c->collision_flag); + GetPlaneNormal(&pNorm_list[n], plane3); + pNorm_list[n + 1] = pNorm_list[n]; + return 2; + } + } } // IDA: void __usercall GetPlaneNormal(br_vector3 *n@, int p@) void GetPlaneNormal(br_vector3* n, int p) { int d; LOG_TRACE("(%p, %d)", n, p); - NOT_IMPLEMENTED(); + + d = (p - 1) & 3; + n->v[0] = 0.0; + n->v[1] = 0.0; + n->v[2] = 0.0; + if ((p & 4) != 0) { + n->v[d] = 1.0; + } else { + n->v[d] = -1.0; + } } // IDA: int __usercall GetBoundsEdge@(br_vector3 *pos@, br_vector3 *edge@, br_bounds *pB@, int plane1@, int plane2, br_vector3 *a, br_vector3 *b, br_vector3 *c, int flag) @@ -2898,7 +3921,38 @@ int GetBoundsEdge(br_vector3* pos, br_vector3* edge, br_bounds* pB, int plane1, br_vector3 p; br_vector3 q; LOG_TRACE("(%p, %p, %p, %d, %d, %p, %p, %p, %d)", pos, edge, pB, plane1, plane2, a, b, c, flag); - NOT_IMPLEMENTED(); + + d1 = (plane1 - 1) & 3; + d2 = (plane2 - 1) & 3; + n.v[0] = b->v[0] - a->v[0]; + n.v[1] = b->v[1] - a->v[1]; + n.v[2] = b->v[2] - a->v[2]; + p.v[0] = c->v[0] - a->v[0]; + p.v[1] = c->v[1] - a->v[1]; + p.v[2] = c->v[2] - a->v[2]; + q.v[0] = p.v[2] * n.v[1] - p.v[1] * n.v[2]; + q.v[1] = n.v[2] * p.v[0] - p.v[2] * n.v[0]; + q.v[2] = p.v[1] * n.v[0] - n.v[1] * p.v[0]; + if ((plane1 & 4) != 0) { + pos->v[d1] = pB->min.v[d1]; + } else { + pos->v[d1] = pB->max.v[d1]; + } + if ((plane2 & 4) != 0) { + pos->v[d2] = pB->min.v[d2]; + } else { + pos->v[d2] = pB->max.v[d2]; + } + d3 = 3 - d1 - d2; + edge->v[d1] = 0.0; + edge->v[d2] = 0.0; + edge->v[d3] = 1.0; + if ((flag & 1) != 0) { + pos->v[d3] = (c->v[d3] + b->v[d3]) / 2.0; + } else { + pos->v[d3] = a->v[d3] - ((pos->v[d2] - a->v[d2]) * q.v[d2] + (pos->v[d1] - a->v[d1]) * q.v[d1]) / q.v[d3]; + } + return 1; } // IDA: void __usercall oldMoveOurCar(tU32 pTime_difference@) @@ -2951,7 +4005,7 @@ void SetAmbientPratCam(tCar_spec* pCar) { static tU32 last_time_on_ground; LOG_TRACE("(%p)", pCar); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall MungeCarGraphics(tU32 pFrame_period@) @@ -3262,7 +4316,7 @@ void AmIGettingBoredWatchingCameraSpin() { char s[256]; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl ViewNetPlayer() @@ -3323,7 +4377,7 @@ void CheckDisablePlingMaterials(tCar_spec* pCar) { br_scalar height; int i; LOG_TRACE("(%p)", pCar); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall PositionExternalCamera(tCar_spec *c@, tU32 pTime@) @@ -3375,7 +4429,7 @@ void CameraBugFix(tCar_spec* c, tU32 pTime) { br_matrix34* m2; br_vector3 tv; LOG_TRACE("(%p, %d)", c, pTime); - SILENT_STUB(); + STUB_ONCE(); } // IDA: int __usercall PossibleRemoveNonCarFromWorld@(br_actor *pActor@) @@ -4134,7 +5188,7 @@ int CollideCameraWithOtherCars(br_vector3* car_pos, br_vector3* cam_pos) { br_bounds bnds; LOG_TRACE("(%p, %p)", car_pos, cam_pos); - SILENT_STUB(); + STUB_ONCE(); return 0; } @@ -4228,7 +5282,7 @@ void CrashCarsTogether(br_scalar dt) { tCollison_data collide_list[32]; LOG_TRACE("(%f)", dt); - STUB(); + STUB_ONCE(); } // IDA: int __cdecl CrashCarsTogetherSinglePass(br_scalar dt, int pPass, tCollison_data *collide_list) @@ -4608,7 +5662,7 @@ void CheckForDeAttachmentOfNonCars(tU32 pTime) { br_matrix34 mat; LOG_TRACE("(%d)", pTime); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall AdjustNonCar(br_actor *pActor@, br_matrix34 *pMat@) diff --git a/src/DETHRACE/common/controls.c b/src/DETHRACE/common/controls.c index 8ca4f6fe..1415b798 100644 --- a/src/DETHRACE/common/controls.c +++ b/src/DETHRACE/common/controls.c @@ -163,7 +163,7 @@ void FinishLap(int i) { // IDA: void __cdecl EnsureSpecialVolumesHidden() void EnsureSpecialVolumesHidden() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl ShowSpecialVolumesIfRequ() @@ -691,7 +691,7 @@ void CheckRecoveryOfCars(tU32 pEndFrameTime) { int time; char s[256]; LOG_TRACE("(%d)", pEndFrameTime); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall LoseSomePSPowerups(int pNumber@) @@ -722,7 +722,7 @@ void CheckOtherRacingKeys() { static int stopped_repairing; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: int __cdecl CheckRecoverCost() @@ -1054,7 +1054,7 @@ void ToggleMap() { static int old_indent; static int was_in_cockpit; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: int __cdecl HornBlowing() @@ -1250,7 +1250,7 @@ void EnterUserMessage() { int the_key; int abuse_num; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl DisplayUserMessage() diff --git a/src/DETHRACE/common/crush.c b/src/DETHRACE/common/crush.c index 440dc664..14c2e8e5 100644 --- a/src/DETHRACE/common/crush.c +++ b/src/DETHRACE/common/crush.c @@ -249,7 +249,7 @@ void RecordLastDamage(tCar_spec* pCar) { int i; LOG_TRACE("(%p)", pCar); - STUB(); + STUB_ONCE(); } // IDA: void __usercall DoDamage(tCar_spec *pCar@, tDamage_type pDamage_type@, float pMagnitude, float pNastiness) @@ -328,7 +328,7 @@ void SetSmokeLastDamageLevel(tCar_spec* pCar) { int i; LOG_TRACE("(%p)", pCar); - STUB(); + STUB_ONCE(); } // IDA: void __usercall SortOutSmoke(tCar_spec *pCar@) @@ -404,11 +404,11 @@ void DoWheelDamage(tU32 pFrame_period) { br_vector3 wonky_vector; static int kev_index[4]; LOG_TRACE("(%d)", pFrame_period); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall CrashEarnings(tCar_spec *pCar1@, tCar_spec *pCar2@) void CrashEarnings(tCar_spec* pCar1, tCar_spec* pCar2) { LOG_TRACE("(%p, %p)", pCar1, pCar2); - NOT_IMPLEMENTED(); + STUB(); } diff --git a/src/DETHRACE/common/depth.c b/src/DETHRACE/common/depth.c index 5dc9899d..b76899a4 100644 --- a/src/DETHRACE/common/depth.c +++ b/src/DETHRACE/common/depth.c @@ -344,13 +344,13 @@ void DoFog(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer) { // IDA: void __usercall DepthEffect(br_pixelmap *pRender_buffer@, br_pixelmap *pDepth_buffer@, br_actor *pCamera@, br_matrix34 *pCamera_to_world@) void DepthEffect(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) { LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall DepthEffectSky(br_pixelmap *pRender_buffer@, br_pixelmap *pDepth_buffer@, br_actor *pCamera@, br_matrix34 *pCamera_to_world@) void DepthEffectSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) { LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall DoWobbleCamera(br_actor *pCamera@) @@ -406,7 +406,7 @@ void DoDrugWobbleCamera(br_actor* pCamera) { // IDA: void __usercall DoSpecialCameraEffect(br_actor *pCamera@, br_matrix34 *pCamera_to_world@) void DoSpecialCameraEffect(br_actor* pCamera, br_matrix34* pCamera_to_world) { LOG_TRACE("(%p, %p)", pCamera, pCamera_to_world); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl LessDepthFactor() @@ -622,7 +622,7 @@ void ChangeDepthEffect() { br_scalar distance; tSpecial_volume* special_volume; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl MungeForwardSky() diff --git a/src/DETHRACE/common/displays.c b/src/DETHRACE/common/displays.c index 74fa6d1e..6848ab8f 100644 --- a/src/DETHRACE/common/displays.c +++ b/src/DETHRACE/common/displays.c @@ -219,7 +219,7 @@ void DimRectangle(br_pixelmap* pPixelmap, int pLeft, int pTop, int pRight, int p int line_skip; int width; LOG_TRACE9("(%p, %d, %d, %d, %d, %d)", pPixelmap, pLeft, pTop, pRight, pBottom, pKnock_out_corners); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl DimAFewBits() @@ -264,7 +264,7 @@ void DoPSPowerHeadup(int pY, int pLevel, char* pName, int pBar_colour) { // IDA: void __cdecl DoPSPowerupHeadups() void DoPSPowerupHeadups() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall DoHeadups(tU32 pThe_time@) @@ -890,7 +890,7 @@ void DoDamageScreen(tU32 pThe_time) { br_pixelmap* the_image; tDamage_unit* the_damage; LOG_TRACE("(%d)", pThe_time); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl PoshDrawLine(float pAngle, br_pixelmap *pDestn, int pX1, int pY1, int pX2, int pY2, int pColour) @@ -1147,14 +1147,14 @@ void DoSteeringWheel(tU32 pThe_time) { br_pixelmap* hands_image; int hands_index; LOG_TRACE("(%d)", pThe_time); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl ChangingView() void ChangingView() { tU32 the_time; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall EarnCredits2(int pAmount@, char *pPrefix_text@) diff --git a/src/DETHRACE/common/finteray.c b/src/DETHRACE/common/finteray.c index fdbff07e..c72d7132 100644 --- a/src/DETHRACE/common/finteray.c +++ b/src/DETHRACE/common/finteray.c @@ -419,7 +419,80 @@ void CheckSingleFace(tFace_ref* pFace, br_vector3* ray_pos, br_vector3* ray_dir, double f_numerator; br_material* this_material; LOG_TRACE("(%p, %p, %p, %p, %p)", pFace, ray_pos, ray_dir, normal, rt); - NOT_IMPLEMENTED(); + + this_material = pFace->material; + *rt = 100.0; + d = pFace->normal.v[1] * ray_dir->v[1] + ray_dir->v[2] * pFace->normal.v[2] + ray_dir->v[0] * pFace->normal.v[0]; + if ((!this_material || (this_material->flags & 0x1800) != 0 || d <= 0.0) + && (!this_material || !this_material->identifier || *this_material->identifier != '!' || !gPling_materials) + && fabs(d) >= 0.00000023841858) { + p.v[0] = ray_pos->v[0] - pFace->v[0].v[0]; + p.v[1] = ray_pos->v[1] - pFace->v[0].v[1]; + p.v[2] = ray_pos->v[2] - pFace->v[0].v[2]; + numerator = pFace->normal.v[1] * p.v[1] + pFace->normal.v[2] * p.v[2] + pFace->normal.v[0] * p.v[0]; + if (!BadDiv__finteray(numerator, d)) { + if (d > 0.0) { + if (-numerator < -0.001 || -numerator > d + 0.003) { + return; + } + } else if (numerator < -0.001 || 0.003 - d < numerator) { + return; + } + t = -(numerator / d); + if (t > 1.0) { + t = 1.0; + } + tv.v[0] = ray_dir->v[0] * t; + tv.v[1] = ray_dir->v[1] * t; + tv.v[2] = ray_dir->v[2] * t; + tv.v[0] = ray_pos->v[0] + tv.v[0]; + tv.v[1] = ray_pos->v[1] + tv.v[1]; + tv.v[2] = ray_pos->v[2] + tv.v[2]; + axis_m = fabs(pFace->normal.v[0]) < fabs(pFace->normal.v[1]); + if (fabs(pFace->normal.v[2]) > fabs(pFace->normal.v[axis_m])) { + axis_m = 2; + } + if (axis_m) { + axis_0 = 0; + if (axis_m == 1) { + axis_1 = 2; + } else { + axis_1 = 1; + } + } else { + axis_0 = 1; + axis_1 = 2; + } + v0i1 = pFace->v[0].v[axis_0]; + v0i2 = pFace->v[0].v[axis_1]; + u0 = pFace->v[1].v[axis_0] - v0i1; + u1 = pFace->v[1].v[axis_1] - v0i2; + v0 = pFace->v[2].v[axis_0] - v0i1; + v1 = pFace->v[2].v[axis_1] - v0i2; + u2 = tv.v[axis_0] - v0i1; + v2 = tv.v[axis_1] - v0i2; + if (fabs(u0) > 0.0000002384185791015625) { + f_d = v1 * u0 - u1 * v0; + if (f_d == 0) { + return; + } + alpha = (v2 * u0 - u1 * u2) / f_d; + beta = (u2 - alpha * v0) / u0; + } else { + alpha = u2 / v0; + beta = (v2 - alpha * v1) / u1; + } + if (beta >= -0.0001 && alpha >= -0.0001 && alpha + beta <= 1.0001) { + *rt = t; + *normal = pFace->normal; + if (d > 0.0) { + normal->v[0] = -normal->v[0]; + normal->v[1] = -normal->v[1]; + normal->v[2] = -normal->v[2]; + } + } + } + } } // IDA: void __usercall MultiRayCheckSingleFace(int pNum_rays@, tFace_ref *pFace@, br_vector3 *ray_pos@, br_vector3 *ray_dir@, br_vector3 *normal, br_scalar *rt) @@ -1071,7 +1144,59 @@ int LineBoxColl(br_vector3* o, br_vector3* p, br_bounds* pB, br_vector3* pHit_po br_scalar max_t[3]; br_scalar cp[3]; LOG_TRACE("(%p, %p, %p, %p)", o, p, pB, pHit_point); - NOT_IMPLEMENTED(); + + inside = 1; + dir.v[0] = p->v[0] - o->v[0]; + dir.v[1] = p->v[1] - o->v[1]; + dir.v[2] = p->v[2] - o->v[2]; + for (i = 0; i < 3; ++i) { + if (pB->min.v[i] <= o->v[i]) { + if (pB->max.v[i] >= o->v[i]) { + quad[i] = 2; + } else { + quad[i] = 0; + max_t[i] = pB->max.v[i]; + inside = 0; + } + } else { + quad[i] = 1; + max_t[i] = pB->min.v[i]; + inside = 0; + } + } + if (inside) { + *pHit_point = *o; + return 8; + } else { + for (i = 0; i < 3; ++i) { + if (quad[i] == 2 || dir.v[i] == 0.0) { + cp[i] = -1.0; + } else { + cp[i] = (max_t[i] - o->v[i]) / dir.v[i]; + } + } + which_plane = 0; + for (i = 1; i < 3; ++i) { + if (cp[which_plane] < cp[i]) { + which_plane = i; + } + } + if (cp[which_plane] >= 0.0 && cp[which_plane] <= 1.0) { + for (i = 0; i < 3; ++i) { + if (which_plane == i) { + pHit_point->v[i] = max_t[i]; + } else { + pHit_point->v[i] = dir.v[i] * cp[which_plane] + o->v[i]; + if (pHit_point->v[i] < pB->min.v[i] || pB->max.v[i] < pHit_point->v[i]) { + return 0; + } + } + } + return which_plane + 4 * quad[which_plane] + 1; + } else { + return 0; + } + } } // IDA: int __usercall SphereBoxIntersection@(br_bounds *pB@, br_vector3 *pC@, br_scalar pR_squared, br_vector3 *pHit_point) diff --git a/src/DETHRACE/common/graphics.c b/src/DETHRACE/common/graphics.c index 31960599..5c202251 100644 --- a/src/DETHRACE/common/graphics.c +++ b/src/DETHRACE/common/graphics.c @@ -196,7 +196,7 @@ void RenderLollipops() { br_actor** the_actor; br_actor* old_parent; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall DRDrawLine(br_pixelmap *pDestn@, int pX1@, int pY1@, int pX2@, int pY2, int pColour) @@ -625,7 +625,7 @@ void CalculateWobblitude(tU32 pThe_time) { gScreen_wobble_x = 0; gScreen_wobble_y = 0; - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall CalculateConcussion(tU32 pThe_time@) @@ -640,7 +640,7 @@ void CalculateConcussion(tU32 pThe_time) { LOG_TRACE("(%d)", pThe_time); gConcussion.concussed = 0; - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl SufferFromConcussion(float pSeriousness) @@ -811,7 +811,7 @@ void RenderShadows(br_actor* pWorld, tTrack_spec* pTrack_spec, br_actor* pCamera br_vector3 camera_to_car; br_scalar distance_factor; LOG_TRACE("(%p, %p, %p, %p)", pWorld, pTrack_spec, pCamera, pCamera_to_world_transform); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall FlashyMapCheckpoint(int pIndex@, tU32 pTime@) @@ -820,7 +820,7 @@ void FlashyMapCheckpoint(int pIndex, tU32 pTime) { static tU32 last_flash; static int flash_state; LOG_TRACE("(%d, %d)", pIndex, pTime); - SILENT_STUB(); + STUB_ONCE(); } // IDA: int __usercall ConditionallyFillWithSky@(br_pixelmap *pPixelmap@) @@ -828,7 +828,7 @@ int ConditionallyFillWithSky(br_pixelmap* pPixelmap) { int bgnd_col; LOG_TRACE("(%p)", pPixelmap); - SILENT_STUB(); + STUB_ONCE(); return 0; } @@ -1375,7 +1375,7 @@ void ChangeAmbience(br_scalar pDelta) { void InitAmbience() { LOG_TRACE("()"); gCurrent_ambience = gAmbient_adjustment; - return ChangeAmbience(gAmbient_adjustment); + ChangeAmbience(gAmbient_adjustment); } // IDA: void __usercall DRPixelmapRectangleMaskedCopy(br_pixelmap *pDest@, br_int_16 pDest_x@, br_int_16 pDest_y@, br_pixelmap *pSource@, br_int_16 pSource_x, br_int_16 pSource_y, br_int_16 pWidth, br_int_16 pHeight) @@ -1580,7 +1580,7 @@ void DeallocateAllTransientBitmaps() { void RemoveTransientBitmaps(int pGraphically_remove_them) { int i; int order_number; - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall SaveTransient(int pIndex@, int pX_coord@, int pY_coord@) @@ -1635,7 +1635,8 @@ int DoMouseCursor() { static int required_cursor; static int zero_count; static int button_was_down; - SILENT_STUB(); + STUB_ONCE(); + return 0; } // IDA: int __cdecl AllocateCursorTransient() diff --git a/src/DETHRACE/common/loading.c b/src/DETHRACE/common/loading.c index ca407cee..5c42707c 100644 --- a/src/DETHRACE/common/loading.c +++ b/src/DETHRACE/common/loading.c @@ -122,8 +122,6 @@ int gDemo_opponents[5]; int gDemo_power; int gDemo_offensive; -#define DOUBLESIDED_FLAG_COLOR_MAP (br_pixelmap*)12345 - // IDA: tU32 __usercall ReadU32@(FILE *pF@) tU32 ReadU32(FILE* pF) { tU32 raw_long; diff --git a/src/DETHRACE/common/netgame.c b/src/DETHRACE/common/netgame.c index 59a28e64..1a6460e0 100644 --- a/src/DETHRACE/common/netgame.c +++ b/src/DETHRACE/common/netgame.c @@ -151,7 +151,7 @@ void DoNetworkHeadups(int pCredits) { static tU32 last_flash; static int flash_state; LOG_TRACE("(%d)", pCredits); - SILENT_STUB(); + STUB_ONCE(); } // IDA: int __usercall SortNetHeadAscending@(void *pFirst_one@, void *pSecond_one@) @@ -295,7 +295,7 @@ void SendPlayerScores() { // IDA: void __cdecl DoNetGameManagement() void DoNetGameManagement() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall InitialisePlayerScore(tNet_game_player_info *pPlayer@) @@ -381,7 +381,7 @@ void SendGameplayToAllPlayers(tNet_gameplay_mess pMess, int pParam_1, int pParam tNet_message* the_message; LOG_TRACE("(%d, %d, %d, %d, %d)", pMess, pParam_1, pParam_2, pParam_3, pParam_4); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall SendGameplayToHost(tNet_gameplay_mess pMess@, int pParam_1@, int pParam_2@, int pParam_3@, int pParam_4) diff --git a/src/DETHRACE/common/network.c b/src/DETHRACE/common/network.c index 4346d36d..db4c9bbd 100644 --- a/src/DETHRACE/common/network.c +++ b/src/DETHRACE/common/network.c @@ -373,7 +373,7 @@ tNet_contents* NetGetBroadcastContents(tNet_message_type pType, tS32 pSize_decid // IDA: void __cdecl NetSendMessageStacks() void NetSendMessageStacks() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: tNet_message* __usercall NetAllocateMessage@(int pSize@) @@ -691,7 +691,7 @@ void NetReceiveAndProcessMessages() { tU32 receive_time; int old_net_service; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl BroadcastStatus() @@ -723,7 +723,7 @@ void CheckForPendingStartRace() { void NetService(int pIn_race) { tU32 time; static tU32 last_status_broadcast; - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall NetFinishRace(tNet_game_details *pDetails@, tRace_over_reason pReason@) diff --git a/src/DETHRACE/common/oil.c b/src/DETHRACE/common/oil.c index 05ca707d..8931667a 100644 --- a/src/DETHRACE/common/oil.c +++ b/src/DETHRACE/common/oil.c @@ -166,7 +166,7 @@ void ProcessOilSpills(tU32 pFrame_period) { br_vector3 v; tNet_message* message; LOG_TRACE("(%d)", pFrame_period); - SILENT_STUB(); + STUB_ONCE(); } // IDA: int __cdecl GetOilSpillCount() diff --git a/src/DETHRACE/common/opponent.c b/src/DETHRACE/common/opponent.c index 209a8eb3..7abc7867 100644 --- a/src/DETHRACE/common/opponent.c +++ b/src/DETHRACE/common/opponent.c @@ -916,7 +916,7 @@ void MungeOpponents(tU32 pFrame_period) { int i; int un_stun_flag; LOG_TRACE("(%d)", pFrame_period); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl SetInitialCopPositions() diff --git a/src/DETHRACE/common/pedestrn.c b/src/DETHRACE/common/pedestrn.c index 517a6aee..2931d84b 100644 --- a/src/DETHRACE/common/pedestrn.c +++ b/src/DETHRACE/common/pedestrn.c @@ -386,7 +386,7 @@ void MungePedestrianSequence(tPedestrian_data* pPedestrian, int pAction_changed) float heading_difference; tPedestrian_sequence* sequence_ptr; LOG_TRACE("(%p, %d)", pPedestrian, pAction_changed); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall DetachPedFromCar(tPedestrian_data *pPedestrian@) @@ -735,7 +735,7 @@ void MungePedestrians(tU32 pFrame_period) { br_scalar z_delta; tS32 diff; LOG_TRACE("(%d)", pFrame_period); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl RespawnPedestrians() @@ -1581,7 +1581,7 @@ void RenderProximityRays(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer br_scalar distance; br_scalar t; LOG_TRACE("(%p, %p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pCamera_to_world, pTime); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall AdjustProxRay(int pRay_index@, tU16 pCar_ID@, tU16 pPed_index@, tU32 pTime@) diff --git a/src/DETHRACE/common/piping.c b/src/DETHRACE/common/piping.c index 064b6338..5dc6d1b0 100644 --- a/src/DETHRACE/common/piping.c +++ b/src/DETHRACE/common/piping.c @@ -101,7 +101,7 @@ void StartPipingSession2(tPipe_chunk_type pThe_type, int pMunge_reentrancy) { void StartPipingSession(tPipe_chunk_type pThe_type) { LOG_TRACE("(%d)", pThe_type); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall EndPipingSession2(int pMunge_reentrancy@) @@ -115,7 +115,7 @@ void EndPipingSession2(int pMunge_reentrancy) { void EndPipingSession() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall AddDataToSession(int pSubject_index@, void *pData@, tU32 pData_length@) @@ -210,7 +210,7 @@ void AddSplashToPipingSession(tCollision_info* pCar) { tPipe_splash_data data; LOG_TRACE("(%p)", pCar); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall AddOilSpillToPipingSession(int pIndex@, br_matrix34 *pMat@, br_scalar pFull_size, br_scalar pGrow_rate, tU32 pSpill_time, tU32 pStop_time, tCar_spec *pCar, br_vector3 *pOriginal_pos, br_pixelmap *pPixelmap) @@ -379,7 +379,7 @@ void PipeSingleGrooveStop(int pGroove_index, br_matrix34* pMatrix, int pPath_int // IDA: void __cdecl PipeFrameFinish() void PipeFrameFinish() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl PipingFrameReset() @@ -404,7 +404,7 @@ void ResetPiping() { // IDA: void __cdecl InitialisePiping() void InitialisePiping() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl DisposePiping() @@ -466,7 +466,7 @@ void PipeCarPositions() { tS8 damage_deltas[12]; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl ResetPipePlayToEnd() diff --git a/src/DETHRACE/common/powerup.c b/src/DETHRACE/common/powerup.c index f81339c6..6615b8c8 100644 --- a/src/DETHRACE/common/powerup.c +++ b/src/DETHRACE/common/powerup.c @@ -162,7 +162,7 @@ void DrawPowerups(tU32 pTime) { tHeadup_icon* the_icon; br_pixelmap* fizzle_pix; LOG_TRACE("(%d)", pTime); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall DoPowerupPeriodics(tU32 pFrame_period@) @@ -171,7 +171,7 @@ void DoPowerupPeriodics(tU32 pFrame_period) { tPowerup* the_powerup; tU32 the_time; LOG_TRACE("(%d)", pFrame_period); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall GotPowerupN(int pN@) diff --git a/src/DETHRACE/common/pratcam.c b/src/DETHRACE/common/pratcam.c index f24537eb..25142171 100644 --- a/src/DETHRACE/common/pratcam.c +++ b/src/DETHRACE/common/pratcam.c @@ -20,7 +20,7 @@ int gCurrent_pratcam_alternative; int PratcamGetCurrent() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); return 0; } @@ -28,7 +28,7 @@ int PratcamGetCurrent() { int PratcamGetAmbient() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); return 0; } @@ -36,7 +36,7 @@ int PratcamGetAmbient() { int PratcamGetPending() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); return 0; } @@ -151,7 +151,7 @@ void DoPratcam(tU32 pThe_time) { br_pixelmap* left_image; br_pixelmap* right_image; LOG_TRACE("(%d)", pThe_time); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall TestPratCam(int pIndex@) diff --git a/src/DETHRACE/common/racestrt.c b/src/DETHRACE/common/racestrt.c index a37ddc28..2757f661 100644 --- a/src/DETHRACE/common/racestrt.c +++ b/src/DETHRACE/common/racestrt.c @@ -381,10 +381,7 @@ tSO_result DoAutoPartsShop() { // IDA: void __cdecl SetOpponentFlic() void SetOpponentFlic() { LOG_TRACE("()"); - return ChangePanelFlic( - 0, - gOpponents[gCurrent_race.opponent_list[gOpponent_index].index].mug_shot_image_data, - gOpponents[gCurrent_race.opponent_list[gOpponent_index].index].mug_shot_image_data_length); + ChangePanelFlic(0, gOpponents[gCurrent_race.opponent_list[gOpponent_index].index].mug_shot_image_data, gOpponents[gCurrent_race.opponent_list[gOpponent_index].index].mug_shot_image_data_length); } // IDA: void __cdecl DrawSceneyMappyInfoVieweyThing() diff --git a/src/DETHRACE/common/replay.c b/src/DETHRACE/common/replay.c index f49f3f45..be777376 100644 --- a/src/DETHRACE/common/replay.c +++ b/src/DETHRACE/common/replay.c @@ -91,7 +91,7 @@ void DoZappyActionReplayHeadups(int pSpecial_zappy_bastard) { // IDA: void __cdecl DoActionReplayHeadups() void DoActionReplayHeadups() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall MoveReplayBuffer(tS32 pMove_amount@) @@ -123,7 +123,7 @@ void MoveToStartOfReplay() { // IDA: void __cdecl ToggleReplay() void ToggleReplay() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall ReverseSound(tS3_effect_tag pEffect_index@, tS3_sound_tag pSound_tag@) @@ -153,13 +153,13 @@ void PollActionReplayControls(tU32 pFrame_period) { static int psuedo_mouse_keys[8]; static tRectangle mouse_areas[2][8]; LOG_TRACE("(%d)", pFrame_period); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl CheckReplayTurnOn() void CheckReplayTurnOn() { LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl InitializeActionReplay() diff --git a/src/DETHRACE/common/skidmark.c b/src/DETHRACE/common/skidmark.c index 1415d851..afbb6eda 100644 --- a/src/DETHRACE/common/skidmark.c +++ b/src/DETHRACE/common/skidmark.c @@ -166,7 +166,7 @@ void SkidMark(tCar_spec* pCar, int pWheel_num) { br_material* material; LOG_TRACE("(%p, %d)", pCar, pWheel_num); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall InitCarSkidStuff(tCar_spec *pCar@) @@ -180,7 +180,7 @@ void InitCarSkidStuff(tCar_spec* pCar) { void SkidsPerFrame() { int skid; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl RemoveMaterialsFromSkidmarks() diff --git a/src/DETHRACE/common/sound.c b/src/DETHRACE/common/sound.c index c29817ab..6ef1b96c 100644 --- a/src/DETHRACE/common/sound.c +++ b/src/DETHRACE/common/sound.c @@ -83,6 +83,7 @@ tS3_sound_tag DRS3StartSound(tS3_outlet_ptr pOutlet, tS3_sound_id pSound) { // IDA: tS3_sound_tag __usercall DRS3StartSoundNoPiping@(tS3_outlet_ptr pOutlet@, tS3_sound_id pSound@) tS3_sound_tag DRS3StartSoundNoPiping(tS3_outlet_ptr pOutlet, tS3_sound_id pSound) { STUB(); + return 0; } // IDA: tS3_sound_tag __usercall DRS3StartSound2@(tS3_outlet_ptr pOutlet@, tS3_sound_id pSound@, tS3_repeats pRepeats@, tS3_volume pLVolume@, tS3_volume pRVolume, tS3_pitch pPitch, tS3_speed pSpeed) @@ -178,12 +179,14 @@ int DRS3OverallVolume(tS3_volume pVolume) { // IDA: int __usercall DRS3StopOutletSound@(tS3_outlet_ptr pOutlet@) int DRS3StopOutletSound(tS3_outlet_ptr pOutlet) { STUB(); + return 0; } // IDA: int __cdecl DRS3StopAllOutletSounds() int DRS3StopAllOutletSounds() { LOG_TRACE("()"); STUB(); + return 0; } // IDA: void __cdecl ToggleSoundEnable() @@ -195,7 +198,7 @@ void ToggleSoundEnable() { // IDA: void __cdecl SoundService() void SoundService() { br_matrix34 mat; - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl InitSoundSources() @@ -252,7 +255,7 @@ void MungeEngineNoise() { int stop_all; int type_of_engine_noise; tS3_sound_id engine_noise; - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl SetSoundVolumes() diff --git a/src/DETHRACE/common/spark.c b/src/DETHRACE/common/spark.c index 2a98a8ca..cdebb85e 100644 --- a/src/DETHRACE/common/spark.c +++ b/src/DETHRACE/common/spark.c @@ -134,7 +134,7 @@ void RenderSparks(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_ac br_vector3 new_pos; br_scalar ts; LOG_TRACE("(%p, %p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pCamera_to_world, pTime); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall CreateSingleSpark(tCar_spec *pCar@, br_vector3 *pPos@, br_vector3 *pVel@) @@ -155,7 +155,7 @@ void CreateSparks(br_vector3* pos, br_vector3* v, br_vector3* pForce, br_scalar int num; int i; LOG_TRACE("(%p, %p, %p, %f, %p)", pos, v, pForce, sparkiness, pCar); - NOT_IMPLEMENTED(); + STUB(); } // IDA: void __usercall CreateSparkShower(br_vector3 *pos@, br_vector3 *v@, br_vector3 *pForce@, tCar_spec *pCar1@, tCar_spec *pCar2) @@ -259,7 +259,7 @@ void MungeShrapnel(tU32 pTime) { br_matrix34* mat; br_scalar ts; LOG_TRACE("(%d)", pTime); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall DrMatrix34Rotate(br_matrix34 *mat@, br_angle r@, br_vector3 *a@) @@ -380,7 +380,7 @@ void GenerateContinuousSmoke(tCar_spec* pCar, int wheel, tU32 pTime) { int colour; LOG_TRACE("(%p, %d, %d)", pCar, wheel, pTime); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl DustRotate() @@ -399,7 +399,7 @@ void RenderSmoke(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_act tU32 seed; tU32 not_lonely; LOG_TRACE("(%p, %p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pCamera_to_world, pTime); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall CreatePuffOfSmoke(br_vector3 *pos@, br_vector3 *v@, br_scalar strength, br_scalar pDecay_factor, int pType, tCar_spec *pC) @@ -790,7 +790,7 @@ void MungeSplash(tU32 pTime) { void RenderSplashes() { int i; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall GetSmokeShadeTables(FILE *f@) diff --git a/src/DETHRACE/common/structur.c b/src/DETHRACE/common/structur.c index 2709f49d..94ddf80b 100644 --- a/src/DETHRACE/common/structur.c +++ b/src/DETHRACE/common/structur.c @@ -113,7 +113,7 @@ void CheckCheckpoints() { int car_index; tNet_game_player_info* net_player; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __cdecl TotalRepair() diff --git a/src/DETHRACE/common/world.c b/src/DETHRACE/common/world.c index d8a3efab..e14cbf80 100644 --- a/src/DETHRACE/common/world.c +++ b/src/DETHRACE/common/world.c @@ -2563,7 +2563,7 @@ void FunkThoseTronics() { float f_time_diff; br_pixelmap* old_colour_map; LOG_TRACE("()"); - SILENT_STUB(); + STUB_ONCE(); } // IDA: void __usercall LollipopizeActor(br_actor *pSubject_actor@, br_matrix34 *ref_to_world@, tLollipop_mode pWhich_axis@) diff --git a/src/DETHRACE/constants.h b/src/DETHRACE/constants.h index 403fee42..15e90aaa 100644 --- a/src/DETHRACE/constants.h +++ b/src/DETHRACE/constants.h @@ -294,4 +294,10 @@ typedef enum keymapcodes { #define OPPONENT_COUNT 0 +#define WORLD_SCALE 6.9000001 + +#define DOUBLESIDED_FLAG_COLOR_MAP (br_pixelmap*)12345 + +#define SLOBYTE(x) (*((signed char*)&(x))) + #endif \ No newline at end of file diff --git a/src/harness/harness_trace.h b/src/harness/harness_trace.h index 3323577c..cb75976e 100644 --- a/src/harness/harness_trace.h +++ b/src/harness/harness_trace.h @@ -54,12 +54,10 @@ void debug_print_matrix34(const char* fmt, const char* fn, char* name, br_matrix debug_printf("\033[0;31m[PANIC] %s ", __FUNCTION__, "%s", "code path not expected"); \ exit(1); -#define STUB() \ - if (harness_debug_level >= 5) { \ - debug_printf("\033[0;31m[WARN] %s ", __FUNCTION__, "%s", "stubbed"); \ - } +#define STUB() \ + debug_printf("\033[0;31m[WARN] %s ", __FUNCTION__, "%s", "stubbed"); -#define SILENT_STUB() \ +#define STUB_ONCE() \ static int stub_printed = 0; \ if (!stub_printed) { \ debug_printf("\033[0;31m[WARN] %s ", __FUNCTION__, "%s", "stubbed"); \