Fabien Sanglard's non-blog

  




Quake 2 Source Code Review 1/4

September 16th, 2011


Quake 2 Source Code Review 1/4 (Intro)
Quake 2 Source Code Review 2/4 (Polymorphism)
Quake 2 Source Code Review 3/4 (Software Renderer)
Quake 2 Source Code Review 4/4 (OpenGL Renderer)

Introduction


I spent about a month in my spare time reading the source code of Quake II. It was a wonderful learning experience since one major improvement in idTech3 engine was to unify Quake 1, Quake World and QuakeGL into one beautiful code architecture. The way modularity was achieved even though the C programming language doesn't feature polymorphism was especially interesting.

In a lot of regards Quake II is a shining piece of software history since it is the most popular (in term of licensing) 3D engine of all time. Powering more than 30 games but also marking the gaming industry's departure from software/8bits color system to hardware/24bits color system that occured around 1997.

For all those reasons, I highly recommend anyone that appreciate programming to dive into it. As usual I took numerous notes, cleaned them up and publish them as it may save a few hours to someone.

I got a bit carried away with the "cleanup" process since there is more than 40MB of videos,screenshots and drawings in this article. In the end I am not sure it was worth it and I may just publish my raw ASCII notes in the future (I am thinking of Quake3 and Doom3 source), let me know what you think.

EDIT : Seems this article inspired someone at geek.com since they just wrote an article "John Carmack coded Quake on a 28-inch 16:9 1080p monitor in 1995" (mirror).

EDIT (Oct 11,2011): Wow, 120,000 hits, 75,000 readers and a lot of kind comments/emails: Thanks guys ;) !


First contact and compiling


The source code is available for free on id software ftp website. The project can be opened with Visual Studio Express 2008, also available for free on Microsoft website.

The first striking thing is that the Visual Studio 6 workspace is not made of one project but five. This is because Quake2 is designed to be modular (I will detail this later). Here is a summary of the building targets:

ProjectsBuilds
ctfgamex86.dll
gamegamex86.dll
quake2quake.exe
ref_softref_soft.dll
ref_glref_gl.dll



Note   : "ctf" and "game" projects overwrite each other, more about this later.

Note 2: Building failed at first because of DirectX header missing:


    fatal error C1083: Cannot open include file: 'dsound.h': No such file or directory


Installed Direct3D SDK and Microsoft SDK (for MFC) and the thing compiled fine.

Software erosion: It seems that what happened to Quake codebase has started to happen with Quake 2: You cannot open the workspace with Visual Studio 2010. You will need to use VS 2008 :(.


Note : If after compiling you run into the error: "Couldn't fall back to software refresh!" it means the renderer DLL failed to load properly, this is easy to fix:

Quake2 kernel loads its two dlls using win32 API: LoadLibrary. If the DLL is not exactly what it was expecting or if the DLL dependencies cannot be resolved it will fail silently instead of displaying the error message. So:

If you are using the quake2 release from id software it should fix the issue.


Quake2 architecture


When I read Quake 1 source code I divided it in three part: Network, Prediction and Rendition. This approach would have been valid for Quake 2 because the engine is not fundamentally different but it was easier to spot the improvements by dividing it by the three main project types:


Project typeProject details
Main engine (.exe)Kernel calling modules and performing client/server network communications. This is the quake2 project in the workspace.
Renderer module (.dll)In charge of rendition. A software renderer (ref_soft) and an OpenGL renderer (ref_gl) are available in the workspace.
Game module (.dll)In charge of the player experience (Game content, weapons,monsters behavior...). Singleplayer (game) and Capture The Flag (ctf) are available in the workspace.


Quake2 is mono-threaded, the entry point can be found in win32/sys_win.c. WinMain method can be summarized as follow:

	

  game_export_t   *ge;	// Contains function pointers to game dll
  refexport_t      re;  // Contains function pointers to renderer dll

  WinMain()	//From quake2.exe
  {
	  
        Qcommon_Init (argc, argv);
	
        while(1)
        {
            Qcommon_Frame
            {
                SV_Frame()  //Server Code
                {
                    //In network mode do not act as a server
                    if (!svs.initialized) 
                       return;
                       
                    // Jump into game.dll via function pointer
                    ge->RunFrame();
                }
            	
                CL_Frame()  //Client code
                {
                    //If server only do not render anything
                    if (dedicated->value) 
                       return;    
                       
                    // Jump into rendere.dll via function pointer
                    re.BeginFrame();
                    //[...]
                    re.EndFrame();
                }	
            	
            }
        }
  }

	

Fully unrolled loop in my raw notes.


We may ask "why such a big change in term of architecture ?". To answer let's take a look at all the Quake versions from 1996 to 1997:

A lot of executables were produced and every time the code had to be forked or tweaked via preprocessor #ifdef. It was a mess and the way to solve this was to:

The following drawing summarize the new approach:





The two major improvements are:


Those two changes make the codebase extremely elegant and more readable than Quake 1 which was suffering from code entropy.

From an implementation perspective, the DLL projects must expose only one method GetRefAPI for the renderers and GetGameAPI for the game (Take a look at the .def file in the "Resource Files" folder):

reg_gl/Resource Files/reg_soft.def



    EXPORTS
        GetGameAPI


When the kernel wants to load a module, it loads the DLL into the process space, retrieves GetRefAPI address with GetProcAddress, receive the functions pointers it needs and that's it.

Trivia: When playing locally, the communication Client <-> Server is not performed via sockets. Instead commands are deposed in a "loopback" buffer via NET_SendLoopPacket on the client portion of the code. The server then reconstruct a command from the same buffer using NET_GetLoopPacket.

Random trivia: Ever saw this picture and wondered what kind of monster screen was John Carmack using circa 1996:



It was a 28" InterView 28hd96 monitor manufactured by Intergraph. The beast was capable of a resolution of 1920x1080, quite impressive in 1995 (details here (mirror)).




A youtube video for your nostalgia: Workstations from Intergraph Computer Systems.

EDIT : Seems this article inspired someone at geek.com since they just wrote an article "John Carmack coded Quake on a 28-inch 16:9 1080p monitor in 1995" (mirror). Thanks for crediting me.


EDIT : Seems John Carmack was still using this screen during the development of Doom 3:



Rendition


The software renderer (ref_soft) and the hardware accelerated renderer (ref_gl), modules are so big that they have their own page:


Again, the really cool thing here is that the kernel has no idea what renderer is plugged: It just calls a function pointer in a structure. The rendition pipeline is hence totally abstracted: Who needs C++ ?

Trivia : id software still uses the same coordinate system from 1992 Wolfenstein 3D (as of Doom3 this was still true). It is important to know that if you try to read the renderer source code:

With id's system:

OpenGL's coordinate system:


Hence in the OpenGL renderer the GL_MODELVIEW matrix is setup each frame to "correct" this in the R_SetupGL method (glLoadIdentity + glRotatef).


Dynamic Linking


The kernel/module interactions were too much data: dynamic linking has its own page here.


Modding: gamex86.dll


This part of the project was not very exciting to read but abandoning Quake-C for compiled module provide two good things and one very bad.

Bad :

Good :

Trivia : Ironically id software switched back to a virtual machine (QVM) for game, IA and modding in Quake3.



My quake2


I modified Quake2 source a little bit during my hacking session, I highly recommend to add a DOS console so you can see your printf outputs live instead of having to pause the game and look at the Quake console.:

It is quite easy to add a DOS style console to a Win32 window:



    // sys_win.c

    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
	    
	   AllocConsole();
	   freopen("conin$","r",stdin);
	   freopen("conout$","w",stdout);
	   freopen("conout$","w",stderr);
	   consoleHandle = GetConsoleWindow();
	   MoveWindow(consoleHandle,1,1,680,480,1);
	   printf("[sys_win.c] Console initialized.\n");
	    
     
	   ...   
	   
    }
    
      

Since I was running Windows on a Mac with Parallels it was uneasy to hit "printscreen" while the game was running. I hardcoded the '*' from the keypad to produce the same:



    // keys.c
    
    if (key == '*')
    {
        if (down)  //Avoid auto-repeat !!
            Cmd_ExecuteString("screenshot");
    }
	
	


Finally I added a lot of comments and diagrams. Here is "my" full source code:



Notes : If you start working on this source you need to compile the sub-project libpng first otherwise you will get an error message at runtime: "Couldn't fall back to software refresh!". This is very easy to fix here is the solution i posted on reddit:




   I ran into this issue a month ago and you are right it is a DLL loading error and it
   is very easy to fix. You see quake2 kernel loads some dlls using win32 API: LoadLibrary:
    
    If the DLL is not exactly what it was expecting or if the DLL dependencies cannot be resolved
     it will fail silently instead of displaying the error message. So:
     
     - Make sure you are linking all 5 projects with the same runtime library by right clicking on each project -> properties -> C/C++: 
     Check that "runtime library" = Multi-threaded Debug DLL (with configuration "Debug", otherwise use release).
     
     If you are using the quake2 release from id software it should fix the issue.
     If you are using my version: I added the engine capability to output PNG screenshots, 
     so you also need to build libpng and libz (it is in a subdirectory). Make sure your select the Debug DLL configuration. 
     Once built don't forget to place the libpng and zlib dlls in the same folder as quake2.exe.
     
     Done ;) !

     
     



Memory managment


Doom and Quake1 had their own memory manager called "Zone Memory Allocation": A big malloc was done at startup and the memory block was managed via linked list. Memory Zone could be tagged so a certain category of memory could be freed very fast.

The Zone Memory Allocator(common.c: Z_Malloc, Z_Free, Z_TagMalloc , Z_FreeTags) is still here in Quake2 but it is pretty much useless:

It is still pretty usefull to measure memory consumption thanks to the size attribute in the header inserted before each memory chunks allocated:


  
    #define    Z_MAGIC    0x1d1d


    typedef struct zhead_s
    {
	    
    struct   zhead_s    *prev, *next;
    short    magic;
    short    tag;			// for group free
    int      size;
    
    } zhead_t; 



The Surface caching system has its own memory manager. The amount of memory allocated depends on the resolution with a bizarre formula that has the merit to avoid trashing very efficiently:


      Surface caching inital malloc:
      ==============================
      
        size = SURFCACHE_SIZE_AT_320X240;  //1024*768

        pix = vid.width*vid.height;	
        	
        if (pix > 64000)				
           size += (pix-64000)*3;		





The "Hunk allocator" that is used for resource loading (images, sounds and textures). It is actually pretty cool and try to use virtualAlloc and align with a pagesize (8KB even tough Win98 was using 4KB ?! WTF ?!).

To finish there are a also lot of FIFO stacks (for spans storing among other things), despite the obvious limited capability they work very well.



Memory management: Alignment trick


Since Quake2 still does manipulate a lot of raw pointers there is a nice trick to align a pointer on 32bits (or align on 8KB to minimize PAGE_FAULT...even though windows 98 used 4KB pages).

Page alignment (on 8KB):

    
    
     int roundUpToPageSize(int size)
     {
          size = (size + 8191) & ~8191; 
          return size;
     
     }
    
        
    

Memory alignment (on 4B):

    
   
    
     memLoc = (memLoc + 3) & ~3;                         //Aligning on 4 bytes address.
	
    
        
    



Console subsystem


Quake2 kernel features a powerful console system that relies heavily on linked-lists and linear search.

Three objects types:

From a code perspective, each object type has a linked list:

	 
	     
    cmd_function_t    *cmd_functions     // A linked list, each element contains a string name and a function pointer: void (*)() .
	      
	      
    cvar_t            *cvar_vars         // A linked list, each element contains a string name and a string value.
	      
	      
    cmdalias_t        *cmd_alias         // A linked list, each element contains a string name and a string alias.
	      
	      
	      
	

Every time a line is entered in the console, it is scanned,expanded (completed via alias and cvar matches) and broken into tokens that are stored in two global variables: cmd_argc and cmd_argv:

	    
	    
    static   int       cmd_argc;                     
    static   char     *cmd_argv[MAX_STRING_TOKENS];  
	  
    
	    


Example:

Each token identified in the buffer is memcpyed to a malloced location pointed by an cmd_argv entry. The process is quite inefficient, showing that this subsystem received little attention. This is totally justified by the way: it is rarely used and has little impact hence was not worth the effort. A better approach would have been an in-place patching of the original string, writing pointer value for each token:





Once token are in the argument array, cmd_argv[0] is checked in a very slow and linearly way against all functions declared in the function linked list. If a match exist, the function pointer is called.

If no match exist the alias linked list is checked linearly in order to to check if it is a function call. If the alias did replace a function call, it is called.

Finally if nothing worked, Quake2 treats it like a variable declaration (or update if the variable is already in the linked list).

A lot of linear search in linked list is happening here, a hashmap would have been ideal to reach a O(n) complexity instead of O(n²).

Parsing trivia 1 : ASCII table were cleverly organized: When parsing a string for tokens, you can skip a separators and white space only testing if the character i is inferior to ' ' (space).

		
		
    char* returnNextToken(char* string)
    {
        while (string && *string < ' ')
            string++;
						    
        return string;
    }
    
	
		

Parsing trivia 2 : ASCII table were super cleverly organized: You can convert a char c to an integer as follow:
int value = c - '0' ;

		
		
    int charToInt(char v)
    {
        return  v  - '0' ;
    }
		
		      
		


Cvar value caching:

Since searching for a Cvar (Cvar_Get) memory location in this system is O(n²) (linear search + strcmp on each entry) the renderers cache the cvar memory location:

	    

    //Caching variable
    cvar_t		*crosshair;
	    
    // During engine init step, this create 
    // and return the memory location of the Cvar.
    
    crosshair = Cvar_Get ("crosshair", "0", CVAR_ARCHIVE);    //THIS IS SLOOOOW 
    
    
    //At runtime, in the renderer.
    void SCR_DrawCrosshair (void)
    {                          
	      
        if (!crosshair->value)                                 //THIS IS FAST   
            return;
    }
            
            

The value can then be accessed in O(1).



Anti Badguys systems


A few mecanisms were inserted to prevent cheating:



In-house assembly


Like every version of quake, some useful functions were optimized with assembly (there is no yet trace of the famous "Fast Inverse Square Root", this was in Quake3).

Fast Absolute Value on a 32bits float (most compiler do it automatically now):



    float Q_fabs (float f)
    {
        int tmp = * ( int * ) &f;
        tmp &= 0x7FFFFFFF;
        return * ( float * ) &tmp;
    }

    


Fast Float to Integer



    __declspec( naked ) long Q_ftol( float f )
    {
        static int tmp;
        __asm fld dword ptr [esp+4]
        __asm fistp tmp
        __asm mov eax, tmp
        __asm ret
    }



Code Statistics


Code analysis by Cloc shows a total of 138,240 lines of code. As usual this number is NOT representative of the effort since a lot was discarded during the iterative engine version cycle but I think it is a good indicator of the overall complexity of the engine.



    $ cloc quake2-3.21/
         338 text files.
         319 unique files.
          34 files ignored.

          
    http://cloc.sourceforge.net v 1.53  T=3.0 s (96.0 files/s, 64515.7 lines/s)
    
    -------------------------------------------------------------------------------
    Language                     files          blank        comment           code
    -------------------------------------------------------------------------------
    C                              181          24072          19652         107757
    C/C++ Header                    72           2493           2521          14825
    Assembly                        22           2235           2170           8331
    Objective C                      6           1029            606           4290
    make                             2            436             67           1739
    HTML                             1              3              0           1240
    Bourne Shell                     2             17              6             54
    Teamcenter def                   2              0              0              4
    -------------------------------------------------------------------------------
    SUM:                           288          30285          25022         138240
    -------------------------------------------------------------------------------



Note : All of the assembly was for the handcrafted software renderer.



Recommended tools for Quake2 hacking session





Recommended readings


It seems that I keep on recommending the same books :/ !




Add a comment



Name Homepage
E-mail
(Will not appear online)
Comment



Comments (51)


#1 - Rich Jones - 09/20/2011 - 14:10
This was an awesome, awesome write-up. I love this series. The illustrations are nice too. I can't wait for the Doom3 source to come out and for you to tear that down too. :)
#2 - Luis Merino - 09/20/2011 - 14:44
What a great idea.

I couldn't count the hours played to this game. I am no C programmer, but this is fantastic, can't wait to spare next weekend learning from this!
#3 - James Felix Black - 09/20/2011 - 15:39
Lovely. Thank you.
#4 - Michael Herring - 09/20/2011 - 15:52
I spent quite some time hacking away at the Quake 2 source in undergrad, it was a blast to read about it again. Thanks for the post!
#5 - Paul MULDER - 09/20/2011 - 17:01
How does one plug a PS/2 model-M into a mac?


I'd love to know, as I own both,.
#6 - Fabien Sanglard - 09/20/2011 - 17:07
Paul,

I use a USB adapter:

http://www.clickykeyboards.com/index.cfm/fa/items.main/parentcat/11298/subcatid/0/id/124184

This one in particular:

http://www.clickykeyboard.com/_ebay/modelm_usb/modelm_usb-001.jpg

Fabien
#7 - kobier - 09/20/2011 - 18:56
Cool article! :)
#8 - John McDowall - 09/20/2011 - 21:46
Sir, please do not change anything you do with this series. It's easily one of the most entertaining, informative and well written things on the Internet relating to a critical period in game development history. You're writing this for future generations and your attention to detail is very much appreciated!

Keep up the good work!
#9 - Dave - 09/20/2011 - 23:52
Great Article!

How about the Quake3 engine? It'd be awesome of you to do an in-depth review of that!
#10 - James Miller - 09/21/2011 - 09:37
Very nice article.

I have that same keyboard!
#11 - Fabian Giesen - 09/21/2011 - 10:42
From your raw notes: _controlfp is called every frame because graphics drivers at the time liked to tinker with it (usually to set the FPU to single-precision mode). There's something equivalent in most game loops on PC for that exact reason. :)

"It is actually pretty cool and try to use virtualAlloc and align with a pagesize (8KB even tough Win98 was using 4KB ?! WTF ?!)."
Win98 on x86 uses 4k pages, true, but Windows NT on Alpha workstations had 8k. Since Carmack likes to play with Workstation class hardware, I would guess that that's where this particular magic number comes from :). (8k alignment works on both x86 and Alpha)
#12 - Jay Dolan - 09/21/2011 - 12:44
Nice article! Some of us are still hacking on [what was] the Quake2 code base today :)

quake2world.net
#13 - ****** - 09/21/2011 - 14:24
you have no life
#14 - Aaron James - 09/21/2011 - 16:38
Just wanted to echo my thanks for this article. I enjoyed it tremendously and I'm really impressed how clearly you have been able to describe some pretty complex software functionality.
#15 - markus - 09/22/2011 - 14:35
Your notes and your documentation is so great!!!

I am a sub-par programmer, so I need every help I can get understanding things.

The gurus everywhere won't need this documentation perhaps, but I LOVE it.

Oh, and if making the videos, screenshots etc... is too much work, the explanation in the docs/notes is much more valuable and perhaps less time consuming!
#16 - Duh - 09/23/2011 - 09:53
Instead of "recommanding the same books" all the time, how about you go buy yourself a dictionary?
#17 - Fabien Sanglard - 09/23/2011 - 11:04
Haha, thanks for picking that up: I fixed the typo.
#18 - nickels - 09/23/2011 - 11:12
nice article. I've had trouble latching the debugger onto the server thread...
Spent a lot of time in the code too. Brilliant code, brilliant design. The academics had some
of the theory hashed out, but Carmak did it at 60fps and so he's the one driving the ferrari's now, not
the academics!!
thanks for the details.
#19 - Clinton - 09/23/2011 - 12:36
Now, this is coooooool...!!!!!!, Dude...!
#20 - Clemens Lode - 09/23/2011 - 13:39
I have that big Black Book, too! Kind of useless nowadays, but super-awesome :)) It's kind of an history book, how they programmed in ancient times ;)
#21 - Denis Santos - 09/23/2011 - 14:46
I liked so much to read about a beloved childhood game. And now that im a boring adult, i can dissecate the code ... man, its so nice :)
#22 - Noxwizard - 09/23/2011 - 19:17
If you want to compile it in Visual Studio 2010, you will need to update the Outputs entry for the .asm files in the ref_soft project. For some reason the conversion used $(InputName) (which doesn't exist) instead of %(Filename). A Find/Replace in ref_soft.vcxproj should remove the linker errors about .\..\debug\\.obj and let it compile.
#23 - Pedro Morales - 09/24/2011 - 00:37
awesome article, I spent lots of time playing this game and I remember I eventually downloaded the source code to check it and make some modifications, but that never happened :)
#24 - Kirtan - 09/24/2011 - 02:24
Legendary :)
#25 - Trent - 09/24/2011 - 03:22
Either the link for the source code is not valid, or the entire planet is trying to download the source, thus overloading their servers.
#26 - Bob - 09/24/2011 - 07:17
O(n^2) does not mean what you think it means. Linearly searching a list of strings with strcmp() is O(n) for the size of the list. The operations are O(m) where m is the length of the strings, but that means overall complexity is O(n*m), which can absolutely not be "simplified" to O(n^2).

Another nit: You complain about the efficiency of cmdline parsing? Really? Is *that* where they should have put their effort? Microoptimizing string tokenization for the interactive cmdline?


Independant -> independent

Great analysis though. Thanks.
#27 - bitshifter - 09/24/2011 - 09:46
Thanks for spending the time creating this series of articles.
They are well written and i really enjoyed reading through them.

In reply to one of your comments:

> R_DrawBEntitiesOnList : I seriously have no idea what this thing is doing.

Breakable glass is a brushed entity.
If you comment out its call, the glass is not rendered.
#28 - Fabien Sanglard - 09/25/2011 - 11:15
@Trent: id software website is a bit slow sometimes, try again later.
@Bob: Thanks for the explanation, I also fixed the typo.
#29 - Andrew Nielson - 09/27/2011 - 15:36
Just for everyone's info: back in 1995 when Quake 1, 2 and eventually tournament play were going on; there was one player who was kicking ass, and taking names with impunity. The name of this player was, and still is "Firewalker". She, that's right, SHE, is my daughter. She was 16 when she was playing. One of the player's names was "Sweaty Nipples", and was one of the programmers who's butt Firewalker kicked. If more details are wanted, drop me an e-mail. The Quake series was one of the most important pieces of software, not only for gaming, but the future of audio/video computing.. , Condor;-}
#30 - Daniel Monteiro - 09/28/2011 - 23:03
Very interesting points. Been reading your page since your Doom code review and couldn't stop reading everything else.
Also interesting is that Carmack seem to have used a lot of simple solutions ( some of it I've independently used on my own engines ), but the difference from other's implementations lie in the subtle details. He knows exactly what's going on in the system, thanks to lots of experimentations ( something I shamefully admit not knowing in detail ).

What if Quake1 were a OpenGL game from the start? Would it be simpler as it looks? Would Carmack push for more details? It seems Quake 2 suffer a lot from this legacy requirements....

I also would like thank you for the reading recommendations.

Cheers from Rio.
#31 - Jason Reed - 10/03/2011 - 14:00
First off, thank you very much for all this wonderful content. I programmed simple things in college (microcontrollers, etc). I've always wanted to dive into game programming, this seems like the best place to start with the help of some books.

I always coded in EMACs, so not too familiar with visual studio. I'm assuming I need the C++ version. I'm just used to good ole C, need to learn the ins and outs of C++ and Obj C. But for now I'm just going to look under the hood.

Again, thanks for the awesome work.
#32 - Norbert Klawikowski - 10/04/2011 - 18:34
Thank you for this fantastic article! This was better than a novel(at least for a programmer =) ) and well illustrated. I cant wait for your upcoming articles!
#33 - Rowan Crawford - 10/09/2011 - 10:08
Thanks for this very readable analysis. It gives me a much deeper insight than I would have received from just reading the code.
#34 - Aaron Spehr - 10/10/2011 - 22:29
Cool! I loved playing the Doom games when I was a kid. I tried to teach myself C++ but didn't get anywhere with it. Now that I am doing software development my school doesn't teach it.
#35 - Nicolas Sharp - 10/12/2011 - 05:26
Awesome and helpful article series, thanks a lot.
#36 - Clinton - 10/27/2011 - 02:03
You can get the Graphics Programming Black Book at:

http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/graphics-programming-black-book-r1698
#37 - black menza - 11/02/2011 - 10:12
ooooooowww simply amazing bro:) hacı süpersin yavvvhhh:Ç
#38 - marcelo_20xx - 11/09/2011 - 16:03
Nice article, a good insight into the quake 2 source. I have a question, what programs do I need to compile the source? I had Microsoft Visual Studio 2008, after I opened quake2.dsw I got a message that I needed to update the project to VS 2008 standards and then I tried to compile in release mode but ended with 375 warnings and 5 errors.

"Installed Direct3D SDK and Microsoft SDK (for MFC) and the thing compiled fine." This means that I need nVidia Direct3D SDK and Microsoft DirectX SDK?

Any help is appreciated, thanks peace
#39 - marcelo_20xx - 11/11/2011 - 21:16
Thanks for the response, I downloaded DirectX June SDK and the source compiled fine. Also I am curious if you enabled the option to load hi-res tga textures in your source or if you know how to do it, I got to read and load tga textures instead of the wals for the wall textures of the world but I cant (no matter how I try) to have them scaled properly.

If you give me an advice at this I will be forever grateful!. I know this isnt a support blog for modified sources, but right now you are the only active person who have the knowledge of the code to ask for.
#40 - Daniel Monteiro - 11/11/2011 - 22:59
@Marcelo No I did not try to load the TGA textures and I have not looked into it at all. If only there was a way to look inside the engine to see how it works inside......
#41 - SheridanR - 11/26/2011 - 00:02
I love this, thanks for posting! I'm 17 years old and I am an id enthusiast and a 3D game engine programmer. John Carmack is my hero, and I'm surprised how simple and elegant the Quake II engine really was. I even understand the assembler snippets you put up on this page (I discovered the fld/fistp trick on my own not long ago!)
#42 - zero - 02/07/2012 - 11:34
太给力了!你真是个天才!I LIKE YOUR ARTICLES!加油,doom3 code review is very good too!
#43 - viiceenttee! - 02/23/2012 - 15:07
como se crea una cuenta?
#44 - Andrey - 03/08/2012 - 03:31
PVS-Studio: analyzing Doom 3 code - http://www.viva64.com/en/b/0120/

Analyzing the Quake III Arena GPL project - http://www.viva64.com/en/b/0130/
#45 - Den - 04/03/2012 - 12:59
Awesome.thank you. very helpful to understand the code
#46 - leroyx - 04/05/2012 - 17:25
Awesome research about the quake engine!

thanks
leroyx
#47 - Jonathan - 06/13/2012 - 01:49
I was unable to get this to compile under VS 2008 and VS 2010 (and VS 2012). However, someone modified the code enough to get it to compile under VS 2010.

For anyone who is interested....

http://gregs-blog.com/2007/11/25/update-quake-2-net-port-with-visual-studio-2008-v90-and-managed-c/
#48 - duhi - 06/16/2012 - 00:43
Having problems running the .exe file, I am getting the following error "Couldn't load pics/colormap.pcx", it looks like I am missing something (well a pics folder)??
#49 - recover deleted files - 08/23/2012 - 05:32
More than 40 GB of videos, pics and musics in this article. That's unbelievable. Spent a lot of time in the code too. Brilliant code, brilliant design. The academics had some of the theory hashed out, but Carmak did it and so he's the one driving the ferrari's now, not the academics!!
#50 - boredcentral - 09/20/2012 - 08:18
I just love this page. Sometimes I wonder how you could come up with such terrific blog and game such as quake. I truly appreciate for your effort. Thanks.
#51 - Chung - 10/05/2012 - 10:30
Love this, Very nice write up! I'm getting into coding and such , hoping to attend a collegde soon, I'v always been a fan of the series and loved reading this.

 

Fabien Sanglard @ 2011