Skip to content

Instantly share code, notes, and snippets.

@StanHash
Last active February 6, 2022 13:00
Show Gist options
  • Save StanHash/b85905da8da16522fd769fdf843876a5 to your computer and use it in GitHub Desktop.
Save StanHash/b85905da8da16522fd769fdf843876a5 to your computer and use it in GitHub Desktop.

Coding Style

Consistency is the most important.

General

  • 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.

Naming conventions

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 lowercase g (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).

ASM Coding Style

  • 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).

Example

    .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

C Code Style

  • 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 putting void 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 over int *ptr, and int * 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 over const int val, but I know this can be is a touchy subject so do as you please (but stay consistent).

Example

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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment