6.5 KiB
Style Guide
Contents
General Rules
Please try and follow these general rules when writing your code:
- Indent with 4 spaces, not tabs.
- Put opening curly braces on a new line.
- Don't leave trailing whitespace at the end of lines.
- End every file with a single blank line.
- Keep lines between 80-100 character long at most.
Symbol Names
For new symbols (i.e. classes, variables, and functions), use the official name from the May 19 2002 demo if it is known. If it is not known, use a clear and descriptive name.
When making up symbol names, mimic the style of the official symbol names, Official names use a variation of Hungarian Notation. The most important part is the prefixes used to denote the type and scope of a symbol, as shown below.
These prefixes denote the type of a symbol:
Prefix | Type | Examples |
---|---|---|
p |
Pointer | CLOCK* pclock - Pointer an instance of the CLOCK struct |
n |
Integer/numeric value | int nScore - Numeric score value |
c |
Integer/count or quantity | int ccoin - A quantity of coins |
f |
Flag (boolean) | int fSneakyFeet - Footstep noises flag |
l |
Long | long lTime - A time in seconds |
d |
Float | float dTime - A time in seconds |
ch |
Char | char chCur - Current character in a loop |
b |
Byte | byte bData - A single byte of data |
u |
Unsigned | float uSuck - Unsigned value representing the player's suck score |
z |
Zero-terminated string | char chzBuffer[64] - Zero-terminated string buffer |
C |
Class | class CBinaryInputStream - Class that reads data from binary streams |
These prefixes denote the scope of a variable:
Prefix | Type | Examples |
---|---|---|
g_ |
Global variable | LM g_lmZeroOne - A global LM struct |
m_ |
Class member | int m_cbRaw - Count of raw bytes on a CBinaryInputStream |
s_ |
Static class member | TICK s_tickLastRaw - Static value for last raw tick on CLOCK struct |
Examples of combining these prefixes:
g_pgsCur
- Pointer to the current global GS structg_pchzArgs
- Pointer a global zero-terminated char array of argumentsm_cbBulkData
- Class member variable that stores the count of bytes in a data block
Capitalization
Use ALLCAPS
for struct/enum names.
- e.g.
struct DIFFICULTY
,enum FLS
Use UpperCamelCase
for function names, classes and enum values.
- e.g.
void OnDifficultyGameLoad()
,class CBinaryInputStream
,FCHT_InfiniteCharms
Use lowerCamelCase
for local variables, function parameters, and class members.
- e.g.
char nextXorChar
,Coin* pcoin
,float m_rxScale
Documentation
Comment your code with Doxygen-style comments. They will be used to automatically generate a documentation website. You don't need to read the whole Doxygen style guide, just follow these rules.
File Comments
Put file comments at the top of each file, before any includes.
/**
* @file filename.xyz
* @brief A brief description of the file.
*
* @details A longer description of the file that goes into more detail
* if you feel it is necessary.
*/
Function Comments
Put function comments before the declaration of each function in the header files.
/**
* @brief A brief summary of the function.
*
* @details A longer summary of the function that goes into more detail
* if you feel it is necessary.
*
* @param param1 Description of the first parameter
* @param param2 Description of the second parameter
* ...
*
* @return What the function returns, if not void
*/
int ExampleFunction(param1, param2 ...);
Document all parameters and return values using @param
and @return
/@retval
, even if they are obvious. You can omit them if the function has no parameters or returns void.
Class Comments
Put class (and struct) comments before the class declaration in the header file.
/**
* @brief Full name of the struct/class.
*
* @details A longer summary of the struct/class that goes into more detail
* if you feel it is necessary.
*/
Todo and Notes
Use @todo
to mark something that needs to be done in the future.
/**
* ...
* @todo Implement this function.
* ...
*/
Use @note
to add a note which will be differentiated form the rest of the comment.
/**
* ...
* @note The name of this struct is not official.
* ...
*/
Example Code
This code is clear and conforms to the style guide:
// joy.h
/**
* @brief Activates a cheat code.
*
* @details Sets the given flag on the global fcht variable. Also reloads the
* level if it is a reload code.
*
* @param nparam Cheat code to check
*/
void AddFcht(int nParam);
// joy.cpp
void AddFcht(int nParam)
{
g_grfcht |= nParam & ~(int)FCHT_ResetWorld;
// Check if reload flag is set
if ((nParam & 0x4000) != 0)
{
ResetWorld(FTRANS_None);
}
}
This code does not conform to the style guide and should be rewritten:
// vec.h
// Sets the vector cylinder
void SetVectorCylind(float x, float y, float z, VECTOR* pvec);
// vec.cpp
void SetVectorCylind(float param_1, float param_2, float param_3, VECTOR* param_4)
{
float local_40;
float local_3c;
//CalculateSinCos(param_1, &local_40, (float*)((uint32_t)&local_40 | 4));
param_4->z = param_3;
param_4->x = local_3c * param_2;
param_4->y = local_40 * param_2;
return;
}