dethrace-labs / dethrace

Reverse engineering the 1997 game "Carmageddon"
https://twitter.com/dethrace_labs
GNU General Public License v3.0
859 stars 44 forks source link

Cockpit view not displaying correctly #271

Closed zear closed 1 year ago

zear commented 1 year ago

The cockpit view in Dethrace is currently not rendering correctly. This can be split down into 3 separate issues:

1. Camera

The cockpit viewport (gCamera_list[0]) matrix never gets updated. Technically, this can be fixed by adding the following lines in graphics.c:

     old_camera_matrix = gCamera->t.t.mat;
     if (gMirror_on__graphics) {
         old_mirror_cam_matrix = gRearview_camera->t.t.mat;
+        BrMatrix34Copy(&gRearview_camera->t.t.mat, &gRearview_camera_to_world);
     }
+    BrMatrix34Copy(&gCamera->t.t.mat, &gCamera_to_world);

...however, an implementation derived from OG needs to be tracked down. Perhaps old_camera_matrix = gCamera->t.t.mat is there for a related reason.

Deathrace after applying the above workaround: deathrace

2. Cockpit dashboard

The cockpit dashboard bitmap only displays for the standard resolution and is missing in the hires mode. In OG, it is displayed for both resolutions.

3. Background

The background, aka. "sky" does not render while in cockpit view. This is because ExternalSky and DepthEffectSky explicitly return early if cockpit_on == true. However, in OG the sky is still rendered in standard resolution and only gets ignored for hires.

OG sky in standard resolution: og

OG sky in hires mode: og_hires

dethrace-labs commented 1 year ago

Hi @zear! Thanks for #272. Are you actively working on any other part of the cockpit issues? If not, its something I'm interested in fixing, so I can take it.

zear commented 1 year ago

@dethrace-labs I sunk a couple extra days into this, but nothing bigger came out of it. Feel free to take over. Let me just dump some insights, so that you don't have to rediscover it yourself.

https://github.com/dethrace-labs/dethrace/blob/716b98c25a2717862c528b630c18655b247e1e68/src/DETHRACE/common/world.c#L2641-L2643 As the value of GetAnInt(f) evaluates to 5 (at least for the first race data), the above code results in complete precision loss of gSky_image_width during a cast from float to long:

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

According to the type name (br_fixed_luf), gSky_image_width is supposed to represent the fractional part of a fixed point value, so I think that instead of discarding the fractional part through a cast, we should be doing a multiply by 65536.0f to preserve it in integral form.

Right now gSky_image_width evaluates to 0, which when used in code below, produces a nan: https://github.com/dethrace-labs/dethrace/blob/716b98c25a2717862c528b630c18655b247e1e68/src/DETHRACE/common/depth.c#L537

On a side note, there are embedded comments for these three consecutive values of the sky data:

5       // Horizontal repetitions of sky texture
66      // Vertical size of sky texture (degrees)
182     // Position of horizon (pixels below top)

To me this reads like we should be doing gSky_image_width = (360.0 / GetAnInt(f)) directly, without converting the value into an angle, however code disassembly does not corroborate with it. Perhaps this is why the skybox is broken in hires mode of OG as well?

zear commented 1 year ago

As for the cockpit camera, I couldn't find any place in the OG disassembly where the cockpit camera would be translated to the world (or vice versa). Perhaps this happens inside the renderer loop rather than in game logic? I haven't dabbled with 3d geometry before, so perhaps missed something very obvious.

dethrace-labs commented 1 year ago

thanks for the tips, they were very helpful. Heres the fix for the cockpit camera - we were missing some brender code (https://github.com/dethrace-labs/dethrace/pull/279).

Haven't looked at the sky yet, DoHorizon is specifically for rendering the sky from cockpit view, which it does by rendering a sky object rather than drawing into back buffer.

dethrace-labs commented 1 year ago

This is fixed in #279