Digital Foundry Retro Discussion [2016 - 2017]

Status
Not open for further replies.
Good lord that gorilla is awful. Even by PS1 standards. Well, it was an early game...
I suspect it was never expected to be rendered at more than, say, VGA let alone 1024, so the gaps would've been masked by chunky pixels.

After so many years, let me thank you for the long evenings enjoying this utterly difficult but fantastic game with my Tseng Labs plus Matrox M3D.
I'm sure "Nobby" & Mick would also be pleased to hear that. We certainly had fun doing it. Core's code was really cleanly written and nice to work with.

For posterity, I should probably jot down a few things we did while doing the port.

  1. The transform pipeline was originally coded in fixed point, which makes a lot of sense for the machines that it was targeting, but since the Pentium now provided decent floating-point performance, we changed it over to FP.

  2. Further, since the PCX1/PCX2 had in effect sub-pixel precision for vertex positions (and we now had float transforms) we removed the rounding to integer in the pipeline which meant animation became smoother.

  3. The textures were packed as multiple 256x256 atlases, some with mixtures of opaque and translucent data. Since PowerVR gets a huge performance boost from opaque overdraw, we scanned through those atlases and created opaque 565 and, where necessary, translucent, 4444, variants, and chose the appropriate one on the fly. MIP maps were also generated but I can't recall if that was in the original code or not. (It was nearly 20 years ago so forgive me)

  4. However, having generated all these textures, they couldn't all be resident in the on-board texture memory (which was < 4MB: Some of the on-board mem was required for geometry/shading data). We thus had to implement a 'caching' scheme tracking active textures. This is slightly more interesting when you note that the previous frame would still be rendering and accessing textures while the SW was constructing the geometry/display list for the subsequent frame. We thus sometimes had to drop the resolution of a texture to get it to fit rather than pause the rendering.

    (I have a vague feeling that the 3DFX port may have worked around this issue to some extent by using the 8bpp "narrow channel" texture compression but that might lead to some washed-out/desaturated results)

  5. I think we sorted translucent objects (e.g. the medical kits, water surface, vines) by Z so were able to turn on bilinear filtering. I noticed some other variants just used alpha test to avoid the sorting issue, but this results in rather jaggy edges.

  6. (Blue) Fog was turned on for 'under water' objects. This was free in the hardware so seemed a shame not to use it. It, perhaps, could have been a bit more subtle but you should seen some of the settings we started with. (Cherenkov radiation to the max :))

  7. The max resolution was increased to 1024 (probably in both X and Y) depending on the 2D graphics card's support in terms of resolution and memory. Initially the code only supported double buffered, but I got annoyed as my dev PC's graphics card didn't have enough RAM for 1024x768 DB, so added a single buffered mode. Because it's a TBDR, you can get away with SB as tearing artefacts are 'nearly invisible'. (FWIW, if you look at the first image I posted, you can see the SB next to the resolution)

  8. PCX1/2 could render quads faster than the equivalent two triangles so I think there was code to detect if a pair of triangles (and the associated texture coordinates) was 'flat' and merged the data.

  9. The save/restore menu had to be rendered over a snapshot of the previous frame. Because the max texture resolution was 256x256, I think I divided the frame into 3x2 sections, each of which was put into its own texture. That was then rendered along with the menu objects.
 
Last edited:
I suspect it was never expected to be rendered at more than, say, VGA let alone 1024, so the gaps would've been masked by chunky pixels.


I'm sure "Nobby" & Mick would also be pleased to hear that. We certainly had fun doing it. Core's code was really cleanly written and nice to work with.

For posterity, I should probably jot down a few things we did while doing the port.

  1. The transform pipeline was originally coded in fixed point, which makes a lot of sense for the machines that it was targeting, but since the Pentium now provided decent floating-point performance, we changed it over to FP.

  2. Further, since the PCX1/PCX2 had in effect sub-pixel precision for vertex positions (and we now had float transforms) we removed the rounding to integer in the pipeline which meant animation became smoother.

  3. The textures were packed as multiple 256x256 atlases, some with mixtures of opaque and translucent data. Since PowerVR gets a huge performance boost from opaque overdraw, we scanned through those atlases and created opaque 565 and, where necessary, translucent, 4444, variants, and chose the appropriate one on the fly. MIP maps were also generated but I can't recall if that was in the original code or not. (It was nearly 20 years ago so forgive me)

  4. However, having generated all these textures, they couldn't all be resident in the on-board texture memory (which was < 4MB: Some of the on-board mem was required for geometry/shading data). We thus had to implement a 'caching' scheme tracking active textures. This is slightly more interesting when you note that the previous frame would still be rendering and accessing textures while the SW was constructing the current list. We thus sometimes had to drop the resolution of a texture to get it to fit rather than pause the rendering.

    (I have a vague feeling that the 3DFX port may have worked around this issue to some extent by using the 8bpp "narrow channel" texture compression but that might lead to some washed-out/desaturated results)

  5. I think we sorted translucent objects (e.g. the medical kits) by Z so were able to turn on bilinear filtering. I noticed some other variants just used alpha test to avoid the sorting issue, but this results in rather jaggy edges.

  6. (Blue) Fog was turned on for 'under water' objects. This was free in the hardware so seemed a shame not to use it. It, perhaps, could have been a bit more subtle but you should seen some of the settings we started with. :)

  7. The max resolution was increased to 1024 (probably in both X and Y) depending on the 2D graphics card's support in terms of resolution and memory. Initially the code only supported double buffered, but I got annoyed as my dev PC's graphics card didn't have enough RAM for 1024x768 DB, so added a single buffered mode. Because it's a TBDR, you can get away with SB as tearing artefacts are 'nearly invisible'. (FWIW, if you look at the first image I posted, you can see the SB next to the resolution)
"listening" to you is fascinating to me. So you did program it using a double, or float? What's the language in which you programmed the game if it is not asking much?
 
Last edited:
"listening" to you is fascinating to me. So you did program it using a double, or float? What's the language in which you programmed the game if it is not asking much?
Float or double?Hmm. I suspect it would have only been float but I can't really be certain. PCX2 took geometry in IEEE float format so that would probably be the likely choice. Further I just took a quick look at Agner Fog's x86 instruction timings to see if there's a performance difference; divide is certainly considerably faster with float than double on the Pentium so it's more likely we used the former.

The original code from Core was (IIRC) all C and we continued with that. As I mentioned earlier, it was written in a logical and clean fashion. It was then a matter of making the necessary changes to that code in order to make calls to our triangle/quad graphics library (SGL-Lite), e.g. replacing the software triangle rasteriser call to one that added geometry to the PVR 'display list'.

FWIW another group @IMG (nee Videologic) were aiming to port a different game (I won't say what it was) but that code base was littered with random snippets of inline ASM and calls to a different vendors graphics API. They wisely gave up before insanity set in.

(also just remembered another tweak so updated the earlier post)
 
And what did you do to make it run at 60 fps, whereas all the other versions were locked at 30 fps?
I'm not sure if I worked on that bit but I have a feeling that the original code might have accidentally(?) been waiting 2 vsyncs per frame.

[Update: as it was a long time ago (and pre-children) I might have worked on it. I don't really know]
 
Last edited:
Float or double?Hmm. I suspect it would have only been float but I can't really be certain. PCX2 took geometry in IEEE float format so that would probably be the likely choice. Further I just took a quick look at Agner Fog's x86 instruction timings to see if there's a performance difference; divide is certainly considerably faster with float than double on the Pentium so it's more likely we used the former.

The original code from Core was (IIRC) all C and we continued with that. As I mentioned earlier, it was written in a logical and clean fashion. It was then a matter of making the necessary changes to that code in order to make calls to our triangle/quad graphics library (SGL-Lite), e.g. replacing the software triangle rasteriser call to one that added geometry to the PVR 'display list'.

FWIW another group @IMG (nee Videologic) were aiming to port a different game (I won't say what it was) but that code base was littered with random snippets of inline ASM and calls to a different vendors graphics API. They wisely gave up before insanity set in.

(also just remembered another tweak so updated the earlier post)
Thanks for the insight Simon F. It's quite curious because float and double seem to do more or less the same, although double allows for larger numbers. I can imagine how complex a game like that is, and programming it might be a work of art. Which leads me to the question....when you mean C...do you mean that you literally used C or was it C++?

As of currently, I am learning Java (and C# is next) as I am studying programming and they wholeheartedly recommend you to use that object-oriented approach where you have a main method but you can create as many methods as you can to create cleaner to understand, reusable code.

Most of the appointments I have aren't requiring methods that much, they are simple programs, like painting diamonds with asterisks, loops, switch menus, printf, etc etc.

So I am used to working with the main method without calling other methods to help. But I wonder, do you really think it is beneficial to program in an object oriented manner or C was fine enough if you knew how to keep your code clean and readable?
 
Thanks for the insight Simon F. It's quite curious because float and double seem to do more or less the same, although double allows for larger numbers.Which leads me to the question....when you mean C...do you mean that you literally used C or was it C++?
There can be a cost with using double rather than float though sometimes some of it's hidden by the HW designers using more silicon.
For something like TR, float rep should be fine. After all you should be able to represent any location in, say, a 8x8x8km cube world with a precision of at least 0.5mm.
Which leads me to the question....when you mean C...do you mean that you literally used C or was it C++?
C.
But I wonder, do you really think it is beneficial to program in an object oriented manner or C was fine enough if you knew how to keep your code clean and readable?
Whatever you feel comfortable with, but FWIW I never really got into C++. I used it a bit in Win95/MSVC days but when you needed to work on more esoteric HW, (e.g. DSPs) C++ wasn't always available. Further I just got tired of chasing through N-levels of software (classes built on classes) to find out why "X" wasn't working. Further, found some devs would use a ridiculously flexible class to implement things that could be done with, say, a simple array and then wonder why the code was a bit slow. <shrug>.

Accidentally? Any chance this accident could be exploited to made this run at 60 fps then:
http://www.tombraiderforums.com/showthread.php?t=214779
:smile2:
I don't know anything about the Rage patch. I have a feeling we were given either (or both) the standard DOS and/or 3dfx port as a starting point. We certainly didn't have a Windows 95 version.
I'm not sure if reverse engineering is legal but I suppose someone could try looking for the vsync test, seeing if it tests twice in a row and, if so, replace the 2nd with NOPs.
 
Last edited:
There can be a cost with using double rather than float though sometimes some of it's hidden by the HW designers using more silicon.
For something like TR, float rep should be fine. After all you should be able to represent any location in, say, a 8x8x8km cube world with a precision of at least 0.5mm.

C.

Whatever you feel comfortable with, but FWIW I never really got into C++. I used it a bit in Win95/MSVC days but when you needed to work on more esoteric HW, (e.g. DSPs) C++ wasn't always available. Further I just got tired of chasing through N-levels of software (classes built on classes) to find out why "X" wasn't working. Further, found some devs would use a ridiculously flexible class to implement things that could be done with, say, a simple array and then wonder why the code was a bit slow. <shrug>.


I don't know anything about the Rage patch. I have a feeling we were given either (or both) the standard DOS and/or 3dfx port as a starting point. We certainly didn't have a Windows 95 version.
I'm not sure if reverse engineering is legal but I suppose someone could try looking for the vsync test, seeing if it tests twice in a row and, if so, replace the 2nd with NOPs.
So the Windows 95 compatible 3D dll that we can use to enjoy super high resolutions and stuff, wasn't meant to be? One always think that if a hardware company publishes a specific file for a game, it is legal, programmed by the creators of the game. Did you know at the time?

Performance wise, was there a huge difference between a pure DOS game (allegedly faster) and a Windows game (allegedly slower)?

On a different note, your game is a timeless classic. I have a 17 years old friend who played the original Tomb Raider on his father's PC starting from a very early age, at 4 or 5. He also played the 8 bits game Master of Orion, Pandemonium, Doom 1 and 2, Age of Empires 1 and 2, Total Annihilation, Heroes of Might and Magic 1, 2, 3.., Super Mario Bros, Unreal Tournament, etc etc etc etc.
That is not an object oriented approach, that is just code separation for readability and/or removing code duplication. But this is OT.
ok, thanks for the clarification
 
So the Windows 95 compatible 3D dll that we can use to enjoy super high resolutions and stuff, wasn't meant to be? One always think that if a hardware company publishes a specific file for a game, it is legal, programmed by the creators of the game. Did you know at the time?
I'm sorry but I don't know what you mean.
 
I'm sorry but I don't know what you mean.

I think Cyan means one of the video card vendors released a patched dll for their hardware that was Win95 compatible and not DOS as per all the other versions, I believe this dll is the base for all current mods keeping the game playable.

So I assume the question was if the game was always supposed to be in DOS only and the(your) actual team never worked on this version of the DLL that is now so critical to being able to play the title still today.

Any history on the DOS Win95 platform decisions and reasons would be very interesting, as pre Windows is probably quite difficult for many to fathom now.
 
AFAICR the code that Core supplied to us was for DOS and I suspect we thought it was simpler to create a DOS version of our graphics library than to move the game code to Windows 95. <shrug>
 
AFAICR the code that Core supplied to us was for DOS and I suspect we thought it was simpler to create a DOS version of our graphics library than to move the game code to Windows 95. <shrug>
so..., do you think your code was re-engineered? I wonder how difficult would it be to port the game from DOS to a Win95 compatible dll or so.

New video, this time it features a game which is considered a masterpiece, the second iteration of Shenmue (alas I played none but one can see why it is considered a great game):

 
so..., do you think your code was re-engineered? I wonder how difficult would it be to port the game from DOS to a Win95 compatible dll or so.
I think you might have misunderstood me. Core, the TR developers, sent Img Tech (nee Videologic) a version of their code to allow us to modify it to run on the PowerVR hardware. I assume this was done as a mutually beneficial exercise: IIRC the hardware came with a free demo version of the game which would make the card a more appealing purchase and, similarly, should boost sales of the full game for Core.

I should imagine similar agreements were made with other hardware vendors who would do their own ports.

I don't recall our modifications ever being sent back to Core so I doubt they would have been incorporated into any other version.
 
ICO revisited. I had a PS2 -along with a brother of mine- quite late in that console cycle, but never played this game. I remember the discussions with PS2 fans about this game. They considered it a true unique masterpiece.

Gotta say it never achieved the commercial success of many other PS2 games, and it is pretty low in the list of higher selling PS2 games ever. Shadow of Colossus wasn't quite the seller either, and sits at the 300 something position iirc, but sold more than ICO.


As for the author talking about emulation, to me emulation is like the best thing ever!! You get to keep your old games playabe in a single machine with a experience tailored to your needs -or your machine- without losing an ounce of the original's game feel..
 
PCem, the PC emulator of old PCs. This is great news.

https://pcem-emulator.co.uk/

It's a PC emulator, think like... VMware and Virtualbox, being the difference that this one, besides installing the old OS that you want, allows emulating the hardware, that is, it runs a processor and a graphics card that you choose from a list!!

The emulator has its time, but it hasn't been until recently that it has hit the definitive big pull with the emulation of the Vodoo1. If you try the last version it will run ALL the games you try, at least afaik. Okay, in my case I have 4 examples or so to share, but all are emulated to perfection, with hardware acceleration and the glorious resolution of 800x600.

Examples are (for the emulated PC the chosen OS was Windows 98, the mentioned Voodoo1, and a Pentium 233 MHz processor):
Dino Crisis
Need for speed hot pursuit
SIN


Some videos showing it in action.





It should be noted that the installation of the OS is as is, drivers included, either W95, 98, ME ,,,. That is, think of installing an OS in virtual box but you also add the original drivers, and they work!! That's a big, big difference with Virtualbox and VMWare, where the original drivers don't work !

I remember trying to play Command & Conquer on VirtualBox for Windows 95 and it was impossible. :( -same for XCom and many other-
So now I can play my first games ever, which where The Need for Speed and Microsoft Golf. And games like one of my favourites to date, lots of hours into it, impressive graphics at the time Need for Speed 3 Hot Pursuit.. :)

This emulator also has its cons: Asks for a good machine to make it work well. Logically the more demanding the components to emulate the higher performance it will need. It seems that with an all powerful i7 and the emulated Pentium at 300 MHz, it can struggle at times.

This isn't like DOSBox, this emulates Windows. And that means DOS too. You can emulate a Voodoo on Windows 95..

They are making giant strides, and now that the Voodoo1 is perfectly emulated (what enjoyment I got from my standalone Monster3D back in the day), and everything is on a roll. They are working on implementing full emulation of the Voodoo2.
 
Last edited:
Yeah, that one's been around for a while. Still early stages for much of what it supports, and etc. It's in the "Lots of stuff will work, lots won't" stage of emulation development.
 
Status
Not open for further replies.
Back
Top