Implement edit functions + functions around camera + ... (#146)
* Fix SEGFAULT due to reading out of bounds (we were using wrong index) * Use floats instead of doubles * Implement all flicplay.c functions * Compare ptr against NULL * Implement TotalRepair * Implement some edit functions * Implement actor/special volume related edit functions * Implement MungeSpecialVolume * Implement a few depth functions * Fix location of spawned actors (when SHIFT was not pressed) Co-authored-by: Dethrace Engineering Department <78985374+dethrace-labs@users.noreply.github.com>
This commit is contained in:
parent
b5ccfe7dd2
commit
db3d6ac91e
|
@ -12,6 +12,7 @@ extern struct br_font* BrFontProp7x9;
|
|||
// BrActor
|
||||
br_actor* BrActorLoad(char* filename);
|
||||
br_uint_32 BrActorLoadMany(char* filename, br_actor** actors, br_uint_16 num);
|
||||
br_uint_32 BrActorSave(char* filename, br_actor* ptr);
|
||||
br_actor* BrActorAllocate(br_uint_8 type, void* type_data);
|
||||
br_actor* BrActorAdd(br_actor* parent, br_actor* a);
|
||||
void BrActorRelink(br_actor* parent, br_actor* a);
|
||||
|
@ -77,6 +78,7 @@ void BrMatrix34Copy(br_matrix34* A, br_matrix34* B);
|
|||
void BrMatrix34PreRotateY(br_matrix34* mat, br_angle ry);
|
||||
void BrMatrix34RotateY(br_matrix34* mat, br_angle ry);
|
||||
void BrMatrix34PostScale(br_matrix34* mat, br_scalar sx, br_scalar sy, br_scalar sz);
|
||||
void BrMatrix34PreScale(br_matrix34* mat, br_scalar sx, br_scalar sy, br_scalar sz);
|
||||
void BrMatrix34PreTransform(br_matrix34* mat, br_transform* xform);
|
||||
void BrMatrix34PostTransform(br_matrix34* mat, br_transform* xform);
|
||||
void BrMatrix34PreRotateX(br_matrix34* mat, br_angle rx);
|
||||
|
@ -118,6 +120,7 @@ br_model* BrModelLoad(char* filename);
|
|||
void BrModelFree(br_model* model);
|
||||
void BrModelUpdate(br_model* model, br_uint_16 flags);
|
||||
br_uint_32 BrModelLoadMany(char* filename, br_model** models, br_uint_16 num);
|
||||
br_uint_32 BrModelSaveMany(char* filename, br_model** models, br_uint_16 num);
|
||||
br_model_find_cbfn* BrModelFindHook(br_model_find_cbfn* hook);
|
||||
|
||||
// BrPixelmap
|
||||
|
|
|
@ -1206,7 +1206,26 @@ void MungeSpecialVolume(tCollision_info* pCar) {
|
|||
tCar_spec* car;
|
||||
LOG_TRACE("(%p)", pCar);
|
||||
|
||||
STUB_ONCE();
|
||||
new_special_volume = FindSpecialVolume(&pCar->pos, pCar->last_special_volume);
|
||||
if (pCar->auto_special_volume != NULL && (new_special_volume == NULL || new_special_volume->gravity_multiplier == 1.f)) {
|
||||
if (pCar->water_d == 10000.f && pCar->water_depth_factor != 1.f) {
|
||||
pCar->auto_special_volume = NULL;
|
||||
} else {
|
||||
new_special_volume = pCar->auto_special_volume;
|
||||
}
|
||||
}
|
||||
if (pCar->last_special_volume != new_special_volume && pCar->driver == eDriver_local_human) {
|
||||
if (pCar->last_special_volume != NULL && pCar->last_special_volume->exit_noise >= 0 && (new_special_volume == NULL || pCar->last_special_volume->exit_noise != new_special_volume->exit_noise)) {
|
||||
DRS3StartSound(gCar_outlet, pCar->last_special_volume->exit_noise);
|
||||
}
|
||||
if (new_special_volume != NULL && new_special_volume->entry_noise >= 0 && (pCar->last_special_volume == NULL || pCar->last_special_volume->entry_noise != new_special_volume->entry_noise)) {
|
||||
DRS3StartSound(gCar_outlet, new_special_volume->entry_noise);
|
||||
}
|
||||
}
|
||||
pCar->last_special_volume = new_special_volume;
|
||||
if (new_special_volume != NULL && pCar->num_smoke_columns != 0 && pCar->last_special_volume != NULL && pCar->last_special_volume->gravity_multiplier < 1.f) {
|
||||
StopCarSmoking((tCar_spec*)pCar);
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall ResetCarSpecialVolume(tCollision_info *pCar@<EAX>)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "controls.h"
|
||||
|
||||
#include "brender/brender.h"
|
||||
#include "brucetrk.h"
|
||||
#include "car.h"
|
||||
#include "constants.h"
|
||||
#include "crush.h"
|
||||
|
@ -826,7 +827,6 @@ void LookRight() {
|
|||
// IDA: void __cdecl DamageTest()
|
||||
void DamageTest() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
}
|
||||
|
||||
// IDA: void __cdecl TDamageEngine()
|
||||
|
@ -920,7 +920,8 @@ void TDamageRRWheel() {
|
|||
// IDA: void __cdecl MoveBonnetForward()
|
||||
void MoveBonnetForward() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[2] -= .005f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl SaveBonnet()
|
||||
|
@ -928,109 +929,129 @@ void SaveBonnet() {
|
|||
br_actor* bonny;
|
||||
tPath_name the_path;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
bonny = gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor;
|
||||
PathCat(the_path, gApplication_path, bonny->identifier);
|
||||
BrActorSave(the_path, bonny);
|
||||
}
|
||||
|
||||
// IDA: void __cdecl MoveBonnetBackward()
|
||||
void MoveBonnetBackward() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[2] += .005f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl MoveBonnetLeft()
|
||||
void MoveBonnetLeft() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[0] -= .005f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl ShrinkBonnetX()
|
||||
void ShrinkBonnetX() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[0][0] *= .98f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl SwellBonnetX()
|
||||
void SwellBonnetX() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[0][0] *= 1.02f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl ShrinkBonnetY()
|
||||
void ShrinkBonnetY() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[1][1] *= .98f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl SwellBonnetY()
|
||||
void SwellBonnetY() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[1][1] *= 1.02f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl ShrinkBonnetZ()
|
||||
void ShrinkBonnetZ() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[2][2] *= .98f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl SwellBonnetZ()
|
||||
void SwellBonnetZ() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat.m[2][2] *= 1.02f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl MoveBonnetDown()
|
||||
void MoveBonnetDown() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[1] += .005f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl MoveBonnetRight()
|
||||
void MoveBonnetRight() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[0] += .005f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl MoveBonnetUp()
|
||||
void MoveBonnetUp() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.translate.t.v[1] -= .005f;
|
||||
}
|
||||
|
||||
// IDA: void __cdecl TiltBonnetDownX()
|
||||
void TiltBonnetDownX() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
BrMatrix34PreRotateX(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, BR_ANGLE_DEG(.5f));
|
||||
}
|
||||
|
||||
// IDA: void __cdecl TiltBonnetUpX()
|
||||
void TiltBonnetUpX() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
BrMatrix34PreRotateX(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, -BR_ANGLE_DEG(.5f));
|
||||
}
|
||||
|
||||
// IDA: void __cdecl TiltBonnetDownY()
|
||||
void TiltBonnetDownY() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
BrMatrix34PreRotateY(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, BR_ANGLE_DEG(.5f));
|
||||
}
|
||||
|
||||
// IDA: void __cdecl TiltBonnetUpY()
|
||||
void TiltBonnetUpY() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
BrMatrix34PreRotateY(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, -BR_ANGLE_DEG(.5f));
|
||||
}
|
||||
|
||||
// IDA: void __cdecl TiltBonnetDownZ()
|
||||
void TiltBonnetDownZ() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
BrMatrix34PreRotateZ(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, BR_ANGLE_DEG(.5f));
|
||||
}
|
||||
|
||||
// IDA: void __cdecl TiltBonnetUpZ()
|
||||
void TiltBonnetUpZ() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
BrMatrix34PreRotateZ(&gProgram_state.current_car.car_model_actors[gProgram_state.current_car.car_actor_count - 1].actor->t.t.mat, -BR_ANGLE_DEG(.5f));
|
||||
}
|
||||
|
||||
// IDA: void __cdecl ToggleCockpit()
|
||||
|
@ -1073,7 +1094,10 @@ void ToggleMirror() {
|
|||
// IDA: void __cdecl ConcussMe()
|
||||
void ConcussMe() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
SufferFromConcussion(1.f);
|
||||
NewScreenWobble(IRandomPosNeg(15), IRandomPosNeg(10), IRandomBetween(10, 60));
|
||||
PratcamEvent(3);
|
||||
}
|
||||
|
||||
// IDA: void __cdecl CheckHelp()
|
||||
|
@ -1370,7 +1394,19 @@ void ExplodeCar(tCar_spec* pCar) {
|
|||
br_vector3 tv;
|
||||
br_vector3 pos;
|
||||
LOG_TRACE("(%p)", pCar);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
pCar->last_car_car_collision = 0;
|
||||
pos.v[0] = .1449275f * pCar->cmpos.v[0];
|
||||
pos.v[1] = .1449275f * pCar->cmpos.v[1];
|
||||
pos.v[2] = pCar->bounds[0].min.v[2] + .3f * (pCar->bounds[0].max.v[2] - pCar->bounds[0].min.v[2]);
|
||||
BrMatrix34ApplyP(&tv, &pos, &pCar->car_master_actor->t.t.mat);
|
||||
CreatePuffOfSmoke(&tv, &pCar->v, 1.f, 1.f, 7, pCar);
|
||||
|
||||
pos.v[2] = pCar->bounds[0].min.v[2] + .7f * (pCar->bounds[0].max.v[2] - pCar->bounds[0].min.v[2]);
|
||||
BrMatrix34ApplyP(&tv, &pos, &pCar->car_master_actor->t.t.mat);
|
||||
CreatePuffOfSmoke(&tv, &pCar->v, 1.f, 1.f, 7, pCar);
|
||||
|
||||
DisableCar(pCar);
|
||||
}
|
||||
|
||||
// IDA: void __usercall CheckRecoveryOfCars(tU32 pEndFrameTime@<EAX>)
|
||||
|
@ -2168,21 +2204,60 @@ void ResetRecoveryVouchers() {
|
|||
void CycleCarTexturingLevel() {
|
||||
tCar_texturing_level new_level;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
new_level = (GetCarTexturingLevel() + 1) % eCTL_count;
|
||||
SetCarTexturingLevel(new_level);
|
||||
switch (new_level) {
|
||||
case eCTL_none:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(50));
|
||||
break;
|
||||
case eCTL_transparent:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(51));
|
||||
break;
|
||||
case eCTL_full:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(52));
|
||||
break;
|
||||
case eCTL_count:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl CycleWallTexturingLevel()
|
||||
void CycleWallTexturingLevel() {
|
||||
tWall_texturing_level new_level;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
new_level = (GetWallTexturingLevel() + 1) % eWTL_count;
|
||||
ReallySetWallTexturingLevel(new_level);
|
||||
SetWallTexturingLevel(new_level);
|
||||
switch (new_level) {
|
||||
case eWTL_none:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(55));
|
||||
break;
|
||||
case eWTL_linear:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(56));
|
||||
break;
|
||||
case eWTL_full:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(57));
|
||||
break;
|
||||
case eWTL_count:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl CycleRoadTexturingLevel()
|
||||
void CycleRoadTexturingLevel() {
|
||||
tRoad_texturing_level new_level;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
new_level = (GetRoadTexturingLevel() + 1) % 3;
|
||||
ReallySetRoadTexturingLevel(new_level);
|
||||
SetRoadTexturingLevel(new_level);
|
||||
if (new_level == eRTL_none) {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(53));
|
||||
} else if (new_level == eRTL_full) {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(54));
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl CycleYonFactor()
|
||||
|
@ -2190,7 +2265,21 @@ void CycleYonFactor() {
|
|||
br_scalar new_factor;
|
||||
char factor_str[5];
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
new_factor = GetYonFactor() / 2.f;
|
||||
if (new_factor < .1f) {
|
||||
new_factor = 1.f;
|
||||
}
|
||||
SetYonFactor(new_factor);
|
||||
if (new_factor > .75f) {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(100));
|
||||
} else if (new_factor > .375f) {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(101));
|
||||
} else if (new_factor > .187f) {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(102));
|
||||
} else {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(103));
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall SetSoundDetailLevel(int pLevel@<EAX>)
|
||||
|
@ -2222,7 +2311,21 @@ int GetSoundDetailLevel() {
|
|||
void CycleSoundDetailLevel() {
|
||||
int new_level;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
new_level = (gSound_detail_level + 1) % 3;
|
||||
ReallySetSoundDetailLevel(new_level);
|
||||
SetSoundDetailLevel(new_level);
|
||||
switch(new_level) {
|
||||
case 0:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(116));
|
||||
break;
|
||||
case 1:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(117));
|
||||
break;
|
||||
case 2:
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(118));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl CycleCarSimplificationLevel()
|
||||
|
@ -2230,21 +2333,46 @@ void CycleCarSimplificationLevel() {
|
|||
char* src;
|
||||
char* dst;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
gCar_simplification_level = (gCar_simplification_level + 1) % 5;
|
||||
src = GetMiscString(119);
|
||||
dst = BrMemAllocate(strlen(src), kMem_simp_level);
|
||||
sprintf(dst, src, gCar_simplification_level);
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, dst);
|
||||
BrMemFree(dst);
|
||||
}
|
||||
|
||||
// IDA: void __cdecl ToggleAccessoryRendering()
|
||||
void ToggleAccessoryRendering() {
|
||||
int on;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
if (gNet_mode == eNet_mode_none) {
|
||||
on = !GetAccessoryRendering();
|
||||
SetAccessoryRendering(on);
|
||||
if (on) {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(120));
|
||||
} else {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(121));
|
||||
}
|
||||
} else {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(124));
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __cdecl ToggleSmoke()
|
||||
void ToggleSmoke() {
|
||||
int on;
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
on = !GetSmokeOn();
|
||||
ReallySetSmokeOn(on);
|
||||
SetSmokeOn(on);
|
||||
if (on) {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(122));
|
||||
} else {
|
||||
NewTextHeadupSlot(4, 0, 2000, -4, GetMiscString(123));
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall DrawSomeText2(tDR_font *pFont@<EAX>)
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
#include "errors.h"
|
||||
#include "globvars.h"
|
||||
#include "globvrkm.h"
|
||||
#include "globvrpb.h"
|
||||
#include "harness/hooks.h"
|
||||
#include "harness/trace.h"
|
||||
#include "replay.h"
|
||||
#include "spark.h"
|
||||
#include "utility.h"
|
||||
#include <math.h>
|
||||
|
@ -80,7 +82,15 @@ br_scalar CalculateWrappingMultiplier(br_scalar pValue, br_scalar pYon) {
|
|||
br_scalar trunc_k;
|
||||
int int_k;
|
||||
LOG_TRACE("(%f, %f)", pValue, pYon);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
k = pYon * 1.3f * TAU / pValue;
|
||||
int_k = (int)k;
|
||||
if (k - int_k <= .5f) {
|
||||
trunc_k = int_k;
|
||||
} else {
|
||||
trunc_k = int_k + 1.f;
|
||||
}
|
||||
return trunc_k / TAU * pValue;
|
||||
}
|
||||
|
||||
// IDA: br_scalar __usercall DepthCueingShiftToDistance@<ST0>(int pShift@<EAX>)
|
||||
|
@ -128,6 +138,7 @@ void InstantDepthChange(tDepth_effect_type pType, br_pixelmap* pSky_texture, int
|
|||
// IDA: br_scalar __cdecl Tan(br_scalar pAngle)
|
||||
br_scalar Tan(br_scalar pAngle) {
|
||||
LOG_TRACE("(%f)", pAngle);
|
||||
|
||||
return sinf(BrAngleToRadian(pAngle)) / cosf(BrAngleToRadian(pAngle));
|
||||
}
|
||||
|
||||
|
@ -137,7 +148,11 @@ br_scalar EdgeU(br_angle pSky, br_angle pView, br_angle pPerfect) {
|
|||
br_scalar b;
|
||||
br_scalar c;
|
||||
LOG_TRACE("(%d, %d, %d)", pSky, pView, pPerfect);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
a = cosf(BrAngleToRadian(pPerfect));
|
||||
b = sinf(BrAngleToRadian(pView));
|
||||
c = cosf(BrAngleToRadian(pView));
|
||||
return b * a * a / (BrAngleToRadian(pSky) * (1.f + c));
|
||||
}
|
||||
|
||||
// IDA: void __usercall MungeSkyModel(br_actor *pCamera@<EAX>, br_model *pModel@<EDX>)
|
||||
|
@ -160,7 +175,71 @@ void MungeSkyModel(br_actor* pCamera, br_model* pModel) {
|
|||
br_angle angle_range;
|
||||
br_angle angle;
|
||||
LOG_TRACE("(%p, %p)", pCamera, pModel);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
camera_data = pCamera->type_data;
|
||||
|
||||
tan_half_fov = Tan(camera_data->field_of_view / 2);
|
||||
// BR_ANGLE_RAD(atan2f(tan_half_fov, camera_data->aspect / 2));
|
||||
horizon_half_width = (camera_data->yon_z - 1.f) * tan_half_fov;
|
||||
horizon_half_height = horizon_half_width * camera_data->aspect;
|
||||
horizon_half_diag = BR_LENGTH2(horizon_half_width, horizon_half_height);
|
||||
min_angle = BR_ANGLE_RAD(atan2f(horizon_half_diag, camera_data->yon_z - 1.f));
|
||||
edge_u = EdgeU(gSky_image_width, 2 * min_angle, BR_ANGLE_DEG(10));
|
||||
gSky_width = 2.f * horizon_half_width;
|
||||
gSky_height = 2.f * horizon_half_height;
|
||||
gSky_x_multiplier = CalculateWrappingMultiplier(gSky_width, camera_data->yon_z);
|
||||
gSky_y_multiplier = CalculateWrappingMultiplier(gSky_height, camera_data->yon_z);
|
||||
|
||||
for (vertex = 0; vertex < 88; vertex += 4) {
|
||||
pModel->vertices[vertex].map.v[0] = -edge_u;
|
||||
}
|
||||
for (vertex = 1; vertex < 88; vertex += 4) {
|
||||
pModel->vertices[vertex].map.v[0] = -edge_u / 2.f;
|
||||
}
|
||||
for (vertex = 2; vertex < 88; vertex += 4) {
|
||||
pModel->vertices[vertex].map.v[0] = edge_u / 2.f;
|
||||
}
|
||||
for (vertex = 3; vertex < 88; vertex += 4) {
|
||||
pModel->vertices[vertex].map.v[0] = edge_u;
|
||||
}
|
||||
for (vertex = 0; vertex < 88; vertex += 4) {
|
||||
pModel->vertices[vertex].p.v[0] = -horizon_half_diag;
|
||||
}
|
||||
for (vertex = 1; vertex < 88; vertex += 4) {
|
||||
pModel->vertices[vertex].p.v[0] = -horizon_half_diag / 2.f;
|
||||
}
|
||||
for (vertex = 2; vertex < 88; vertex += 4) {
|
||||
pModel->vertices[vertex].p.v[0] = horizon_half_diag / 2.f;
|
||||
}
|
||||
for (vertex = 3; vertex < 88; vertex += 4) {
|
||||
pModel->vertices[vertex].p.v[0] = horizon_half_diag;
|
||||
}
|
||||
PossibleService();
|
||||
angle_range = -(gSky_image_underground + (BR_ANGLE_DEG(90) - min_angle));
|
||||
for (vertex = 0; vertex < 2; vertex++) {
|
||||
angle = vertex * angle_range / 2 - (BR_ANGLE_DEG(90) + min_angle);
|
||||
pModel->vertices[0 + 4 * vertex].p.v[1] = sinf(BrAngleToRadian(angle)) * (camera_data->yon_z - 1.f);
|
||||
pModel->vertices[0 + 4 * vertex].p.v[2] = -cosf(BrAngleToRadian(angle)) * (camera_data->yon_z - 1.f);
|
||||
}
|
||||
for (vertex = 0; vertex < 18; vertex++) {
|
||||
angle = vertex * gSky_image_height / 18 - gSky_image_height;
|
||||
pModel->vertices[8 + 4 * vertex].p.v[1] = sinf(BrAngleToRadian(angle)) * (camera_data->yon_z - 1.f);
|
||||
pModel->vertices[8 + 4 * vertex].p.v[2] = -cosf(BrAngleToRadian(angle)) * (camera_data->yon_z - 1.f);
|
||||
}
|
||||
for (vertex = 0; vertex < 2; vertex++) {
|
||||
angle = vertex * (min_angle + BR_ANGLE_DEG(90) - (gSky_image_height - gSky_image_underground)) - (gSky_image_height - gSky_image_underground);
|
||||
pModel->vertices[80 + 4 * vertex].p.v[1] = sinf(BrAngleToRadian(angle)) * (camera_data->yon_z - 1.f);
|
||||
pModel->vertices[80 + 4 * vertex].p.v[2] = -cosf(BrAngleToRadian(angle)) * (camera_data->yon_z - 1.f);
|
||||
}
|
||||
PossibleService();
|
||||
for (band = 0; band < 22; band++) {
|
||||
for (vertex = 1; vertex < 4; vertex++) {
|
||||
pModel->vertices[4 * band + vertex].p.v[1] = pModel->vertices[vertex].p.v[1];
|
||||
pModel->vertices[4 * band + vertex].p.v[2] = pModel->vertices[vertex].p.v[2];
|
||||
}
|
||||
}
|
||||
// FIXME: unknown model flag disabled
|
||||
BrModelUpdate(pModel, BR_MODU_ALL & ~0x80);
|
||||
}
|
||||
|
||||
// IDA: br_model* __usercall CreateHorizonModel@<EAX>(br_actor *pCamera@<EAX>)
|
||||
|
@ -171,8 +250,36 @@ br_model* CreateHorizonModel(br_actor* pCamera) {
|
|||
tU8 stripe;
|
||||
br_model* model;
|
||||
LOG_TRACE("(%p)", pCamera);
|
||||
STUB();
|
||||
return NULL;
|
||||
|
||||
model = BrModelAllocate(NULL, 88, 126);
|
||||
model->flags |= BR_MODF_KEEP_ORIGINAL;
|
||||
for (band = 0; band < 21; band++) {
|
||||
for (stripe = 0; stripe < 3; stripe++) {
|
||||
model->faces[6 * band + 2 * stripe].vertices[0] = stripe + 4 * band + 0;
|
||||
model->faces[6 * band + 2 * stripe].vertices[1] = stripe + 4 * band + 1;
|
||||
model->faces[6 * band + 2 * stripe].vertices[2] = stripe + 4 * band + 5;
|
||||
model->faces[6 * band + 2 * stripe + 1].vertices[0] = stripe + 4 * band + 0;
|
||||
model->faces[6 * band + 2 * stripe + 1].vertices[1] = stripe + 4 * band + 5;
|
||||
model->faces[6 * band + 2 * stripe + 1].vertices[2] = stripe + 4 * band + 4;
|
||||
model->faces[6 * band + 2 * stripe + 0].smoothing = 1;
|
||||
model->faces[6 * band + 2 * stripe + 1].smoothing = 1;
|
||||
model->faces[6 * band + 2 * stripe + 0].material = NULL;
|
||||
model->faces[6 * band + 2 * stripe + 1].material = NULL;
|
||||
}
|
||||
}
|
||||
for (vertex = 0; vertex < 12; vertex++) {
|
||||
model->vertices[vertex].map.v[1] = 0.9999999f;
|
||||
}
|
||||
for (vertex = 80; vertex < 88; vertex++) {
|
||||
model->vertices[vertex].map.v[1] = 0.f;
|
||||
}
|
||||
for (band = 1; band < 18; band++) {
|
||||
model->vertices[4 * band + 8].map.v[1] = (float)(18 - band) / 18.f;
|
||||
for (stripe = 1; stripe < 4; stripe++) {
|
||||
model->vertices[4 * band + 8 + stripe].map.v[1] = model->vertices[4 * band + 8].map.v[1];
|
||||
}
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
// IDA: void __usercall LoadDepthTable(char *pName@<EAX>, br_pixelmap **pTable@<EDX>, int *pPower@<EBX>)
|
||||
|
@ -231,19 +338,18 @@ void InitDepthEffects() {
|
|||
BrMaterialAdd(gHorizon_material);
|
||||
gForward_sky_model = CreateHorizonModel(gCamera);
|
||||
gRearview_sky_model = CreateHorizonModel(gRearview_camera);
|
||||
LOG_WARN("InitDepthEffects not fully implemented. This will break cockpit views");
|
||||
// BrModelAdd(gForward_sky_model);
|
||||
// BrModelAdd(gRearview_sky_model);
|
||||
// gForward_sky_actor = BrActorAllocate(BR_ACTOR_MODEL, 0);
|
||||
// gForward_sky_actor->model = gForward_sky_model;
|
||||
// gForward_sky_actor->material = gHorizon_material;
|
||||
// gForward_sky_actor->render_style = BR_RSTYLE_NONE;
|
||||
// BrActorAdd(gUniverse_actor, gForward_sky_actor);
|
||||
// gRearview_sky_actor = BrActorAllocate(BR_ACTOR_MODEL, 0);
|
||||
// gRearview_sky_actor->model = gRearview_sky_model;
|
||||
// gRearview_sky_actor->material = gHorizon_material;
|
||||
// gRearview_sky_actor->render_style = BR_RSTYLE_NONE;
|
||||
// BrActorAdd(gUniverse_actor, gRearview_sky_actor);
|
||||
BrModelAdd(gForward_sky_model);
|
||||
BrModelAdd(gRearview_sky_model);
|
||||
gForward_sky_actor = BrActorAllocate(BR_ACTOR_MODEL, NULL);
|
||||
gForward_sky_actor->model = gForward_sky_model;
|
||||
gForward_sky_actor->material = gHorizon_material;
|
||||
gForward_sky_actor->render_style = BR_RSTYLE_NONE;
|
||||
BrActorAdd(gUniverse_actor, gForward_sky_actor);
|
||||
gRearview_sky_actor = BrActorAllocate(BR_ACTOR_MODEL, NULL);
|
||||
gRearview_sky_actor->model = gRearview_sky_model;
|
||||
gRearview_sky_actor->material = gHorizon_material;
|
||||
gRearview_sky_actor->render_style = BR_RSTYLE_NONE;
|
||||
BrActorAdd(gUniverse_actor, gRearview_sky_actor);
|
||||
gLast_camera_special_volume = 0;
|
||||
}
|
||||
|
||||
|
@ -397,13 +503,40 @@ void ExternalSky(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_act
|
|||
}
|
||||
}
|
||||
|
||||
#define ACTOR_CAMERA(ACTOR) ((br_camera*)((ACTOR)->type_data))
|
||||
|
||||
// IDA: void __usercall DoHorizon(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>, br_actor *pCamera@<EBX>, br_matrix34 *pCamera_to_world@<ECX>)
|
||||
void DoHorizon(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor* pCamera, br_matrix34* pCamera_to_world) {
|
||||
br_angle yaw;
|
||||
br_actor* actor;
|
||||
LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);
|
||||
|
||||
STUB_ONCE();
|
||||
yaw = BR_ANGLE_RAD(atan2f(pCamera_to_world->m[2][0], pCamera_to_world->m[2][2]));
|
||||
if (!gProgram_state.cockpit_on && !(gAction_replay_mode && gAction_replay_camera_mode)) {
|
||||
return;
|
||||
}
|
||||
if (gRendering_mirror) {
|
||||
actor = gRearview_sky_actor;
|
||||
} else {
|
||||
actor = gForward_sky_actor;
|
||||
if (ACTOR_CAMERA(gCamera)->field_of_view != gOld_fov || ACTOR_CAMERA(gCamera)->yon_z != gOld_yon) {
|
||||
gOld_fov = ACTOR_CAMERA(gCamera)->field_of_view;
|
||||
gOld_yon = ACTOR_CAMERA(gCamera)->yon_z;
|
||||
MungeSkyModel(gCamera, gForward_sky_model);
|
||||
}
|
||||
}
|
||||
BrMatrix34RotateY(&actor->t.t.mat, yaw);
|
||||
BrVector3Copy(&actor->t.t.translate.t, (br_vector3*)pCamera_to_world->m[3]);
|
||||
gHorizon_material->map_transform.m[0][0] = 1.f;
|
||||
gHorizon_material->map_transform.m[0][1] = 0.f;
|
||||
gHorizon_material->map_transform.m[1][0] = 0.f;
|
||||
gHorizon_material->map_transform.m[1][1] = 1.f;
|
||||
gHorizon_material->map_transform.m[2][0] = -BrFixedToFloat(yaw) / BrFixedToFloat(gSky_image_width);
|
||||
gHorizon_material->map_transform.m[2][1] = 0.f;
|
||||
BrMaterialUpdate(gHorizon_material, BR_MATU_ALL);
|
||||
actor->render_style = BR_RSTYLE_FACES;
|
||||
BrZbSceneRenderAdd(actor);
|
||||
actor->render_style = BR_RSTYLE_NONE;
|
||||
}
|
||||
|
||||
// IDA: void __usercall DoDepthCue(br_pixelmap *pRender_buffer@<EAX>, br_pixelmap *pDepth_buffer@<EDX>)
|
||||
|
|
|
@ -865,7 +865,35 @@ void DoDifferenceX(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
|
|||
tU8 the_byte;
|
||||
tU32 the_row_bytes;
|
||||
LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
first_line = MemReadU16(&pFlic_info->data);
|
||||
line_count = MemReadU16(&pFlic_info->data);
|
||||
the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
|
||||
line_pixel_ptr = pFlic_info->first_pixel + first_line * the_row_bytes;
|
||||
for (i = 0; i < line_count; i++) {
|
||||
pixel_ptr = line_pixel_ptr;
|
||||
number_of_packets = MemReadU8(&pFlic_info->data);
|
||||
for (j = 0; j < number_of_packets; j++) {
|
||||
skip_count = MemReadU8(&pFlic_info->data);
|
||||
size_count = MemReadS8(&pFlic_info->data);
|
||||
pixel_ptr += skip_count;
|
||||
if (size_count >= 0) {
|
||||
for (k = 0; k < size_count; k++) {
|
||||
*pixel_ptr = *pFlic_info->data;
|
||||
pFlic_info->data++;
|
||||
pixel_ptr++;
|
||||
}
|
||||
} else {
|
||||
the_byte = *pFlic_info->data;
|
||||
pFlic_info->data++;
|
||||
for (k = 0; k < -size_count; k++) {
|
||||
*pixel_ptr = the_byte;
|
||||
pixel_ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
line_pixel_ptr += the_row_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall DoDifferenceTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
|
||||
|
@ -883,7 +911,42 @@ void DoDifferenceTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
|
|||
tU8 the_byte;
|
||||
tU32 the_row_bytes;
|
||||
LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
first_line = MemReadU16(&pFlic_info->data);
|
||||
line_count = MemReadU16(&pFlic_info->data);
|
||||
the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
|
||||
line_pixel_ptr = pFlic_info->first_pixel + first_line * the_row_bytes;
|
||||
for (i = 0; i < line_count; i++) {
|
||||
pixel_ptr = line_pixel_ptr;
|
||||
number_of_packets = MemReadU8(&pFlic_info->data);
|
||||
for (j = 0; j < number_of_packets; j++) {
|
||||
skip_count = MemReadU8(&pFlic_info->data);
|
||||
size_count = MemReadS8(&pFlic_info->data);
|
||||
pixel_ptr += skip_count;
|
||||
if (size_count >= 0) {
|
||||
for (k = 0; k < size_count; k++) {
|
||||
the_byte = *pFlic_info->data;
|
||||
pFlic_info->data++;
|
||||
if (the_byte != '\0') {
|
||||
*pixel_ptr = the_byte;
|
||||
}
|
||||
pixel_ptr++;
|
||||
}
|
||||
} else {
|
||||
the_byte = *pFlic_info->data;
|
||||
pFlic_info->data++;
|
||||
if (the_byte == '\0') {
|
||||
pixel_ptr += size_count;
|
||||
} else {
|
||||
for (k = 0; k < -size_count; k++) {
|
||||
*pixel_ptr = the_byte;
|
||||
pixel_ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
line_pixel_ptr += the_row_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall DoColour256(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
|
||||
|
@ -1068,7 +1131,18 @@ void DoBlack(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
|
|||
tU32 the_row_bytes;
|
||||
tU32* line_pixel_ptr;
|
||||
LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
pixel_ptr = pFlic_info->first_pixel;
|
||||
the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
|
||||
the_width = pFlic_info->width;
|
||||
for (i = 0; i < pFlic_info->height; i++) {
|
||||
line_pixel_ptr = (tU32*)pixel_ptr;
|
||||
for (j = 0; j < the_width / sizeof(tU32); j++) {
|
||||
*line_pixel_ptr = 0;
|
||||
line_pixel_ptr++;
|
||||
}
|
||||
pixel_ptr += the_row_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall DoRunLengthX(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
|
||||
|
@ -1163,7 +1237,18 @@ void DoUncompressed(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
|
|||
tU32 the_row_bytes;
|
||||
tU32* line_pixel_ptr;
|
||||
LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
pixel_ptr = pFlic_info->first_pixel;
|
||||
the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
|
||||
the_width = pFlic_info->width;
|
||||
for (i = 0; i < pFlic_info->height; i++) {
|
||||
line_pixel_ptr = (tU32*)pixel_ptr;
|
||||
for (j = 0; j < the_width / 4; j++) {
|
||||
*line_pixel_ptr = MemReadU32(&pFlic_info->data);
|
||||
line_pixel_ptr++;
|
||||
}
|
||||
pixel_ptr += the_row_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall DoUncompressedTrans(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
|
||||
|
@ -1176,7 +1261,25 @@ void DoUncompressedTrans(tFlic_descriptor* pFlic_info, tU32 chunk_length) {
|
|||
tU8 the_byte;
|
||||
tU32 the_row_bytes;
|
||||
LOG_TRACE("(%p, %d)", pFlic_info, chunk_length);
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
pixel_ptr = pFlic_info->first_pixel;
|
||||
the_row_bytes = pFlic_info->the_pixelmap->row_bytes;
|
||||
the_width = pFlic_info->width;
|
||||
for (i = 0; i < pFlic_info->height; i++) {
|
||||
line_pixel_ptr = pixel_ptr;
|
||||
for (j = 0; j < the_width; j++) {
|
||||
#if defined (DETHRACE_FIX_BUGS)
|
||||
the_byte = MemReadU8(&pFlic_info->data);
|
||||
#else
|
||||
the_byte = MemReadU32(&pFlic_info->data);
|
||||
#endif
|
||||
if (the_byte != '\0') {
|
||||
*line_pixel_ptr = the_byte;
|
||||
}
|
||||
line_pixel_ptr++;
|
||||
}
|
||||
pixel_ptr += the_row_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
// IDA: void __usercall DoMini(tFlic_descriptor *pFlic_info@<EAX>, tU32 chunk_length@<EDX>)
|
||||
|
|
|
@ -1229,7 +1229,7 @@ void ProcessGetNearPlayer(tOpponent_spec* pOpponent_spec, tProcess_objective_com
|
|||
return;
|
||||
}
|
||||
if (pCommand == ePOC_run) {
|
||||
if ((pOpponent_spec->car_spec->car_ID & 0xFF00) == 768 && pOpponent_spec->distance_from_home > 75.0) {
|
||||
if ((pOpponent_spec->car_spec->car_ID & 0xff00) == 768 && pOpponent_spec->distance_from_home > 75.0) {
|
||||
dr_dprintf("%s: Completing get_near objective because I'm out of my precinct", pOpponent_spec->car_spec->driver_name);
|
||||
NewObjective(pOpponent_spec, eOOT_return_to_start);
|
||||
return;
|
||||
|
|
|
@ -624,7 +624,7 @@ void SetSoundVolumes() {
|
|||
if (!gSound_enabled) {
|
||||
return;
|
||||
}
|
||||
if (gEffects_outlet) {
|
||||
if (gEffects_outlet != NULL) {
|
||||
DRS3SetOutletVolume(gEffects_outlet, 42 * gProgram_state.effects_volume);
|
||||
}
|
||||
DRS3SetOutletVolume(gCar_outlet, 42 * gProgram_state.effects_volume);
|
||||
|
|
|
@ -82,7 +82,7 @@ void SetWorldToScreen(br_pixelmap* pScreen) {
|
|||
LOG_TRACE("(%p)", pScreen);
|
||||
|
||||
BrMatrix4Perspective(&mat, gSpark_cam->field_of_view, gSpark_cam->aspect, -gSpark_cam->hither_z, -gSpark_cam->yon_z);
|
||||
BrMatrix4Scale(&mat2, pScreen->width / 2, pScreen->height / 2, 1.0);
|
||||
BrMatrix4Scale(&mat2, pScreen->width / 2, pScreen->height / 2, 1.0f);
|
||||
BrMatrix4Mul(&gCameraToScreen, &mat, &mat2);
|
||||
}
|
||||
|
||||
|
|
|
@ -296,7 +296,9 @@ void CheckCheckpoints() {
|
|||
// IDA: void __cdecl TotalRepair()
|
||||
void TotalRepair() {
|
||||
LOG_TRACE("()");
|
||||
NOT_IMPLEMENTED();
|
||||
|
||||
TotallyRepairCar();
|
||||
NewTextHeadupSlot(4, 0, 1000, -4, GetMiscString(41));
|
||||
}
|
||||
|
||||
// IDA: void __cdecl DoLogos()
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue