-
Notifications
You must be signed in to change notification settings - Fork 33
Coding Style Guidelines
The following opinionated coding style guidelines go beyond what is enforced by clang-format. Please consider following them.
This codebase is annotated with Doxygen plate comments. Doxygen plate comments look like the following:
/**
* @todo Documentation
*/Note the double asterisk on the opening multi-line comment; this is required for Doxygen to recognize the comment. For documentation on the special commands (e.g. @todo, @note, @brief, etc.) found in Doxygen plate comments, visit this website: https://www.doxygen.nl/manual/commands.html.
Functions and data types should be annotated at their site of definition, not at any site(s) of declaration. Many deadstripped functions from the original codebase (unused or auto-inlined) are included in this decomp with a message in the the Doxygen plate comment indicating the known function size from the (usually USA rev 1) MetroWerks linker map:
/**
* @todo Documentation
* @note UNUSED Size: 00004C
*/If you are decompiling a completely unused function that only survived in the DLL, what you have decompiled matches the UNUSED Size stated in the plate comment, and you are reasonably certain what you have written is correct, append (Matching by size) to the aforementioned comment to make it known that the function is as correct as we (currently) can guarantee. For example:
/**
* @todo Documentation
* @note UNUSED Size: 00004C (Matching by size)
*/This is a temporary measure until an automated solution is devised for checking which unused functions are matching by size (if we ever get around to that).
Members of a struct/class or enum are documented in Doxygen with a decorated single-line comment syntax ///< (this is required for some reason). Consider the following stripped-down example from the codebase:
struct Collision
{
Vector3f mNormal; ///< Contact normal (i.e. line collision happens along).
Vector3f mContactPoint; ///< Contact point (between objects).
RigidBody* mColliderBody; ///< Rigid body causing the collision.
};Hi, Minty Meeo here. The coding style guideline I am about to share is hardly enforced in the codebase at the time of writing. However, it is one I strive to follow in any files I had a hand in first creating, and it would not be an extreme change to apply this rule across the entire codebase should I decide that's worth doing / worth my time, so here goes.
There are typically four categories of headers that one may need to include at the top of any file:
- Parent : In header files, this is the "types.h" header which contains primitive typedefs and decompilation infrastructure necessary everywhere in the codebase. In source files, this is the header which exports the functions and/or objects you are defining in that file.
- Pikmin : These are headers specific to the Pikmin codebase, e.g. "system.h", "Graphics.h", "CoreNode.h", "DebugLog.h", "GlobalGameOptions.h", etc.
- Third-Party Library : These are libraries from outside of the Pikmin codebase. This includes truly external libraries (e.g. OpenGL, WinAPI) and libraries that were external but are a part of our decompiled repository (Dolphin OS). JAudio and HVQM4 are a bit nebulous in this regard; as I am writing this I think I would consider them a category 2.5. HVQM4 probably belongs in third-party. JAudio especially blurs the line, as it also contains Pikmin-specific headers, so maybe put them in their own grouping between the two? JAudio does contain a lot of headers from our decompilation process, so it probably deserves one regardless.
- Standard Library : Any headers that come from the C/C++ standard library.
Parent and Pikmin include directives should always use double quotes (e.g. #include "Stream.h"). Third-Party Library and Standard Library include directives should always use angle braces (e.g. #include <stdio.h>).
The motivation for this organization scheme is to reduce the amount of dependency chains (files that rely on header A to include header B when really the file should have included header A in the first place). Headers are sorted alphabetically in our clang-format rule, so it is necessary to insert an additional line between these header categories so they do not get all mixed up by clang-format. There is room for exceptions, of course. "bigFont.h" comes to mind, and so do the OS redirect files "OSExi.c", "OSSerial.c", and "OSUartExi.c".
#ifndef _EXAMPLE_H
#define _EXAMPLE_H
#include "types.h"
#include "Creature.h"
#include "sysMath.h"
#include "Texture.h"
#include <Dolphin/os.h>
#include <gl/gl.h>
#include <windows.h>
#include <math.h>
#include <stddef.h>
#include <string.h>
// Header contents go here
#endifOperands following the instruction mnemonic should be aligned to at least two spaces after the longest instruction mnemonic in a block of code.
psq_l fp2, 0x0000 (r31), 0, 0
lfs fp1, 0x0008 (r31)
ps_merge00 fp0, fp3, fp3psq_l fp2, 0x0000 (r31), 0, 0
lfs fp1, 0x0008 (r31)
ps_merge00 fp0, fp3, fp3