Documents:
An archive version of the original documents can be found here.I had a hard time finding this recently, so I've posted it in this set incase a repeat happens.
FTE qcc has a typical set of C pre-compiler directives that allow for more complex code and projects.
The details provided here are a basic guide to usage.
Full credit and kudos to the FTE team for the entire creation.
Precompiler definitions
Contents |
Definitions
#define
Syntax: #define <defname>[(<macroparams>)] [<defvalue>]
Defines a precompiler define or macro.
- <defname> contains the define name
- <macroparams> contains a list of parameters, seperated by commas, to use with a macro (optional)
- - {param spec} must NOT include numerals 0 - 9
- <defvalue> contains the define value (optional)
After statement parsing, <defname> is considered defined. Then, FTEQCC encounters <defname> or #<defname> during parsing, it will be replaced with <defvalue>, or <defname> will be erased if <defvalue> is not defined. If <macroparams> are defined, FTEQCC will use <defvalue> in the following fashion:
- If a parameter in <macroparams> as an isolated token is found, it is replaced into the result.
- If a parameter in <macroparams> is found with a preceding #, it is surrounded in quotes, then placed into the result.
- If a parameter in <macroparams> is found with 2 preceding #, it is concatenated into the result.
Examples:
// Simple defines for use in precompiler control logic later on #define MONSTERS #define NEWWEAPONS
// Use of defines as constants #define NEWWEAPONNAME "chainsaw with lasersight" string s; s = NEWWEAPONNAME; // Same as s = "chainsaw with lasersight"; s = #NEWWEAPONNAME; // Also same as s = "chainsaw with lasersight";
// Simple use of macros #define ISEQUAL(a,b) (a == b) float float1, float2; if (float1 == float2) dosomething(); if (ISEQUAL(float1, float2)) // Does the same thing as the previous if dosomething();
// Use of stringify with macros #define OBJECT(a) #a string s; s = OBJECT(mouse); // Same as s = "mouse";
// Use of concatenate with macros #define SPECIALCLASS(a) float special_##a SPECIALCLASS(thing); // same as float special_thing;
Warning: Macros are not the same as functions. For example:
float x; #define SQRT(x) (x*x) float squareroot (float x) { return x * x; } float subtract2fromx (void) { x = x - 2; return x; } void testfunction (void) { x = 7; y = squareroot(subtract2fromx()); // Results in (7-2) * (7-2) = 25 x = 7; z = SQRT(subtract2fromx()); // Results in (7-2) * ((7-2)-2) = 15 }
#undef
Syntax: #undef <defname>
After statement parsing, <defname> is considered undefined. FTEQCC will no longer parse <defname> or #<defname> when it is encountered.
Control Logic
Preprocessor control logic statements allow flow of control over program compilation. Note that these statements can be nested.
#ifdef
Syntax: #ifdef <defname>
See also: #else, #endif
Includes all lines contained within the terminated #ifdef block for compilation if <defname> is a defined preprocessor define.
Examples:
#define SOMETHING float x; #ifdef SOMETHING // Since SOMETHING is defined, this block gets compiled x = 1; #endif // x = 1 at this point. #ifdef SOMETHINGELSE // This block does not get compiled since I did not define SOMETHINGELSE x = 2; #endif // x does not change. x = 1 at this point.
// ifdef nesting example #define SOMETHING #define SOMETHINGELSE #define SOMETHINGOTHER float x; #ifdef SOMETHING x = 2; #ifdef SOMETHINGELSE x = 3; #ifdef SOMETHINGOTHER x = 4; // this endif terminates ifdef SOMETHINGOTHER #endif // this endif terminates ifdef SOMETHINGELSE #endif // this endif terminates ifdef SOMETHING #endif // x = 4 at this point
#ifndef
Syntax: #ifndef <defname>
See also: #else, #endif
Includes all lines contained within the terminated #ifdef block for compilation if <defname> is not a defined preprocessor define.
Example:
#define SOMETHINGELSE float x; #ifndef SOMETHING // Since SOMETHING is not defined, this block gets compiled x = 3; #endif // x = 3 at this point. #ifndef SOMETHINGELSE // This block does not get compiled since SOMETHINGELSE is defined x = 4; #endif // x does not change. x = 3 at this point.
#if
Syntax: #if <value>
See also: #else, #endif
Includes all lines contained within the terminated #if block for compilation if <value> is non-zero, otherwise falls through to block termination.
Example:
float x; #if 1 // This block is compiled x = 2; #endif // x = 2 at this point. #if 0 // This block is not compiled x = 3; #endif // x doesn't change. x = 2 at this point.
#else
Syntax: #else
See also: #endif
Terminates an #if, #ifdef, or #ifndef block. Includes all lines contained within the terminated #else block for compilation if the previous #ifdef, #ifndef, or #if condition fails.
Example:
float x; // This condition always fails #if 0 // so this code block never gets compiled x = 1; #else // but the code contained in this block will x = 2; #endif // x = 2 at this point.
#endif
Syntax: #endif
Terminates an #if, #ifdef, #ifndef, or #else block.
Compiler Messages
#message
Syntax: #message <message>
Prints a message of <message> in FTEQCC's output.
#warning
Syntax: #warning <message>
Causes FTEQCC to send a warning in compilation containing the message <message>.
#error
Syntax: #error <message>
Causes FTEQCC to error in compilation with the message <message>.
Compilation
#include
Syntax: #include <file>
Includes <file> for compilation with FTEQCC.
#includelist
Syntax: #includelist
See also: #endlist
Includes all lines within the terminated #includelist block as files for compilation within FTEQCC.
Example:
#includelist first.qc second.qc third.qc #endlist // FTEQCC will compile first.qc, second.qc, third.qc
#endlist
Syntax: #endlist
Terminates an #includelist block.
#eof
Syntax: #eof
Terminates FTEQCC parsing. No compilation or preprocessor parsing will be done after an #eof in the file.
Progs Control
#output
Depreciated, use #pragma PROGS_DAT instead.
#forcecrc
Syntax: #forcecrc <crc>
Forces the progs to compile with a specific CRC value instead of the precalculated one depending on target type.
#copyright
Depreciated, use #pragma COPYRIGHT instead.
#datafile
Syntax: #datafile <file>
Embeds <file> within the progs. Only available for FTE target type progs. FTEQW does not expand these embedded files within its' filesystem yet.
Pack (PAK) files
Although made obsolete by decent PAK editors and engines supporting other archive formats, FTEQCC still includes support for generating PAK files just as the original QCC did. FTEQCC also has support for precompiler statements for creating PAK files to avoid wasting statements within the QuakeC code itself. Note that the pack statements have no effect unless FTEQCC is passed the parameters required to generate PAK files.
#packid
Syntax: #packid <id>
Selects <id> as the current pack id.
#pack
Syntax: #pack <file>
See also: #packid
Groups <file> with the previous #packid.
Example:
#packid 0 #pack "progs/rocket.mdl" // Will generate pak0.pak containing progs/rocket.mdl
Pragma (#pragma)
#pragma is an extensive precompiler statement which controls many aspects of the compiler. Note that all unknown #pragma statements encountered by FTEQCC are ignored (with a warning.)
#pragma DONT_COMPILE_THIS_FILE
This pragma is parsed but ignored by FTEQCC so PREQCC-using code can compile cleanly.
#pragma COPYRIGHT
Syntax: #pragma COPYRIGHT <message>
Changes the string to be embedded at the end of a compiled progs. <message> is the message to embed.
#pragma TARGET
Syntax: #pragma TARGET <target>
Switches compiled progs to a specific target type.
<target> can be the following:
- ID, STANDARD: standard Quake progs
- KK7: kkqwsv progs
- H2, HEXEN2: Hexen 2 progs
- FTE: FTE progs
- DEBUG, FTEDEBUG: FTE progs with debug information
It is not recommended to switch target types during compilation.
#pragma PROGS_SRC
This pragma is parsed but ignored by FTEQCC so PREQCC-using code can compile cleanly.
#pragma PROGS_DAT
Syntax: #pragma PROGS_DAT <progsfile>
Changes the destination file you wish to compile to. <progsfile> contains the new file name.
Example:
#ifdef MONSTERS #pragma PROGS_DAT monsters.dat #message FTEQCC will now compile to monsters.dat #else #pragma PROGS_DAT nomonsters.dat #message FTEQCC will now compile to nomonsters.dat #endif
#pragma keyword and #pragma flag
Syntax:
- #pragma keyword <onoroff> <keywordid>
- #pragma flag <onoroff> <keywordid>
Enables or disables a keyword or compiler flag matching <keywordid>. #pragma keyword and #pragma flag are functionally equal.
<onoroff> can be the following:
- enable, on: enable the chosen keyword or compiler flag
- disable, off: disable the chosen keyword or compiler flag
See FTEQCC Keywords for all of the possibilities of <keywordid>.
#pragma warning
Syntax: #pragma warning <onoroff> <warningid>
Enables or disables a compiler warning matching <warningid>.
<onoroff> can be the following:
- enable, on: enable the chosen warning
- disable, off: disable the chosen warning
- toggle: toggle the warning state
FTEQCC Warnings and Errors for all of the possibilities of <warningid>.