--------------------------------------------- Compiling Quake3 source using Borland C++ 5.0 --------------------------------------------- Index ----- What this archive is for Files in the archive Installation Modifications to source files Some Q&A Warranty and redistribution What this archive is for ------------------------ The files in this archive allow you to build, maintain, and develop the Quake III source using Borland tools and header files. Specifically Borland C++ 5.0, as I don't have C++ Builder to try this out on. I created these files because I don't have a Microsoft compiler. Along the way I found there were several issues that needed to be resolved, mainly a difference in the way the Borland libraries handles math errors. I've released this archive for use by the Quake3 developing community. If you find this archive useful or can improve upon it then please let me know. If you build a mod using Borland tools then please send me an e-mail letting me know were I can get it from (oh, and a credit somewhere in your mod would also be appreciated!) If there's demand for Borland C++ 4.5 I can create the IDE for that version of the compiler. Cheers! Ian Jefferies (aka HypoThermia) quake3@eudoxus.demon.co.uk http://www.eudoxus.demon.co.uk/quake3/index.htm Acknowledgements: id Software for Quake3 (doh!) -and writing very portable C code Borland International (are they still Inprise?) -for making life hell (for a while) by the way they chose to handle math errors. Files in the archive -------------------- q3source.ide Project file for editing/compiling in Borland IDE borland\readme.txt This file! borland\compile.bat Compiles a single .c file to .asm using lcc borland\ui.bat Batch files for compiling .qvm borland\game.bat borland\cgame.bat borland\ui.def New linker .def files for Borland tools borland\game.def borland\cgame.def borland\ui.q3asm Response file for linking .asm to make .qvm borland\game.q3asm borland\cgame.q3asm borland\borland_hack.c Small hack required to make the cgame.dll behave borland\obj\obj.txt Creates borland/obj directory, can be deleted borland\Debug\debug.txt Creates borland/Debug directory, can be deleted Installation ------------ You should already have the compiler tools installed in \Quake3\bin_nt and the Quake 3 source files in \Quake3\source. 1) Unzip this archive into the \Quake3\source directory, making sure that subdirectories are created. At this point you can delete obj.txt and debug.txt if you wish. 2) Open the file borland\compile.bat and find the part of the line that says: -Ie:\bc5\include Replace it with: -I\include where is the full path to your Borland C++ installation directory (surprise!). 3) Open the q3source.ide using Borland C++. Open the Options|Project... dialog. Select the Directories entry and modify the absolute paths to the Borland "include" and "lib" directories to match your installation. 4) Follow the "Modifications to source files" below (two changes only!). 5) Try a full build of the three dll's, copy them from the borland\Debug directory to the \Quake3 directory, and fire up Quake3 for a test. 6) Try a full build of the .qvm. Run game.bat, cgame.bat and ui.bat from the source\borland directory at the command prompt. The new .qvm files should appear in the \Quake3\baseq3\vm directory. 7) Try the TestMod described in the makeamod_readme.txt file supplied in the Q3 source distribution. ----------------------------- Modifications to source files ----------------------------- Only one modification is required to the Q3 source files, and one to Borland header files. Quake 3 source files -------------------- Open the header file game\q_shared.h and move to line 424, it should be: float Q_crandom(int* seed); Insert after it the following: #ifdef __BORLANDC__ #ifdef random #undef random #endif #endif The Borland header files define the macro random() already. To remove the possibility of a clash with the definition of random() that follows it is undef'd here. The error is also flagged when compiling lcc.exe, and a clear, unambiguous, and correct definition of random() is required. The file game\q_shared.h contains most or all of the compiler specific flags so I have no qualms in modifying it. If a new Quake3 source is added or reinstalled then this modification will have to be applied again. Borland header file ------------------- In your Borland C++ install directory open the file include\stdarg.h. Move down to line 20, it should say: #error Can't include both STDARG.H and VARARGS.H Change it to: #error "Can't include both STDARG.H and VARARGS.H" This removes one compiler warning produced by lcc.exe. That's it! Some Q&A -------- Q: When compiling the .qvm files using the batch files I get warning messages. What gives? These error messages are caused by "issues" within either the Borland header files or the Q3 source. limits.h:31 Character constant taken as not signed The header file is intended to detect whether the data type char is signed or unsigned. ui/ui_ingame.c:103 warning: Conversion of 'pointer to void'... ui/ui_ingame.c:107 ui/ui_atoms.c:739 ui/ui_atoms.c:742 Compiler is warning of a non-portable pointer conversion. Not a problem with BC++ or the VM. Anything else is something you've introduced! Q: Can I build the .dll's into another directory? Yes! Open the project options dialog Options|Project... and select Directories. Change the final output directory to the absolute/relative path you want. e.g. changing to ..\ compiles directly to the Quake3 directory. Remember, paths are relative to \Quake3\source. Q: Why create the \borland directory? It keeps the modifications that I've had to make to the supplied files away from the source distribution as much as possible. It also invites others to work in the same way; and for Borland, Microsoft, and other compiler tools to co-exist side by side and work with the same code source. Q: What is borland_hack.c for? When running cgamex86.dll there was the occasional hang that wase cleared by pressing ESC twice. It was always reproducable in the same places by running a timedemo of demo001.dm3. What was happening was that the math library was generating an error dialog. borland_hack.c traps the error before the dialog is shown and "fixes" it by, effectively, ignoring the problem. The problem was created after a call into trap_CM_BoxTrace() returned a null vector when a unit vector was expected. It only appears to occur in the CG_PlayerShadow() function. A bug report has been sent to id. It appears that the Microsoft based builds of this .dll pass over this error silently. Q: What are the .def files for? The Borland compiler places an underscore (_) in front of every name generated that uses the C calling convention. The new .def files rename these exported functions to remove the underscore so Q3 can bind to the .dll's. Q: Can I get some more performance out of these DLL's? If you have TASM try removing the C_ONLY define in the Compiler|Defines of the project options. I don't have TASM so this is untested. Compile using the Intel optimizing compiler, and use Pentium scheduling. Turbo Debugger doesn't work too well on these builds because of the way the Intel compiler moves code around. Q: Why are the .qvm files a different size to those distributed by id? I suspect that this is caused by differences in the implementation of the header files by Microsoft and Borland. Presumably static data is included in the .qvm files, and if the Microsoft headers use more static data then this will be reflected in the size of the .qvm. Q: How do I change the directory the .qvm files are built to? Modify the cgame.q3asm, game.q3asm and ui.q3asm files. In each case the first line (beginning with -o) contains the destination directory of the .qvm files. Q: What's with all those -Dxxxxx things in compile.bat They pass defined constants to lcc.exe, the equivalent to #define xxxxx in C source code or header files. Borland header files use predefined constants that match the requirements of the compiling model. These are all defined in _defs.h, so that file is bypassed by defining ___DEFS_H and appropriate definitions are supplied instead. Q: How do I debug using these dll's? This is not straight forward. Quake3 is a demanding executable, any number of problems can arise depending on the implementation of your sound drivers, GL drivers etc. etc. I have found that the following works most of the time: 1) Compile your DLL's and move them to the \Quake3 directory. 2) Open a windowed DOS box in your Quake3 directory. 3) Run Turbo Debugger, TD32.EXE QUAKE3.EXE 4) Quake 3 should start OK, if not jump to step 7 5) If your .dll's are crashing then generate the event that causes the crash. The machine should appear to lock solid. Press Alt-Enter to get to the debugger. 6) If Q3 locks during startup then try Alt-Enter to get to the debugger. Quit the debugger. 7) Do a full reboot of the machine to avoid any instability. Any enhancements/improvements to this method are invited, particularly on how to attach to DLL's loaded using LoadLibrary(). To generate your own crash deliberately insert the code: *(long*)(-4)=0; This is a one time only crash, and cannot be recovered from. Warranty and redistribution --------------------------- This archive is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You may redistribute this archive as you see fit so long as it is not sold for commercial gain. You must redistribute the archive intact and unchanged.