Archive for February, 2024

QfG5: some notes about the design

Wednesday, February 21st, 2024

Since I have not progressed far in the recent weeks (the current events put me out of mood) I can at least document some bits before I forget them completely. In this post I’d like to outline the overall game engine design.

FFhistory: ProRes

Monday, February 5th, 2024

Apparently there’s some work been done recently on the ProRes encoders in jbmpeg with the intent not merely to fix the bugs but also to leave just one. So why not talk about the format support, it’s about as entertaining as the recent story in the project demonstrating once again that most of the problems in open-source development can’t be solved by throwing donations, even moderately large ones.

So, ProRes, the format with its history being a rather good demonstration about the project issues (CEmpeg and libav back then, and FFmpeg throughout its history in general). This tale is full of whimsy (depending on your sense of humour of course) and contains moral as well.

QfG5: panorama projection

Saturday, February 3rd, 2024

While I’m slowly, very slowly, approach model rendering, here’s something that is between 2D and 3D.

As I mentioned in my previous post, room backgrounds are supposed to be used as a texture on a virtual cylinder. After some investigations I figured out more details and have somewhat working code.

If you forgot geometry as much as I did, here’s a reminder: cylinder is an extruded circle and an image painted on it will be seen in a distorted way with more of the picture seen in the middle (because the distance varies) and sides of the picture being squished (because cylinder curve is at larger angle to the projection plane).

Computing how the pixels should map to the projection is a costly operation so the engine pre-computes tables for the columns to take, actual amount of that column to scale and the scaling step. As the result, during rendering stage all that is needed is to look up the column offsets for each output column, offset inside the column and scaling coefficient (both stored as 16-bit fixed-point for faster calculations). This also explains why background images are stored in the transposed format, it’s definitely easier to manipulate them this way.

Also while fiddling with all this I understood at last what the floating-point numbers in the header mean—they denote start and end angle for the panorama. Those angles are also used in limiting the distance from which the panorama may be seen.

In case of underwater panorama (with its wavy distortion) there’s yet another table in play but I’ve not touched it yet.

The main problem figuring out the code is that Ghidra has problems dealing with x87 code (and it’s hard to blame it, x87 is even worse in some aspects than x86) and I’m not eager to do it by hoof. In the code calculating those projection coefficients step -= delta * 2.0 / width was decompiled as step -= width / (delta * 2.0), I could understand that the called function is arccosine only from the context as Ghidra refused to decompile it and it also failed to recognize the case when common sub-expression was used in two subsequent calculations i.e. instead of y_offset[i] = (int)(offset * 65536.0); scale[i] = (int)((height * 0.5 - offset) * 2.0 / disp_h) - 1; it had scale[i] = (int)((height * 0.5 - extraout_ST0) * 2.0 / disp_h) - 1; where offset=(1.0 - angle * scale) * height * 0.5 but it’s not stored anywhere except in x87 register. As I said, I understand why decompiling it hard but such mistakes require either to try and reconstruct x87 code by hoof or resort to the geometry to derive the proper formulae and I don’t know which one is worse.

In either case here is an example to conclude the post: