---------------------------------------------
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<path to your Borland C++ dir>\include

   where <path to your Borland C++ dir> 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.




