Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement cockpit view #279

Merged
merged 12 commits into from
Feb 18, 2023
18 changes: 9 additions & 9 deletions src/BRSRC13/CORE/V1DB/modrend.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
#include "harness/trace.h"

render_style_cbfn RenderStyleCalls[8] = {
renderFaces, /* BR_RSTYLE_DEFAULT */
nullRender, /* BR_RSTYLE_NONE */
renderPoints, /* BR_RSTYLE_POINTS */
renderEdges, /* BR_RSTYLE_EDGES */
renderFaces, /* BR_RSTYLE_FACES */
renderFaces, /* BR_RSTYLE_DEFAULT */
nullRender, /* BR_RSTYLE_NONE */
renderPoints, /* BR_RSTYLE_POINTS */
renderEdges, /* BR_RSTYLE_EDGES */
renderFaces, /* BR_RSTYLE_FACES */
boundingBoxRenderPoints, /* BR_RSTYLE_BOUNDING_POINTS */
boundingBoxRenderEdges, /* BR_RSTYLE_BOUNDING_EDGES */
boundingBoxRenderFaces, /* BR_RSTYLE_BOUNDING_FACES */
boundingBoxRenderEdges, /* BR_RSTYLE_BOUNDING_EDGES */
boundingBoxRenderFaces, /* BR_RSTYLE_BOUNDING_FACES */
};

v11face bounds_faces[12] = {
Expand Down Expand Up @@ -64,13 +64,13 @@ br_model bounds_model = {
// IDA: void __usercall renderFaces(br_actor *actor@<EAX>, br_model *model@<EDX>, br_material *material@<EBX>, void *render_data@<ECX>, br_uint_8 style, int on_screen)
void renderFaces(br_actor* actor, br_model* model, br_material* material, void* render_data, br_uint_8 style, int on_screen) {
LOG_TRACE9("(%p, %p, %p, %p, %d, %d)", actor, model, material, render_data, style, on_screen);
Harness_Hook_renderFaces(actor, model, material, BRT_TRIANGLE);
Harness_Hook_renderActor(actor, model, material, BRT_TRIANGLE);
}

// IDA: void __usercall renderEdges(br_actor *actor@<EAX>, br_model *model@<EDX>, br_material *material@<EBX>, void *render_data@<ECX>, br_uint_8 style, int on_screen)
void renderEdges(br_actor* actor, br_model* model, br_material* material, void* render_data, br_uint_8 style, int on_screen) {
LOG_TRACE("(%p, %p, %p, %p, %d, %d)", actor, model, material, render_data, style, on_screen);
NOT_IMPLEMENTED();
Harness_Hook_renderActor(actor, model, material, BRT_LINE);
}

// IDA: void __usercall renderPoints(br_actor *actor@<EAX>, br_model *model@<EDX>, br_material *material@<EBX>, void *render_data@<ECX>, br_uint_8 style, int on_screen)
Expand Down
14 changes: 7 additions & 7 deletions src/BRSRC13/CORE/V1DB/prepmesh.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,13 +607,13 @@ void BrModelUpdate(br_model* model, br_uint_16 flags) {
if (model->faces == NULL || model->vertices == NULL) {
BrFailure("BrModelUpdate: model has no faces or vertices (%s)", model->identifier != NULL ? model->identifier : "<NULL>");
}
if (flags & BR_MODU_UNKNOWN) {
flags |= BR_MODU_NORMALS;
if (flags & BR_MODU_PIVOT) {
flags |= BR_MODU_VERTEX_POSITIONS;
}
if (model->flags & (BR_MODF_KEEP_ORIGINAL | BR_MODF_GENERATE_TAGS)) {
model->flags |= BR_MODF_UPDATEABLE;
}
if (!(model->flags & BR_MODF_CUSTOM_BOUNDS) && (flags & (BR_MODU_MATERIALS | BR_MODU_GROUPS | BR_MODU_NORMALS))) {
if (!(model->flags & BR_MODF_CUSTOM_BOUNDS) && (flags & (BR_MODU_PRIMITIVE_COLOURS | BR_MODU_VERTEX_NORMALS | BR_MODU_VERTEX_POSITIONS))) {
PrepareBoundingRadius(model);
PrepareBoundingBox(model);
}
Expand Down Expand Up @@ -651,19 +651,19 @@ void BrModelUpdate(br_model* model, br_uint_16 flags) {
} else {

// some additional code paths might exist, but maybe not used?
if (flags != BR_MODU_NORMALS) {
if (flags != BR_MODU_VERTEX_POSITIONS) {
TELL_ME_IF_WE_PASS_THIS_WAY();
}

v11m = model->prepared;

if (model->vertices && (flags & BR_MODU_NORMALS)) {
if (model->vertices && (flags & BR_MODU_VERTEX_POSITIONS)) {
for (g = 0; g < v11m->ngroups; g++) {
for (v = 0; v < v11m->groups[g].nvertices; v++) {
fvp = &v11m->groups[g].vertices[v];
vp = model->vertices + v11m->groups[g].vertex_user[v];

if (flags & BR_MODU_NORMALS) {
if (flags & BR_MODU_VERTEX_POSITIONS) {
fvp->p.v[0] = vp->p.v[0] - model->pivot.v[0];
fvp->p.v[1] = vp->p.v[1] - model->pivot.v[1];
fvp->p.v[2] = vp->p.v[2] - model->pivot.v[2];
Expand All @@ -672,7 +672,7 @@ void BrModelUpdate(br_model* model, br_uint_16 flags) {
}
}

if (flags & BR_MODU_NORMALS) {
if (flags & BR_MODU_VERTEX_POSITIONS) {
if (!(model->flags & BR_MODF_CUSTOM_NORMALS)) {
RegenerateVertexNormals(v11m);
}
Expand Down
35 changes: 33 additions & 2 deletions src/BRSRC13/CORE/V1DB/render.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,38 @@ void BrDbSceneRenderBegin(br_actor* world, br_actor* camera) {
br_token vtos_type;
br_uint_32 dummy;
LOG_TRACE("(%p, %p)", world, camera);
NOT_IMPLEMENTED();

// this is not complete
STUB_ONCE();

/*
* Collect transforms from camera to root
*
* Make a stack of cumulative transforms for each level between
* the camera and the root - this is so that model->view
* transforms can use the shortest route, rather than via the root
*/
for (i = 0; i < BR_ASIZE(v1db.camera_path); i++) {
v1db.camera_path[i].a = NULL;
}

i = camera->depth;
a = camera;
BrMatrix34Identity(&v1db.camera_path[i].m);
v1db.camera_path[i].transform_type = BR_TRANSFORM_IDENTITY;

for (; (i > 0) && (a != world); a = a->parent, i--) {
BrTransformToMatrix34(&tfm, &a->t);
BrMatrix34Mul(&v1db.camera_path[i - 1].m, &v1db.camera_path[i].m, &tfm);

v1db.camera_path[i - 1].transform_type = BrTransformCombineTypes(v1db.camera_path[i].transform_type, a->t.type);

v1db.camera_path[i].a = a;
}

if (world != a) {
// BrFailure("camera is not in world hierachy");
}
}

// IDA: br_renderbounds_cbfn* __cdecl BrDbSetRenderBoundsCallback(br_renderbounds_cbfn *new_cbfn)
Expand All @@ -291,7 +322,7 @@ void SetViewport(br_pixelmap* buffer) {
void BrZbSceneRenderBegin(br_actor* world, br_actor* camera, br_pixelmap* colour_buffer, br_pixelmap* depth_buffer) {
// LOG_TRACE("(%p, %p, %p, %p)", world, camera, colour_buffer, depth_buffer);

// BrDbSceneRenderBegin(world, camera);
BrDbSceneRenderBegin(world, camera);
Harness_Hook_BrZbSceneRenderBegin(world, camera, colour_buffer, depth_buffer);
}

Expand Down
2 changes: 1 addition & 1 deletion src/BRSRC13/include/brender/br_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

#define BrDegreeToRadian(d) ((br_scalar)((d) * (PI / 180.0)))

#define BrDegreeToAngle(d) ((br_angle)(long)((d) * (65536.0f / 360.0f))) // "d * 182.044444444"
#define BrDegreeToAngle(d) ((br_angle)(long)((d) * (65536.0f / 360.0f))) // "d * 182.044444444"
#define BrAngleToDegrees(a) ((br_angle)(long)((a) * (360.0f / 65536.0f))) // "d * 0.0054931640625"

#define BR_SCALAR(x) ((br_scalar)(x))
Expand Down
34 changes: 20 additions & 14 deletions src/BRSRC13/include/brender/br_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -2648,13 +2648,13 @@ typedef struct resource_header { // size: 24
br_uint_8 size_m;
br_uint_8 size_l;
#else
br_uint_8 size_l; // @12
br_uint_8 size_m; // @13
br_uint_8 size_h; // @14
br_uint_8 size_l; // @12
br_uint_8 size_m; // @13
br_uint_8 size_h; // @14
#endif
br_uint_8 class; // @15
void* magic_ptr; // @16
br_uint_32 magic_num; // @20
br_uint_8 class; // @15
void* magic_ptr; // @16
br_uint_32 magic_num; // @20
} resource_header;
#pragma pack(pop)

Expand Down Expand Up @@ -2952,14 +2952,20 @@ enum {
* Flags to BrModelUpdate()
*/
enum {
BR_MODU_NORMALS = 0x0001,
BR_MODU_EDGES = 0x0002,
BR_MODU_RADIUS = 0x0004,
BR_MODU_GROUPS = 0x0008,
BR_MODU_BOUNDING_BOX = 0x0010,
BR_MODU_MATERIALS = 0x0020,
BR_MODU_UNKNOWN = 0x0100, /* Added by Jeff. Referred to in code */
BR_MODU_ALL = 0x7fff
BR_MODU_VERTEX_POSITIONS = 0x0001,
BR_MODU_VERTEX_COLOURS = 0x0002,
BR_MODU_VERTEX_MAPPING = 0x0004,
BR_MODU_VERTEX_NORMALS = 0x0008,
BR_MODU_PRIMITIVE_MATERIALS = 0x0010,
BR_MODU_PRIMITIVE_COLOURS = 0x0020,
BR_MODU_VERTICES = 0x0040,
BR_MODU_FACES = 0x0080,
BR_MODU_PIVOT = 0x0100,
BR_MODU_PREPARED = 0x0200,
BR_MODU_PRIMITIVE_EQUATIONS = 0x0400,
BR_MODU_ALL = 0x7FFF,

_BR_MODU_RESERVED = 0x8000
};

/*
Expand Down
6 changes: 3 additions & 3 deletions src/DETHRACE/common/crush.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ void CrushModel(tCar_spec* pCar, int pModel_index, br_actor* pActor, br_vector3*
void JitModelUpdate(br_actor* actor, br_model* model, br_material* material, void* render_data, br_uint_8 style, int on_screen) {
LOG_TRACE("(%p, %p, %p, %p, %d, %d)", actor, model, material, render_data, style, on_screen);

BrModelUpdate(model, BR_MODU_NORMALS);
BrModelUpdate(model, BR_MODU_VERTEX_POSITIONS);
model->flags &= ~(BR_MODF_CUSTOM);
BrZbModelRender(actor, model, material, style, BrOnScreenCheck(&model->bounds), 0);
}
Expand Down Expand Up @@ -483,8 +483,8 @@ void TotallyRepairACar(tCar_spec* pCar) {
memcpy(the_car_actor->actor->model->vertices,
the_car_actor->undamaged_vertices,
the_car_actor->actor->model->nvertices * sizeof(br_vertex));
// FIXME: BrModelUpdate(..., BR_MODU_EDGES | BR_MODU_NORMALS) fails on TELL_ME_IF_WE_PASS_THIS_WAY
// BrModelUpdate(the_car_actor->actor->model, BR_MODU_EDGES | BR_MODU_NORMALS);
// FIXME: BrModelUpdate(..., BR_MODU_VERTEX_COLOURS | BR_MODU_VERTEX_POSITIONS) fails on TELL_ME_IF_WE_PASS_THIS_WAY
// BrModelUpdate(the_car_actor->actor->model, BR_MODU_VERTEX_COLOURS | BR_MODU_VERTEX_POSITIONS);
BrModelUpdate(the_car_actor->actor->model, BR_MODU_ALL);
if (pipe_vertex_count != 0 && IsActionReplayAvailable()) {
PipeSingleModelGeometry(pCar->car_ID, j, pipe_vertex_count, pipe_array);
Expand Down
85 changes: 48 additions & 37 deletions src/DETHRACE/common/depth.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,27 +180,27 @@ void MungeSkyModel(br_actor* pCamera, br_model* pModel) {
LOG_TRACE("(%p, %p)", pCamera, pModel);

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;
sky_distance = camera_data->yon_z - 1.f;
horizon_half_width = sky_distance * 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;
horizon_half_diag = sqrtf(horizon_half_height * horizon_half_height + horizon_half_width * horizon_half_width);
half_diag_fov = BrRadianToAngle(atan2f(horizon_half_diag, sky_distance));
edge_u = EdgeU(gSky_image_width, 2 * half_diag_fov, BR_ANGLE_DEG(10));
narrow_u = edge_u / 2.f;
gSky_width = horizon_half_width * 2.f;
gSky_height = horizon_half_height * 2.f;
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;
pModel->vertices[vertex].map.v[0] = -narrow_u;
}
for (vertex = 2; vertex < 88; vertex += 4) {
pModel->vertices[vertex].map.v[0] = edge_u / 2.f;
pModel->vertices[vertex].map.v[0] = narrow_u;
}
for (vertex = 3; vertex < 88; vertex += 4) {
pModel->vertices[vertex].map.v[0] = edge_u;
Expand All @@ -209,7 +209,7 @@ void MungeSkyModel(br_actor* pCamera, br_model* pModel) {
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;
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;
Expand All @@ -218,31 +218,39 @@ void MungeSkyModel(br_actor* pCamera, br_model* pModel) {
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);
angle_range = -gSky_image_underground - (-BR_ANGLE_DEG(90) - half_diag_fov);
for (band = 0; band < 2u; band++) {
vertex = 4 * band;
angle = -BR_ANGLE_DEG(90) - half_diag_fov + angle_range * band / 2;
pModel->vertices[vertex].p.v[1] = sinf(BrAngleToRadian(angle)) * sky_distance;
pModel->vertices[vertex].p.v[2] = -cosf(BrAngleToRadian(angle)) * sky_distance;
}
min_angle = -gSky_image_underground;
angle_range = gSky_image_height;
nbands = 18;
for (band = 0; band < nbands; band++) {
vertex = 4 * band + 8;
pModel->vertices[vertex].p.v[1] = sinf(BrAngleToRadian(min_angle + angle_range * band / nbands)) * sky_distance;
pModel->vertices[vertex].p.v[2] = -cosf(BrAngleToRadian(min_angle + angle_range * band / nbands)) * sky_distance;
}
min_angle = gSky_image_height - gSky_image_underground;
angle_range = half_diag_fov + BR_ANGLE_DEG(90) - (gSky_image_height - gSky_image_underground);
for (band = 0; band <= 1u; band++) {
vertex = 4 * band + 80;
angle = min_angle + angle_range * band;
pModel->vertices[vertex].p.v[1] = sinf(BrAngleToRadian(angle)) * sky_distance;
pModel->vertices[vertex].p.v[2] = -cosf(BrAngleToRadian(angle)) * sky_distance;
}
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];
for (band = 0; band <= 21u; ++band) {
vertex = 4 * band;
for (stripe = 1; stripe < 4u; ++stripe) {
pModel->vertices[vertex + stripe].p.v[1] = pModel->vertices[vertex].p.v[1];
pModel->vertices[vertex + stripe].p.v[2] = pModel->vertices[vertex].p.v[2];
}
}
// FIXME: unknown model flag disabled
BrModelUpdate(pModel, BR_MODU_ALL & ~0x80);

BrModelUpdate(pModel, BR_MODU_ALL & ~BR_MODU_VERTEX_NORMALS);
}

// IDA: br_model* __usercall CreateHorizonModel@<EAX>(br_actor *pCamera@<EAX>)
Expand Down Expand Up @@ -331,12 +339,18 @@ void InitDepthEffects() {
FatalError(kFatalError_FindSkyMaterial_S, "HORIZON.MAT"); // 2nd argument added
}
gHorizon_material->index_blend = BrPixelmapAllocate(BR_PMT_INDEX_8, 256, 256, NULL, 0);
BrTableAdd(gHorizon_material->index_blend);

// HACK: moved below loop
// BrTableAdd(gHorizon_material->index_blend);
for (i = 0; i < 256; i++) {
for (j = 0; j < 256; j++) {
*((tU8*)gHorizon_material->index_blend->pixels + 256 * i + j) = j;
}
}
// HACK: this should be above the for loop. Haven't been able to figure out how this is working in OG, as changes made to the pixelmap
// don't update the stored copy without calling `BrTableUpdate`.
BrTableAdd(gHorizon_material->index_blend);

gHorizon_material->flags |= BR_MATF_PERSPECTIVE;
BrMaterialAdd(gHorizon_material);
gForward_sky_model = CreateHorizonModel(gCamera);
Expand Down Expand Up @@ -371,9 +385,6 @@ void DoDepthByShadeTable(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer
int render_line_skip;
LOG_TRACE("(%p, %p, %p, %d, %d, %d)", pRender_buffer, pDepth_buffer, pShade_table, pShade_table_power, pStart, pEnd);

// Added to ensure we've copied the framebuffer+depthbuffer back into main memory
Harness_Hook_FlushRenderer();

too_near = 0xffff - (1 << pStart);
shade_table_pixels = pShade_table->pixels;
depth_shift_amount = pShade_table_power + 8 - pStart - pEnd;
Expand Down Expand Up @@ -514,7 +525,7 @@ void DoHorizon(br_pixelmap* pRender_buffer, br_pixelmap* pDepth_buffer, br_actor
br_actor* actor;
LOG_TRACE("(%p, %p, %p, %p)", pRender_buffer, pDepth_buffer, pCamera, pCamera_to_world);

yaw = BR_ANGLE_RAD(atan2f(pCamera_to_world->m[2][0], pCamera_to_world->m[2][2]));
yaw = BrRadianToAngle(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;
}
Expand Down
Loading