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.
(more…)
Archive for February, 2024
QfG5: some notes about the design
Wednesday, February 21st, 2024FFhistory: ProRes
Monday, February 5th, 2024Apparently 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.
(more…)
QfG5: panorama projection
Saturday, February 3rd, 2024While 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:
(more…)