Getting started with the C front - DavidPH/GDCC GitHub Wiki
Let's start with compiling a pair of basic Hello World programs to get started with GDCC. GDCC only has a command line interface, and won't work with drag and dropping, and unlike the ACS front, it doesn't work with SLADE either. As such, it is heavily recommended users have some basic knowledge on using the command line to be able to use GDCC's C front efficiently.
This is the first program we'll be compiling, which won't require any extra library linking:
// Includes functions from Hexen, ZDoom and those exclusive to Zandronum.
#include <ACS_Zandronum.h>
// This is an attribute specifier. In GDCC's C front, scripts are functions with a different calltype.
// This is set with the "call" attribute, and the "ScriptS" parameter is equivalent to a named script.
// The "script" attribute sets script type and/or flags. Here it is set to the enter type, same as in ACS.
[[call("ScriptS"), script("enter")]]
void HelloWorld (void)
{
// ACS function names included with the "ACS_*.h" headers have an "ACS_" prefix by default, to avoid conflicts with C functions.
// This is the internal function to start a print.
ACS_BeginPrint();
// Strings prefixed with "s" are of the "__str_ent *" (ACS string) type, instead of the default "char[]" (C string) type.
// This is the internal function to add a string to the currently open print.
ACS_PrintString(s"Hello, world!");
// And this is the instruction to finish a basic print and put it on the activating player's screen.
// This sequence is equivalent to Print(s:"Hello, world!") in ACS.
ACS_EndPrint();
}
Some descriptive comments giving a simple overview of the features in use are included in the above example, but more in-depth information is available on the dedicated wiki pages.
To compile this example:
gdcc-cc --target-engine Zandronum program.c -o program.o
--target-engine
specifies the engine GDCC will target when compiling. ZDoom
is another supported engine target. Zandronum
is more or less the same, it simply generates extra code for initializing objects clientside, but will work fine in ZDoom and other derivatives. -o
specifies the output filename and path. program.o
here is the bytecode result, and is meant to be used exactly like the output from ACC would be.
This program makes use of libc, which is the standard C library.
#include <stdio.h>
[[call("ScriptS"), script("enter")]]
void HelloWorld (void)
{
// printf is equivalent to a Log call in ACS. The buffer that printf uses is only
// written when a linefeed/newline is used, hence the trailing "\n".
printf("Hello, world!\n");
}
Any program with StdCall
functions (which is the default calltype, and is also used nearly exclusively in libc) will also require a library handling dynamic memory allocation, like libGDCC. As such, compiling these libraries and linking them to the main program is a little more involved. Here's an example both compiling and linking them statically:
gdcc-makelib --target-engine Zandronum libGDCC -c -o libGDCC.ir
gdcc-makelib --target-engine Zandronum libc -c -o libc.ir
gdcc-cc --target-engine Zandronum program.c -c -o program.ir
gdcc-ld --target-engine Zandronum libGDCC.ir libc.ir program.ir -o program.o
There's quite a bit more going on here. gdcc-makelib
is sort of an alias to gdcc-cc
that can automatically compile both libGDCC and libc. The -c
parameter means that the output will be an IR (intermediary representation) suitable for linking (but this IR is itself not ready for use with ZDoom). gdcc-ld
is a linker that can link these IR files into an ACS bytecode module that can be used like the output of ACC would.
This is quite a lot to type in every single time, this is because GDCC is designed to be used with automated build systems like Ninja and Make. It's recommended to either use those, or a simple batch/shell script to execute the commands when the project needs recompiling.