diff --git a/TOMB4/game/bike.cpp b/TOMB4/game/bike.cpp index c6edd220..c46ca0d3 100644 --- a/TOMB4/game/bike.cpp +++ b/TOMB4/game/bike.cpp @@ -1308,7 +1308,7 @@ long BikeDynamics(ITEM_INFO* item) front_right2 = TestHeight(item, 500, 128, &frPos2); if (front_right2 < frPos.y - 256) - shift2 = abs(DoShift(item, &frPos2, &frPos) << 2); //using the ABS macro gives wrong results?? + shift2 = -abs(DoShift(item, &frPos2, &frPos) << 2); front_mid2 = TestHeight(item, -500, 0, &fmPos2); diff --git a/TOMB4/game/jeep.cpp b/TOMB4/game/jeep.cpp index 6f29183c..5159a585 100644 --- a/TOMB4/game/jeep.cpp +++ b/TOMB4/game/jeep.cpp @@ -21,6 +21,7 @@ #include "effects.h" #include "traps.h" #include "debris.h" +#include "bike.h" void InitialiseJeep(short item_number) { @@ -1236,6 +1237,441 @@ void JeepCollideStaticObjects(long x, long y, long z, short room_number, long he } } +long JeepDynamics(ITEM_INFO* item) +{ + JEEPINFO* jeep; + FLOOR_INFO* floor; + PHD_VECTOR pos, newPos; + PHD_VECTOR flPos, frPos, blPos, brPos, fmPos, flPos2, frPos2, blPos2, brPos2, fmPos2; + long front_left, front_right, back_left, back_right, front_mid, front_left2, front_right2, back_left2, back_right2, front_mid2; + long h, speed, shift, shift2, anim, dx, dz; + short ang, ang2, vel, room_number; + + dont_exit_jeep = 0; + jeep = (JEEPINFO*)item->data; + front_left = TestHeight(item, 550, -256, &flPos); + front_right = TestHeight(item, 550, 256, &frPos); + back_left = TestHeight(item, -600, -256, &blPos); + back_right = TestHeight(item, -600, 256, &brPos); + front_mid = TestHeight(item, -600, 0, &fmPos); + pos.x = item->pos.x_pos; + pos.y = item->pos.y_pos; + pos.z = item->pos.z_pos; + + if (blPos.y > back_left) + blPos.y = back_left; + + if (brPos.y > back_right) + brPos.y = back_right; + + if (flPos.y > front_left) + flPos.y = front_left; + + if (frPos.y > front_right) + frPos.y = front_right; + + if (fmPos.y > front_mid) + fmPos.y = front_mid; + + if (item->pos.y_pos <= item->floor - 8) + { + if (jeep->turn_rate < -91) + jeep->turn_rate += 91; + else if (jeep->turn_rate > 91) + jeep->turn_rate -= 91; + else + jeep->turn_rate = 0; + + item->pos.y_rot += short(jeep->turn_rate + jeep->extra_rotation); + jeep->move_angle += (item->pos.y_rot - jeep->move_angle) >> 5; + } + else + { + if (jeep->turn_rate < -182) + jeep->turn_rate += 182; + else if (jeep->turn_rate > 182) + jeep->turn_rate -= 182; + else + jeep->turn_rate = 0; + + item->pos.y_rot += short(jeep->turn_rate + jeep->extra_rotation); + ang = item->pos.y_rot - jeep->move_angle; + vel = short(728 - ((3 * jeep->velocity) >> 11)); + + if (!(input & IN_ACTION) && jeep->velocity > 0) + vel -= vel >> 2; + + if (ang < -273) + { + if (ang < -13650) + { + item->pos.y_pos -= 41; + item->fallspeed = -6 - (GetRandomControl() & 3); + jeep->turn_rate = 0; + jeep->velocity -= jeep->velocity >> 3; + } + + if (ang < -16380) + jeep->move_angle = item->pos.y_rot + 0x3FFC; + else + jeep->move_angle -= vel; + } + else if (ang > 273) + { + if (ang > 13650) + { + item->pos.y_pos -= 41; + item->fallspeed = -6 - (GetRandomControl() & 3); + jeep->turn_rate = 0; + jeep->velocity -= jeep->velocity >> 3; + } + + if (ang > 16380) + jeep->move_angle = item->pos.y_rot - 0x3FFC; + else + jeep->move_angle += vel; + } + else + jeep->move_angle = item->pos.y_rot; + } + + room_number = item->room_number; + floor = GetFloor(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number); + h = GetHeight(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos); + + if (item->pos.y_pos < h) + speed = item->speed; + else + speed = (item->speed * phd_cos(item->pos.x_rot)) >> 14; + + item->pos.x_pos += (speed * phd_sin(jeep->move_angle)) >> 14; + item->pos.z_pos += (speed * phd_cos(jeep->move_angle)) >> 14; + + if (item->pos.y_pos >= h) + { + ang = (100 * phd_sin(item->pos.x_rot)) >> 14; + + if (ABS(ang) > 16) + { + dont_exit_jeep = 1; + + if (ang < 0) + jeep->velocity += SQUARE(ang + 16) >> 1; + else + jeep->velocity -= SQUARE(ang - 16) >> 1; + } + + ang = (128 * phd_sin(item->pos.z_rot)) >> 14; + + if (ABS(ang) > 32) + { + dont_exit_jeep = 1; + + if (ang < 0) + ang2 = item->pos.y_rot - 0x4000; + else + ang2 = item->pos.y_rot + 0x4000; + + item->pos.x_pos += ((ABS(ang) - 24) * phd_sin(ang2)) >> 14; + item->pos.z_pos += ((ABS(ang) - 24) * phd_cos(ang2)) >> 14; + } + } + + if (jeep->velocity > 0x8000) + jeep->velocity = 0x8000; + else if (jeep->velocity < -0x4000) + jeep->velocity = -0x4000; + + newPos.x = item->pos.x_pos; + newPos.z = item->pos.z_pos; + + if (!(item->flags & IFL_INVISIBLE)) + { + JeepBaddieCollision(item); + JeepCollideStaticObjects(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, item->room_number, 512); + } + + shift = 0; + shift2 = 0; + front_left2 = TestHeight(item, 550, -256, &flPos2); + + if (front_left2 < flPos.y - 256) + shift = abs(DoShift(item, &flPos2, &flPos) << 2); + + back_left2 = TestHeight(item, -600, -256, &blPos2); + + if (back_left2 < blPos.y - 256) + { + if (shift) + shift += abs(DoShift(item, &blPos2, &blPos) << 2); + else + shift = abs(DoShift(item, &blPos2, &blPos) << 2); + } + + front_right2 = TestHeight(item, 550, 256, &frPos2); + + if (front_right2 < frPos.y - 256) + shift2 = -abs(DoShift(item, &frPos2, &frPos) << 2); + + front_mid2 = TestHeight(item, -600, 0, &fmPos2); + + if (front_mid2 < fmPos.y - 256) + DoShift(item, &fmPos2, &fmPos); + + back_right2 = TestHeight(item, -600, 256, &brPos2); + + if (back_right2 < brPos.y - 256) + { + if (shift2) + shift2 -= abs(DoShift(item, &brPos2, &brPos) << 2); + else + shift2 = abs(DoShift(item, &brPos2, &brPos) << 2); + } + + if (!shift) + shift = shift2; + + room_number = item->room_number; + floor = GetFloor(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number); + h = GetHeight(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos); + + if (h < item->pos.y_pos - 256) + DoShift(item, (PHD_VECTOR*)&item->pos, &pos); + + if (!jeep->velocity) + shift = 0; + + jeep->rot_thing = short((jeep->rot_thing + shift) >> 1); + + if (ABS(jeep->rot_thing) < 2) + jeep->rot_thing = 0; + + if (ABS(jeep->rot_thing - jeep->extra_rotation) < 4) + jeep->extra_rotation = jeep->rot_thing; + else + jeep->extra_rotation += (jeep->rot_thing - jeep->extra_rotation) >> 2; + + anim = GetCollisionAnim(item, &newPos, 0); + + if (anim) + { + dx = item->pos.x_pos - pos.x; + dz = item->pos.z_pos - pos.z; + speed = (dx * phd_sin(jeep->move_angle) + dz * phd_cos(jeep->move_angle)) >> 14; + speed <<= 8; + + if (&items[lara.vehicle] == item && jeep->velocity == 0x8000 && speed < 0x7FF6) + { + lara_item->hit_points -= short((0x8000 - speed) >> 7); + lara_item->hit_status = 1; + } + + if (jeep->velocity > 0 && speed < jeep->velocity) + jeep->velocity = speed < 0 ? 0 : speed; + else if (jeep->velocity < 0 && speed > jeep->velocity) + jeep->velocity = speed > 0 ? 0 : speed; + + if (jeep->velocity < -0x4000) + jeep->velocity = -0x4000; + } + + return anim; +} + +void JeepControl(short item_number) +{ + ITEM_INFO* item; + JEEPINFO* jeep; + FLOOR_INFO* floor; + PHD_VECTOR flPos, frPos, fmPos; + PHD_VECTOR pos; + long front_left, front_right, front_mid; + long hitWall, h, driving, killed, pitch, oldY, hdiff, smokeVel; + short room_number, wheelRot, xRot, zRot; + static uchar ExhaustSmokeVel; + + driving = -1; + killed = 0; +#ifdef GENERAL_FIXES + pitch = 0; +#endif + item = &items[item_number]; + jeep = (JEEPINFO*)item->data; + hitWall = JeepDynamics(item); + room_number = item->room_number; + floor = GetFloor(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number); + GetHeight(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos); + GetCeiling(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos); + front_left = TestHeight(item, 550, -256, &flPos); + front_right = TestHeight(item, 550, 256, &frPos); + front_mid = TestHeight(item, -600, 0, &fmPos); + room_number = item->room_number; + floor = GetFloor(item->pos.x_pos, item->pos.y_pos, item->pos.z_pos, &room_number); + h = GetHeight(floor, item->pos.x_pos, item->pos.y_pos, item->pos.z_pos); + TestTriggers(trigger_index, 1, 0); + TestTriggers(trigger_index, 0, 0); + + if (lara_item->hit_points <= 0) + { + killed = 1; + input &= ~(IN_FORWARD | IN_BACK | IN_LEFT | IN_RIGHT | IN_LSTEP | IN_RSTEP); + } + + if (jeep->flags) + hitWall = 0; + else + { + if (lara_item->current_anim_state != 9) + driving = UserControl(item, h, &pitch); + else + { + driving = -1; + hitWall = 0; + } + } + + if (jeep->velocity || jeep->unused1) + { + jeep->pitch2 = pitch; + + if (jeep->pitch2 < -0x8000) + jeep->pitch2 = -0x8000; + else if (jeep->pitch2 > 0xA000) + jeep->pitch2 = 0xA000; + + SoundEffect(SFX_JEEP_MOVE, &item->pos, (jeep->pitch2 << 8) + (SFX_SETPITCH | 0x1000000)); + } + else + { + if (driving != -1) + SoundEffect(SFX_JEEP_IDLE, &item->pos, SFX_DEFAULT); + + jeep->pitch2 = 0; + } + + item->floor = h; + wheelRot = short(jeep->velocity >> 2); + jeep->right_front_wheelrot -= wheelRot; + jeep->left_front_wheelrot -= wheelRot; + jeep->left_back_wheelrot -= wheelRot; + jeep->right_back_wheelrot -= wheelRot; + oldY = item->pos.y_pos; + item->fallspeed = (short)DoDynamics(h, item->fallspeed, &item->pos.y_pos, 0); + hdiff = (frPos.y + flPos.y) >> 1; + + if (fmPos.y < front_mid) + { + if (hdiff < (front_left + front_right) >> 1) + { + xRot = (short)phd_atan(137, oldY - item->pos.y_pos); + + if (jeep->velocity < 0) + xRot = -xRot; + } + else + xRot = (short)phd_atan(550, item->pos.y_pos - hdiff); + } + else + { + if (hdiff < (front_left + front_right) >> 1) + xRot = (short)phd_atan(550, front_mid - item->pos.y_pos); + else + xRot = (short)phd_atan(1100, front_mid - hdiff); + } + + zRot = (short)phd_atan(350, hdiff - flPos.y); + item->pos.x_rot += (xRot - item->pos.x_rot) >> 2; + item->pos.z_rot += (zRot - item->pos.z_rot) >> 2; + + if (!(jeep->flags & 0x80)) + { + if (room_number != item->room_number) + { + ItemNewRoom(lara.vehicle, room_number); + ItemNewRoom(lara.item_number, room_number); + } + + lara_item->pos.x_pos = item->pos.x_pos; + lara_item->pos.y_pos = item->pos.y_pos; + lara_item->pos.z_pos = item->pos.z_pos; + lara_item->pos.x_rot = item->pos.x_rot; + lara_item->pos.y_rot = item->pos.y_rot; + lara_item->pos.z_rot = item->pos.z_rot; + AnimateJeep(item, hitWall, killed); + AnimateItem(lara_item); + item->anim_number = objects[JEEP].anim_index + lara_item->anim_number - objects[VEHICLE_EXTRA].anim_index; + item->frame_number = lara_item->frame_number + anims[item->anim_number].frame_base - anims[lara_item->anim_number].frame_base; + camera.target_elevation = -5460; + camera.target_distance = 2048; + + if (!jeep->gear) + jeep->camera_angle -= jeep->camera_angle >> 3; + else if (jeep->gear == 1) + jeep->camera_angle += (0x7F42 - jeep->camera_angle) >> 3; + + camera.target_angle = (short)jeep->camera_angle; + + if (jeep->flags & 0x40 && item->pos.y_pos == item->floor) + { + lara_item->mesh_bits = 0; + lara_item->hit_points = 0; + lara_item->flags |= IFL_INVISIBLE; + JeepExplode(item); + return; + } + } + + if (lara_item->current_anim_state == 9 || lara_item->current_anim_state == 10) + ExhaustSmokeVel = 0; + { + pos.x = 80; + pos.y = 0; + pos.z = -500; + GetJointAbsPosition(item, &pos, 11); + + if (item->speed > 32) + { + if (item->speed < 64) + TriggerExhaustSmoke(pos.x, pos.y, pos.z, item->pos.y_rot + 0x8000, 64 - item->speed, 1); + } + else + { + if (ExhaustSmokeVel < 16) + { + smokeVel = ((GetRandomControl() & 7) + (GetRandomControl() & 0x10) + 2 * ExhaustSmokeVel) << 6; + ExhaustSmokeVel++; + } + else if (GetRandomControl() & 3) + smokeVel = 0; + else + smokeVel = ((GetRandomControl() & 0xF) + (GetRandomControl() & 0x10)) << 6; + + TriggerExhaustSmoke(pos.x, pos.y, pos.z, item->pos.y_rot + 0x8000, smokeVel, 0); + } + } + + JeepCheckGetOut(); +} + +void JeepStart(ITEM_INFO* item, ITEM_INFO* l) +{ + JEEPINFO* jeep; + + jeep = (JEEPINFO*)item->data; + lara.gun_status = LG_HANDS_BUSY; + lara.hit_direction = -1; + l->current_anim_state = 0; + l->goal_anim_state = 0; + l->anim_number = objects[VEHICLE_EXTRA].anim_index + 14; + l->frame_number = anims[l->anim_number].frame_base; + item->anim_number = l->anim_number + objects[JEEP].anim_index - objects[VEHICLE_EXTRA].anim_index; + item->frame_number = l->frame_number + anims[item->anim_number].frame_base - anims[l->anim_number].frame_base; + item->flags |= IFL_TRIGGERED; + item->hit_points = 1; + jeep->unused1 = 0; + jeep->gear = 0; +} + void inject_jeep(bool replace) { INJECT(0x00466F40, InitialiseJeep, replace); @@ -1253,4 +1689,7 @@ void inject_jeep(bool replace) INJECT(0x00469870, UserControl, replace); INJECT(0x004687E0, JeepBaddieCollision, replace); INJECT(0x004684D0, JeepCollideStaticObjects, replace); + INJECT(0x00467CF0, JeepDynamics, replace); + INJECT(0x00467380, JeepControl, replace); + INJECT(0x0046A620, JeepStart, replace); } diff --git a/TOMB4/game/jeep.h b/TOMB4/game/jeep.h index 22b6cf70..88a0408d 100644 --- a/TOMB4/game/jeep.h +++ b/TOMB4/game/jeep.h @@ -11,6 +11,6 @@ long GetCollisionAnim(ITEM_INFO* item, PHD_VECTOR* pos, BIKEINFO* vehicle); long DoShift(ITEM_INFO* item, PHD_VECTOR* newPos, PHD_VECTOR* oldPos); void JeepBaddieCollision(ITEM_INFO* item); void JeepCollideStaticObjects(long x, long y, long z, short room_number, long height); - -#define JeepControl ( (void(__cdecl*)(short)) 0x00467380 ) -#define JeepStart ( (void(__cdecl*)(ITEM_INFO*, ITEM_INFO*)) 0x0046A620 ) +long JeepDynamics(ITEM_INFO* item); +void JeepControl(short item_number); +void JeepStart(ITEM_INFO* item, ITEM_INFO* l); diff --git a/TOMB4/global/progress.txt b/TOMB4/global/progress.txt index c9a67cf1..bf97e9e8 100644 --- a/TOMB4/global/progress.txt +++ b/TOMB4/global/progress.txt @@ -593,12 +593,12 @@ x for functions decompiled but not injected, for one reason or another. 0x00466FA0 + JeepCollision 0x004671B0 + GetOnJeep 0x00467330 + DrawJeepExtras -0x00467380 JeepControl +0x00467380 + JeepControl 0x00467920 + TriggerExhaustSmoke 0x00467AC0 + JeepExplode 0x00467B90 + JeepCheckGetOut 0x00467C60 + DoDynamics -0x00467CF0 JeepDynamics +0x00467CF0 + JeepDynamics 0x004684D0 + JeepCollideStaticObjects 0x004687E0 + JeepBaddieCollision 0x00468AE0 + GetCollisionAnim @@ -609,7 +609,7 @@ x for functions decompiled but not injected, for one reason or another. 0x00469B90 InitialiseEnemyJeep 0x00469C20 EnemyJeepControl 0x0046A4D0 JeepFireGrenade -0x0046A620 JeepStart +0x0046A620 + JeepStart game/lara.cpp diff --git a/TOMB4/specific/drawroom.cpp b/TOMB4/specific/drawroom.cpp index 398e80f4..90d94116 100644 --- a/TOMB4/specific/drawroom.cpp +++ b/TOMB4/specific/drawroom.cpp @@ -670,11 +670,7 @@ void ProcessMeshData(long num_meshes) if (mesh->nNorms > 0) { -#ifdef GENERAL_FIXES - mesh->Normals = (D3DVECTOR*)game_malloc((mesh->nNorms + mesh->nVerts) * sizeof(D3DVECTOR)); -#else mesh->Normals = (D3DVECTOR*)game_malloc(mesh->nNorms * sizeof(D3DVECTOR)); -#endif for (int j = 0; j < mesh->nVerts; j++) { @@ -686,22 +682,13 @@ void ProcessMeshData(long num_meshes) mesh->Normals[j].x = vtx[j].nx; mesh->Normals[j].y = vtx[j].ny; mesh->Normals[j].z = vtx[j].nz; -#ifdef GENERAL_FIXES - mesh->Normals[mesh->nNorms + j].x = vtx[j].x; - mesh->Normals[mesh->nNorms + j].y = vtx[j].y; - mesh->Normals[mesh->nNorms + j].z = vtx[j].z; -#endif } mesh->prelight = NULL; } else { -#ifdef GENERAL_FIXES - mesh->Normals = (D3DVECTOR*)game_malloc(mesh->nVerts * sizeof(D3DVECTOR)); -#else mesh->Normals = NULL; -#endif mesh->prelight = (long*)game_malloc(4 * mesh->nVerts); for (int j = 0; j < mesh->nVerts; j++) @@ -709,11 +696,6 @@ void ProcessMeshData(long num_meshes) c = 255 - (mesh_ptr[0] >> 5); mesh->prelight[j] = RGBONLY(c, c, c); mesh_ptr++; -#ifdef GENERAL_FIXES - mesh->Normals[j].x = vtx[j].x; - mesh->Normals[j].y = vtx[j].y; - mesh->Normals[j].z = vtx[j].z; -#endif } } diff --git a/TOMB4/specific/output.cpp b/TOMB4/specific/output.cpp index 56e5c627..a5100340 100644 --- a/TOMB4/specific/output.cpp +++ b/TOMB4/specific/output.cpp @@ -374,6 +374,7 @@ void ProjectTrainVerts(short nVerts, D3DTLVERTEX* v, short* clip, long x) void PrelightVerts(long nVerts, D3DTLVERTEX* v, MESH_DATA* mesh) { #ifdef GENERAL_FIXES + D3DVERTEX* vtx; DYNAMIC* dptr; PHD_VECTOR t, d, u, w; float fVal; @@ -391,6 +392,7 @@ void PrelightVerts(long nVerts, D3DTLVERTEX* v, MESH_DATA* mesh) t.x += w2v_matrix[M03]; t.y += w2v_matrix[M13]; t.z += w2v_matrix[M23]; + mesh->SourceVB->Lock(DDLOCK_READONLY, (void**)&vtx, NULL); #endif for (int i = 0; i < nVerts; i++) @@ -411,8 +413,8 @@ void PrelightVerts(long nVerts, D3DTLVERTEX* v, MESH_DATA* mesh) d.z = dptr->z - t.z; ApplyMatrix(w2v_matrix, &d, &w); ApplyTransposeMatrix(phd_mxptr, &w, &u); - fVal = sqrt(SQUARE(u.x - mesh->Normals[i].x) + SQUARE(u.y - mesh->Normals[i].y) + SQUARE(u.z - mesh->Normals[i].z)); - + fVal = sqrt(SQUARE(u.x - vtx[i].x) + SQUARE(u.y - vtx[i].y) + SQUARE(u.z - vtx[i].z)) * 1.7F; + if (fVal <= dptr->falloff) { fVal = (dptr->falloff - fVal) / dptr->falloff; @@ -444,6 +446,10 @@ void PrelightVerts(long nVerts, D3DTLVERTEX* v, MESH_DATA* mesh) CalcColorSplit(v->color, &v->color); v++; } + +#ifdef GENERAL_FIXES + mesh->SourceVB->Unlock(); +#endif } void _InsertRoom(ROOM_INFO* r)