📜 ⬆️ ⬇️

DOOM 3 BFG - source code review: introduction (part 1 of 4)

Part 1: Introduction.
Part 2: Multithreading
Part 3: Rendering (Approx. Translation - in the process of translation)
Part 4: Doom classic - integration (Approx. Translation - in the process of translation)

November 26, 2012 ID Software released the source code Doom 3 BFG edition (just a month after the game appeared on store shelves). The idTech4 engine, which is almost 10 years old, was updated with the solutions used in idTech 5 ( Rage is the first game on this engine), and it was very interesting to get acquainted with its source code.

I would call the engine idTech4 improved, because in essence, this is idTech4, but using idTech5 elements:

Until now, the most attractive aspect is the flow control system: Doom 3 was developed at the dawn of the era of multi-core systems, when few computers used SMP . Now the rules have changed, even the phones are equipped with several cores and the game engine must be multi-threaded in order to use the full potential of the machine.
')
I hope that this will inspire people to understand the source code, improve their skills and become better engineers.

First contact


Getting to know Doom 3 BFG is impressive, because To run from source, you need to do only 2 steps:
  1. Get the sources located on GitHub:
    git clone https://github.com/id-Software/DOOM-3-BFG 

  2. Open Visual Studio 2010 Express and press F8 to compile. Done!

Note: If the Direct3D SDK is installed, the complete project is compiled in less than a minute, issuing 5 minimal warnings.

Debug mode


Only 3 steps are needed to start tinkering with Visual Studio 2010 Express:
  1. In the debug command line, specify the base path:
      +set fs_basepath "C:\Program Files\Steam\SteamApps\common\DOOM 3 BFG Edition" +set r_fullscreen 0 

  2. Open the project "Doom3BFG".
  3. Press F5



Readability source code


Subset C ++:

Doom 3 BFG is written in C ++, a language so great that it can be used both to create great code and for such an abomination from which your eyes will bleed . Fortunately, ID Software used a subset of the C ++ language, close to “C with Classes,” which will not be so difficult to understand:

And despite the multithreading, the code does not use smart pointers or Boost . What a relief (after all, this is what usually makes code unreadable).

Comments

There are a lot of comments and they are quite useful, as they, as a rule, describe what goes on in the most important places of the next block in one sentence. Here is an example from ParallelJobList.cpp :

  int idJobThread::Run() { threadJobListState_t threadJobListState[MAX_JOBLISTS]; int numJobLists = 0; int lastStalledJobList = -1; while ( !IsTerminating() ) { // fetch any new job lists and add them to the local list if ( numJobLists < MAX_JOBLISTS && firstJobList < lastJobList ) { threadJobListState[numJobLists].jobList = jobLists[firstJobList & ( MAX_JOBLISTS - 1 )].jobList; threadJobListState[numJobLists].version = jobLists[firstJobList & ( MAX_JOBLISTS - 1 )].version; threadJobListState[numJobLists].signalIndex = 0; threadJobListState[numJobLists].lastJobIndex = 0; threadJobListState[numJobLists].nextJobIndex = -1; numJobLists++; firstJobList++; } // if the priority is high then try to run through the whole list to reduce the overhead // otherwise run a single job and re-evaluate priorities for the next job bool singleJob = ( priority == JOBLIST_PRIORITY_HIGH ) ? false : jobs_prioritize.GetBool(); // try running one or more jobs from the current job list int result = threadJobListState[currentJobList].jobList->RunJobs( threadNum, threadJobListState[currentJobList], singleJob ); 


In general, the reader gets a direct understanding of each part of the algorithm, and I hope that this will inspire people to write better code: after all, when developing software, it’s not important to be a big ace than others. It is equally important to be able to work in a team by creating code:

Doom 3 BFG has high rates in both of these positions.

What changed?



Solution Explorer (solution explorer) in Visual Studio has become noticeably cleaner (before and after):


Doom 3 BFG Sub Projects

Projects
Builds
Observations
AmplitudeAmplitude.libUsed in Doom Classic: A tool to adjust the amplitude of the WAV.
Doom3bfgDoom3BFG.exeEngine Doom 3 BFG.
doomclassicdoomclassic.libSeriously revised Doom1 / 2 engine.
externalexternal.libSources jpeg-6 and zlib.
Game-d3xpGame-d3xp.libA single library of the game, including the original game + expansion + new levels. Please note that now it is going to a static library instead of a DLL.
idLibidLib.libPackage software tools id software to work with the file system.
timiditytimidity.libUsed in Doom Classic to convert MIDI files to WAV format.


New architecture


The architecture is significantly different from the original Doom III: now everything is compiled into one monolithic executable file (the original Doom III was compiled into one executable file and one DLL containing the game logic). This was done for two reasons (according to the main developer Brian Harris):


Changes related to development for consoles:


The orientation of the Xbox 360 and PS3 in the project, initially focused on the PC led to many important updates:
  1. As mentioned earlier, the whole game is contained in one executable file.
  2. In the game, PAK files (which are ZIP archives) are used to store various parts. The high latency of the DVD drives pushed ID Software to the following resource allocation: one file, it contains everything you need for one load level.
  3. Game assets were textual, but in order to reduce load time, some of the assets, such as models and animation, are now binary (.bmd5mesh and .bmd5anim).
  4. Doom 3 was designed to work with a resolution of 640x480 with a 4: 3 aspect ratio. Currently, TVs and monitors most often have an aspect ratio of 16: 9, so all the menus have been redone. Probably, in order to speed up development, it is implemented on Adobe Flash. Doom 3 BFG uses its own Flash interpreter (/ neo / swf /). Again, Flash is used to speed development.
  5. Shader rendering was rewritten using GLSL 1.5. HLSL shaders can be converted on the fly.
  6. To obtain an acceptable frame rate, the flashlight could not be used with a weapon. (Approx. Trans. - in the original there is the phrase "Now with Doom 3” Most likely, it means not “duck taped”, but “duct taped "- Scotch tape, i.e." Now, in Doom 3 BFG it can be attached to a weapon ... ")
  7. Since the PC menu is now cross-platform PC has largely lost rendering settings: we get a simple version that is used in both PCs and consoles.


Multithreading


In the 10 years that have passed between the development of the old and the new engine, a paradigm shift has occurred: the “free cheese” has ended, and the game engines must be developed using multi-threading. Therefore, the most attractive thing to read in a Doom III BFG is the idTech5 Threading architecture. (Detailed review in the second part of the translation).

Rendering


There are 2 main changes:
(Detailed overview in the third part of the translation)

Doom classic


Doom III BFG allows you to play Doom 1 and Doom 2. At first glance, the simple task is to integrate the old Doom1 engine into the new Doom 3 BFG: just redirect all the inputs / outputs! But given the split-screen mode on the PS3 and Xbox360, this is not realizable. (Detailed overview in the 4th part of the translation)



Post is a translation, but because published from the sandbox - I can not change the type of post. Subsequent parts will be arranged correctly. Translation errors, typos are happy to correct, write in HP.

The original of the first part - Fabien Sanglard

Source: https://habr.com/ru/post/180973/


All Articles