2023-12-04 06:06:41 +00:00
# Style Guide
## Contents
1. [General Rules ](#general-rules )
2. [Symbol Names ](#symbol-names )
3. [Documentation ](#documentation )
4. [Example Code ](#example-code )
## 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.
2023-12-17 03:29:05 +00:00
* Keep lines between 80-100 character long at most.
2023-12-04 06:06:41 +00:00
## Symbol Names
2023-12-17 03:29:05 +00:00
For new symbols (i.e. classes, variables, and functions), use the official name from the [May 19 2002 demo ](https://hiddenpalace.org/Sly_Cooper_and_the_Thievius_Raccoonus_(May_19,_2002_prototype )) if it is known. If it is not known, use a clear and descriptive name.
2023-12-04 06:06:41 +00:00
2023-12-17 03:29:05 +00:00
When making up symbol names, mimic the style of the official symbol names, Official names use a variation of [Hungarian Notation ](https://en.wikipedia.org/wiki/Hungarian_notation ). The most important part is the prefixes used to denote the **type** and **scope** of a symbol, as shown below.
2023-12-04 06:06:41 +00:00
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 struct
* `g_pchzArgs` - Pointer a global zero-terminated char array of arguments
* `m_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
2023-12-17 03:29:05 +00:00
Comment your code with [Doxygen-style comments ](http://micro-os-plus.github.io/develop/doxygen-style-guide/ ). They will be used to automatically generate a [documentation website ](https://theonlyzac.github.io/sly1 ). You don't need to read the whole Doxygen style guide, just follow these rules.
2023-12-04 06:06:41 +00:00
### File Comments
Put file comments at the top of each file, before any includes.
```c
/**
* @file filename.xyz
* @brief A brief description of the file.
*
2023-12-17 03:29:05 +00:00
* @details A longer description of the file that goes into more detail
2023-12-04 06:06:41 +00:00
* if you feel it is necessary.
*/
```
### Function Comments
Put function comments before the declaration of each function in the header files.
```c
/**
* @brief A brief summary of the function.
*
2023-12-17 03:29:05 +00:00
* @details A longer summary of the function that goes into more detail
2023-12-04 06:06:41 +00:00
* 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.
```c
/**
* @brief Full name of the struct/class.
*
2023-12-17 03:29:05 +00:00
* @details A longer summary of the struct/class that goes into more detail
2023-12-04 06:06:41 +00:00
* if you feel it is necessary.
*/
```
### Todo and Notes
Use `@todo` to mark something that needs to be done in the future.
```c
/**
* ...
* @todo Implement this function.
* ...
*/
```
Use `@note` to add a note which will be differentiated form the rest of the comment.
2023-12-17 03:29:05 +00:00
```c
2023-12-04 06:06:41 +00:00
/**
* ...
* @note The name of this struct is not official.
* ...
*/
```
## Example Code
This code is clear and conforms to the style guide:
```c
// joy.h
/**
* @brief Activates a cheat code.
*
2023-12-17 03:29:05 +00:00
* @details Sets the given flag on the global fcht variable. Also reloads the
* level if it is a reload code.
2023-12-04 06:06:41 +00:00
*
* @param nparam Cheat code to check
*/
void AddFcht(int nParam);
2023-12-17 03:29:05 +00:00
// joy.cpp
2023-12-04 06:06:41 +00:00
void AddFcht(int nParam)
{
g_grfcht |= nParam & ~(int)FCHT_ResetWorld;
// Check if reload flag is set
if ((nParam & 0x4000) != 0)
{
2023-12-08 07:52:27 +00:00
ResetWorld(FTRANS_None);
2023-12-04 06:06:41 +00:00
}
}
```
This code does **not** conform to the style guide and should be rewritten:
```cpp
// vec.h
2023-12-17 03:29:05 +00:00
// Sets the vector cylinder
2023-12-04 06:06:41 +00:00
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;
}
```