18-08-17, 22:17 | #1 |
Member
Joined: Jan 2010
Posts: 384
|
Playstation Waving Inventory algorithm + Patch
Hello! Some of you know that I have been working for a long time on a project, related with the decompilation, bugfixing and software improvement of the first games of the Tomb Raider series, mainly TR2 and TR3. Several people even accused me of not sharing the technical details of my work with the community. Well, in my defense, I can say that I spend almost all my free time on the project itself, and most of the knowledge received and still rapidly arriving is in the form of separate drafts that have not been properly drawn up for use by anyone else. It's just pointless to give out incomprehensible material, 50% consisting of wild pseudocode, 25% of the assembler and 25% of the notes that are clear to me alone.
Nevertheless, I plan to write and submit to you articles with the most interesting in my opinion details in the jungle of the program code of the Tomb Raider games. Here is the first such article, and it describes the animated wallpaper of the PlayStation TR2 inventory. It takes time to complete the documentation, but time is not always there. The preparation of this article and the project itself for the release into open source took two weeks. All these two weeks I did not deal with the main programming tasks (except, of course, my fulltime work in the office, for which I get wages). But sooner or later, it was necessary to do this. Update: Beta test is started. You can inspect the code and try the patch right now. As bonus you get all pictures properly remastered by me (including all versions of title pictures). Just unzip the latest version, copy to your game folder and launch. Don't forget to try some nice options, that can be toggled by reg files from ExtraOptions folder. Introduction Before we begin, I want to say that all of the below that I discovered in the PlayStation game code I've implemented for PC too. Version of the game itself with the necessary improvements is in active development. Though it is in closed beta testing now, but will soon be available for everyone. Before this happens, I need to complete my TR2Draw dynamic library, which will allow to port the game to native DirectX 9 code (or any other API later, since the DLL is opensource). At last we could throw away DirectX 5 and the wrapper crutches (Yuk, I fiercely hate these workarounds!). The source code of a small part of this TR2Draw library, related to the animated wallpaper of the inventory, is already presented on GitHub. There is video on YouTube comparing the original implementation of wallpaper on the PlayStaion, my implentation for the PC with the original textures, as well as one with the HD textures (also remastered by me). If this article is TLDR for you, you can just click through links, videos, images and animations. For everyone else, here we go! Preparation Behind the scenes, the Playstation TR2 generates an 13x9 array of vertices located in 2D plane. These vertices form 12x8 grid of equal textured squares. The center vertex is anchored to the center of the screen. The resulting grid of squares is scaled so that the height of the screen is equal to 4.5 of the height of a square. You can see bright red frame on the image below - this is game screen limits. Click to enlarge tne image Every such vertex has 3 parameters:
All vertices receive a base 50% brightness (128/255), except for the farther ones (all of them are outside visible screen by the way). The farthermost vertices receive a 25% brightness (64/255), and the neighboring farther vertices receive 37.5% (96/255). Any square gets a gradient brightness depending on the brightness of each of its vertices. I do not know why the developers implemented a separate lighting scheme for these farther vertices, because this shade effect is actually not noticeable within the game screen at all. In my implementation for the PC, I did not obscure the vertices far beyond the screen. Then the game initializes three angular variables that will control all subsequent animation. There is one small, but important detail. For most trigonometric calculations, Tomb Raider uses short integer (2 bytes) representations of angles, as well as the results of various functions such as the sine and cosine. This is in some way convenient, and also such calculations work much faster than full-fledged trigonometric floating-point operations. For all angle values we will use hexadecimal integer representation in this article. Angle examples:
Well so, the game initializes three angle variables. Code:
static unsigned short deformWavePhase = 0x0000; // 0 degrees static unsigned short shortWavePhase = 0x4000; // 90 degrees static unsigned short longWavePhase = 0xA000; // 225 degrees
We will need them in the next stages. Deformation Each vertex of the grid mesh, which we prepared in the last stage, must be shifted from the base position to a distance of 10% of the grid square width before the rendering. The direction of the shift is given by the individual angular phase of each vertex, which depends on the common phase (common phase is stored in deformWavePhase variable). In fact, each vertex spins in a circle around its base position with a radius equal to 10% of the grid square width. Cosines of its phase is X offset, sines is Y offset. The extreme upper left vertex gets the common angular phase. The right vertex next to it gets a phase increased by 0x3000 (67.5 degrees), the lower vertex next to it gets a phase increased by 0x33E7 (73 degrees). And so each of the points gets its individual phase, calculated from points to the left and above. With every new frame, the phase changes, and all points synchronously rotate counter-clockwise by the amount of the common phase value change. Schematically the simplified deformation is shown in the figure below. To shift the phase down and to the left, a value of 60 degrees is taken. Thus, in this simplified scheme, vertices are arranged at the corners of synchronously rotating hexagons (as you know the angle between the corners of the hexagon is 60 degrees). Click to enlarge tne image Lighting This animated wallpaper is completely flat but it looks three-dimensional. This illusion is created by a special lighting formula that, like a deformation, spreads from the vertex to the vertex beginning from the top left corner. The lighting of the vertices depends on two waves. One is short but slower, the second is long but faster. Each uses its common angular phase: shortWavePhase and longWavePhase. We need to get sines of these phases to get brightness values. As you remember, the base brightness of each vertex was 50% (128/255). In the highest position, each wave increases the base vertex brightness by 12.5% of the maximum (+32/255). At the lowest position, the wave reduces the brightness by 12.5% (-32/255). Two waves are summed up and, in some cases, the brightness value is changed to 25% (64/255) in the higher or lower side. So the resultant vertex brightness varies from 25% (64/255) to 75% (192/255). Like for deformation, there are phase shifts from top left corner of the grid. Short wave horizontal and vertical shifts are exactly the same as deformation shifts: 0x3000 (67.5 degrees) and 0x33E7 (73 degrees) Long wave horizontal and vertical shifts have individual values: 0x1822 (33.94 degrees) and 0x1422 (28.31 degrees) Click to enlarge tne image These different shifts give us interesting two dimensional wave interference effects, because we have different wave lengths, different wave velocities, and even little different wave 2D directions. By the way you can read on the wikipedia about wave interference. You can see the animated lighting scheme on the link below. For clarity, a pure red, undeformed, untextured sheet is used. For this demonstration, I wrote several chart functions, executed right in the game. Click to play the animation There is even more to come! This is only one feature, which I tried to describe as clearly and briefly as possible. Maybe I missed something. In any case, I still have a whole warehouse for such improvements and even more bugfixes, and they are waiting for their time to be published. I propose to discuss these in the thread. Last edited by Arsunt; 05-06-23 at 16:11. |
18-08-17, 22:32 | #2 |
Member
Joined: Jul 2012
Posts: 6,507
|
That's so cool! Will you try to bring the other PS1 features to the PC versions?
|
18-08-17, 22:37 | #3 |
Member
Joined: Jan 2010
Posts: 384
|
|
18-08-17, 22:46 | #4 |
Member
Joined: Nov 2011
Posts: 1,709
|
woah this is cool! Nice work!
|
18-08-17, 23:15 | #5 |
Member
Joined: Oct 2006
Posts: 2,374
|
Great work! Thanks for taking the time to share this.
|
19-08-17, 00:28 | #6 |
Member
Joined: Jun 2007
Posts: 26,990
|
Great job ! Not just implementing the feature but also explaining it to us in so much detail. This is really interesting, thank you !
|
19-08-17, 05:14 | #7 |
Golden
Joined: May 2005
Posts: 7,562
|
That was a very interesting read, thanks!
|
19-08-17, 10:16 | #8 |
Member
Joined: May 2006
Posts: 16,794
|
omg, would love to see a HD video
|
19-08-17, 12:13 | #9 |
Member
Joined: Dec 2006
Posts: 2,159
|
This is amazing! Do you plan to release this to the public?
What else do you hope to bring to PC players? I'm thinking of the reflective save crystals and gold Lara from TR1. |
19-08-17, 18:42 | #10 |
Inactive
Joined: Dec 2006
Posts: 31,966
|
Wow this is awesome and fascinating! Great job!
|
Bookmarks |
Thread Tools | |
|
|