Add action replay (#230)
* Add replay * Hide action replay behind --enable-replay * Update src/DETHRACE/dr_types.h * Compy OS_ALlocateACtionReplayBuffer from linux to macos * Add missing macro * Fix LengthOfSession for smudges * Implement PipeInstantUnSmudge
This commit is contained in:
parent
e1cbc20465
commit
5eebedfdc9
|
|
@ -22,6 +22,9 @@ br_uint_32 BrActorEnum(br_actor* parent, br_actor_enum_cbfn* callback, void* arg
|
|||
br_bounds* BrActorToBounds(br_bounds* b, br_actor* ap);
|
||||
br_uint_16 BrActorToActorMatrix34(br_matrix34* m, br_actor* a, br_actor* b);
|
||||
|
||||
void BrLightEnable(br_actor* l);
|
||||
void BrLightDisable(br_actor* l);
|
||||
|
||||
// BrAllocator
|
||||
br_allocator* BrAllocatorSet(br_allocator* newal);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
# Create object files so we can link them into the main binary and into tests without building twice.
|
||||
add_library(dethrace_obj OBJECT)
|
||||
|
||||
option(DETHRACE_REPLAY_DEBUG "Debug replay" OFF)
|
||||
|
||||
target_include_directories(dethrace_obj
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
|
|
@ -43,6 +45,10 @@ else()
|
|||
target_compile_definitions(dethrace_obj PRIVATE BR_ENDIAN_LITTLE=1)
|
||||
endif()
|
||||
|
||||
if(DETHRACE_REPLAY_DEBUG)
|
||||
target_compile_definitions(dethrace_obj PRIVATE DETHRACE_REPLAY_DEBUG)
|
||||
endif()
|
||||
|
||||
target_sources(dethrace_obj PRIVATE
|
||||
common/brucetrk.c
|
||||
common/brucetrk.h
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "oil.h"
|
||||
#include "opponent.h"
|
||||
#include "pd/sys.h"
|
||||
#include "pedestrn.h"
|
||||
#include "piping.h"
|
||||
#include "pratcam.h"
|
||||
#include "raycast.h"
|
||||
|
|
@ -34,8 +35,8 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int gDoing_physics;
|
||||
br_scalar gDt;
|
||||
int gDoing_physics = 0;
|
||||
br_scalar gDt = 0.f;
|
||||
// suffix added to avoid duplicate symbol
|
||||
int gCollision_detection_on__car = 1;
|
||||
// suffix added to avoid duplicate symbol
|
||||
|
|
@ -51,9 +52,9 @@ void (*ControlCar[6])(tCar_spec*, br_scalar) = {
|
|||
};
|
||||
int gControl__car = 3; // suffix added to avoid duplicate symbol
|
||||
int gFace_num__car = 1; // suffix added to avoid duplicate symbol
|
||||
br_angle gOld_yaw__car; // suffix added to avoid duplicate symbol
|
||||
br_angle gOld_zoom;
|
||||
br_vector3 gCamera_pos_before_collide;
|
||||
br_angle gOld_yaw__car = 0; // suffix added to avoid duplicate symbol
|
||||
br_angle gOld_zoom = 0;
|
||||
br_vector3 gCamera_pos_before_collide = { { 0 } };
|
||||
int gMetal_crunch_sound_id__car[5] = {
|
||||
// suffix added to avoid duplicate symbol
|
||||
5000,
|
||||
|
|
@ -69,24 +70,24 @@ int gMetal_scrape_sound_id__car[3] = {
|
|||
5012,
|
||||
};
|
||||
int gCar_car_collisions = 1;
|
||||
int gFreeze_mechanics;
|
||||
tU32 gLast_cunning_stunt;
|
||||
tU32 gWild_start;
|
||||
tU32 gQuite_wild_start;
|
||||
tU32 gQuite_wild_end;
|
||||
tU32 gOn_me_wheels_start;
|
||||
int gWoz_upside_down_at_all;
|
||||
tS3_sound_tag gSkid_tag[2];
|
||||
tCar_spec* gLast_car_to_skid[2];
|
||||
int gEliminate_faces;
|
||||
br_vector3 gZero_v__car; // suffix added to avoid duplicate symbol
|
||||
tU32 gSwitch_time;
|
||||
int gFreeze_mechanics = 0;
|
||||
tU32 gLast_cunning_stunt = 0;
|
||||
tU32 gWild_start = 0;
|
||||
tU32 gQuite_wild_start = 0;
|
||||
tU32 gQuite_wild_end = 0;
|
||||
tU32 gOn_me_wheels_start = 0;
|
||||
int gWoz_upside_down_at_all = 0;
|
||||
tS3_sound_tag gSkid_tag[2] = { 0, 0 };
|
||||
tCar_spec* gLast_car_to_skid[2] = { NULL, NULL};
|
||||
int gEliminate_faces = 0;
|
||||
br_vector3 gZero_v__car = { { 0 } }; // suffix added to avoid duplicate symbol
|
||||
tU32 gSwitch_time = 0;
|
||||
tSave_camera gSave_camera[2];
|
||||
tU32 gLast_mechanics_time;
|
||||
int gOpponent_viewing_mode;
|
||||
int gNet_player_to_view_index;
|
||||
int gDouble_pling_water;
|
||||
int gStop_opponents_moving;
|
||||
int gNet_player_to_view_index = -1;
|
||||
int gDouble_pling_water = 0;
|
||||
int gStop_opponents_moving = 0;
|
||||
float gDefensive_powerup_factor[6] = { 1.0f, 0.825f, 0.65f, 0.475f, 0.3f, 0.01f };
|
||||
float gOffensive_powerup_factor[6] = { 1.0f, 1.5f, 2.0f, 3.0f, 5.0f, 10.0f };
|
||||
float gEngine_powerup_factor[6] = { 1.3f, 1.9f, 2.5f, 3.2f, 4.0f, 10.0f };
|
||||
|
|
@ -4505,8 +4506,14 @@ void PutOpponentsInNeutral() {
|
|||
// IDA: void __cdecl SetPanningFieldOfView()
|
||||
void SetPanningFieldOfView() {
|
||||
br_camera* camera_ptr;
|
||||
static br_angle panning_angle = 0; // Added by DethRace
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
camera_ptr = gCamera->type_data;
|
||||
if (panning_angle == 0) {
|
||||
panning_angle = BrDegreeToAngle(gCamera_angle) * 0.7f;
|
||||
}
|
||||
camera_ptr->field_of_view = panning_angle;
|
||||
}
|
||||
|
||||
// IDA: void __usercall CheckDisablePlingMaterials(tCar_spec *pCar@<EAX>)
|
||||
|
|
@ -4515,7 +4522,23 @@ void CheckDisablePlingMaterials(tCar_spec* pCar) {
|
|||
br_scalar height;
|
||||
int i;
|
||||
LOG_TRACE("(%p)", pCar);
|
||||
STUB_ONCE();
|
||||
|
||||
height = 0.f;
|
||||
if (pCar->water_d == 10000.f) {
|
||||
DisablePlingMaterials();
|
||||
} else {
|
||||
mat = &pCar->car_master_actor->t.t.mat;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (mat->m[i][1] > 0.f) {
|
||||
height += pCar->bounds[0].max.v[i] * mat->m[i][1];
|
||||
} else {
|
||||
height += pCar->bounds[0].min.v[i] * mat->m[i][1];
|
||||
}
|
||||
}
|
||||
if (mat->m[3][1] / WORLD_SCALE + height < pCar->water_d) {
|
||||
DisablePlingMaterials();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall PositionExternalCamera(tCar_spec *c@<EAX>, tU32 pTime@<EDX>)
|
||||
|
|
@ -4537,23 +4560,25 @@ void PositionExternalCamera(tCar_spec* c, tU32 pTime) {
|
|||
} else {
|
||||
c = gCar_to_view;
|
||||
}
|
||||
if (c->car_master_actor->t.t.mat.m[3][0] <= 500.0) {
|
||||
if (c->car_master_actor->t.t.translate.t.v[0] <= 500.0) {
|
||||
if (gAction_replay_mode && gAction_replay_camera_mode) {
|
||||
LOG_PANIC("%d, %d", gAction_replay_mode, gAction_replay_camera_mode);
|
||||
if (gAction_replay_camera_mode == eAction_replay_action && (CheckDisablePlingMaterials(c), IncidentCam(c, pTime))) {
|
||||
SetPanningFieldOfView();
|
||||
EnablePlingMaterials();
|
||||
old_camera_mode = gAction_replay_camera_mode;
|
||||
} else {
|
||||
if (gAction_replay_camera_mode == eAction_replay_action) {
|
||||
CheckDisablePlingMaterials(c);
|
||||
SetPanningFieldOfView();
|
||||
if (gAction_replay_camera_mode != old_camera_mode) {
|
||||
SetUpPanningCamera(c);
|
||||
if (IncidentCam(c, pTime)) {
|
||||
SetPanningFieldOfView();
|
||||
EnablePlingMaterials();
|
||||
old_camera_mode = gAction_replay_camera_mode;
|
||||
return;
|
||||
}
|
||||
PanningExternalCamera(c, pTime);
|
||||
EnablePlingMaterials();
|
||||
}
|
||||
CheckDisablePlingMaterials(c);
|
||||
SetPanningFieldOfView();
|
||||
if (gAction_replay_camera_mode != old_camera_mode) {
|
||||
SetUpPanningCamera(c);
|
||||
old_camera_mode = gAction_replay_camera_mode;
|
||||
}
|
||||
PanningExternalCamera(c, pTime);
|
||||
EnablePlingMaterials();
|
||||
} else {
|
||||
NormalPositionExternalCamera(c, pTime);
|
||||
}
|
||||
|
|
@ -4567,16 +4592,25 @@ void CameraBugFix(tCar_spec* c, tU32 pTime) {
|
|||
br_matrix34* m2;
|
||||
br_vector3 tv;
|
||||
LOG_TRACE("(%p, %d)", c, pTime);
|
||||
STUB_ONCE();
|
||||
}
|
||||
|
||||
if (gAction_replay_mode && gAction_replay_camera_mode != eAction_replay_standard && gPed_actor != NULL && !gProgram_state.cockpit_on) {
|
||||
IncidentCam(c, pTime);
|
||||
}
|
||||
}
|
||||
// IDA: int __usercall PossibleRemoveNonCarFromWorld@<EAX>(br_actor *pActor@<EAX>)
|
||||
int PossibleRemoveNonCarFromWorld(br_actor* pActor) {
|
||||
tU8 cx;
|
||||
tU8 cz;
|
||||
tTrack_spec* track_spec;
|
||||
LOG_TRACE("(%p)", pActor);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
track_spec = &gProgram_state.track_spec;
|
||||
XZToColumnXZ(&cx, &cz, pActor->t.t.translate.t.v[0], pActor->t.t.translate.t.v[2], track_spec);
|
||||
if (track_spec->columns[cz][cx] == pActor->parent) {
|
||||
BrActorRemove(pActor);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: void __usercall PutNonCarBackInWorld(br_actor *pActor@<EAX>)
|
||||
|
|
@ -4585,7 +4619,10 @@ void PutNonCarBackInWorld(br_actor* pActor) {
|
|||
tU8 cz;
|
||||
tTrack_spec* track_spec;
|
||||
LOG_TRACE("(%p)", pActor);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
track_spec = &gProgram_state.track_spec;
|
||||
XZToColumnXZ(&cx, &cz, pActor->t.t.translate.t.v[0], pActor->t.t.translate.t.v[2], track_spec);
|
||||
BrActorAdd(track_spec->columns[cz][cx], pActor);
|
||||
}
|
||||
|
||||
// IDA: int __usercall IncidentCam@<EAX>(tCar_spec *c@<EAX>, tU32 pTime@<EDX>)
|
||||
|
|
@ -4599,17 +4636,125 @@ int IncidentCam(tCar_spec* c, tU32 pTime) {
|
|||
br_vector3 murderer_pos;
|
||||
br_scalar ts;
|
||||
tCar_spec* car2;
|
||||
static tU32 next_incident_time;
|
||||
static tU32 next_incident_time = 0;
|
||||
static tIncident_type type = eNo_incident;
|
||||
static float severity;
|
||||
static tIncident_info info;
|
||||
static int random;
|
||||
static int count;
|
||||
static int random = 1;
|
||||
static int count = 0;
|
||||
br_scalar temp;
|
||||
br_vector3 old_cam_pos;
|
||||
int removed;
|
||||
LOG_TRACE("(%p, %d)", c, pTime);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gPed_actor = NULL;
|
||||
m2 = &gCamera->t.t.mat;
|
||||
if (type == eNo_incident) {
|
||||
MoveCamToIncident(c, &type, &severity, &info, &next_incident_time);
|
||||
}
|
||||
if (type == eNo_incident) {
|
||||
return 0;
|
||||
}
|
||||
if (type == eIncident_ped) {
|
||||
BrVector3Copy(&old_cam_pos, &gCamera->t.t.translate.t);
|
||||
gPed_actor = info.ped_info.ped_actor;
|
||||
removed = PossibleRemoveNonCarFromWorld(info.ped_info.murderer_actor);
|
||||
BrMatrix34Mul(&mat, &gPed_actor->t.t.mat, &gPed_actor->parent->t.t.mat);
|
||||
info.ped_info.murderer_actor = c->car_master_actor;
|
||||
if (info.ped_info.murderer_actor != NULL) {
|
||||
BrVector3Copy(&murderer_pos, &c->pos);
|
||||
} else if (info.ped_info.murderer_actor->model != NULL) {
|
||||
BrVector3Add(&murderer_pos, &info.ped_info.murderer_actor->model->bounds.max, &info.ped_info.murderer_actor->model->bounds.min);
|
||||
BrVector3Scale(&murderer_pos, &murderer_pos, 0.5f);
|
||||
BrMatrix34ApplyP(&murderer_pos, &murderer_pos, &info.ped_info.murderer_actor->t.t.mat);
|
||||
} else {
|
||||
BrVector3Copy(&murderer_pos, &info.ped_info.murderer_actor->t.t.translate.t);
|
||||
}
|
||||
BrVector3Normalise(&vertical, (br_vector3*)mat.m[1]);
|
||||
BrVector3Scale(&vertical, &vertical, PedHeightFromActor(info.ped_info.ped_actor) / 2.f);
|
||||
BrVector3Accumulate((br_vector3*)mat.m[3], &vertical);
|
||||
if (next_incident_time > GetTotalTime() || !PipeSearchForwards()) {
|
||||
BrVector3Sub(&tv, (br_vector3*)mat.m[3], &murderer_pos);
|
||||
tv.v[1] = 0.f;
|
||||
BrVector3Normalise(&tv, &tv);
|
||||
BrVector3Set(&vertical, .0f, .4f, .0f);
|
||||
BrVector3Cross(&perp, &tv, &vertical);
|
||||
if (random) {
|
||||
BrVector3Negate(&perp, &perp);
|
||||
}
|
||||
if (PipeSearchForwards()) {
|
||||
BrVector3Accumulate(&perp, &tv);
|
||||
}
|
||||
BrVector3Add(&gCamera->t.t.translate.t, (br_vector3*)mat.m[3], &perp);
|
||||
CollideCamera2(&murderer_pos, &gCamera->t.t.translate.t, NULL, 1);
|
||||
}
|
||||
PointCamera((br_vector3*)mat.m[3], m2);
|
||||
BrVector3Sub(&tv, &gCamera->t.t.translate.t, &info.ped_info.murderer_actor->t.t.translate.t);
|
||||
ts = BrVector3LengthSquared(&tv);
|
||||
if (abs(GetTotalTime() - next_incident_time) > 2500) {
|
||||
type = eNo_incident;
|
||||
}
|
||||
if ((PipeSearchForwards() ? (next_incident_time < GetTotalTime()) : (next_incident_time > GetTotalTime()))
|
||||
&& (ts > 25.f || CheckForWall(&info.ped_info.murderer_actor->t.t.translate.t, &gCamera->t.t.translate.t))) {
|
||||
type = eNo_incident;
|
||||
}
|
||||
if (removed) {
|
||||
PutNonCarBackInWorld(info.ped_info.murderer_actor);
|
||||
}
|
||||
if (Vector3DistanceSquared((br_vector3*)mat.m[3], &gCamera->t.t.translate.t) < .15f * .15f) {
|
||||
BrVector3Copy(&gCamera->t.t.translate.t, &old_cam_pos);
|
||||
gPed_actor = NULL;
|
||||
return 0;
|
||||
}
|
||||
} else if (type == eIncident_car) {
|
||||
BrVector3Sub(&tv, &info.car_info.car->pos, &c->pos);
|
||||
tv.v[1] = 0.f;
|
||||
BrVector3Normalise(&tv, &tv);
|
||||
BrVector3Scale(&tv, &tv, 2.f);
|
||||
BrVector3Add(&gCamera->t.t.translate.t, &info.car_info.car->pos, &tv);
|
||||
gCamera->t.t.translate.t.v[1] += 1.f;
|
||||
CollideCamera2(&info.car_info.car->pos, &gCamera->t.t.translate.t, NULL, 1);
|
||||
PointCamera(&info.car_info.car->pos, m2);
|
||||
BrVector3Sub(&tv, &gCamera->t.t.translate.t, &c->pos);
|
||||
ts = BrVector3LengthSquared(&tv);
|
||||
if (abs(GetTotalTime() - next_incident_time) > 2500) {
|
||||
type = eNo_incident;
|
||||
}
|
||||
if ((PipeSearchForwards() ? (next_incident_time < GetTotalTime()) : (next_incident_time > GetTotalTime()))
|
||||
&& (ts > 25.f || CheckForWall(&c->pos, &gCamera->t.t.translate.t))) {
|
||||
type = eNo_incident;
|
||||
}
|
||||
} else if (type == eIncident_wall) {
|
||||
PointCamera(&c->pos, m2);
|
||||
BrVector3Sub(&tv, &gCamera->t.t.translate.t, &c->pos);
|
||||
ts = BrVector3LengthSquared(&tv);
|
||||
if (abs(GetTotalTime() - next_incident_time) > 2500) {
|
||||
type = eNo_incident;
|
||||
}
|
||||
if ((PipeSearchForwards() ? (next_incident_time < GetTotalTime()) : (next_incident_time > GetTotalTime()))
|
||||
&& (ts > 25.f || CheckForWall(&c->pos, &gCamera->t.t.translate.t))) {
|
||||
type = eNo_incident;
|
||||
}
|
||||
} else {
|
||||
type = eNo_incident;
|
||||
}
|
||||
if (type == eNo_incident) {
|
||||
if (count > 1) {
|
||||
SetUpPanningCamera(c);
|
||||
return 0;
|
||||
} else {
|
||||
count++;
|
||||
if (IncidentCam(c, pTime)) {
|
||||
count--;
|
||||
return 1;
|
||||
} else {
|
||||
count--;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: int __usercall MoveCamToIncident@<EAX>(tCar_spec *c@<EAX>, tIncident_type *type@<EDX>, float *severity@<EBX>, tIncident_info *info@<ECX>, tU32 *next_incident_time)
|
||||
|
|
@ -4628,7 +4773,67 @@ int MoveCamToIncident(tCar_spec* c, tIncident_type* type, float* severity, tInci
|
|||
br_vector3 perp;
|
||||
int test;
|
||||
LOG_TRACE("(%p, %p, %p, %p, %p)", c, type, severity, info, next_incident_time);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
test = 0;
|
||||
if (!GetNextIncident(-1, type, severity, info, next_incident_time)) {
|
||||
*type = eNo_incident;
|
||||
} else {
|
||||
if (abs(*next_incident_time) > 2500) {
|
||||
*type = eNo_incident;
|
||||
} else {
|
||||
t = *next_incident_time;
|
||||
for (test = 0; GetNextIncident(abs(t), &type2, &severity2, &info2, &next_incident_time2) && test <= 10 && abs(next_incident_time2) <= 3500; test++) {
|
||||
if ((*type != type2 && type2 < *type) || (*type == type2 && *severity <= severity2)) {
|
||||
*info = info2;
|
||||
*severity = severity2;
|
||||
*type = type2;
|
||||
*next_incident_time = next_incident_time2;
|
||||
}
|
||||
t = next_incident_time2;
|
||||
}
|
||||
if (abs(*next_incident_time) > 2500) {
|
||||
*type = eNo_incident;
|
||||
} else {
|
||||
if (*type == eIncident_wall) {
|
||||
if (*severity < 0.1f) {
|
||||
*type = eNo_incident;
|
||||
return 0;
|
||||
}
|
||||
ScanCarsPositions(c, &c->pos, 100000.f, -1, abs(*next_incident_time), &pos, &t);
|
||||
if (t == 0) {
|
||||
*type = eNo_incident;
|
||||
} else {
|
||||
BrVector3Sub(&tv, &pos, &c->pos);
|
||||
if (BrVector3LengthSquared(&tv) > 102.91955471539592f) {
|
||||
*type = eNo_incident;
|
||||
} else {
|
||||
BrVector3Sub(&tv, &pos, &info->wall_info.pos);
|
||||
BrVector3Normalise(&tv, &tv);
|
||||
BrVector3Scale(&tv, &tv, 2.f);
|
||||
BrVector3Set(&vertical, 0.f, 1.f, 0.f);
|
||||
BrVector3Cross(&perp, &vertical, &tv);
|
||||
BrVector3Add(&left, &pos, &tv);
|
||||
BrVector3Add(&left, &left, &perp);
|
||||
left.v[1] += 2.f;
|
||||
BrVector3Add(&right, &pos, &tv);
|
||||
BrVector3Sub(&right, &right, &perp);
|
||||
right.v[1] += 2.f;
|
||||
CollideCamera2(&pos, &left, NULL, 1);
|
||||
CollideCamera2(&pos, &right, NULL, 1);
|
||||
if (Vector3DistanceSquared(&left, &pos) <= Vector3DistanceSquared(&right, &pos)) {
|
||||
BrVector3Copy(&tv, &right);
|
||||
} else {
|
||||
BrVector3Copy(&tv, &left);
|
||||
}
|
||||
BrVector3Copy(&gCamera->t.t.translate.t, &tv);
|
||||
}
|
||||
}
|
||||
}
|
||||
*next_incident_time += GetTotalTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: void __usercall PanningExternalCamera(tCar_spec *c@<EAX>, tU32 pTime@<EDX>)
|
||||
|
|
@ -4637,9 +4842,22 @@ void PanningExternalCamera(tCar_spec* c, tU32 pTime) {
|
|||
br_matrix34* m1;
|
||||
br_vector3 tv;
|
||||
br_scalar ts;
|
||||
static int inside_camera_zone;
|
||||
static int inside_camera_zone = 1;
|
||||
LOG_TRACE("(%p, %d)", c, pTime);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
BrVector3Sub(&tv, &gCamera->t.t.translate.t, &c->pos);
|
||||
ts = BrVector3LengthSquared(&tv);
|
||||
if (ts > 102.91955471539592f || (gSwitch_time != 0 && (PipeSearchForwards() ? (gSwitch_time <= GetTotalTime()) : (gSwitch_time >= GetTotalTime())))) {
|
||||
if ((inside_camera_zone || ts > 205.83910943079184f) && (ts > 25.f || CheckForWall(&c->pos, &gCamera->t.t.translate.t))) {
|
||||
SetUpPanningCamera(c);
|
||||
inside_camera_zone = 0;
|
||||
}
|
||||
} else {
|
||||
inside_camera_zone = 1;
|
||||
}
|
||||
m1 = &c->car_master_actor->t.t.mat;
|
||||
m2 = &gCamera->t.t.mat;
|
||||
PointCameraAtCar(c, m1, m2);
|
||||
}
|
||||
|
||||
// IDA: int __usercall CheckForWall@<EAX>(br_vector3 *start@<EAX>, br_vector3 *end@<EDX>)
|
||||
|
|
@ -4649,7 +4867,10 @@ int CheckForWall(br_vector3* start, br_vector3* end) {
|
|||
br_vector3 normal;
|
||||
br_scalar d;
|
||||
LOG_TRACE("(%p, %p)", start, end);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
BrVector3Sub(&dir, end, start);
|
||||
FindFace(start, &dir, &normal, &d, &material);
|
||||
return d <= 1.f;
|
||||
}
|
||||
|
||||
// IDA: void __usercall SetUpPanningCamera(tCar_spec *c@<EAX>)
|
||||
|
|
@ -4672,7 +4893,64 @@ void SetUpPanningCamera(tCar_spec* c) {
|
|||
int left_score;
|
||||
int right_score;
|
||||
LOG_TRACE("(%p)", c);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
ScanCarsPositions(c, &c->pos, 411.6782f, -1, 5000, &car_centre, &t);
|
||||
BrVector3Sub(&dir, &car_centre, &c->pos);
|
||||
time_step = ((t > GetTotalTime()) ? t - GetTotalTime() : GetTotalTime() - t) * SRandomBetween(0.8f, 1.5f);
|
||||
if (BrVector3LengthSquared(&dir) >= .01f && t != 0) {
|
||||
ScanCarsPositions(c, &c->pos, 102.9196f, -1, time_step / 2, &pos, &t2);
|
||||
if (t2 == 0) {
|
||||
BrVector3Copy(&pos, &c->pos);
|
||||
}
|
||||
} else {
|
||||
BrVector3Negate(&dir, (br_vector3*)&c->car_master_actor->t.t.mat.m[2]);
|
||||
BrVector3Copy(&pos, &c->pos);
|
||||
time_step = 0;
|
||||
}
|
||||
BrVector3SetFloat(&tv, 0.f, 1.f, 0.f);
|
||||
BrVector3Cross(&perp, &tv, &dir);
|
||||
ts = BrVector3Length(&perp);
|
||||
if (ts >= .1f) {
|
||||
BrVector3Scale(&perp, &perp, 2.f / ts * SRandomBetween(0.3333333f, 1.f));
|
||||
BrVector3Set(&tv2, 0.f, 2 * SRandomBetween(0.3333333f, 1.f), 0.f);
|
||||
BrVector3Add(&tv, &pos, &tv2);
|
||||
BrVector3Add(&left, &tv, &perp);
|
||||
BrVector3Sub(&right, &tv, &perp);
|
||||
CollideCamera2(&pos, &left, NULL, 1);
|
||||
CollideCamera2(&pos, &right, NULL, 1);
|
||||
BrVector3Sub(&tv, &left, &pos);
|
||||
BrVector3Sub(&tv2, &right, &pos);
|
||||
if (BrVector3LengthSquared(&tv) + SRandomPosNeg(.01f) <= BrVector3LengthSquared(&tv2)) {
|
||||
BrVector3Copy(&gCamera->t.t.translate.t, &right);
|
||||
} else {
|
||||
BrVector3Copy(&gCamera->t.t.translate.t, &left);
|
||||
}
|
||||
if (t != 0 && CheckForWall(&c->pos, &gCamera->t.t.translate.t)) {
|
||||
ScanCarsPositions(c, &c->pos, 10000.f, -1, 1000, &tv, &time);
|
||||
CollideCamera2(&tv, &gCamera->t.t.translate.t, NULL, 1);
|
||||
}
|
||||
if (t != 0 && CheckForWall(&car_centre, &gCamera->t.t.translate.t)) {
|
||||
time_step = time_step / 16;
|
||||
BrVector3Copy(&tv, &pos);
|
||||
while (1) {
|
||||
ScanCarsPositions(c, &tv, 10000.f, abs(t2 - GetTotalTime()), time_step, &tv2, &time);
|
||||
t2 += (GetReplayDirection() ? 1 : -1) * time_step;
|
||||
BrVector3Copy(&tv, &tv2);
|
||||
if (CheckForWall(&tv, &gCamera->t.t.translate.t)) {
|
||||
break;
|
||||
}
|
||||
if (t2 >= GetTotalTime() + 5000) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
gSwitch_time = t2;
|
||||
} else {
|
||||
if (t == 0) {
|
||||
t = 5000;
|
||||
}
|
||||
gSwitch_time = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall SaveCameraPosition(int i@<EAX>)
|
||||
|
|
@ -4729,7 +5007,7 @@ void NormalPositionExternalCamera(tCar_spec* c, tU32 pTime) {
|
|||
swoop = gCountdown && c->pos.v[1] + 0.001f < gCamera_height;
|
||||
manual_swing = gOld_yaw__car != gCamera_yaw || swoop;
|
||||
manual_zoom = (double)gOld_zoom != gCamera_zoom;
|
||||
old_camera_pos = *(br_vector3*)&m1->m[3][0];
|
||||
BrVector3Copy(&old_camera_pos, &gCamera->t.t.translate.t);
|
||||
if (!gProgram_state.cockpit_on) {
|
||||
if (swoop) {
|
||||
gCamera_yaw = 0;
|
||||
|
|
@ -4737,10 +5015,7 @@ void NormalPositionExternalCamera(tCar_spec* c, tU32 pTime) {
|
|||
}
|
||||
if (fabs(c->speedo_speed) > 0.0006f && gCamera_mode > 0) {
|
||||
gCamera_mode = -1;
|
||||
gCamera_sign = m2->m[2][1] * c->direction.v[1]
|
||||
+ m2->m[2][2] * c->direction.v[2]
|
||||
+ m2->m[2][0] * c->direction.v[0]
|
||||
> 0.0;
|
||||
gCamera_sign = BrVector3Dot((br_vector3*)m2->m[2], &c->direction) > 0.0f;
|
||||
}
|
||||
if (c->frame_collision_flag && gCamera_mode != -2) {
|
||||
gCamera_mode = 1;
|
||||
|
|
@ -4748,34 +5023,32 @@ void NormalPositionExternalCamera(tCar_spec* c, tU32 pTime) {
|
|||
if (gCar_flying || gCamera_reset || gCamera_mode == -2) {
|
||||
gCamera_mode = 0;
|
||||
}
|
||||
d = sqrtf((float)gCamera_zoom) + 0.57971013f;
|
||||
d = sqrtf(gCamera_zoom) + 0.57971013f;
|
||||
if (!gCamera_mode || gCamera_mode == -1) {
|
||||
vn = c->direction;
|
||||
BrVector3Copy(&vn, &c->direction);
|
||||
MoveWithWheels(c, &vn, manual_swing);
|
||||
vn.v[1] = 0.0;
|
||||
vn.v[1] = 0.0f;
|
||||
BrVector3Normalise(&vn, &vn);
|
||||
if (gCar_flying) {
|
||||
gCamera_sign = 0;
|
||||
}
|
||||
SwingCamera(c, m2, m1, &vn, pTime);
|
||||
BrVector3Scale(&a, &vn, d);
|
||||
m1->m[3][0] = c->pos.v[0] - a.v[0];
|
||||
m1->m[3][1] = c->pos.v[1] - a.v[1];
|
||||
m1->m[3][2] = c->pos.v[2] - a.v[2];
|
||||
gView_direction = vn;
|
||||
BrVector3Sub(&gCamera->t.t.translate.t, &c->pos, &a);
|
||||
BrVector3Copy(&gView_direction, &vn);
|
||||
}
|
||||
if (gCamera_mode == 1) {
|
||||
if (manual_swing || manual_zoom) {
|
||||
old_camera_pos = gCamera_pos_before_collide;
|
||||
BrVector3Copy(&old_camera_pos, &gCamera_pos_before_collide);
|
||||
}
|
||||
BrVector3Sub(&a, &c->pos, &old_camera_pos);
|
||||
a.v[1] = 0.0;
|
||||
a.v[1] = 0.0f;
|
||||
if (manual_swing) {
|
||||
DrVector3RotateY(&a, (gCamera_sign == 0 ? 1 : -1) * (gCamera_yaw - gOld_yaw__car));
|
||||
gCamera_yaw = gOld_yaw__car;
|
||||
}
|
||||
BrVector3Normalise(&vn, &a);
|
||||
gView_direction = vn;
|
||||
BrVector3Copy(&gView_direction, &vn);
|
||||
BrVector3Scale(&vn, &vn, -d);
|
||||
BrVector3Accumulate(&a, &vn);
|
||||
dist = BrVector3Length(&a);
|
||||
|
|
@ -4784,28 +5057,24 @@ void NormalPositionExternalCamera(tCar_spec* c, tU32 pTime) {
|
|||
BrVector3Scale(&a, &a, (l - 1.f));
|
||||
BrVector3Accumulate(&vn, &a);
|
||||
}
|
||||
m1->m[3][0] = c->pos.v[0] + vn.v[0];
|
||||
m1->m[3][1] = c->pos.v[1] + vn.v[1];
|
||||
m1->m[3][2] = c->pos.v[2] + vn.v[2];
|
||||
BrVector3Add(&gCamera->t.t.translate.t, &c->pos, &vn);
|
||||
}
|
||||
height_inc = gCamera_zoom * gCamera_zoom + 0.3f;
|
||||
time = pTime * 0.001f;
|
||||
if (!gCamera_frozen || gAction_replay_mode) {
|
||||
if (pTime < 5000) {
|
||||
if (swoop) {
|
||||
if (time > 0.2) {
|
||||
time = 0.2;
|
||||
}
|
||||
gCamera_height -= time * 5.0;
|
||||
if (gCamera_height < c->pos.v[1]) {
|
||||
gCamera_height = c->pos.v[1];
|
||||
}
|
||||
} else {
|
||||
gCamera_height = time * 5.0 * c->pos.v[1] + gCamera_height;
|
||||
gCamera_height = gCamera_height / (time * 5.0 + 1.0);
|
||||
if (pTime >= 5000) {
|
||||
gCamera_height = c->pos.v[1];
|
||||
} else if (swoop) {
|
||||
if (time > 0.2f) {
|
||||
time = 0.2f;
|
||||
}
|
||||
gCamera_height -= time * 5.0f;
|
||||
if (gCamera_height < c->pos.v[1]) {
|
||||
gCamera_height = c->pos.v[1];
|
||||
}
|
||||
} else {
|
||||
gCamera_height = c->pos.v[1];
|
||||
gCamera_height = time * 5.0f * c->pos.v[1] + gCamera_height;
|
||||
gCamera_height = gCamera_height / (time * 5.0f + 1.0f);
|
||||
}
|
||||
}
|
||||
l = c->direction.v[1] * d;
|
||||
|
|
@ -4815,14 +5084,10 @@ void NormalPositionExternalCamera(tCar_spec* c, tU32 pTime) {
|
|||
}
|
||||
}
|
||||
|
||||
m1->m[3][1] = height_inc + gCamera_height;
|
||||
gCamera_pos_before_collide = *(br_vector3*)&m1->m[3][0];
|
||||
CollideCameraWithOtherCars(&c->pos, (br_vector3*)m1->m[3]);
|
||||
if (manual_swing || manual_zoom) {
|
||||
CollideCamera2(&c->pos, (br_vector3*)m1->m[3], &old_camera_pos, 1);
|
||||
} else {
|
||||
CollideCamera2(&c->pos, (br_vector3*)m1->m[3], &old_camera_pos, 0);
|
||||
}
|
||||
gCamera->t.t.translate.t.v[1] = height_inc + gCamera_height;
|
||||
BrVector3Copy(&gCamera_pos_before_collide, &gCamera->t.t.translate.t);
|
||||
CollideCameraWithOtherCars(&c->pos, &gCamera->t.t.translate.t);
|
||||
CollideCamera2(&c->pos, &gCamera->t.t.translate.t, &old_camera_pos, manual_swing || manual_zoom);
|
||||
if (gCamera_has_collided && swoop) {
|
||||
gCamera_height = c->pos.v[1];
|
||||
}
|
||||
|
|
@ -5045,7 +5310,23 @@ void PointCamera(br_vector3* pos, br_matrix34* m2) {
|
|||
br_angle theta;
|
||||
br_camera* camera_ptr;
|
||||
LOG_TRACE("(%p, %p)", pos, m2);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
camera_ptr = gCamera->type_data;
|
||||
BrVector3Sub(&vn, pos, (br_vector3*)m2->m[3]);
|
||||
vn.v[1] = 0.f;
|
||||
BrVector3Normalise(&vn, &vn);
|
||||
m2->m[0][0] = -vn.v[2];
|
||||
m2->m[0][1] = 0.f;
|
||||
m2->m[0][2] = vn.v[0];
|
||||
m2->m[1][0] = 0.f;
|
||||
m2->m[1][1] = 1.f;
|
||||
m2->m[1][2] = 0.f;
|
||||
m2->m[2][0] = -vn.v[0];
|
||||
m2->m[2][1] = 0.f;
|
||||
m2->m[2][2] = -vn.v[2];
|
||||
dist = BrVector3LengthSquared(&vn);
|
||||
theta = BR_ATAN2(m2->m[3][1] - pos->v[1], dist);
|
||||
BrMatrix34PreRotateX(m2, camera_ptr->field_of_view / 5 - theta);
|
||||
}
|
||||
|
||||
// IDA: int __usercall CollideCamera2@<EAX>(br_vector3 *car_pos@<EAX>, br_vector3 *cam_pos@<EDX>, br_vector3 *old_camera_pos@<EBX>, int manual_move@<ECX>)
|
||||
|
|
@ -6963,14 +7244,31 @@ void AdjustNonCar(br_actor* pActor, br_matrix34* pMat) {
|
|||
tU8 cz;
|
||||
tTrack_spec* track_spec;
|
||||
LOG_TRACE("(%p, %p)", pActor, pMat);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
track_spec = &gProgram_state.track_spec;
|
||||
BrMatrix34Copy(&pActor->t.t.mat, pMat);
|
||||
if (pActor->parent != gNon_track_actor) {
|
||||
XZToColumnXZ(&cx, &cz, pActor->t.t.translate.t.v[0], pActor->t.t.translate.t.v[2], track_spec);
|
||||
if (track_spec->columns[cz][cx] != pActor->parent && track_spec->columns[cz][cx] != NULL) {
|
||||
BrActorRemove(pActor);
|
||||
BrActorAdd(track_spec->columns[cz][cx], pActor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall PipeSingleNonCar(tCollision_info *c@<EAX>)
|
||||
void PipeSingleNonCar(tCollision_info* c) {
|
||||
LOG_TRACE("(%p)", c);
|
||||
|
||||
STUB_ONCE();
|
||||
StartPipingSession(ePipe_chunk_non_car);
|
||||
if (gDoing_physics) {
|
||||
BrVector3InvScale(&c->car_master_actor->t.t.translate.t, &c->car_master_actor->t.t.translate.t, WORLD_SCALE);
|
||||
}
|
||||
AddNonCarToPipingSession(c->car_ID, c->car_master_actor);
|
||||
if (gDoing_physics) {
|
||||
BrVector3Scale(&c->car_master_actor->t.t.translate.t, &c->car_master_actor->t.t.translate.t, WORLD_SCALE);
|
||||
}
|
||||
EndPipingSession();
|
||||
}
|
||||
|
||||
// IDA: int __usercall GetPrecalculatedFacesUnderCar@<EAX>(tCar_spec *pCar@<EAX>, tFace_ref **pFace_refs@<EDX>)
|
||||
|
|
|
|||
|
|
@ -770,13 +770,16 @@ void NewScreenWobble(double pAmplitude_x, double pAmplitude_y, double pPeriod) {
|
|||
// IDA: void __usercall SetScreenWobble(int pWobble_x@<EAX>, int pWobble_y@<EDX>)
|
||||
void SetScreenWobble(int pWobble_x, int pWobble_y) {
|
||||
LOG_TRACE("(%d, %d)", pWobble_x, pWobble_y);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gScreen_wobble_y = pWobble_y;
|
||||
gScreen_wobble_x = pWobble_x;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl ResetScreenWobble()
|
||||
void ResetScreenWobble() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
SetScreenWobble(0, 0);
|
||||
}
|
||||
|
||||
// IDA: void __usercall CalculateWobblitude(tU32 pThe_time@<EAX>)
|
||||
|
|
@ -1784,7 +1787,7 @@ void RenderAFrame(int pDepth_mask_on) {
|
|||
PipeFrameFinish();
|
||||
}
|
||||
gRender_screen->pixels = old_pixels;
|
||||
if (!gPalette_fade_time || GetRaceTime() > (gPalette_fade_time + 500)) {
|
||||
if (!gPalette_fade_time || GetRaceTime() > gPalette_fade_time + 500) {
|
||||
PDScreenBufferSwap(0);
|
||||
}
|
||||
if (gAction_replay_mode) {
|
||||
|
|
@ -2092,7 +2095,15 @@ void DRPixelmapRectangleMaskedCopy(br_pixelmap* pDest, br_int_16 pDest_x, br_int
|
|||
// IDA: void __usercall DRMaskedStamp(br_int_16 pDest_x@<EAX>, br_int_16 pDest_y@<EDX>, br_pixelmap *pSource@<EBX>)
|
||||
void DRMaskedStamp(br_int_16 pDest_x, br_int_16 pDest_y, br_pixelmap* pSource) {
|
||||
LOG_TRACE("(%d, %d, %p)", pDest_x, pDest_y, pSource);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
DRPixelmapRectangleMaskedCopy(gBack_screen,
|
||||
pDest_x,
|
||||
pDest_y,
|
||||
pSource,
|
||||
0,
|
||||
0,
|
||||
pSource->width,
|
||||
pSource->height);
|
||||
}
|
||||
|
||||
// IDA: void __usercall DRPixelmapRectangleOnscreenCopy(br_pixelmap *pDest@<EAX>, br_int_16 pDest_x@<EDX>, br_int_16 pDest_y@<EBX>, br_pixelmap *pSource@<ECX>, br_int_16 pSource_x, br_int_16 pSource_y, br_int_16 pWidth, br_int_16 pHeight)
|
||||
|
|
|
|||
|
|
@ -2295,7 +2295,7 @@ void RevivePedestrian(tPedestrian_data* pPedestrian, int pAnimate) {
|
|||
pPedestrian->fate = NULL;
|
||||
gInitial_instruction = NULL;
|
||||
PedestrianNextInstruction(pPedestrian, 0.f, 1, 0);
|
||||
pPedestrian->from_pos = pPedestrian->actor->t.t.translate.t;
|
||||
BrVector3Copy(&pPedestrian->from_pos, &pPedestrian->actor->t.t.translate.t);
|
||||
MungePedModel(pPedestrian);
|
||||
pPedestrian->pos.v[V_Y] += pPedestrian->sequences[pPedestrian->current_sequence].frames[0].offset.v[V_Y];
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,9 +1,30 @@
|
|||
#include "replay.h"
|
||||
#include "harness/trace.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <brender/brender.h>
|
||||
#include "car.h"
|
||||
#include "controls.h"
|
||||
#include "displays.h"
|
||||
#include "globvars.h"
|
||||
#include "globvrpb.h"
|
||||
#include "grafdata.h"
|
||||
#include "graphics.h"
|
||||
#include "input.h"
|
||||
#include "loading.h"
|
||||
#include "main.h"
|
||||
#include "netgame.h"
|
||||
#include "oil.h"
|
||||
#include "opponent.h"
|
||||
#include "piping.h"
|
||||
#include "s3/s3.h"
|
||||
#include "sys.h"
|
||||
#include "utility.h"
|
||||
#include "world.h"
|
||||
|
||||
#include "harness/config.h"
|
||||
#include "harness/os.h"
|
||||
#include "harness/trace.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
char* gReplay_pixie_names[10] = {
|
||||
"REPLAY.PIX",
|
||||
|
|
@ -15,14 +36,14 @@ char* gReplay_pixie_names[10] = {
|
|||
"PLAY.PIX",
|
||||
"FFWD.PIX",
|
||||
"FWDEND.PIX",
|
||||
"CAMERA.PIX"
|
||||
"CAMERA.PIX",
|
||||
};
|
||||
int gSingle_frame_mode;
|
||||
tU32 gCam_change_time;
|
||||
int gSave_file;
|
||||
int gProgress_line_left[2];
|
||||
int gProgress_line_right[2];
|
||||
int gProgress_line_top[2];
|
||||
int gSingle_frame_mode = 0;
|
||||
tU32 gCam_change_time = 0;
|
||||
int gSave_file = 0;
|
||||
int gProgress_line_left[2] = { 70, 141 };
|
||||
int gProgress_line_right[2] = { 279, 558 };
|
||||
int gProgress_line_top[2] = { 178, 429 };
|
||||
br_pixelmap* gReplay_pixies[10];
|
||||
int gKey_down;
|
||||
int gNo_cursor;
|
||||
|
|
@ -43,7 +64,7 @@ tAction_replay_camera_type gAction_replay_camera_mode;
|
|||
int ReplayIsPaused() {
|
||||
LOG_TRACE8("()");
|
||||
|
||||
return gReplay_rate == 0.0;
|
||||
return gReplay_rate == 0.f;
|
||||
}
|
||||
|
||||
// IDA: float __cdecl GetReplayRate()
|
||||
|
|
@ -56,13 +77,16 @@ float GetReplayRate() {
|
|||
// IDA: int __cdecl GetReplayDirection()
|
||||
int GetReplayDirection() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
return gPlay_direction;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl StopSaving()
|
||||
void StopSaving() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gSave_file = 0;
|
||||
gPaused = 1;
|
||||
}
|
||||
|
||||
// IDA: void __usercall ActualActionReplayHeadups(int pSpecial_zappy_bastard@<EAX>)
|
||||
|
|
@ -74,7 +98,104 @@ void ActualActionReplayHeadups(int pSpecial_zappy_bastard) {
|
|||
tU16 to_play_col1;
|
||||
tU16 to_play_col2;
|
||||
LOG_TRACE("(%d)", pSpecial_zappy_bastard);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
the_time = PDGetTotalTime();
|
||||
if (gSave_file || PDKeyDown(KEY_SHIFT_ANY)) {
|
||||
return;
|
||||
}
|
||||
if ((the_time / 400) % 2) {
|
||||
DRMaskedStamp(gCurrent_graf_data->action_replay_R_x,
|
||||
gCurrent_graf_data->action_replay_R_y,
|
||||
gReplay_pixies[0]);
|
||||
}
|
||||
DRMaskedStamp(gCurrent_graf_data->action_replay_controls_x,
|
||||
gCurrent_graf_data->action_replay_controls_y,
|
||||
gReplay_pixies[1]);
|
||||
if (pSpecial_zappy_bastard < 0) {
|
||||
DRMaskedStamp(gCurrent_graf_data->action_replay_rew_start_x,
|
||||
gCurrent_graf_data->action_replay_hilite_y,
|
||||
gReplay_pixies[2]);
|
||||
} else if (pSpecial_zappy_bastard == 0) {
|
||||
if (gReplay_rate < -1.f) {
|
||||
DRMaskedStamp(gCurrent_graf_data->action_replay_rew_x,
|
||||
gCurrent_graf_data->action_replay_hilite_y,
|
||||
gReplay_pixies[3]);
|
||||
} else if (gReplay_rate > 1.f) {
|
||||
DRMaskedStamp(gCurrent_graf_data->action_replay_ffwd_x,
|
||||
gCurrent_graf_data->action_replay_hilite_y,
|
||||
gReplay_pixies[7]);
|
||||
} else if (gReplay_rate == 1.f) {
|
||||
DRMaskedStamp(gCurrent_graf_data->action_replay_play_x,
|
||||
gCurrent_graf_data->action_replay_hilite_y,
|
||||
gReplay_pixies[6]);
|
||||
} else if (gReplay_rate == -1.f) {
|
||||
DRMaskedStamp(gCurrent_graf_data->action_replay_rev_play_x,
|
||||
gCurrent_graf_data->action_replay_hilite_y,
|
||||
gReplay_pixies[4]);
|
||||
} else {
|
||||
DRMaskedStamp(gCurrent_graf_data->action_replay_pause_x,
|
||||
gCurrent_graf_data->action_replay_hilite_y,
|
||||
gReplay_pixies[5]);
|
||||
}
|
||||
} else {
|
||||
DRMaskedStamp(gCurrent_graf_data->action_replay_fwd_end_x,
|
||||
gCurrent_graf_data->action_replay_hilite_y,
|
||||
gReplay_pixies[8]);
|
||||
}
|
||||
|
||||
x = gProgress_line_left[gGraf_data_index] + (float)(gProgress_line_right[gGraf_data_index] - gProgress_line_left[gGraf_data_index]) * (gLast_replay_frame_time - gAction_replay_start_time) / (gAction_replay_end_time - gAction_replay_start_time);
|
||||
if (x > gProgress_line_left[gGraf_data_index]) {
|
||||
BrPixelmapLine(gBack_screen,
|
||||
gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index],
|
||||
x - 1, gProgress_line_top[gGraf_data_index],
|
||||
2);
|
||||
BrPixelmapLine(gBack_screen,
|
||||
gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 1,
|
||||
x - 1, gProgress_line_top[gGraf_data_index] + 1,
|
||||
4);
|
||||
BrPixelmapLine(gBack_screen,
|
||||
gProgress_line_left[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 2,
|
||||
x - 1, gProgress_line_top[gGraf_data_index] + 2,
|
||||
2);
|
||||
}
|
||||
if (x < gProgress_line_right[gGraf_data_index]) {
|
||||
BrPixelmapLine(gBack_screen,
|
||||
x, gProgress_line_top[gGraf_data_index],
|
||||
gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index],
|
||||
81);
|
||||
BrPixelmapLine(gBack_screen,
|
||||
x, gProgress_line_top[gGraf_data_index] + 1,
|
||||
gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 1,
|
||||
82);
|
||||
BrPixelmapLine(gBack_screen,
|
||||
x, gProgress_line_top[gGraf_data_index] + 2,
|
||||
gProgress_line_right[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 2,
|
||||
81);
|
||||
}
|
||||
BrPixelmapLine(gBack_screen,
|
||||
gProgress_line_left[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index],
|
||||
gProgress_line_left[gGraf_data_index] - 1, gProgress_line_top[gGraf_data_index] + 2,
|
||||
2);
|
||||
BrPixelmapLine(gBack_screen,
|
||||
gProgress_line_right[gGraf_data_index], gProgress_line_top[gGraf_data_index],
|
||||
gProgress_line_right[gGraf_data_index], gProgress_line_top[gGraf_data_index] + 2,
|
||||
81);
|
||||
if (gCam_change_button_down) {
|
||||
DRMaskedStamp(gCurrent_graf_data->action_replay_camera_x,
|
||||
gCurrent_graf_data->action_replay_hilite_y,
|
||||
gReplay_pixies[9]);
|
||||
}
|
||||
if (the_time - gCam_change_time < 2000) {
|
||||
TransDRPixelmapText(gBack_screen,
|
||||
gCurrent_graf_data->action_replay_cam_text_x - DRTextWidth(&gFonts[1], GetMiscString(gAction_replay_camera_mode ? 39 : 38)),
|
||||
gCurrent_graf_data->action_replay_cam_text_y,
|
||||
&gFonts[1],
|
||||
GetMiscString(gAction_replay_camera_mode ? 39 : 38),
|
||||
2 * gCurrent_graf_data->action_replay_cam_text_x);
|
||||
}
|
||||
TurnOnPaletteConversion();
|
||||
DoMouseCursor();
|
||||
TurnOffPaletteConversion();
|
||||
}
|
||||
|
||||
// IDA: void __cdecl DoActionReplayPostSwap()
|
||||
|
|
@ -88,13 +209,22 @@ void DoActionReplayPostSwap() {
|
|||
void DoZappyActionReplayHeadups(int pSpecial_zappy_bastard) {
|
||||
tU32 the_time;
|
||||
LOG_TRACE("(%d)", pSpecial_zappy_bastard);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
the_time = PDGetTotalTime();
|
||||
// Draw screen every 50ms (when we are going fast)
|
||||
if (abs(pSpecial_zappy_bastard) > 10000 && the_time - gLast_replay_zappy_screen > 50) {
|
||||
ActualActionReplayHeadups(pSpecial_zappy_bastard);
|
||||
gLast_replay_zappy_screen = the_time;
|
||||
PDScreenBufferSwap(0);
|
||||
RemoveTransientBitmaps(1);
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl DoActionReplayHeadups()
|
||||
void DoActionReplayHeadups() {
|
||||
LOG_TRACE("()");
|
||||
STUB_ONCE();
|
||||
|
||||
ActualActionReplayHeadups(0);
|
||||
}
|
||||
|
||||
// IDA: void __usercall MoveReplayBuffer(tS32 pMove_amount@<EAX>)
|
||||
|
|
@ -106,27 +236,123 @@ void MoveReplayBuffer(tS32 pMove_amount) {
|
|||
int a;
|
||||
tU32 old_time;
|
||||
LOG_TRACE("(%d)", pMove_amount);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
old_play_ptr = NULL;
|
||||
gLast_replay_zappy_screen = 0;
|
||||
old_play_ptr2 = GetPipePlayPtr();
|
||||
play_ptr = old_play_ptr2;
|
||||
old_time = GetTotalTime();
|
||||
for (i = 0; i < abs(pMove_amount) && play_ptr != old_play_ptr; i++) {
|
||||
if (KeyIsDown(KEYMAP_ESCAPE)) {
|
||||
break;
|
||||
}
|
||||
if (SomeReplayLeft()) {
|
||||
PipingFrameReset();
|
||||
}
|
||||
old_play_ptr = play_ptr;
|
||||
if (pMove_amount >= 1) {
|
||||
while (!ApplyPipedSession(&play_ptr)) {
|
||||
DoZappyActionReplayHeadups(pMove_amount);
|
||||
}
|
||||
SetPipePlayPtr(play_ptr);
|
||||
} else if (pMove_amount <= -1) {
|
||||
while (!UndoPipedSession(&play_ptr)) {
|
||||
DoZappyActionReplayHeadups(pMove_amount);
|
||||
}
|
||||
SetPipePlayPtr(play_ptr);
|
||||
}
|
||||
ProcessOilSpills(gFrame_period);
|
||||
}
|
||||
if (gReplay_rate < 0.f) {
|
||||
CheckSound((tPipe_chunk*)old_play_ptr2, old_time, GetTotalTime());
|
||||
}
|
||||
if (old_play_ptr == play_ptr) {
|
||||
gReplay_rate = 0.f;
|
||||
gPaused = 1;
|
||||
StopSaving();
|
||||
}
|
||||
if (KeyIsDown(KEYMAP_ESCAPE)) {
|
||||
WaitForNoKeys();
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl MoveToEndOfReplay()
|
||||
void MoveToEndOfReplay() {
|
||||
float old_replay_rate;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
DisablePipedSounds();
|
||||
old_replay_rate = gReplay_rate;
|
||||
gReplay_rate = 100.f;
|
||||
MoveReplayBuffer(INT32_MAX);
|
||||
gReplay_rate = old_replay_rate;
|
||||
EnablePipedSounds();
|
||||
}
|
||||
|
||||
// IDA: void __cdecl MoveToStartOfReplay()
|
||||
void MoveToStartOfReplay() {
|
||||
float old_replay_rate;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
DisablePipedSounds();
|
||||
old_replay_rate = gReplay_rate;
|
||||
gReplay_rate = -100.f;
|
||||
MoveReplayBuffer(-INT32_MAX);
|
||||
gReplay_rate = old_replay_rate;
|
||||
EnablePipedSounds();
|
||||
}
|
||||
|
||||
// IDA: void __cdecl ToggleReplay()
|
||||
void ToggleReplay() {
|
||||
LOG_TRACE("()");
|
||||
STUB_ONCE();
|
||||
|
||||
if (!harness_game_config.enable_replay) {
|
||||
NewTextHeadupSlot(4, 0, 1000, -4, "Action replay disabled (start dethrace with --enable-replay)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsActionReplayAvailable()) {
|
||||
NewTextHeadupSlot(4, 0, 1000, -4, GetMiscString(37));
|
||||
return;
|
||||
}
|
||||
if (!gAction_replay_mode) {
|
||||
if (gMap_mode) {
|
||||
ToggleMap();
|
||||
}
|
||||
if (gNet_mode == eNet_mode_host) {
|
||||
SendGameplayToAllPlayers(eNet_gameplay_host_paused, 0, 0, 0, 0);
|
||||
}
|
||||
gReplay_rate = 1.f;
|
||||
gPaused = 1;
|
||||
gStopped_time = PDGetTotalTime();
|
||||
gPlay_direction = 1;
|
||||
gAction_replay_end_time = GetTotalTime();
|
||||
gLast_replay_frame_time = gAction_replay_end_time;
|
||||
gAction_replay_start_time = GetARStartTime();
|
||||
ResetPipePlayToEnd();
|
||||
LoadInterfaceStuff(1);
|
||||
StartMouseCursor();
|
||||
gKey_down = KEY_KP_ENTER;
|
||||
gPending_replay_rate = 0;
|
||||
gCam_change_time = PDGetTotalTime();
|
||||
if (!gRace_finished) {
|
||||
SaveCameraPosition(0);
|
||||
}
|
||||
} else {
|
||||
MoveToEndOfReplay();
|
||||
EndMouseCursor();
|
||||
S3SetEffects(NULL, NULL);
|
||||
UnlockInterfaceStuff();
|
||||
AddLostTime(PDGetTotalTime() - gStopped_time);
|
||||
if (!gRace_finished) {
|
||||
RestoreCameraPosition(0);
|
||||
}
|
||||
if (gNet_mode == eNet_mode_host) {
|
||||
SendGameplayToAllPlayers(eNet_gameplay_host_unpaused, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
gAction_replay_mode = !gAction_replay_mode;
|
||||
ForceRebuildActiveCarList();
|
||||
}
|
||||
|
||||
// IDA: void __usercall ReverseSound(tS3_effect_tag pEffect_index@<EAX>, tS3_sound_tag pSound_tag@<EDX>)
|
||||
|
|
@ -141,7 +367,19 @@ int FindUniqueFile() {
|
|||
FILE* f;
|
||||
tPath_name the_path;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
for (index = 0; index < 1000; index++) {
|
||||
PathCat(the_path, gApplication_path, "BMPFILES");
|
||||
PathCat(the_path, the_path, "");
|
||||
sprintf(&the_path[strlen(the_path)], "%03d", index);
|
||||
strcat(the_path, "_0000.BMP");
|
||||
f = DRfopen(the_path, "rt");
|
||||
if (f == NULL) {
|
||||
return index;
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// IDA: void __usercall PollActionReplayControls(tU32 pFrame_period@<EAX>)
|
||||
|
|
@ -152,17 +390,193 @@ void PollActionReplayControls(tU32 pFrame_period) {
|
|||
int y_coord;
|
||||
int i;
|
||||
tU32 real_time;
|
||||
static tU32 last_real_time;
|
||||
static int psuedo_mouse_keys[8];
|
||||
static tRectangle mouse_areas[2][8];
|
||||
static tU32 last_real_time = 0;
|
||||
static int psuedo_mouse_keys[8] = {
|
||||
KEY_KP_7,
|
||||
KEY_KP_4,
|
||||
KEY_COMMA,
|
||||
KEY_SPACE,
|
||||
KEY_PERIOD,
|
||||
KEY_KP_6,
|
||||
KEY_KP_9,
|
||||
KEY_KP_MULTIPLY,
|
||||
};
|
||||
static tRectangle mouse_areas[2][8] = {
|
||||
{
|
||||
{ 63, 182, 92, 198, },
|
||||
{ 93, 182, 118, 198, },
|
||||
{ 119, 182, 144, 198, },
|
||||
{ 145, 182, 166, 198, },
|
||||
{ 167, 182, 192, 198, },
|
||||
{ 193, 182, 218, 198, },
|
||||
{ 219, 182, 244, 198, },
|
||||
{ 245, 182, 272, 198, },
|
||||
},
|
||||
{
|
||||
{ 126, 436, 184, 475, },
|
||||
{ 186, 436, 236, 475, },
|
||||
{ 238, 436, 288, 475, },
|
||||
{ 290, 436, 332, 475, },
|
||||
{ 334, 436, 384, 475, },
|
||||
{ 386, 436, 436, 475, },
|
||||
{ 438, 436, 488, 475, },
|
||||
{ 490, 436, 544, 475, },
|
||||
},
|
||||
};
|
||||
LOG_TRACE("(%d)", pFrame_period);
|
||||
STUB_ONCE();
|
||||
|
||||
real_time = PDGetTotalTime();
|
||||
old_replay_rate = gReplay_rate;
|
||||
old_key_down = gKey_down == KEY_CAPSLOCK ? -1 : gKey_down;
|
||||
gKey_down = PDAnyKeyDown();
|
||||
if (KeyIsDown(KEYMAP_REPLAYMODE) && old_key_down == -1) {
|
||||
ToggleReplay();
|
||||
return;
|
||||
}
|
||||
|
||||
if (gKey_down == -1) {
|
||||
if ((old_key_down == -1 || old_key_down == KEY_KP_4 || old_key_down == KEY_KP_6 || old_key_down == KEY_KP_MULTIPLY) && EitherMouseButtonDown()) {
|
||||
GetMousePosition(&x_coord, &y_coord);
|
||||
for (i = 0; i < COUNT_OF(mouse_areas[0]); i++) {
|
||||
if (mouse_areas[gGraf_data_index][i].left <= x_coord && mouse_areas[gGraf_data_index][i].top <= y_coord &&
|
||||
mouse_areas[gGraf_data_index][i].right >= x_coord && mouse_areas[gGraf_data_index][i].bottom >= y_coord) {
|
||||
gKey_down = psuedo_mouse_keys[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gMouse_in_use = 0;
|
||||
}
|
||||
|
||||
if (gKey_down == KEY_KP_DIVIDE && old_key_down != KEY_KP_DIVIDE) {
|
||||
if (gSave_file) {
|
||||
StopSaving();
|
||||
} else {
|
||||
gSave_bunch_ID = FindUniqueFile();
|
||||
gSave_frame_number = 0;
|
||||
gSave_file = 1;
|
||||
gPlay_direction = 1;
|
||||
gPaused = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (gKey_down == KEY_KP_MULTIPLY) {
|
||||
gCam_change_button_down = 1;
|
||||
if (old_key_down != KEY_KP_MULTIPLY) {
|
||||
gCam_change_time = PDGetTotalTime();
|
||||
if (gAction_replay_camera_mode == eAction_replay_action) {
|
||||
gAction_replay_camera_mode = eAction_replay_standard;
|
||||
} else {
|
||||
gAction_replay_camera_mode++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gCam_change_button_down = 0;
|
||||
}
|
||||
|
||||
if ((gKey_down == KEY_KP_5 || gKey_down == KEY_SPACE) && old_key_down == -1) {
|
||||
gPaused = !gPaused;
|
||||
} else if ((gKey_down == KEY_KP_0 || gKey_down == KEY_BACKSPACE) && old_key_down == -1) {
|
||||
gPlay_direction = -gPlay_direction;
|
||||
if (gPaused) {
|
||||
gPaused = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (gKey_down == KEY_KP_1 && old_key_down == -1) {
|
||||
gReplay_rate = -1.f;
|
||||
gPlay_direction = -1;
|
||||
gSingle_frame_mode = 1;
|
||||
} else if (gKey_down == KEY_KP_3 && old_key_down == -1) {
|
||||
gReplay_rate = 1.f;
|
||||
gPlay_direction = 1;
|
||||
gSingle_frame_mode = 1;
|
||||
} else if (gKey_down == KEY_KP_4 || gKey_down == KEY_PAGEUP) {
|
||||
if (gReplay_rate > -1.2f) {
|
||||
gReplay_rate = -1.2f;
|
||||
}
|
||||
if (last_real_time != 0) {
|
||||
gReplay_rate -= 0.002f * (real_time - last_real_time);
|
||||
}
|
||||
if (gReplay_rate < -8.f) {
|
||||
gReplay_rate = -8.f;
|
||||
}
|
||||
} else if (gKey_down == KEY_KP_6 || gKey_down == KEY_PAGEDOWN) {
|
||||
if (gReplay_rate < 1.2f) {
|
||||
gReplay_rate = 1.2f;
|
||||
}
|
||||
if (last_real_time != 0) {
|
||||
gReplay_rate += 0.002f * (real_time - last_real_time);
|
||||
}
|
||||
if (gReplay_rate > 8.f) {
|
||||
gReplay_rate = 8.f;
|
||||
}
|
||||
} else if (gKey_down == KEY_COMMA) {
|
||||
gReplay_rate = -1.f;
|
||||
gPlay_direction = -1;
|
||||
gPaused = 0;
|
||||
} else if (gKey_down == KEY_PERIOD) {
|
||||
gReplay_rate = 1.f;
|
||||
gPlay_direction = 1;
|
||||
gPaused = 0;
|
||||
} else if (gPaused) {
|
||||
gReplay_rate = 0.f;
|
||||
} else {
|
||||
gReplay_rate = (float)gPlay_direction;
|
||||
}
|
||||
|
||||
if ((gKey_down == KEY_KP_7 || gKey_down == KEY_HOME) && old_key_down == -1) {
|
||||
MoveToStartOfReplay();
|
||||
gReplay_rate = 1.f;
|
||||
MungeCarGraphics(gFrame_period);
|
||||
GrooveThoseDelics();
|
||||
gReplay_rate = 0.f;
|
||||
gPlay_direction = 1;
|
||||
gPaused = 1;
|
||||
} else if ((gKey_down == KEY_KP_9 || gKey_down == KEY_END) && old_key_down == -1) {
|
||||
MoveToEndOfReplay();
|
||||
gReplay_rate = -1.f;
|
||||
MungeCarGraphics(gFrame_period);
|
||||
GrooveThoseDelics();
|
||||
gReplay_rate = 0.f;
|
||||
gPlay_direction = -1;
|
||||
gPaused = 1;
|
||||
}
|
||||
|
||||
if (gPending_replay_rate != 0.f) {
|
||||
gReplay_rate = gPending_replay_rate;
|
||||
}
|
||||
if (old_replay_rate * gReplay_rate >= 0.f) {
|
||||
gPending_replay_rate = 0.f;
|
||||
} else {
|
||||
gPending_replay_rate = gReplay_rate;
|
||||
gReplay_rate = 0.f;
|
||||
}
|
||||
|
||||
if (old_replay_rate != 0.f) {
|
||||
gFrame_period = gFrame_period * gReplay_rate / old_replay_rate;
|
||||
}
|
||||
last_real_time = fabsf(gReplay_rate) >= 1.2f ? real_time : 0;
|
||||
|
||||
if (old_replay_rate <= 0.f && gReplay_rate > 0.f) {
|
||||
S3SetEffects(NULL, NULL);
|
||||
} else if (old_replay_rate >= 0.f && gReplay_rate < 0.f) {
|
||||
S3SetEffects(ReverseSound, ReverseSound);
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl CheckReplayTurnOn()
|
||||
void CheckReplayTurnOn() {
|
||||
LOG_TRACE("()");
|
||||
STUB_ONCE();
|
||||
|
||||
if (!gAction_replay_mode) {
|
||||
if (!KeyIsDown(KEYMAP_REPLAYMODE) || gEntering_message) {
|
||||
gKey_down = -1;
|
||||
} else if (gKey_down == -1) {
|
||||
ToggleReplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl InitializeActionReplay()
|
||||
|
|
@ -170,7 +584,7 @@ void InitializeActionReplay() {
|
|||
int i;
|
||||
LOG_TRACE("()");
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (i = 0; i < COUNT_OF(gReplay_pixie_names); i++) {
|
||||
gReplay_pixies[i] = LoadPixelmap(gReplay_pixie_names[i]);
|
||||
}
|
||||
gAction_replay_camera_mode = eAction_replay_action;
|
||||
|
|
@ -179,7 +593,10 @@ void InitializeActionReplay() {
|
|||
// IDA: void __usercall DoActionReplay(tU32 pFrame_period@<EAX>)
|
||||
void DoActionReplay(tU32 pFrame_period) {
|
||||
LOG_TRACE("(%d)", pFrame_period);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (gReplay_rate != 0.f) {
|
||||
MoveReplayBuffer((tS32)gReplay_rate);
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl SynchronizeActionReplay()
|
||||
|
|
@ -188,5 +605,28 @@ void SynchronizeActionReplay() {
|
|||
tPath_name the_path;
|
||||
static tU32 gLast_synch_time;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
while (gReplay_rate != 0.f) {
|
||||
if (PDGetTotalTime() - gLast_synch_time >= gFrame_period / fabsf(gReplay_rate)) {
|
||||
break;
|
||||
}
|
||||
ServiceGameInRace();
|
||||
}
|
||||
gLast_synch_time = PDGetTotalTime();
|
||||
if (gSingle_frame_mode) {
|
||||
gReplay_rate = 0.f;
|
||||
gSingle_frame_mode = 0;
|
||||
}
|
||||
|
||||
if (gSave_file) {
|
||||
PathCat(the_path, gApplication_path, "BMPFILES");
|
||||
strcat(the_path, gDir_separator);
|
||||
sprintf(&the_path[strlen(the_path)], "%03d_%04d.BMP", gSave_bunch_ID, gSave_frame_number);
|
||||
f = DRfopen(the_path, "wb");
|
||||
if (f != NULL) {
|
||||
PrintScreenFile(f);
|
||||
fclose(f);
|
||||
}
|
||||
gSave_frame_number++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -637,7 +637,8 @@ void SetSoundVolumes() {
|
|||
// IDA: tS3_outlet_ptr __usercall GetOutletFromIndex@<EAX>(int pIndex@<EAX>)
|
||||
tS3_outlet_ptr GetOutletFromIndex(int pIndex) {
|
||||
LOG_TRACE("(%d)", pIndex);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
return gIndexed_outlets[pIndex];
|
||||
}
|
||||
|
||||
// IDA: int __usercall GetIndexFromOutlet@<EAX>(tS3_outlet_ptr pOutlet@<EAX>)
|
||||
|
|
|
|||
|
|
@ -312,7 +312,28 @@ void ReplaySparks(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_ac
|
|||
br_vector3 tv;
|
||||
br_vector3 new_pos;
|
||||
LOG_TRACE("(%p, %p, %p, %d)", pRender_screen, pDepth_buffer, pCamera, pTime);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
for (i = 0; i < COUNT_OF(gSparks); i++) {
|
||||
if (gSpark_flags & (1 << i)) {
|
||||
if (gSparks[i].car == NULL) {
|
||||
BrVector3Copy(&pos, &gSparks[i].pos);
|
||||
} else {
|
||||
BrMatrix34ApplyP(&tv, &o, &gSparks[i].car->car_master_actor->t.t.mat);
|
||||
BrVector3Copy(&o, &tv);
|
||||
BrMatrix34ApplyP(&pos, &gSparks[i].pos, &gSparks[i].car->car_master_actor->t.t.mat);
|
||||
}
|
||||
BrVector3Add(&o, &pos, &gSparks[i].length);
|
||||
BrVector3Sub(&tv, &pos, (br_vector3*)gCamera_to_world.m[3]);
|
||||
BrMatrix34TApplyV(&new_pos, &tv, &gCamera_to_world);
|
||||
BrVector3Sub(&tv, &o, (br_vector3*)gCamera_to_world.m[3]);
|
||||
BrMatrix34TApplyV(&p, &tv, &gCamera_to_world);
|
||||
if (gSparks[i].colour) {
|
||||
DrawLine3D(&p, &new_pos, pRender_screen, pDepth_buffer, gFog_shade_table);
|
||||
} else {
|
||||
DrawLine3D(&p, &new_pos, pRender_screen, pDepth_buffer, gAcid_shade_table);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall RenderSparks(br_pixelmap *pRender_screen@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>, tU32 pTime)
|
||||
|
|
@ -737,7 +758,15 @@ void ReplayShrapnel(tU32 pTime) {
|
|||
int i;
|
||||
br_matrix34* mat;
|
||||
LOG_TRACE("(%d)", pTime);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
for (i = 0; i < COUNT_OF(gShrapnel); i++) {
|
||||
mat = &gShrapnel[i].actor->t.t.mat;
|
||||
if (gShrapnel_flags & (1 << i)) {
|
||||
gShrapnel[i].age += GetReplayRate() * pTime;
|
||||
DrMatrix34Rotate(mat, gShrapnel[i].age * BrDegreeToAngle(1), &gShrapnel[i].axis);
|
||||
BrMatrix34PreShearX(mat, gShrapnel[i].shear1, gShrapnel[i].shear2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall MungeShrapnel(tU32 pTime@<EAX>)
|
||||
|
|
@ -1090,7 +1119,19 @@ void ReplaySmoke(br_pixelmap* pRender_screen, br_pixelmap* pDepth_buffer, br_act
|
|||
br_scalar aspect;
|
||||
int i;
|
||||
LOG_TRACE("(%p, %p, %p)", pRender_screen, pDepth_buffer, pCamera);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
for (i = 0; i < COUNT_OF(gSmoke_column); i++) {
|
||||
if (gSmoke_flags & (1 << i)) {
|
||||
aspect = 1.f + (gSmoke[i].radius - .05f) / .25f * .5f;
|
||||
if (gSmoke[i].type & 0x10) {
|
||||
SmokeCircle3D(&gSmoke[i].pos, gSmoke[i].radius / aspect, gSmoke[i].strength, 1.f,
|
||||
pRender_screen, pDepth_buffer, gShade_list[gSmoke[i].type & 0xf], pCamera);
|
||||
} else {
|
||||
SmokeCircle3D(&gSmoke[i].pos, gSmoke[i].radius, gSmoke[i].strength, aspect,
|
||||
pRender_screen, pDepth_buffer, gShade_list[gSmoke[i].type & 0xf], pCamera);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall GenerateContinuousSmoke(tCar_spec *pCar@<EAX>, int wheel@<EDX>, tU32 pTime@<EBX>)
|
||||
|
|
@ -1301,19 +1342,25 @@ void CreatePuffOfSmoke(br_vector3* pos, br_vector3* v, br_scalar strength, br_sc
|
|||
// IDA: void __cdecl ResetSmoke()
|
||||
void ResetSmoke() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gSmoke_flags = 0;;
|
||||
}
|
||||
|
||||
// IDA: void __usercall AdjustSmoke(int pIndex@<EAX>, tU8 pType@<EDX>, br_vector3 *pPos@<EBX>, br_scalar pRadius, br_scalar pStrength)
|
||||
void AdjustSmoke(int pIndex, tU8 pType, br_vector3* pPos, br_scalar pRadius, br_scalar pStrength) {
|
||||
LOG_TRACE("(%d, %d, %p, %f, %f)", pIndex, pType, pPos, pRadius, pStrength);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gSmoke[pIndex].type = pType;
|
||||
gSmoke[pIndex].radius = pRadius;
|
||||
gSmoke[pIndex].strength = pStrength;
|
||||
BrVector3Copy(&gSmoke[pIndex].pos, pPos);
|
||||
gSmoke_flags |= 1 << pIndex;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl ActorError()
|
||||
void ActorError() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
}
|
||||
|
||||
// IDA: void __usercall AdjustSmokeColumn(int pIndex@<EAX>, tCar_spec *pCar@<EDX>, int pVertex@<EBX>, int pColour@<ECX>)
|
||||
|
|
@ -1321,7 +1368,27 @@ void AdjustSmokeColumn(int pIndex, tCar_spec* pCar, int pVertex, int pColour) {
|
|||
int i;
|
||||
br_actor* actor;
|
||||
LOG_TRACE("(%d, %p, %d, %d)", pIndex, pCar, pVertex, pColour);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gColumn_flags ^= 1 << pIndex;
|
||||
gSmoke_column[pIndex].car = pCar;
|
||||
gSmoke_column[pIndex].vertex_index = pVertex;
|
||||
gSmoke_column[pIndex].colour = pColour;
|
||||
for (i = 0; i < COUNT_OF(gSmoke_column->frame_count); i++) {
|
||||
gSmoke_column[pIndex].frame_count[i] = 100;
|
||||
}
|
||||
if (pColour == 0) {
|
||||
if ((gColumn_flags & (1 << pIndex)) != 0) {
|
||||
if (gSmoke_column[pIndex].flame_actor->depth != 0) {
|
||||
ActorError();
|
||||
}
|
||||
BrActorAdd(gNon_track_actor, gSmoke_column[pIndex].flame_actor);
|
||||
} else {
|
||||
if (gSmoke_column[pIndex].flame_actor->depth == 0) {
|
||||
ActorError();
|
||||
}
|
||||
BrActorRemove(gSmoke_column[pIndex].flame_actor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall CreateSmokeColumn(tCar_spec *pCar@<EAX>, int pColour@<EDX>, int pVertex_index@<EBX>, tU32 pLifetime@<ECX>)
|
||||
|
|
@ -1431,14 +1498,38 @@ void AdjustFlame(int pIndex, int pFrame_count, br_scalar pScale_x, br_scalar pSc
|
|||
tSmoke_column* col;
|
||||
br_actor* actor;
|
||||
LOG_TRACE("(%d, %d, %f, %f, %f, %f)", pIndex, pFrame_count, pScale_x, pScale_y, pOffset_x, pOffset_z);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
i = pIndex >> 4;
|
||||
j = pIndex & 0xf;
|
||||
col = &gSmoke_column[i];
|
||||
col->frame_count[j] = pFrame_count;
|
||||
col->scale_x[j] = pScale_x;
|
||||
col->scale_y[j] = pScale_y;
|
||||
col->offset_x[j] = pOffset_x;
|
||||
col->offset_z[j] = pOffset_z;
|
||||
}
|
||||
|
||||
// IDA: void __usercall ReplayFlame(tSmoke_column *col@<EAX>, br_actor *actor@<EDX>)
|
||||
void ReplayFlame(tSmoke_column* col, br_actor* actor) {
|
||||
int i;
|
||||
LOG_TRACE("(%p, %p)", col, actor);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
for (i = 0; i < COUNT_OF(col->frame_count); i++, actor = actor->next) {
|
||||
col->frame_count[i] += GetReplayRate();
|
||||
if (col->frame_count[i] < 0 || col->frame_count[i] >= COUNT_OF(gFlame_map)) {
|
||||
actor->type = BR_ACTOR_NONE;
|
||||
} else {
|
||||
actor->type = BR_ACTOR_MODEL;
|
||||
actor->material->colour_map = gFlame_map[col->frame_count[i]];
|
||||
BrMaterialUpdate(actor->material, BR_MATU_ALL);
|
||||
BrMatrix34Scale(&actor->t.t.mat,
|
||||
col->scale_x[i] * gFlame_map[col->frame_count[i]]->width,
|
||||
col->scale_y[i] * gFlame_map[col->frame_count[i]]->height,
|
||||
1.f);
|
||||
actor->t.t.translate.t.v[0] = col->offset_x[i];
|
||||
actor->t.t.translate.t.v[2] = col->offset_z[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall FlameAnimate(int c@<EAX>, br_vector3 *pPos@<EDX>, tU32 pTime@<EBX>)
|
||||
|
|
@ -1540,7 +1631,15 @@ void ReplaySmokeColumn(tU32 pTime) {
|
|||
int i;
|
||||
br_vector3 dummy;
|
||||
LOG_TRACE("(%d)", pTime);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
for (i = 0; i < MAX_SMOKE_COLUMNS; i++) {
|
||||
if ((gColumn_flags & (1 << i)) != 0) {
|
||||
DoSmokeColumn(i, pTime, &dummy);
|
||||
if (gSmoke_column[i].colour == 0) {
|
||||
FlameAnimate(i, &gSmoke_column[i].pos, pTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall MungeSmokeColumn(tU32 pTime@<EAX>)
|
||||
|
|
@ -1866,7 +1965,66 @@ void PipeInstantUnSmudge(tCar_spec* pCar) {
|
|||
int group;
|
||||
tSmudged_vertex data[1000];
|
||||
LOG_TRACE("(%p)", pCar);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (!gAction_replay_mode) {
|
||||
return;
|
||||
}
|
||||
actor = pCar->car_model_actors[pCar->principal_car_actor].actor;
|
||||
model = actor->model;
|
||||
bonny = pCar->car_model_actors[pCar->car_actor_count - 1].actor;
|
||||
n = 0;
|
||||
if ((model->flags & BR_MODF_KEEP_ORIGINAL) != 0 || (model->flags & BR_MODF_UPDATEABLE) != 0) {
|
||||
StartPipingSession(ePipe_chunk_smudge);
|
||||
j = 0;
|
||||
for (group = 0; group < V11MODEL(model)->ngroups; group++) {
|
||||
for (v = 0; v < V11MODEL(model)->groups[group].nvertices; v++) {
|
||||
if ((V11MODEL(model)->groups[group].vertex_colours[v] >> 24) != 0) {
|
||||
data[n].vertex_index = j;
|
||||
data[n].light_index = -(V11MODEL(model)->groups[group].vertex_colours[v] >> 24);
|
||||
n += 1;
|
||||
V11MODEL(model)->groups[group].vertex_colours[v] = 0;
|
||||
if ((model->flags & 0x80) != 0) {
|
||||
model->vertices[V11MODEL(model)->groups[group].vertex_user[v]].index = 0;
|
||||
}
|
||||
if (n >= COUNT_OF(data)) {
|
||||
group = V11MODEL(model)->ngroups;
|
||||
break;
|
||||
}
|
||||
}
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
if (n != 0) {
|
||||
AddSmudgeToPipingSession(pCar->car_ID, pCar->principal_car_actor, n, data);
|
||||
}
|
||||
if (bonny != actor) {
|
||||
b_model = bonny->model;
|
||||
n = 0;
|
||||
j = 0;
|
||||
for (group = 0; group < V11MODEL(model)->ngroups; group++) {
|
||||
for (v = 0; v < V11MODEL(model)->groups[group].nvertices; v++) {
|
||||
if ((V11MODEL(model)->groups[group].vertex_colours[v] >> 24) != 0) {
|
||||
data[n].vertex_index = j;
|
||||
data[n].light_index = -V11MODEL(model)->groups[group].nvertices;
|
||||
n += 1;
|
||||
V11MODEL(model)->groups[group].vertex_colours[v] = 0;
|
||||
if ((b_model->flags & BR_MODF_UPDATEABLE) != 0) {
|
||||
b_model->vertices[V11MODEL(model)->groups[group].vertex_user[v]].index = 0;
|
||||
}
|
||||
if (n >= COUNT_OF(data)) {
|
||||
group = V11MODEL(model)->groups[group].nvertices;
|
||||
break;
|
||||
}
|
||||
}
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
if (n != 0) {
|
||||
AddSmudgeToPipingSession(pCar->car_ID, pCar->car_actor_count - 1, n, data);
|
||||
}
|
||||
}
|
||||
EndPipingSession();
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall SmudgeCar(tCar_spec *pCar@<EAX>, int fire_point@<EDX>)
|
||||
|
|
|
|||
|
|
@ -305,6 +305,7 @@ typedef enum keymapcodes {
|
|||
KEYMAP_SEND_MESSAGE = 66, // default `
|
||||
KEYMAP_ARROW = 25, // default R
|
||||
KEYMAP_INFO = 26, // default I
|
||||
KEYMAP_REPLAYMODE = 57, // default KP_ENTER
|
||||
} keymapcodes;
|
||||
|
||||
enum {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ typedef struct tCar_spec_struct2 tCar_spec2;
|
|||
typedef struct tPath_node_struct tPath_node;
|
||||
typedef struct tPath_section_struct tPath_section;
|
||||
typedef tU32 tPlayer_ID;
|
||||
typedef void* tPipe_reset_proc(void);
|
||||
typedef void tPipe_reset_proc(void);
|
||||
typedef struct tPowerup tPowerup;
|
||||
#ifdef DETHRACE_FIX_BUGS
|
||||
typedef int tGot_proc(tPowerup*, tCar_spec*);
|
||||
|
|
@ -2700,6 +2700,9 @@ typedef struct tPipe_chunk { // size: 0x58
|
|||
typedef struct tPipe_session {
|
||||
tPipe_chunk_type chunk_type;
|
||||
tU8 number_of_chunks;
|
||||
#if defined(DETHRACE_REPLAY_DEBUG)
|
||||
int magic1;
|
||||
#endif
|
||||
tPipe_chunk chunks;
|
||||
} tPipe_session;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@
|
|||
#define Vector3EqualElements(V, A, B, C) \
|
||||
((V)->v[0] == (A) && (V)->v[1] == (B) && (V)->v[2] == (C))
|
||||
#define Vector3IsZero(V) Vector3EqualElements((V), 0.f, 0.f, 0.f)
|
||||
|
||||
#define Vector3AddFloats(V1, V2, X, Y, Z) \
|
||||
do { (V1)->v[0] = (V2)->v[0] + (X); (V1)->v[1] = (V2)->v[1] + (Y); (V1)->v[2] = (V2)->v[2] + (Z); } while (0)
|
||||
#define SwapValuesUsingTemporary(V1, V2, T) \
|
||||
do { \
|
||||
(T) = (V1); \
|
||||
|
|
@ -47,4 +48,4 @@
|
|||
(V2) = (T); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ void PDFatalError(char* pThe_str) {
|
|||
|
||||
// wait for keypress
|
||||
|
||||
exit(1);
|
||||
abort();
|
||||
}
|
||||
|
||||
// IDA: void __usercall PDNonFatalError(char *pThe_str@<EAX>)
|
||||
|
|
@ -595,13 +595,13 @@ void PDAllocateActionReplayBuffer(char** pBuffer, tU32* pBuffer_size) {
|
|||
tU32 lba;
|
||||
tU32 required;
|
||||
LOG_TRACE("(%p, %p)", pBuffer, pBuffer_size);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
OS_AllocateActionReplayBuffer(pBuffer, pBuffer_size);
|
||||
}
|
||||
|
||||
// IDA: void __usercall PDDisposeActionReplayBuffer(char *pBuffer@<EAX>)
|
||||
void PDDisposeActionReplayBuffer(char* pBuffer) {
|
||||
LOG_TRACE("(\"%s\")", pBuffer);
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: void __usercall Usage(char *pProgpath@<EAX>)
|
||||
|
|
|
|||
|
|
@ -60,4 +60,6 @@ void S3BindListenerLeftBRender(br_vector3* left);
|
|||
|
||||
int S3IsCDAPlaying2();
|
||||
|
||||
int S3SetEffects(tS3_sample_filter* filter1, tS3_sample_filter* filter2);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "harness/config.h"
|
||||
#include "miniaudio/miniaudio.h"
|
||||
#include "resource.h"
|
||||
#include "harness/trace.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
@ -356,4 +357,8 @@ int S3SyncSampleRate(tS3_channel* chan) {
|
|||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void S3SetEffects(tS3_sample_filter* filter1, tS3_sample_filter* filter2) {
|
||||
STUB_ONCE();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -195,6 +195,8 @@ void Harness_Init(int* argc, char* argv[]) {
|
|||
harness_game_config.volume_multiplier = 1.0f;
|
||||
// start window in windowed mode
|
||||
harness_game_config.start_full_screen = 0;
|
||||
// disable replay by default
|
||||
harness_game_config.enable_replay = 0;
|
||||
|
||||
// install signal handler by default
|
||||
harness_game_config.install_signalhandler = 1;
|
||||
|
|
@ -284,6 +286,9 @@ int Harness_ProcessCommandLine(int* argc, char* argv[]) {
|
|||
} else if (strcasecmp(argv[i], "--full-screen") == 0) {
|
||||
harness_game_config.start_full_screen = 1;
|
||||
handled = 1;
|
||||
} else if (strcasecmp(argv[i], "--enable-replay") == 0) {
|
||||
harness_game_config.enable_replay = 1;
|
||||
handled = 1;
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ typedef struct tHarness_game_config {
|
|||
int enable_diagnostics;
|
||||
float volume_multiplier;
|
||||
int start_full_screen;
|
||||
int enable_replay;
|
||||
|
||||
int install_signalhandler;
|
||||
} tHarness_game_config;
|
||||
|
|
|
|||
|
|
@ -46,4 +46,7 @@ void OS_InstallSignalHandler(char* program_name);
|
|||
|
||||
FILE* OS_fopen(const char* pathname, const char* mode);
|
||||
|
||||
// Required: return a buffer for action replay. Preferably 20MB. If that is not available, then allocate a buffer of 12MB, 6MB, 4MB, 500kB or 64kiB
|
||||
void OS_AllocateActionReplayBuffer(char** pBuffer, unsigned* pBuffer_size);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0]))
|
||||
|
||||
static int stack_nbr = 0;
|
||||
static char _program_name[1024];
|
||||
#define MAX_STACK_FRAMES 64
|
||||
|
|
@ -335,3 +337,31 @@ FILE* OS_fopen(const char* pathname, const char* mode) {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void OS_AllocateActionReplayBuffer(char** pBuffer, unsigned* pBuffer_size) {
|
||||
static int allocated = 0;
|
||||
static char* buffer = NULL;
|
||||
static unsigned buffer_size = 0;
|
||||
unsigned i;
|
||||
const int wanted_sizes[] = {
|
||||
20000000,
|
||||
16000000,
|
||||
6000000,
|
||||
4000000,
|
||||
500000,
|
||||
};
|
||||
|
||||
if (!allocated) {
|
||||
allocated = 1;
|
||||
buffer_size = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(wanted_sizes); i++) {
|
||||
buffer = malloc(wanted_sizes[i]);
|
||||
if (buffer != NULL) {
|
||||
buffer_size = wanted_sizes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*pBuffer = buffer;
|
||||
*pBuffer_size = buffer_size;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0]))
|
||||
|
||||
static int stack_nbr = 0;
|
||||
static char _program_name[1024];
|
||||
#define MAX_STACK_FRAMES 64
|
||||
|
|
@ -294,3 +296,31 @@ void OS_InstallSignalHandler(char* program_name) {
|
|||
FILE* OS_fopen(const char* pathname, const char* mode) {
|
||||
return fopen(pathname, mode);
|
||||
}
|
||||
|
||||
void OS_AllocateActionReplayBuffer(char** pBuffer, unsigned* pBuffer_size) {
|
||||
static int allocated = 0;
|
||||
static char* buffer = NULL;
|
||||
static unsigned buffer_size = 0;
|
||||
unsigned i;
|
||||
const int wanted_sizes[] = {
|
||||
20000000,
|
||||
16000000,
|
||||
6000000,
|
||||
4000000,
|
||||
500000,
|
||||
};
|
||||
|
||||
if (!allocated) {
|
||||
allocated = 1;
|
||||
buffer_size = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(wanted_sizes); i++) {
|
||||
buffer = malloc(wanted_sizes[i]);
|
||||
if (buffer != NULL) {
|
||||
buffer_size = wanted_sizes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*pBuffer = buffer;
|
||||
*pBuffer_size = buffer_size;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <imagehlp.h>
|
||||
|
||||
#include "harness/os.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <direct.h>
|
||||
#include <errno.h>
|
||||
|
|
@ -23,6 +24,8 @@
|
|||
#define Ebp Rbp
|
||||
#endif
|
||||
|
||||
void dr_dprintf(char* fmt_string, ...);
|
||||
|
||||
static int stack_nbr = 0;
|
||||
static char _program_name[1024];
|
||||
LARGE_INTEGER qpc_start_time, EndingTime, ElapsedMicroseconds;
|
||||
|
|
@ -216,3 +219,92 @@ FILE* OS_fopen(const char* pathname, const char* mode) {
|
|||
|
||||
return f;
|
||||
}
|
||||
|
||||
void OS_AllocateActionReplayBuffer(char** pBuffer, unsigned* pBuffer_size) {
|
||||
static int allocated = 0;
|
||||
static char* buffer = NULL;
|
||||
static unsigned buffer_size = 0;
|
||||
MEMORYSTATUS memory_status;
|
||||
unsigned wanted;
|
||||
|
||||
if (allocated) {
|
||||
*pBuffer = buffer;
|
||||
*pBuffer_size = buffer_size;
|
||||
return;
|
||||
}
|
||||
allocated = 1;
|
||||
buffer = NULL;
|
||||
memory_status.dwLength = sizeof(memory_status);
|
||||
GlobalMemoryStatus(&memory_status);
|
||||
dr_dprintf(
|
||||
"Win32AllocateActionReplayBuffer(): Memory Status BEFORE Action Replay Allocation:\n"
|
||||
" dwLength %u\n"
|
||||
" dwMemoryLoad %u\n"
|
||||
" dwTotalPhys %u\n"
|
||||
" dwAvailPhys %u\n"
|
||||
" dwTotalPageFile %u\n"
|
||||
" dwAvailPageFile %u\n"
|
||||
" dwTotalVirtual %u\n"
|
||||
" dwAvailVirtual %u",
|
||||
memory_status.dwLength,
|
||||
memory_status.dwMemoryLoad,
|
||||
memory_status.dwTotalPhys,
|
||||
memory_status.dwAvailPhys,
|
||||
memory_status.dwTotalPageFile,
|
||||
memory_status.dwAvailPageFile,
|
||||
memory_status.dwTotalVirtual,
|
||||
memory_status.dwAvailVirtual);
|
||||
wanted = 20000000;
|
||||
if (memory_status.dwTotalPhys < 16000000) {
|
||||
wanted = 500000;
|
||||
} else if (memory_status.dwTotalPhys < 24000000) {
|
||||
wanted = 4000000;
|
||||
} else if (memory_status.dwTotalPhys < 32000000) {
|
||||
wanted = 6000000;
|
||||
} else if (memory_status.dwTotalPhys < 48000000) {
|
||||
wanted = 12000000;
|
||||
}
|
||||
dr_dprintf("Win32AllocateActionReplayBuffer(): We want %d bytes...", wanted);
|
||||
if (memory_status.dwAvailPageFile + memory_status.dwAvailPhys < wanted) {
|
||||
wanted = (memory_status.dwAvailPageFile + memory_status.dwAvailPhys) - 0x100000;
|
||||
dr_dprintf("Win32AllocateActionReplayBuffer(): ...but there's only %d bytes available...", wanted);
|
||||
}
|
||||
if (wanted < 0x10000) {
|
||||
wanted = 0x10000;
|
||||
dr_dprintf("Win32AllocateActionReplayBuffer(): ...but we have to have a minimum size of %d bytes...", wanted);
|
||||
}
|
||||
while (wanted >= 0x10000) {
|
||||
buffer = malloc(wanted);
|
||||
if (buffer != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (buffer == NULL) {
|
||||
buffer_size = 0;
|
||||
} else {
|
||||
buffer_size = wanted;
|
||||
// Sleep(1000); // Commented out 1s sleep
|
||||
}
|
||||
dr_dprintf("Win32AllocateActionReplayBuffer(): Actually allocated %d bytes.", wanted);
|
||||
GlobalMemoryStatus(&memory_status);
|
||||
dr_dprintf(
|
||||
"Win32AllocateActionReplayBuffer(): Memory Status AFTER Action Replay Allocation:\n"
|
||||
" dwLength %u\n"
|
||||
" dwMemoryLoad %u\n"
|
||||
" dwTotalPhys %u\n"
|
||||
" dwAvailPhys %u\n"
|
||||
" dwTotalPageFile %u\n"
|
||||
" dwAvailPageFile %u\n"
|
||||
" dwTotalVirtual %u\n"
|
||||
" dwAvailVirtual %u",
|
||||
memory_status.dwLength,
|
||||
memory_status.dwMemoryLoad,
|
||||
memory_status.dwTotalPhys,
|
||||
memory_status.dwAvailPhys,
|
||||
memory_status.dwTotalPageFile,
|
||||
memory_status.dwAvailPageFile,
|
||||
memory_status.dwTotalVirtual,
|
||||
memory_status.dwAvailVirtual);
|
||||
*pBuffer = buffer;
|
||||
*pBuffer_size = buffer_size;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue