ARTICLE 10 - Compiling with Metrowerks CodeWarrior
by Tony Kostanjsek
CodeWarrior is cool. This is for all the people who also appreciate its
features and want to use it for Q3 development.
I assume that you know how to set up a mod, where to put DLLs and
QVMs and how to start quake so it actually finds and loads your files.
In the following text you'll only find the details you need to take your
work to the CodeWarrior IDE. Contact me if you have any further questions
or spotted any mistakes.
But before we continue, heres some additional info you might want to know:
CodeWarrior: is a Compiler/IDE made by
Metrowerks. It runs on various
platforms including MacOS, Windows, Solaris and as a front-end for
the Linux GNU compilers. It allows you to build projects for various
platforms including Java, PalmOS, Playstation and others besides the ones
you're using to run the IDE.
The IDE has lots of useful features that make it very easy to navigate
between source files, very powerful search functions, manage groups of
files and targets. And I mean VERY easy and VERY powerful
compared to (say) VC++. Grab a copy and try it.
Lcc: is a retargetable C compiler by Chris Fraser and David Hanson.
For more infos, distributions, source code, documentation and books
about it, head to the
Lcc pages at Princeton.edu.
Our friends at Id have modified it to spit out QVM bytecode as we know it.
1. Building DLLs
The following steps were only tested for release builds. I haven't tried
using the debugger while running Quake3 in a window.
Follow these steps to build a server DLL:
Building targets for client and ui DLLs is just the same.
If you can't be bothered to set up a project yourself, download this
Make a copy of the original sources.
Assuming that your mod's sources are located in the folder 'CoolMod', create a
folder 'cwq3project' inside 'CoolMod'. Unzip 'cwq3project.zip' inside
'CoolMod/cwq3project' and you're done. You can rename the folder
'cwq3project' and 'cwq3project.mcp' to whatever you like.
You should keep the extra folder inside 'CoolMod' because CodeWarrior
creates some additional project data thats stored inside it.
- create a Win32 C DLL Project as the starting point
- select the 'Win32 C DLL Release' target
- delete the 'Win32 C DLL Debug' target. We don't need it.
- open the preferences of the current target
- in 'Target/Target Settings' change the 'Target Name' to 'server'
- in the same panel set the output directory to the one of your mod
- in 'Target/x86 Target' change the 'File Name' to 'qagamex86.dll'. The names for the other DLLs are 'cgamex86.dll' and 'uix86.dll'
- in 'Code Generation/x86 Processor' set Byte Alignment to '4'. I was successfully running DLLs with the default '8', but Hypothermia pointed out that Q3 requires '4' so we'll set it.
- in 'Language Settings/C/C++ Language' enable 'Enums always int'
- in the same panel, remove the prefix file (Win32Headers.mch or similar) or you'll get multiple defines.
- CodeWarrior has some cool keyword highlighting features. If you want to use them, go to 'Target/Build Extras' and check 'Activate Browser'
- save the preferences and close them
- remove all files from the 'Source' folder in your project window and rename the folder to 'Server'
- now open the 'game.bat' file that comes with the sources and is used to compile the QVMs. You'll see a list of .c files.
Find all of them in the 'quake3/source/game' folder and drop them in your project window in the 'Server' folder.
- don't put in 'bg_lib.c' as it only includes stdlib functions we already have in the libs.
- add 'g_syscalls.c' to the server target, 'cg_syscalls.c' to the client and 'ui_syscalls.c' to the ui. These enable your DLLs to call the trap_* functions that talk to the Q3 core.
- add the 'game.def' file along with the .c files, otherwise the compiler won't know which symbols to export and Q3 won't be able to load our DLL
- open the 'Win32 SDK Libraries' folder in the project window and remove the 'Gdi32.lib'. We don't need it. Required libraries are: Ansicx86.lib, Mwcrtl.lib, Kernel32.lib, User32.lib
- build the DLL, start the mod with something like: C:\quake3\quake3.exe +sv_pure 0 +set fs_game MyModFolder. Always set +sv_pure 0 if you're trying your own maps and mods to avoid problems.
2. Building QVMs
The ReadMe provided with the sources suggests that you use the VC++ headers
to compile the QVMs. At first I thought I could also get lcc to
compile with the MSL headers, but it wouldn't work.
The '__option' switches made it abort compilation, and I didn't
succeed in defining a valid set of switches so the cross
platform headers would turn into something useful.
After some research I decided to go with the
Put them in quake3/source/lcc/bin/include and in all compile.bat files add
-D_stdcall="" to the command line. Now you can use the .bat files to
compile your QVMs just as you were supposed to.
But is this really it? Didn't we get a groovy IDE to avoid .bat files?
Yup! That's why I downloaded the Metrowerks PlugIn SDK and wrote some ...
3. IDE PlugIns for the Q3 tools
These are really front-ends for lcc and q3asm that make them look like an
integral part of the IDE. Kinda.
here and put them in your CW PlugIns-Folder. The sources also include
a sample project.
Unfortunately there are some drawbacks....
It's not my fault, honestly! Or ... at least I don't know what I did wrong.
Look at the following:
The performance is the main reason why I can't really advise you to use
the PlugIns for frequent use. You should rather build DLLs until
the final release. Then, you could build the QVMs with the
.bats or with new targets that use the PlugIns.
- Paths: The IDE does a lot for you. It also does a lot for
its PlugIns. It takes care of the access paths and if a PlugIn
says 'gimme file deathwish.h' it'll find and load it and pass
it a handle to the file. Unfortunately, we're not a true
compiler, only a front-end. And as the IDE won't give us the
paths, just the files, you have to enter the whole lcc command
line parameters in the cwq3panel, complete with include paths.
- Performance: Again, we're only a front-end. The tools
are started as child processes and their output is redirected
to the message window. Process maintenance and output
redirection takes a while. Worst case for q3asm on my machine
was nearly 60 seconds compared to 20 seconds if you use the
.bat files. Lcc is also a lot slower.
In fact, I was so disappointed with the performance and the restricted
access to the path settings that I left the PlugIns in an
unpolished state. They work, but could do with some tidying up.
For example, there is no panel for controlling the lcc or q3asm
flags via checkboxes etc. Instead, you have to specify everything
in a command line string. Theres also no way yet to select folders
through a dialog. You have to enter the pathnames manually.
So, if anyone wants to take a look at the sources and see if theres
a way to optimize things, feel free to do so and please share your
Anyway, you should really stop messing around with that compiler
and get coding your mod! NOW!