Set Initial Grid Position (#46)

* Implements SetInitialPosition, fixed prepareGroups vertices
This commit is contained in:
Jeff Harris 2021-04-13 14:04:03 +12:00 committed by GitHub
parent 1ce611e9d8
commit 43f517234d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 856 additions and 95 deletions

View File

@ -1,7 +1,6 @@
name: linux
on:
pull_request:
push:
release:
types: published

View File

@ -45,11 +45,11 @@ jobs:
echo "$Env:TEMP\ninja" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
ninja --version
- name: Configure Deathrace
- name: Configure
run: |
cmake -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DSDL2=ON "-DSDL2_ROOT_DIR=$($Env:TEMP)\SDL2-2.0.12" -B build
- name: Build Deathrace
- name: Build
run: |
cmake --build build --config RelWithDebInfo

View File

@ -4,11 +4,6 @@
#include "br_types.h"
#include <math.h>
#define BrAngleToRadian(a) ((br_scalar)((a) * (M_PI / 32768.0)))
#define BrRadianToAngle(r) ((br_angle)(long)((r) * (32768.0 / M_PI)))
#define BR_COS(a) ((br_scalar)cos(BrAngleToRadian(a)))
br_matrix34* BrEulerToMatrix34(br_matrix34* mat, br_euler* euler);
br_euler* BrMatrix34ToEuler(br_euler* euler, br_matrix34* mat);

View File

@ -86,7 +86,22 @@ void BrMatrix34RotateY(br_matrix34* mat, br_angle ry) {
br_scalar s;
br_scalar c;
LOG_TRACE("(%p, %d)", mat, ry);
NOT_IMPLEMENTED();
s = BR_SIN(ry);
c = BR_COS(ry);
M(0, 0) = c;
M(0, 1) = 0;
M(0, 2) = -s;
M(1, 0) = 0;
M(1, 1) = 1;
M(1, 2) = 0;
M(2, 0) = s;
M(2, 1) = 0;
M(2, 2) = c;
M(3, 0) = 0;
M(3, 1) = 0;
M(3, 2) = 0;
}
// IDA: void __cdecl BrMatrix34RotateZ(br_matrix34 *mat, br_angle rz)
@ -177,7 +192,69 @@ br_scalar BrMatrix34Inverse(br_matrix34* B, br_matrix34* A) {
float BF[4][3];
int i;
LOG_TRACE("(%p, %p)", B, A);
NOT_IMPLEMENTED();
#define AF(x, y) (AF[x][y])
#define BF(x, y) (BF[x][y])
#define ACCUMULATE \
if (temp >= 0.0) \
pos += temp; \
else \
neg += temp;
#define PRECISION_LIMIT BR_SCALAR(1.0e-15)
#define ABS(a) (((a) < 0) ? -(a) : (a))
for (i = 0; i < 4; i++) {
AF(i, 0) = A(i, 0);
AF(i, 1) = A(i, 1);
AF(i, 2) = A(i, 2);
}
pos = neg = 0.0F;
temp = AF(0, 0) * AF(1, 1) * AF(2, 2);
ACCUMULATE
temp = AF(0, 1) * AF(1, 2) * AF(2, 0);
ACCUMULATE
temp = AF(0, 2) * AF(1, 0) * AF(2, 1);
ACCUMULATE
temp = -AF(0, 2) * AF(1, 1) * AF(2, 0);
ACCUMULATE
temp = -AF(0, 1) * AF(1, 0) * AF(2, 2);
ACCUMULATE
temp = -AF(0, 0) * AF(1, 2) * AF(2, 1);
ACCUMULATE
det = pos + neg;
if (ABS(det) <= PRECISION_LIMIT)
return 0;
if ((ABS(det / (pos - neg)) < PRECISION_LIMIT)) {
return 0;
}
idet = 1.0F / det;
BF(0, 0) = (AF(1, 1) * AF(2, 2) - AF(1, 2) * AF(2, 1)) * idet;
BF(1, 0) = -(AF(1, 0) * AF(2, 2) - AF(1, 2) * AF(2, 0)) * idet;
BF(2, 0) = (AF(1, 0) * AF(2, 1) - AF(1, 1) * AF(2, 0)) * idet;
BF(0, 1) = -(AF(0, 1) * AF(2, 2) - AF(0, 2) * AF(2, 1)) * idet;
BF(1, 1) = (AF(0, 0) * AF(2, 2) - AF(0, 2) * AF(2, 0)) * idet;
BF(2, 1) = -(AF(0, 0) * AF(2, 1) - AF(0, 1) * AF(2, 0)) * idet;
BF(0, 2) = (AF(0, 1) * AF(1, 2) - AF(0, 2) * AF(1, 1)) * idet;
BF(1, 2) = -(AF(0, 0) * AF(1, 2) - AF(0, 2) * AF(1, 0)) * idet;
BF(2, 2) = (AF(0, 0) * AF(1, 1) - AF(0, 1) * AF(1, 0)) * idet;
BF(3, 0) = -(AF(3, 0) * BF(0, 0) + AF(3, 1) * BF(1, 0) + AF(3, 2) * BF(2, 0));
BF(3, 1) = -(AF(3, 0) * BF(0, 1) + AF(3, 1) * BF(1, 1) + AF(3, 2) * BF(2, 1));
BF(3, 2) = -(AF(3, 0) * BF(0, 2) + AF(3, 1) * BF(1, 2) + AF(3, 2) * BF(2, 2));
for (i = 0; i < 4; i++) {
B(i, 0) = BF(i, 0);
B(i, 1) = BF(i, 1);
B(i, 2) = BF(i, 2);
}
return det;
}
// IDA: void __cdecl BrMatrix34LPInverse(br_matrix34 *A, br_matrix34 *B)
@ -243,7 +320,10 @@ void BrMatrix34ApplyP(br_vector3* A, br_vector3* B, br_matrix34* C) {
// IDA: void __cdecl BrMatrix34ApplyV(br_vector3 *A, br_vector3 *B, br_matrix34 *C)
void BrMatrix34ApplyV(br_vector3* A, br_vector3* B, br_matrix34* C) {
LOG_TRACE("(%p, %p, %p)", A, B, C);
NOT_IMPLEMENTED();
A->v[0] = BR_MAC3(B->v[0], C(0, 0), B->v[1], C(1, 0), B->v[2], C(2, 0));
A->v[1] = BR_MAC3(B->v[0], C(0, 1), B->v[1], C(1, 1), B->v[2], C(2, 1));
A->v[2] = BR_MAC3(B->v[0], C(0, 2), B->v[1], C(1, 2), B->v[2], C(2, 2));
}
// IDA: void __cdecl BrMatrix34TApply(br_vector4 *A, br_vector4 *B, br_matrix34 *C)
@ -294,7 +374,10 @@ void BrMatrix34PostRotateX(br_matrix34* mat, br_angle rx) {
// IDA: void __cdecl BrMatrix34PreRotateY(br_matrix34 *mat, br_angle ry)
void BrMatrix34PreRotateY(br_matrix34* mat, br_angle ry) {
LOG_TRACE("(%p, %d)", mat, ry);
NOT_IMPLEMENTED();
BrMatrix34RotateY(&mattmp1, ry);
BrMatrix34Mul(&mattmp2, &mattmp1, mat);
BrMatrix34Copy(mat, &mattmp2);
}
// IDA: void __cdecl BrMatrix34PostRotateY(br_matrix34 *mat, br_angle ry)
@ -351,7 +434,10 @@ void BrMatrix34PreScale(br_matrix34* mat, br_scalar sx, br_scalar sy, br_scalar
// IDA: void __cdecl BrMatrix34PostScale(br_matrix34 *mat, br_scalar sx, br_scalar sy, br_scalar sz)
void BrMatrix34PostScale(br_matrix34* mat, br_scalar sx, br_scalar sy, br_scalar sz) {
LOG_TRACE("(%p, %f, %f, %f)", mat, sx, sy, sz);
NOT_IMPLEMENTED();
BrMatrix34Scale(&mattmp1, sx, sy, sz);
BrMatrix34Mul(&mattmp2, mat, &mattmp1);
BrMatrix34Copy(mat, &mattmp2);
}
// IDA: void __cdecl BrMatrix34PreShearX(br_matrix34 *mat, br_scalar sy, br_scalar sz)

View File

@ -97,7 +97,13 @@ void BrMatrix34PreTransform(br_matrix34* mat, br_transform* xform) {
void BrMatrix34PostTransform(br_matrix34* mat, br_transform* xform) {
br_matrix34 tmp;
LOG_TRACE("(%p, %p)", mat, xform);
NOT_IMPLEMENTED();
if (xform->type == BR_TRANSFORM_IDENTITY) {
return;
}
BrTransformToMatrix34(&tmp, xform);
BrMatrix34Post(mat, &tmp);
}
// IDA: void __cdecl BrMatrix4PreTransform(br_matrix4 *mat, br_transform *xform)

View File

@ -476,10 +476,11 @@ void PrepareGroups(br_model* model) {
for (g = 0; g < ng; g++) {
for (f = 0; f < v11g[g].nfaces; f++) {
i = v11g[g].vertices - v11v;
v = v11g[g].face_user[f] * 3;
v11g[g].faces[f].vertices[0] = temp_verts[v + 0].v;
v11g[g].faces[f].vertices[1] = temp_verts[v + 1].v;
v11g[g].faces[f].vertices[2] = temp_verts[v + 2].v;
v11g[g].faces[f].vertices[0] = temp_verts[v + 0].v - i;
v11g[g].faces[f].vertices[1] = temp_verts[v + 1].v - i;
v11g[g].faces[f].vertices[2] = temp_verts[v + 2].v - i;
}
}
BrScratchFree(temp_verts);

45
src/BRSRC13/br_defs.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef BR_DEFS_H
#define BR_DEFS_H
#define PI 3.14159265358979323846
#define BrAngleToRadian(a) ((br_scalar)((a) * (PI / 32768.0))) // a * 0.00009587379924285257
#define BrRadianToAngle(r) ((br_angle)(long)((r) * (32768.0 / PI))) // r * 10430.378350470453
#define BR_COLOUR_RGB(r, g, b) \
((((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b)))
#define BR_ANGLE_DEG(deg) ((br_angle)((deg)*182))
#define BR_ANGLE_RAD(rad) ((br_angle)((rad)*10430))
#define BrDegreeToRadian(d) ((br_scalar)((d) * (PI / 180.0)))
#define BR_SCALAR(x) ((br_scalar)(x))
#define BR_COLOUR_RGBA(r, g, b, a) \
((((unsigned int)(a)) << 24) | (((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b)))
#define BR_LENGTH3(a, b, c) ((br_scalar)sqrt((a) * (a) + (b) * (b) + (c) * (c)))
#define BR_SCALAR_EPSILON 1.192092896e-7f
#define BR_SCALAR_MAX 3.402823466e+38f
#define BR_SCALAR_MIN (-3.402823466e+38f)
#define BR_SIMPLEHEAD(l) (void*)(((br_simple_list*)(l))->head)
#define BR_SIMPLENEXT(n) (void*)(((br_simple_node*)(n))->next)
#define BR_FOR_SIMPLELIST(list, ptr) for ((ptr) = BR_SIMPLEHEAD(list); (ptr); (ptr) = BR_SIMPLENEXT(ptr))
#define V_X 0
#define V_Y 1
#define V_Z 2
#define V_W 3
#define BR_FONTF_PROPORTIONAL 1
#define BR_SIN(a) ((br_scalar)sin(BrAngleToRadian(a)))
#define BR_COS(a) ((br_scalar)cos(BrAngleToRadian(a)))
#define BR_TAN(a) ((br_scalar)tan(BrAngleToRadian(a)))
#define BR_ASIN(a) BrRadianToAngle(asin(a))
#define BR_ACOS(a) BrRadianToAngle(acos(a))
#define BR_ATAN2(a, b) BrRadianToAngle(atan2((a), (b)))
#define BR_ATAN2FAST(a, b) BrRadianToAngle(atan2((a), (b)))
#endif /* BR_DEFS_H */

View File

@ -1,6 +1,7 @@
#ifndef BR_TYPES_H
#define BR_TYPES_H
#include "br_defs.h"
#include <setjmp.h>
#include <stdint.h>
@ -2795,6 +2796,7 @@ typedef struct v11group {
void* stored;
v11face* faces;
br_colour* face_colours;
br_material* face_colours_material; // Jeff added to avoid 64 bit issues trying to pack br_material* into br_colour
br_uint_16* face_user;
fmt_vertex* vertices;
br_colour* vertex_colours;
@ -3003,32 +3005,4 @@ enum {
MODF_USES_DEFAULT = 0x8000
};
#define BR_COLOUR_RGB(r, g, b) \
((((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b)))
#define BR_ANGLE_DEG(deg) ((br_angle)((deg)*182))
#define BR_ANGLE_RAD(rad) ((br_angle)((rad)*10430))
#define BrDegreeToRadian(d) ((br_scalar)((d) * (M_PI / 180.0)))
#define BR_SCALAR(x) ((br_scalar)(x))
#define BR_COLOUR_RGBA(r, g, b, a) \
((((unsigned int)(a)) << 24) | (((unsigned int)(r)) << 16) | (((unsigned int)(g)) << 8) | ((unsigned int)(b)))
#define BR_LENGTH3(a, b, c) ((br_scalar)sqrt((a) * (a) + (b) * (b) + (c) * (c)))
#define BR_SCALAR_EPSILON 1.192092896e-7f
#define BR_SCALAR_MAX 3.402823466e+38f
#define BR_SCALAR_MIN (-3.402823466e+38f)
#define BR_SIMPLEHEAD(l) (void*)(((br_simple_list*)(l))->head)
#define BR_SIMPLENEXT(n) (void*)(((br_simple_node*)(n))->next)
#define BR_FOR_SIMPLELIST(list, ptr) for ((ptr) = BR_SIMPLEHEAD(list); (ptr); (ptr) = BR_SIMPLENEXT(ptr))
#define V_X 0
#define V_Y 1
#define V_Z 2
#define V_W 3
#define BR_FONTF_PROPORTIONAL 1
#endif /* BR_TYPES_H */

View File

@ -56,12 +56,18 @@ br_uint_32 BrMaterialEnum(char* pattern, br_material_enum_cbfn* callback, void*
void BrMatrix23Identity(br_matrix23* mat);
void BrMatrix34Identity(br_matrix34* mat);
void BrMatrix34ApplyV(br_vector3* A, br_vector3* B, br_matrix34* C);
br_scalar BrMatrix34Inverse(br_matrix34* B, br_matrix34* A);
void BrMatrix34ApplyP(br_vector3* A, br_vector3* B, br_matrix34* C);
void BrMatrix34Scale(br_matrix34* mat, br_scalar sx, br_scalar sy, br_scalar sz);
void BrMatrix34PostTranslate(br_matrix34* mat, br_scalar x, br_scalar y, br_scalar z);
void BrMatrix34Mul(br_matrix34* A, br_matrix34* B, br_matrix34* C);
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 BrMatrix34PreTransform(br_matrix34* mat, br_transform* xform);
void BrMatrix34PostTransform(br_matrix34* mat, br_transform* xform);
// BrMem
void BrMemFree(void* block);
@ -106,6 +112,9 @@ br_pixelmap* BrTableFind(char* pattern);
br_pixelmap* BrTableRemove(br_pixelmap* pixelmap);
br_uint_32 BrTableAddMany(br_pixelmap** items, int n);
// BrTransform
void BrTransformToMatrix34(br_matrix34* mat, br_transform* xform);
// BrV1db
void BrV1dbBeginWrapper_Float();

View File

@ -1,4 +1,12 @@
#include "car.h"
#include "brender.h"
#include "globvars.h"
#include "globvrkm.h"
#include "globvrpb.h"
#include "netgame.h"
#include "opponent.h"
#include "raycast.h"
#include "utility.h"
#include <stdlib.h>
float gEngine_powerup_factor[6];
@ -205,7 +213,8 @@ void InitialiseCar2(tCar_spec* pCar, int pClear_disabled_flag) {
// IDA: void __usercall InitialiseCar(tCar_spec *pCar@<EAX>)
void InitialiseCar(tCar_spec* pCar) {
LOG_TRACE("(%p)", pCar);
NOT_IMPLEMENTED();
InitialiseCar2(pCar, 1);
}
// IDA: void __usercall InitialiseCarsEtc(tRace_info *pThe_race@<EAX>)
@ -216,7 +225,33 @@ void InitialiseCarsEtc(tRace_info* pThe_race) {
tCar_spec* car;
br_bounds bnds;
LOG_TRACE("(%p)", pThe_race);
NOT_IMPLEMENTED();
gProgram_state.initial_position = pThe_race->initial_position;
gProgram_state.initial_yaw = pThe_race->initial_yaw;
BrActorToBounds(&bnds, gProgram_state.track_spec.the_actor);
gMin_world_y = bnds.min.v[1];
gNum_active_non_cars = 0;
for (cat = eVehicle_self; cat <= eVehicle_not_really; ++cat) {
if (cat) {
car_count = GetCarCount(cat);
} else {
car_count = 1;
}
for (i = 0; car_count > i; ++i) {
PossibleService();
if (cat) {
car = GetCarSpec(cat, i);
} else {
car = &gProgram_state.current_car;
}
if (cat != eVehicle_not_really) {
InitialiseCar(car);
}
}
}
gCamera_yaw = 0;
InitialiseExternalCamera();
gMechanics_time_sync = 0;
}
// IDA: void __usercall GetAverageGridPosition(tRace_info *pThe_race@<EAX>)
@ -250,14 +285,108 @@ void SetInitialPosition(tRace_info* pThe_race, int pCar_index, int pGrid_index)
br_matrix34 initial_yaw_matrix;
br_bounds bnds;
LOG_TRACE("(%p, %d, %d)", pThe_race, pCar_index, pGrid_index);
NOT_IMPLEMENTED();
car_actor = pThe_race->opponent_list[pCar_index].car_spec->car_master_actor;
car = pThe_race->opponent_list[pCar_index].car_spec;
BrMatrix34Identity(&car_actor->t.t.mat);
place_on_grid = 1;
if (gNet_mode && !gCurrent_net_game->options.grid_start && pThe_race->number_of_net_start_points) {
TELL_ME_IF_WE_PASS_THIS_WAY();
// start_i = IRandomBetween(0, pThe_race->number_of_net_start_points - 1);
// i = start_i;
// while (1) {
// PossibleService();
// for (j = 0; gNumber_of_net_players > j; ++j) {
// if (j != pCar_index) {
// v19 = pThe_race->opponent_list[j].car_spec->car_master_actor->t.t.translate.t.v[0];
// v20 = pThe_race->opponent_list[j].car_spec->car_master_actor->t.t.translate.t.v[1];
// v21 = pThe_race->opponent_list[j].car_spec->car_master_actor->t.t.translate.t.v[2];
// if (v19 > 500.0) {
// v19 = v19 - 1000.0f;
// v20 = v20 - 1000.0f;
// v21 = v21 - 1000.0f;
// }
// dist.v[0] = v19 - pThe_race->net_starts[start_i].pos.v[0];
// dist.v[1] = v20 - pThe_race->net_starts[start_i].pos.v[1];
// dist.v[2] = v21 - pThe_race->net_starts[start_i].pos.v[2];
// if (dist.v[1] * dist.v[1] + dist.v[2] * dist.v[2] + dist.v[0] * dist.v[0] < 16.0) {
// break;
// }
// }
// }
// if (gNumber_of_net_players == j) {
// break;
// }
// if (pThe_race->number_of_net_start_points == ++start_i) {
// start_i = 0;
// }
// if (i == start_i) {
// goto LABEL_17;
// }
// }
// car_actor->t.t.translate.t.v[0] = pThe_race->net_starts[start_i].pos.v[0];
// car_actor->t.t.translate.t.v[1] = pThe_race->net_starts[start_i].pos.v[1];
// car_actor->t.t.translate.t.v[2] = pThe_race->net_starts[start_i].pos.v[2];
// initial_yaw[0] = (__int64)(pThe_race->net_starts[start_i].yaw * 182.0444444444445);
// place_on_grid = 0;
}
LABEL_17:
if (place_on_grid) {
initial_yaw = (pThe_race->initial_yaw * 182.0444444444445);
BrMatrix34RotateY(&initial_yaw_matrix, initial_yaw);
grid_offset.v[0] = 0.0 - pGrid_index % 2;
grid_offset.v[1] = 0.0;
grid_offset.v[2] = (double)(pGrid_index / 2) * 2.0 + (double)(pGrid_index % 2) * 0.40000001;
LOG_DEBUG("grid offset: %f, %f, %f", grid_offset.v[0], grid_offset.v[1], grid_offset.v[2]);
BrMatrix34ApplyV(&car_actor->t.t.translate.t, &grid_offset, &initial_yaw_matrix);
car_actor->t.t.translate.t.v[0] += pThe_race->initial_position.v[0];
car_actor->t.t.translate.t.v[1] += pThe_race->initial_position.v[1];
car_actor->t.t.translate.t.v[2] += pThe_race->initial_position.v[2];
LOG_DEBUG("yaw: %f, pos: %f, %f, %f", pThe_race->initial_yaw, pThe_race->initial_position.v[0], pThe_race->initial_position.v[1], pThe_race->initial_position.v[2]);
}
LOG_DEBUG("grid pos: %d, pos: x=%f, z=%f", pGrid_index, car_actor->t.t.translate.t.v[0], car_actor->t.t.translate.t.v[2]);
FindBestY(
&car_actor->t.t.translate.t,
gTrack_actor,
10.0,
&nearest_y_above,
&nearest_y_below,
&above_model,
&below_model,
&above_face_index,
&below_face_index);
if (nearest_y_above == 30000.0) {
if (nearest_y_below == -30000.0) {
LOG_DEBUG("found pos 1: %f", 0);
car_actor->t.t.translate.t.v[1] = 0.0;
} else {
LOG_DEBUG("found pos 2: %f", nearest_y_below);
car_actor->t.t.translate.t.v[1] = nearest_y_below;
}
} else {
// 20.345
LOG_DEBUG("found pos 3: %f, x: %f, z: %f", nearest_y_above, car_actor->t.t.translate.t.v[0], car_actor->t.t.translate.t.v[2]);
car_actor->t.t.translate.t.v[1] = nearest_y_above;
}
BrMatrix34PreRotateY(&car_actor->t.t.mat, initial_yaw);
if (gNet_mode) {
BrMatrix34Copy(
&gNet_players[pThe_race->opponent_list[pCar_index].net_player_index].initial_position,
&car->car_master_actor->t.t.mat);
}
if (gNet_mode && car->disabled && car_actor->t.t.translate.t.v[0] < 500.0) {
DisableCar(car);
}
}
// IDA: void __usercall SetInitialPositions(tRace_info *pThe_race@<EAX>)
void SetInitialPositions(tRace_info* pThe_race) {
int i;
LOG_TRACE("(%p)", pThe_race);
NOT_IMPLEMENTED();
for (i = 0; i < pThe_race->number_of_racers; i++) {
SetInitialPosition(pThe_race, i, i);
}
}
// IDA: void __usercall InitialiseNonCar(tNon_car_spec *non_car@<EAX>)

View File

@ -1,5 +1,7 @@
#include "finteray.h"
#include "brender.h"
#include "globvars.h"
#include "raycast.h"
#include <stdlib.h>
br_matrix34 gPick_model_to_view;
@ -18,7 +20,9 @@ tFace_ref* gPling_face;
// IDA: void __usercall DRVector2AccumulateScale(br_vector2 *a@<EAX>, br_vector2 *b@<EDX>, br_scalar s)
void DRVector2AccumulateScale(br_vector2* a, br_vector2* b, br_scalar s) {
LOG_TRACE("(%p, %p, %f)", a, b, s);
NOT_IMPLEMENTED();
a->v[0] = b->v[0] * s + a->v[0];
a->v[1] = b->v[1] * s + a->v[1];
}
// IDA: int __usercall ActorRayPick2D@<EAX>(br_actor *ap@<EAX>, br_vector3 *pPosition@<EDX>, br_vector3 *pDir@<EBX>, br_model *model@<ECX>, br_material *material, dr_pick2d_cbfn *callback)
@ -47,13 +51,30 @@ int DRSceneRayPick2D(br_actor* world, br_vector3* pPosition, br_vector3* pDir, d
// IDA: int __cdecl FindHighestPolyCallBack(br_model *pModel, br_material *pMaterial, br_vector3 *pRay_pos, br_vector3 *pRay_dir, br_scalar pT, int pF, int pE, int pV, br_vector3 *pPoint, br_vector2 *pMap, void *pArg)
int FindHighestPolyCallBack(br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pT, int pF, int pE, int pV, br_vector3* pPoint, br_vector2* pMap, void* pArg) {
LOG_TRACE("(%p, %p, %p, %p, %f, %d, %d, %d, %p, %p, %p)", pModel, pMaterial, pRay_pos, pRay_dir, pT, pF, pE, pV, pPoint, pMap, pArg);
NOT_IMPLEMENTED();
if (pPoint->v[1] > gCurrent_y) {
if (gLowest_y_above > pPoint->v[1]) {
gLowest_y_above = pPoint->v[1];
gAbove_face_index = pF;
gAbove_model = pModel;
}
} else if (pPoint->v[1] > gHighest_y_below) {
gHighest_y_below = pPoint->v[1];
gBelow_face_index = pF;
gBelow_model = pModel;
}
return 0;
}
// IDA: int __cdecl FindHighestCallBack(br_actor *pActor, br_model *pModel, br_material *pMaterial, br_vector3 *pRay_pos, br_vector3 *pRay_dir, br_scalar pT_near, br_scalar pT_far, void *pArg)
int FindHighestCallBack(br_actor* pActor, br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pT_near, br_scalar pT_far, void* pArg) {
LOG_TRACE("(%p, %p, %p, %p, %p, %f, %f, %p)", pActor, pModel, pMaterial, pRay_pos, pRay_dir, pT_near, pT_far, pArg);
NOT_IMPLEMENTED();
if (gProgram_state.current_car.current_car_actor < 0
|| gProgram_state.current_car.car_model_actors[gProgram_state.current_car.current_car_actor].actor != pActor) {
DRModelPick2D(pModel, pMaterial, pRay_pos, pRay_dir, pT_near, pT_far, FindHighestPolyCallBack, pArg);
}
return 0;
}
// IDA: void __usercall FindFace(br_vector3 *pPosition@<EAX>, br_vector3 *pDir@<EDX>, br_vector3 *nor@<EBX>, br_scalar *t@<ECX>, br_material **material)

View File

@ -13,7 +13,7 @@ br_scalar gIn_view_distance;
tU8* gBit_per_node;
int gGrudge_reduction_per_period;
int gSFS_max_cycles;
int gChallenger_index;
int gChallenger_index_oppo; // added _oppo suffix to avoid name collision
int gSFS_cycles_this_time;
br_scalar gMinimum_yness_before_knackerisation;
int gWanky_arse_tit_fuck;
@ -643,7 +643,9 @@ void CalcOpponentConspicuousnessWithAViewToCheatingLikeFuck(tOpponent_spec* pOpp
// IDA: void __usercall ChallengeOccurred(int pChallenger_index@<EAX>, int pAccepted@<EDX>)
void ChallengeOccurred(int pChallenger_index, int pAccepted) {
LOG_TRACE("(%d, %d)", pChallenger_index, pAccepted);
NOT_IMPLEMENTED();
if (pAccepted) {
gChallenger_index_oppo = pChallenger_index;
}
}
// IDA: void __cdecl LoadCopCars()
@ -866,7 +868,8 @@ void MungeOpponents(tU32 pFrame_period) {
void SetInitialCopPositions() {
int i;
LOG_TRACE("()");
NOT_IMPLEMENTED();
STUB();
}
// IDA: void __usercall InitOpponents(tRace_info *pRace_info@<EAX>)
@ -877,7 +880,8 @@ void InitOpponents(tRace_info* pRace_info) {
int skill_dependent_difficulty;
br_bounds bounds;
LOG_TRACE("(%p)", pRace_info);
NOT_IMPLEMENTED();
STUB();
}
// IDA: void __cdecl DisposeOpponents()

View File

@ -4,7 +4,70 @@
#include "br_types.h"
#include "dr_types.h"
extern char gOppo_path_filename[256];
extern br_scalar gIn_view_distance;
extern tU8* gBit_per_node;
extern int gGrudge_reduction_per_period;
extern int gSFS_max_cycles;
extern int gChallenger_index_oppo; // added _oppo suffix to avoid name collision
extern int gSFS_cycles_this_time;
extern br_scalar gMinimum_yness_before_knackerisation;
extern int gWanky_arse_tit_fuck;
extern br_scalar gHead_on_cos_value;
extern int gSFS_count;
extern int gSFS_total_cycles;
extern tU32 gNext_grudge_reduction;
extern br_scalar gCop_pursuit_speed_percentage_multiplier;
extern br_scalar gDefinite_cop_pursuit_speed;
extern int gAcknowledged_start;
extern int gMin_bangness;
extern int gStart_jumped;
extern int gNum_of_opponents_getting_near;
extern tU32 gNext_elastication;
extern int gNumber_of_cops_before_faffage;
extern int gFirst_frame;
extern tU32 gAcme_frame_count;
extern char* gDrone_name;
extern br_scalar gDefinite_no_cop_pursuit_speed;
extern tU32 gNext_write_during_elastication;
extern int gNum_of_opponents_completing_race;
extern int gNum_of_opponents_pursuing;
extern int gMax_bangness;
extern int gActive_car_list_rebuild_required;
extern char* gCop_name;
extern br_scalar gFrame_period_for_this_munging_in_secs;
extern int gBig_bang;
extern char* gPath_section_type_names[3];
extern br_material* gMat_lt_blu;
extern int gFaces_used_in_non_edit_paths;
extern br_material* gMat_dk_blu;
extern int gMats_allocated;
extern int gBIG_APC_index;
extern br_material* gMat_lt_red;
extern int gTest_toggle;
extern int gVertices_used_in_non_edit_paths;
extern br_material* gMat_lt_turq;
extern br_material* gMat_lt_grn;
extern int gAlready_elasticating;
extern br_material* gMat_dk_red;
extern int gOppo_paths_shown;
extern br_material* gMat_dk_turq;
extern br_material* gMat_lt_gry;
extern br_material* gMat_md_gry;
extern br_material* gMat_dk_grn;
extern int gMellow_opponents;
extern int gMade_path_filename;
extern int gProcessing_opponents;
extern br_material* gMat_dk_gry;
extern br_material* gMat_dk_yel;
extern br_material* gMat_lt_yel;
extern br_material* gMat_md_yel;
extern br_model* gOppo_path_model;
extern br_actor* gOppo_path_actor;
extern tU32 gFrame_period_for_this_munging;
extern tU32 gTime_stamp_for_this_munging;
extern float gOpponent_nastyness_frigger;
extern tS16 gMobile_section;
void PointActorAlongThisBloodyVector(br_actor* pThe_actor, br_vector3* pThe_vector);

View File

@ -898,10 +898,10 @@ void CreatePedestrian(FILE* pG, tPedestrian_instruction* pInstructions, int pIns
the_pedestrian->killers_ID = -1;
the_pedestrian->murderer = -1;
the_pedestrian->sent_dead_message = 0;
minnest_min = 3.4028235e38;
maxest_min = -3.4028235e38;
minnest_max = 3.4028235e38;
maxest_max = -3.4028235e38;
minnest_min = BR_SCALAR_MAX;
maxest_min = BR_SCALAR_MIN;
minnest_max = BR_SCALAR_MAX;
maxest_max = BR_SCALAR_MIN;
the_pedestrian->number_of_actions = GetAnInt(pG);
the_pedestrian->action_list = BrMemAllocate(sizeof(tPedestrian_action) * the_pedestrian->number_of_actions, kMem_ped_action_list);
the_action = the_pedestrian->action_list;

View File

@ -2,6 +2,7 @@
#include "brender.h"
#include "displays.h"
#include "drmem.h"
#include "errors.h"
#include "flicplay.h"
#include "globvars.h"
#include "grafdata.h"
@ -9,6 +10,7 @@
#include "input.h"
#include "intrface.h"
#include "loading.h"
#include "opponent.h"
#include "pd/sys.h"
#include "sound.h"
#include "structur.h"
@ -1129,31 +1131,176 @@ void ChallengeStart() {
tPath_name the_path;
char s[256];
LOG_TRACE("()");
NOT_IMPLEMENTED();
InitialiseFlicPanel(
0,
gCurrent_graf_data->start_race_panel_left,
gCurrent_graf_data->start_race_panel_top,
gCurrent_graf_data->start_race_panel_right - gCurrent_graf_data->start_race_panel_left,
gCurrent_graf_data->start_race_panel_bottom - gCurrent_graf_data->start_race_panel_top);
ChangePanelFlic(
0,
gOpponents[gChallenger_index].mug_shot_image_data,
gOpponents[gChallenger_index].mug_shot_image_data_length);
if (gScreen->row_bytes < 0) {
BrFatal("C:\\Msdev\\Projects\\DethRace\\Racestrt.c", 2610, "Bruce bug at line %d, file C:\\Msdev\\Projects\\DethRace\\Racestrt.c", 50);
}
the_map = DRPixelmapAllocate(
gScreen->type,
gCurrent_graf_data->dare_mugshot_width,
gCurrent_graf_data->dare_mugshot_height,
0,
0);
BrPixelmapRectangleCopy(the_map, 0, 0, GetPanelPixelmap(0), gCurrent_graf_data->dare_mug_left_margin, gCurrent_graf_data->dare_mug_top_margin, gCurrent_graf_data->dare_mugshot_width, gCurrent_graf_data->dare_mugshot_height);
DisposeFlicPanel(0);
TellyInImage(the_map, gCurrent_graf_data->dare_mugshot_left, gCurrent_graf_data->dare_mugshot_top);
BrPixelmapFree(the_map);
the_map = DRPixelmapAllocate(gScreen->type, gCurrent_graf_data->dare_text_width, gCurrent_graf_data->dare_mugshot_height, 0, 0);
BrPixelmapFill(the_map, 0);
TransBrPixelmapText(the_map, 0, 0, 1u, gBig_font, (signed char*)gOpponents[gChallenger_index].abbrev_name);
PathCat(the_path, gApplication_path, "DARES.TXT");
f = DRfopen(the_path, "rt");
if (!f) {
FatalError(100);
}
dare_index = IRandomBetween(0, GetAnInt(f) - 1);
for (i = 0; i < dare_index; i++) {
line_count = GetAnInt(f);
for (j = 0; j < line_count; j++) {
GetALineAndDontArgue(f, s);
}
}
line_count = GetAnInt(f);
for (i = 0; i < line_count; i++) {
GetALineAndDontArgue(f, s);
TransBrPixelmapText(the_map, 0, 2 * (i + 1) * gBig_font->glyph_y, 0x86u, gBig_font, (signed char*)s);
}
fclose(f);
BrPixelmapLine(the_map, 0, gBig_font->glyph_y + 2, the_map->width, gBig_font->glyph_y + 2, 45);
TellyInImage(the_map, gCurrent_graf_data->dare_text_left, gCurrent_graf_data->dare_mugshot_top);
BrPixelmapFree(the_map);
UnlockOpponentMugshot(gChallenger_index);
gDare_start_time = PDGetTotalTime();
}
// IDA: int __usercall CheckNextStage@<EAX>(int *pCurrent_choice@<EAX>, int *pCurrent_mode@<EDX>)
int CheckNextStage(int* pCurrent_choice, int* pCurrent_mode) {
LOG_TRACE("(%p, %p)", pCurrent_choice, pCurrent_mode);
NOT_IMPLEMENTED();
if (gDare_start_time && (unsigned int)(PDGetTotalTime() - gDare_start_time) >= 7500) {
BrPixelmapRectangleFill(
gBack_screen,
gCurrent_graf_data->grid_left_clip,
gCurrent_graf_data->dare_mugshot_top,
gCurrent_graf_data->grid_right_clip - gCurrent_graf_data->grid_left_clip,
gCurrent_graf_data->dare_mugshot_height,
0);
DoGridTransition(gOur_starting_position, gChallenger_position);
gDraw_grid_status = eGrid_draw_icons_only;
gDare_start_time = 0;
}
return 0;
}
// IDA: int __usercall ChallengeDone@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out)
int ChallengeDone(int pCurrent_choice, int pCurrent_mode, int pGo_ahead, int pEscaped, int pTimed_out) {
LOG_TRACE("(%d, %d, %d, %d, %d)", pCurrent_choice, pCurrent_mode, pGo_ahead, pEscaped, pTimed_out);
NOT_IMPLEMENTED();
if (!pEscaped || gDare_start_time) {
if (!pEscaped && gDare_start_time) {
ActuallySwapOrder(gOur_starting_position, gChallenger_position);
ChallengeOccurred(gChallenger_index, 1);
}
} else {
DoGridTransition(gOur_starting_position, gOriginal_position);
ActuallySwapOrder(gOur_starting_position, gOriginal_position);
ChallengeOccurred(gChallenger_index, 0);
}
ChallengeOccurred(gChallenger_index, pEscaped == 0);
if (pTimed_out) {
return 0;
} else {
return pCurrent_choice;
}
}
// IDA: void __cdecl DoChallengeScreen()
void DoChallengeScreen() {
static tFlicette flicker_on[2];
static tFlicette flicker_off[2];
static tFlicette push[2];
static tMouse_area mouse_areas[2];
static tInterface_spec interface_spec;
static tFlicette flicker_on[2] = { { 43, { 54, 108 }, { 157, 377 } }, { 43, { 218, 436 }, { 157, 377 } } };
static tFlicette flicker_off[2] = { { 42, { 54, 108 }, { 157, 377 } }, { 42, { 218, 436 }, { 157, 377 } } };
static tFlicette push[2] = { { 304, { 54, 108 }, { 157, 377 } }, { 305, { 218, 436 }, { 157, 377 } } };
static tMouse_area mouse_areas[2] = {
{ { 54, 108 }, { 157, 377 }, { 117, 234 }, { 178, 427 }, 0, 0, 0, NULL },
{ { 218, 436 }, { 157, 377 }, { 281, 562 }, { 178, 427 }, 1, 0, 0, NULL }
};
static tInterface_spec interface_spec = {
0, // initial_imode
301, // first_opening_flic
0, // second_opening_flic
-1, // end_flic_go_ahead
-1, // end_flic_escaped
-1, // end_flic_otherwise
0, // flic_bunch_to_load
{ -1, 0 }, // move_left_new_mode
{ -1, 0 }, // move_left_delta
{ 0, 0 }, // move_left_min
{ 1, 0 }, // move_left_max
{ NULL, NULL }, // move_left_proc
{ -1, 0 }, // move_right_new_mode
{ 1, 0 }, // move_right_delta
{ 0, 0 }, // move_right_min
{ 1, 0 }, // move_right_max
{ NULL, NULL }, // move_right_proc
{ -1, 0 }, // move_up_new_mode
{ 0, 0 }, // move_up_delta
{ 0, 0 }, // move_up_min
{ 0, 0 }, // move_up_max
{ NULL, NULL }, // move_up_proc
{ -1, 0 }, // move_down_new_mode
{ 0, 0 }, // move_down_delta
{ 0, 0 }, // move_down_min
{ 0, 0 }, // move_down_max
{ NULL, NULL }, // move_down_proc
{ 1, 1 }, // go_ahead_allowed
{ NULL, NULL }, // go_ahead_proc
{ 1, 1 }, // escape_allowed
{ NULL, NULL }, // escape_proc
&CheckNextStage, // exit_proc
&GridDraw, // draw_proc
0u, // time_out
NULL, // start_proc1
&ChallengeStart, // start_proc2
&ChallengeDone, // done_proc
0, // font_needed
{ 0, 0 }, // typeable
NULL, // get_original_string
1, // escape_code
1, // dont_save_or_load
2, // number_of_button_flics
flicker_on, // flicker_on_flics
flicker_off, // flicker_off_flics
push, // pushed_flics
2, // number_of_mouse_areas
mouse_areas, // mouse_areas
0, // number_of_recopy_areas
NULL // recopy_areas
};
int result;
LOG_TRACE("()");
NOT_IMPLEMENTED();
gOriginal_position = gOur_starting_position;
gChallenger_position = IRandomBetween(0, 1);
if (gOpponents[gCurrent_race.opponent_list[gChallenger_position].index].car_number < 0) {
gChallenger_position ^= 1u;
}
gChallenger_index = gCurrent_race.opponent_list[gChallenger_position].index;
LoadOpponentMugShot(gChallenger_index);
gDraw_grid_status = eGrid_draw_none;
gGrid_y_adjust = gCurrent_graf_data->dare_y_adjust;
DoInterfaceScreen(&interface_spec, 0, 0);
}
// IDA: int __usercall GridDone@<EAX>(int pCurrent_choice@<EAX>, int pCurrent_mode@<EDX>, int pGo_ahead@<EBX>, int pEscaped@<ECX>, int pTimed_out)

View File

@ -1,5 +1,6 @@
#include "raycast.h"
#include "CORE/V1DB/actsupt.h"
#include "brender.h"
#include "finteray.h"
#include <stdlib.h>
br_matrix34 gPick_model_to_view_raycast; //added _raycast suffix to avoid name collision
@ -12,10 +13,25 @@ br_scalar gHighest_y_below;
br_actor* gY_picking_camera;
br_scalar gLowest_y_above;
br_model* model_unk1;
br_material* material_unk1;
// IDA: int __usercall DRActorToRoot@<EAX>(br_actor *a@<EAX>, br_actor *world@<EDX>, br_matrix34 *m@<EBX>)
int DRActorToRoot(br_actor* a, br_actor* world, br_matrix34* m) {
LOG_TRACE("(%p, %p, %p)", a, world, m);
NOT_IMPLEMENTED();
if (world == a) {
BrMatrix34Identity(m);
return 1;
} else {
BrTransformToMatrix34(m, &a->t);
for (a = a->parent; a && world != a; a = a->parent) {
if (a->t.type != BR_TRANSFORM_IDENTITY) {
BrMatrix34PostTransform(m, &a->t);
}
}
return world == a;
}
}
// IDA: void __cdecl InitRayCasting()
@ -45,8 +61,9 @@ void InitRayCasting() {
// IDA: int __cdecl BadDiv(br_scalar a, br_scalar b)
int BadDiv(br_scalar a, br_scalar b) {
LOG_TRACE("(%f, %f)", a, b);
NOT_IMPLEMENTED();
//LOG_TRACE("(%f, %f)", a, b);
return fabs(b) < 1.0 && fabs(a) > fabs(b) * BR_SCALAR_MAX;
}
// IDA: int __usercall PickBoundsTestRay@<EAX>(br_bounds *b@<EAX>, br_vector3 *rp@<EDX>, br_vector3 *rd@<EBX>, br_scalar t_near, br_scalar t_far, br_scalar *new_t_near, br_scalar *new_t_far)
@ -55,7 +72,56 @@ int PickBoundsTestRay(br_bounds* b, br_vector3* rp, br_vector3* rd, br_scalar t_
float s;
float t;
LOG_TRACE("(%p, %p, %p, %f, %f, %p, %p)", b, rp, rd, t_near, t_far, new_t_near, new_t_far);
NOT_IMPLEMENTED();
for (i = 0; i < 3; i++) {
if (rd->v[i] <= 0.00000023841858) {
if (rd->v[i] >= -0.00000023841858) {
if (b->max.v[i] < rp->v[i] || rp->v[i] < b->min.v[i]) {
return 0;
}
} else {
s = (1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]);
if (s >= BR_SCALAR_MIN) {
if (s < t_far) {
t_far = (1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]);
}
} else {
t_far = BR_SCALAR_MIN;
}
t = (1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]);
if (t <= BR_SCALAR_MAX) {
if (t > t_near) {
t_near = (1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]);
}
} else {
t_near = BR_SCALAR_MAX;
}
}
} else {
s = (1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]);
if (s <= BR_SCALAR_MAX) {
if (s > t_near) {
t_near = (1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]);
}
} else {
t_near = BR_SCALAR_MAX;
}
t = (1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]);
if (t >= BR_SCALAR_MIN) {
if (t < t_far) {
t_far = (1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]);
}
} else {
t_far = BR_SCALAR_MIN;
}
}
}
if (t_far < t_near) {
return 0;
}
*new_t_near = t_near;
*new_t_far = t_far;
return 1;
}
// IDA: int __usercall ActorPick2D@<EAX>(br_actor *ap@<EAX>, br_model *model@<EDX>, br_material *material@<EBX>, dr_pick2d_cbfn *callback@<ECX>, void *arg)
@ -68,8 +134,86 @@ int ActorPick2D(br_actor* ap, br_model* model, br_material* material, dr_pick2d_
br_scalar t_near;
br_scalar t_far;
int r;
br_vector3 dir;
LOG_TRACE("(%p, %p, %p, %p, %p)", ap, model, material, callback, arg);
NOT_IMPLEMENTED();
r = 0;
if (ap->model) {
this_model = ap->model;
} else {
this_model = model;
}
if (ap->material) {
this_material = ap->material;
} else {
this_material = material;
}
if (ap->render_style == BR_RSTYLE_NONE) {
return 0;
}
m_to_v = gPick_model_to_view_raycast;
BrMatrix34PreTransform(&gPick_model_to_view_raycast, &ap->t);
if (ap->type == BR_ACTOR_MODEL) {
BrMatrix34Inverse(&v_to_m, &gPick_model_to_view_raycast);
if (PickBoundsTestRay(
&this_model->bounds,
(br_vector3*)v_to_m.m[3],
(br_vector3*)v_to_m.m[2],
0.0,
BR_SCALAR_MAX,
&t_near,
&t_far)) {
dir.v[0] = -v_to_m.m[2][0];
dir.v[1] = -v_to_m.m[2][1];
dir.v[2] = -v_to_m.m[2][2];
r = callback(
ap,
this_model,
this_material,
(br_vector3*)v_to_m.m[3],
&dir,
t_near,
t_far,
arg);
if (r) {
gPick_model_to_view_raycast = m_to_v;
return r;
}
}
if (r) {
gPick_model_to_view_raycast = m_to_v;
return r;
}
} else if (ap->type == BR_ACTOR_BOUNDS || ap->type == BR_ACTOR_BOUNDS_CORRECT) {
BrMatrix34Inverse(&v_to_m, &gPick_model_to_view_raycast);
if (PickBoundsTestRay(
(br_bounds*)ap->type_data,
(br_vector3*)v_to_m.m[3],
(br_vector3*)v_to_m.m[2],
0.0,
BR_SCALAR_MAX,
&t_near,
&t_far)) {
for (a = ap->children; a != NULL; a = a->next) {
r = ActorPick2D(a, this_model, this_material, callback, arg);
if (r) {
break;
}
}
}
gPick_model_to_view_raycast = m_to_v;
return r;
}
for (a = ap->children; a != NULL; a = a->next) {
r = ActorPick2D(a, this_model, this_material, callback, arg);
if (r) {
break;
}
}
gPick_model_to_view_raycast = m_to_v;
return r;
}
// IDA: int __usercall DRScenePick2DXY@<EAX>(br_actor *world@<EAX>, br_actor *camera@<EDX>, br_pixelmap *viewport@<EBX>, int pick_x@<ECX>, int pick_y, dr_pick2d_cbfn *callback, void *arg)
@ -90,7 +234,15 @@ int DRScenePick2D(br_actor* world, br_actor* camera, dr_pick2d_cbfn* callback, v
br_scalar scale;
br_camera* camera_data;
LOG_TRACE("(%p, %p, %p, %p)", world, camera, callback, arg);
NOT_IMPLEMENTED();
camera_data = (br_camera*)camera->type_data;
DRActorToRoot(camera, world, &camera_tfm);
BrMatrix34Inverse(&gPick_model_to_view_raycast, &camera_tfm);
scale = cos(BrAngleToRadian(camera_data->field_of_view / 2));
scale = scale / sin(scale);
BrMatrix34PostScale(&gPick_model_to_view_raycast, scale / camera_data->aspect, scale, 1.0);
return ActorPick2D(world, model_unk1, material_unk1, callback, arg);
}
// IDA: int __usercall DRModelPick2D@<EAX>(br_model *model@<EAX>, br_material *material@<EDX>, br_vector3 *ray_pos@<EBX>, br_vector3 *ray_dir@<ECX>, br_scalar t_near, br_scalar t_far, dr_modelpick2d_cbfn *callback, void *arg)
@ -127,13 +279,140 @@ int DRModelPick2D(br_model* model, br_material* material, br_vector3* ray_pos, b
br_scalar numerator;
double f_numerator;
LOG_TRACE("(%p, %p, %p, %p, %f, %f, %p, %p)", model, material, ray_pos, ray_dir, t_near, t_far, callback, arg);
NOT_IMPLEMENTED();
for (group = 0; group < V11MODEL(model)->ngroups; group++) {
for (f = 0; f < V11MODEL(model)->groups[group].nfaces; f++) {
fp = &V11MODEL(model)->groups[group].faces[f];
if (V11MODEL(model)->groups[group].face_colours_material) {
this_material = V11MODEL(model)->groups[group].face_colours_material;
} else {
this_material = material;
}
d = fp->eqn.v[1] * ray_dir->v[1] + fp->eqn.v[2] * ray_dir->v[2] + fp->eqn.v[0] * ray_dir->v[0];
if (fabs(d) >= 0.00000023841858 && ((this_material->flags & 0x1800) != 0 || d <= 0.0)) // BR_MATF_TWO_SIDED | BR_MATF_ALWAYS_VISIBLE
{
numerator = fp->eqn.v[1] * ray_pos->v[1]
+ fp->eqn.v[2] * ray_pos->v[2]
+ fp->eqn.v[0] * ray_pos->v[0]
- fp->eqn.v[3];
if (!BadDiv(numerator, d)) {
t = -(numerator / d);
if (t >= (t_near - 0.001) && t <= (t_far + 0.001)) {
p.v[0] = ray_dir->v[0] * t;
p.v[1] = ray_dir->v[1] * t;
p.v[2] = ray_dir->v[2] * t;
p.v[0] = ray_pos->v[0] + p.v[0];
p.v[1] = ray_pos->v[1] + p.v[1];
p.v[2] = ray_pos->v[2] + p.v[2];
axis_m = fabs(fp->eqn.v[0]) < fabs(fp->eqn.v[1]);
if (fabs(fp->eqn.v[2]) > fabs(fp->eqn.v[axis_m])) {
axis_m = 2;
}
if (axis_m) {
axis_0 = 0;
if (axis_m == 1) {
axis_1 = 2;
} else {
axis_1 = 1;
}
} else {
axis_0 = 1;
axis_1 = 2;
}
v0 = V11MODEL(model)->groups[group].vertices[fp->vertices[0]].p.v[axis_0];
u0 = V11MODEL(model)->groups[group].vertices[fp->vertices[0]].p.v[axis_1];
v1 = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].p.v[axis_0] - v0;
u1 = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].p.v[axis_1] - u0;
v2 = V11MODEL(model)->groups[group].vertices[fp->vertices[2]].p.v[axis_0] - v0;
u2 = V11MODEL(model)->groups[group].vertices[fp->vertices[2]].p.v[axis_1] - u0;
v0i1 = p.v[axis_0] - v0;
v0i2 = p.v[axis_1] - u0;
if (fabs(v1) > 0.0000002384185791015625) {
f_d = v0i2 * v1 - u1 * v0i1;
f_n = u2 * v1 - u1 * v2;
if (f_d == 0) {
continue;
}
beta = f_d / f_n;
alpha = (v0i1 - beta * v2) / v1;
} else {
beta = v0i1 / v2;
alpha = (v0i2 - beta * u2) / u1;
}
if (alpha >= 0.0 && beta >= 0.0 && beta + alpha <= 1.0) {
s_alpha = alpha;
s_beta = beta;
map.v[0] = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].map.v[0] * s_alpha;
map.v[1] = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].map.v[1] * s_alpha;
DRVector2AccumulateScale(
&map,
&V11MODEL(model)->groups[group].vertices[fp->vertices[2]].map,
s_beta);
DRVector2AccumulateScale(
&map,
&V11MODEL(model)->groups[group].vertices[fp->vertices[0]].map,
1.0 - (s_alpha + s_beta));
v = 0;
e = 1;
if (s_alpha <= s_beta) {
if (0.5 - s_beta / 2.0 > s_alpha) {
e = 0;
}
if (1.0 - s_beta * 2.0 < s_alpha) {
v = 1;
}
} else {
if (1.0 - s_beta * 2.0 > s_alpha) {
e = 2;
}
if (0.5 - s_beta / 2.0 < s_alpha) {
v = 2;
}
}
r = callback(
model,
this_material,
ray_pos,
ray_dir,
t,
f,
e,
v,
&p,
&map,
arg);
if (r) {
return r;
}
}
}
}
}
}
}
return 0;
}
// IDA: void __usercall FindBestY(br_vector3 *pPosition@<EAX>, br_actor *gWorld@<EDX>, br_scalar pStarting_height, br_scalar *pNearest_y_above, br_scalar *pNearest_y_below, br_model **pNearest_above_model, br_model **pNearest_below_model, int *pNearest_above_face_index, int *pNearest_below_face_index)
void FindBestY(br_vector3* pPosition, br_actor* gWorld, br_scalar pStarting_height, br_scalar* pNearest_y_above, br_scalar* pNearest_y_below, br_model** pNearest_above_model, br_model** pNearest_below_model, int* pNearest_above_face_index, int* pNearest_below_face_index) {
LOG_TRACE("(%p, %p, %f, %p, %p, %p, %p, %p, %p)", pPosition, gWorld, pStarting_height, pNearest_y_above, pNearest_y_below, pNearest_above_model, pNearest_below_model, pNearest_above_face_index, pNearest_below_face_index);
NOT_IMPLEMENTED();
gLowest_y_above = 30000.0;
gHighest_y_below = -30000.0;
gCurrent_y = pPosition->v[1] + 0.000011920929;
gY_picking_camera->t.t.euler.t = *pPosition;
gY_picking_camera->t.t.mat.m[3][1] = gY_picking_camera->t.t.mat.m[3][1] + pStarting_height;
DRScenePick2D(gWorld, gY_picking_camera, FindHighestCallBack, 0);
*pNearest_y_above = gLowest_y_above;
*pNearest_y_below = gHighest_y_below;
*pNearest_above_model = gAbove_model;
*pNearest_below_model = gBelow_model;
*pNearest_above_face_index = gAbove_face_index;
*pNearest_below_face_index = gBelow_face_index;
LOG_DEBUG("FindBestY %f %f '%s' '%s' %d %d", gLowest_y_above, gHighest_y_below, gAbove_model->identifier, gBelow_model->identifier, gAbove_face_index, gBelow_face_index);
}
// IDA: int __cdecl FindYVerticallyBelowPolyCallBack(br_model *pModel, br_material *pMaterial, br_vector3 *pRay_pos, br_vector3 *pRay_dir, br_scalar pT, int pF, int pE, int pV, br_vector3 *pPoint, br_vector2 *pMap, void *pArg)

View File

@ -4,6 +4,16 @@
#include "br_types.h"
#include "dr_types.h"
extern br_matrix34 gPick_model_to_view_raycast; //added _raycast suffix to avoid name collision
extern int gBelow_face_index;
extern br_scalar gCurrent_y;
extern int gAbove_face_index;
extern br_model* gAbove_model;
extern br_model* gBelow_model;
extern br_scalar gHighest_y_below;
extern br_actor* gY_picking_camera;
extern br_scalar gLowest_y_above;
int DRActorToRoot(br_actor* a, br_actor* world, br_matrix34* m);
void InitRayCasting();

View File

@ -198,7 +198,8 @@ void InitSoundSources() {
int toggle;
tCar_spec* the_car;
LOG_TRACE("()");
NOT_IMPLEMENTED();
STUB();
}
// IDA: void __cdecl DisposeSoundSources()

View File

@ -2006,12 +2006,6 @@ void LoadTrack(char* pFile_name, tTrack_spec* pTrack_spec, tRace_info* pRace_inf
p[0] = pRace_info->checkpoints[i].vertices[j][0];
p[1] = pRace_info->checkpoints[i].vertices[j][1];
p[2] = pRace_info->checkpoints[i].vertices[j][2];
// v77 = p[1].v[0] - p[0].v[0];
// v78 = p[1].v[1] - p[0].v[1];
// v79 = p[1].v[2] - p[0].v[2];
// v74 = p[2].v[0] - p[0].v[0];
// v75 = p[2].v[1] - p[0].v[1];
// v76 = p[2].v[2] - p[0].v[2];
pRace_info->checkpoints[i].normal[j].v[0] = (p[2].v[2] - p[0].v[2]) * (p[1].v[1] - p[0].v[1]) - (p[1].v[2] - p[0].v[2]) * (p[2].v[1] - p[0].v[1]);
pRace_info->checkpoints[i].normal[j].v[1] = (p[1].v[2] - p[0].v[2]) * (p[2].v[0] - p[0].v[0]) - (p[2].v[2] - p[0].v[2]) * (p[1].v[0] - p[0].v[0]);
pRace_info->checkpoints[i].normal[j].v[2] = (p[2].v[1] - p[0].v[1]) * (p[1].v[0] - p[0].v[0]) - (p[1].v[1] - p[0].v[1]) * (p[2].v[0] - p[0].v[0]);
@ -2104,18 +2098,16 @@ void LoadTrack(char* pFile_name, tTrack_spec* pTrack_spec, tRace_info* pRace_inf
ExtractColumns(pTrack_spec);
for (i = 0; gTrack_storage_space.models_count > i; ++i) {
PossibleService();
//v80 = 0;
if (gTrack_storage_space.models[i] && gTrack_storage_space.models[i]->flags & 0x82) {
gTrack_storage_space.models[i]->flags &= 0xFF7Du;
for (group = 0; V11MODEL(gTrack_storage_space.models[i])->ngroups > group; ++group) {
// TODO: ?
// material = gTrack_storage_space.models[i]->faces[V11MODEL(*gTrack_storage_space.models[i])->groups[group].face_user].material;
// *gTrack_storage_space.models[i]->prepared->groups[group].face_colours = (br_colour)material;
// if (material && !material->index_shade) {
// v9 = BrTableFind("DRRENDER.TAB");
// material->index_shade = v9;
// BrMaterialUpdate(material, 0x7FFFu);
// }
for (group = 0; group < V11MODEL(gTrack_storage_space.models[i])->ngroups; group++) {
int f = V11MODEL(gTrack_storage_space.models[i])->groups[group].face_user[0];
material = gTrack_storage_space.models[i]->faces[f].material;
V11MODEL(gTrack_storage_space.models[i])->groups[group].face_colours_material = material;
if (material && !material->index_shade) {
material->index_shade = BrTableFind("DRRENDER.TAB");
BrMaterialUpdate(material, 0x7FFFu);
}
}
DodgyModelUpdate(gTrack_storage_space.models[i]);
}