Consistency is the most important.
- Use whatever indentation method you prefer (2 spaces, 4 spaces, one tab, 8 spaces, etc...), but stay consistent. I prefer 4 spaces.
- Do not use tabs for alignment, only indentation. This implies only have tabs at the start of lines.
What constitutes a global or local object is somewhat subjective. Just stay consistent.
- Global object names generally use upper camel case (ex:
GetUnit
). Non-function objects are prefixed with either a lowercaseg
(ex:gPal
), or an identifier defining its type followed by an underscore (ex:ProcScr_MapMain
). - Local objects use either lower camel case, lower snake case, or a mix of both (ex:
loop_end
,levelCount
, ...). - Numerical constants use upper ("screaming") snake case (ex:
ITEM_ATTR_WEAPON
).
- Directives (ex:
.thumb
) and instructions (ex:mov
) are indented the same way. - Labels are always indented one level lower than directives and instructions.
- This does mean that as long as there is a label in the code, any directives or instructions need to be indented at least one level.
- Labels are always on their own line. The line following a label cannot be empty (use a comment if needed).
- You can indent blocks of code to suggest structure, but it is not required (just remember the label indentation rule). I prefer not to.
- If your file contains more than one function, you can suggest a label "belonging" to another by using the
.
character, which is legal in symbol names (ex:PackGameSaveUnit.set_class
).
.thumb
.global AddSkills
.type AddSkills, function
AddSkills:
@ Arguments: r0 = Unit, r1 = null terminated skill list
push {r0, r4, lr} @ note: [sp] = Unit
mov r4, r1 @ var r4 = skill list iterator
AddSkills.loop:
ldrb r1, [r4]
add r4, #1
cmp r1, #0
beq AddSkills.end @ end if reached list end
ldr r3, =AddSkill
ldr r0, [sp] @ arg r0 = unit
@ implied @ arg r1 = skill id
bl call_via_r3
b AddSkills.loop
AddSkills.end:
pop {r0, r4}
pop {r3}
call_via_r3:
bx r3
- Use Allman style curly braces, where each brace begins on a new line.
- "Continuation" lines should be indented one level more than the parent line. Don't try to align anything.
- call functions like this:
func(...)
, not like this:func (...)
. typedef
type aliases should end with_t
(ex:typedef struct Unit Unit_t;
).- do this:
int GetLang(void)
, not this:int GetLang()
. Note: this is not only a style issue, not puttingvoid
in C changes the meaning. (this only applies to declaring/defining functions, not calling). - do this:
a, b
, not this:a,b
, nor this:a , b
. Same applies for semicolon within for statements. - do this:
(a + b) * c
, not this:( a+b )*c
. - I prefer
int* ptr
overint *ptr
, andint * ptr
is also okay; but I know this can be a touchy subject so do as you please (but stay consistent). - I prefer
int const val
overconst int val
, but I know this can be is a touchy subject so do as you please (but stay consistent).
static void MapAuraFx_Unit_OnLoop(struct MapAuraFxUnitProc* proc)
{
// Display semi-transparent map sprite + obj window map sprite
SMS_DisplayWindowBlended(
11,
proc->unit->x * 16 - gBmSt.camera.x,
proc->unit->y * 16 - gBmSt.camera.y,
(proc->unit->map_sprite->oam2 & ~OAM2_CHR_MASK) + OAM2_LAYER(2),
proc->unit);
}