Mode Selection

Source: src/mode_selection.c · 57 lines · 2 functions.

Module entry points

These functions are exposed to the rest of the project. Open one to follow its decisions and the helpers it calls.

How to read these diagrams

Each function has its own expandable diagram using the actual expressions and statements from this file. Decisions split into True and False; loop bodies are indented. Returns end the function immediately; break and continue follow their C meanings. Arrows between statements show their order when execution reaches them.

These are structural source diagrams before preprocessing, not runtime traces. Conditional compilation and macros remain source expressions. Ternary choices remain inside their statement. Calls are linked separately; callback execution and task scheduling are not inferred.

Functions in this file

modeSelectionReset() · source line 8
void modeSelectionReset(mode_selection_input_t *input)
  1. Execute*input = (mode_selection_input_t){0};
Read original function source
void modeSelectionReset(mode_selection_input_t *input)
{
    *input = (mode_selection_input_t){0};
}
modeSelectionNext() · source line 13
bool modeSelectionNext(mode_selection_input_t *input, int x_offset, int y_offset,
                       bool joystick_valid, bool left, bool right, uint32_t now_ms)
  1. Decision!joystick_valid
    True
      1. Executeinput->stick_centred = false;
      2. Decision!left && !right
        True
          1. Executeinput->held_direction = 0;
          2. Executeinput->repeating = false;
          3. Exit this functionreturn false;
        False

        Continue after this decision.

    False

    Continue after this decision.

  2. Executeconst int x_magnitude = x_offset < 0 ? -x_offset : x_offset;
  3. Executeconst int y_magnitude = y_offset < 0 ? -y_offset : y_offset;
  4. Decisionjoystick_valid && x_magnitude <= JOYSTICK_CENTRE_LIMIT && y_magnitude <= JOYSTICK_CENTRE_LIMIT
    True
      1. Executeinput->stick_centred = true;
    False

    Continue after this decision.

  5. Executeint direction = 0;
  6. Decisionleft || right
    True
      1. Executedirection = (int)right - (int)left;
    False
      1. Decision!joystick_valid || !input->stick_centred
        True
        1. Exit this functionreturn false;
        False

        Continue after this decision.

      2. Decisionx_magnitude >= y_magnitude && x_magnitude >= JOYSTICK_ENTER_LIMIT
        True
          1. Executedirection = x_offset > 0 ? 1 : -1;
        False
        1. Decisiony_magnitude >= JOYSTICK_ENTER_LIMIT
          True
            1. Executedirection = y_offset < 0 ? 1 : -1;
          False

          Continue after this decision.

  7. Decisiondirection == 0
    True
      1. Executeinput->held_direction = 0;
      2. Executeinput->repeating = false;
      3. Exit this functionreturn false;
    False

    Continue after this decision.

  8. Decisioninput->held_direction == direction && now_ms - input->last_move_ms < (input->repeating ? REPEAT_MS : REPEAT_START_MS)
    True
      1. Exit this functionreturn false;
    False

    Continue after this decision.

  9. Executeinput->repeating = input->held_direction == direction;
  10. Executeinput->held_direction = direction;
  11. Executeinput->last_move_ms = now_ms;
  12. Exit this functionreturn true;
Read original function source
bool modeSelectionNext(mode_selection_input_t *input, int x_offset, int y_offset,
                       bool joystick_valid, bool left, bool right, uint32_t now_ms)
{
    if (!joystick_valid) {
        input->stick_centred = false;
        if (!left && !right) {
            input->held_direction = 0;
            input->repeating = false;
            return false;
        }
    }

    const int x_magnitude = x_offset < 0 ? -x_offset : x_offset;
    const int y_magnitude = y_offset < 0 ? -y_offset : y_offset;
    if (joystick_valid && x_magnitude <= JOYSTICK_CENTRE_LIMIT && y_magnitude <= JOYSTICK_CENTRE_LIMIT) {
        input->stick_centred = true;
    }

    int direction = 0;
    if (left || right) {
        direction = (int)right - (int)left;
    } else {
        if (!joystick_valid || !input->stick_centred) return false;
        if (x_magnitude >= y_magnitude && x_magnitude >= JOYSTICK_ENTER_LIMIT) {
            direction = x_offset > 0 ? 1 : -1;
        } else if (y_magnitude >= JOYSTICK_ENTER_LIMIT) {
            direction = y_offset < 0 ? 1 : -1;
        }
    }

    if (direction == 0) {
        input->held_direction = 0;
        input->repeating = false;
        return false;
    }
    if (input->held_direction == direction &&
        now_ms - input->last_move_ms < (input->repeating ? REPEAT_MS : REPEAT_START_MS)) {
        return false;
    }

    input->repeating = input->held_direction == direction;
    input->held_direction = direction;
    input->last_move_ms = now_ms;
    return true;
}
Complete original file, including constants and data
/* Coded By JD(2026) */
#error "Reference listing only — not provided as build-ready source."
#include "mode_selection.h"

#define JOYSTICK_CENTRE_LIMIT 350
#define JOYSTICK_ENTER_LIMIT 600
#define REPEAT_START_MS 400U
#define REPEAT_MS 150U

void modeSelectionReset(mode_selection_input_t *input)
{
    *input = (mode_selection_input_t){0};
}

bool modeSelectionNext(mode_selection_input_t *input, int x_offset, int y_offset,
                       bool joystick_valid, bool left, bool right, uint32_t now_ms)
{
    if (!joystick_valid) {
        input->stick_centred = false;
        if (!left && !right) {
            input->held_direction = 0;
            input->repeating = false;
            return false;
        }
    }

    const int x_magnitude = x_offset < 0 ? -x_offset : x_offset;
    const int y_magnitude = y_offset < 0 ? -y_offset : y_offset;
    if (joystick_valid && x_magnitude <= JOYSTICK_CENTRE_LIMIT && y_magnitude <= JOYSTICK_CENTRE_LIMIT) {
        input->stick_centred = true;
    }

    int direction = 0;
    if (left || right) {
        direction = (int)right - (int)left;
    } else {
        if (!joystick_valid || !input->stick_centred) return false;
        if (x_magnitude >= y_magnitude && x_magnitude >= JOYSTICK_ENTER_LIMIT) {
            direction = x_offset > 0 ? 1 : -1;
        } else if (y_magnitude >= JOYSTICK_ENTER_LIMIT) {
            direction = y_offset < 0 ? 1 : -1;
        }
    }

    if (direction == 0) {
        input->held_direction = 0;
        input->repeating = false;
        return false;
    }
    if (input->held_direction == direction &&
        now_ms - input->last_move_ms < (input->repeating ? REPEAT_MS : REPEAT_START_MS)) {
        return false;
    }

    input->repeating = input->held_direction == direction;
    input->held_direction = direction;
    input->last_move_ms = now_ms;
    return true;
}