Game Scores

Source: src/game_scores.c · 51 lines · 3 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

game_scores_load() · source line 16
game_score_result_t game_scores_load(game_score_id_t game, game_scores_t *scores)

Calls into this documentation:

  1. Decisionscores == NULL
    True
    1. Exit this functionreturn SCORES_INVALID;
    False

    Continue after this decision.

  2. Execute*scores = (game_scores_t){0};
  3. Decision(unsigned)game >= GAME_SCORE_COUNT
    True
    1. Exit this functionreturn SCORES_INVALID;
    False

    Continue after this decision.

  4. Executeresults_record_t record = {0};
  5. Executebool found = false;
  6. Decision!game_storage_read(RESULTS_NAMESPACE, results_keys[game], &record, sizeof(record), &found)
    True
      1. Exit this functionreturn SCORES_IO_ERROR;
    False

    Continue after this decision.

  7. Decision!found
    True
    1. Exit this functionreturn SCORES_NOT_FOUND;
    False

    Continue after this decision.

  8. Decisionrecord.version != 1U
    True
    1. Exit this functionreturn SCORES_INVALID;
    False

    Continue after this decision.

  9. Execute*scores = record.scores;
  10. Exit this functionreturn SCORES_OK;
Read original function source
game_score_result_t game_scores_load(game_score_id_t game, game_scores_t *scores)
{
    if (scores == NULL) return SCORES_INVALID;
    *scores = (game_scores_t){0};
    if ((unsigned)game >= GAME_SCORE_COUNT) return SCORES_INVALID;
    results_record_t record = {0};
    bool found = false;
    if (!game_storage_read(RESULTS_NAMESPACE, results_keys[game], &record, sizeof(record), &found)) {
        return SCORES_IO_ERROR;
    }
    if (!found) return SCORES_NOT_FOUND;
    if (record.version != 1U) return SCORES_INVALID;
    *scores = record.scores;
    return SCORES_OK;
}
game_scores_save() · source line 32
bool game_scores_save(game_score_id_t game, const game_scores_t *scores)

Calls into this documentation:

  1. Decisionscores == NULL || (unsigned)game >= GAME_SCORE_COUNT
    True
    1. Exit this functionreturn false;
    False

    Continue after this decision.

  2. Executegame_scores_t previous;
  3. Executeconst game_score_result_t loaded = game_scores_load(game, &previous);
  4. Decisionloaded != SCORES_OK && loaded != SCORES_NOT_FOUND
    True
    1. Exit this functionreturn false;
    False

    Continue after this decision.

  5. Executeconst results_record_t record = {1U, *scores};
  6. Exit this functionreturn game_storage_write(RESULTS_NAMESPACE, results_keys[game], &record, sizeof(record));
Read original function source
bool game_scores_save(game_score_id_t game, const game_scores_t *scores)
{
    if (scores == NULL || (unsigned)game >= GAME_SCORE_COUNT) return false;
    game_scores_t previous;
    const game_score_result_t loaded = game_scores_load(game, &previous);
    if (loaded != SCORES_OK && loaded != SCORES_NOT_FOUND) return false;
    const results_record_t record = {1U, *scores};
    return game_storage_write(RESULTS_NAMESPACE, results_keys[game], &record, sizeof(record));
}
game_scores_status_text() · source line 42
const char *game_scores_status_text(game_score_result_t result)
  1. Select a caseresult

    Enter matching case; follow source fall-through until a break, return or end.

      1. Case / labelcase SCORES_OK:
      2. Exit this functionreturn "SCORES OK";
      3. Case / labelcase SCORES_NOT_FOUND:
      4. Exit this functionreturn "NO SCORES YET";
      5. Case / labelcase SCORES_UNAVAILABLE:
      6. Exit this functionreturn "STORAGE UNAVAILABLE";
      7. Case / labelcase SCORES_INVALID:
      8. Exit this functionreturn "SCORE DATA ERROR";
      9. Case / labeldefault:
      10. Exit this functionreturn "SCORE IO ERROR";
Read original function source
const char *game_scores_status_text(game_score_result_t result)
{
    switch (result) {
    case SCORES_OK: return "SCORES OK";
    case SCORES_NOT_FOUND: return "NO SCORES YET";
    case SCORES_UNAVAILABLE: return "STORAGE UNAVAILABLE";
    case SCORES_INVALID: return "SCORE DATA ERROR";
    default: return "SCORE IO ERROR";
    }
}
Complete original file, including constants and data
/* Coded By JD(2026) */
#error "Reference listing only — not provided as build-ready source."
#include "game_scores.h"
#include "game_storage.h"

// All game results use NVS; existing records retain their format and keys.
#define RESULTS_NAMESPACE "arcade_results"
typedef struct {
    uint32_t version;
    game_scores_t scores;
} results_record_t;
_Static_assert(sizeof(results_record_t) == 20, "Results record layout changed");

static const char *results_keys[GAME_SCORE_COUNT] = {
    "checkers", "othello", "connect_four", "battleships", "yahtzee",
};

game_score_result_t game_scores_load(game_score_id_t game, game_scores_t *scores)
{
    if (scores == NULL) return SCORES_INVALID;
    *scores = (game_scores_t){0};
    if ((unsigned)game >= GAME_SCORE_COUNT) return SCORES_INVALID;
    results_record_t record = {0};
    bool found = false;
    if (!game_storage_read(RESULTS_NAMESPACE, results_keys[game], &record, sizeof(record), &found)) {
        return SCORES_IO_ERROR;
    }
    if (!found) return SCORES_NOT_FOUND;
    if (record.version != 1U) return SCORES_INVALID;
    *scores = record.scores;
    return SCORES_OK;
}

bool game_scores_save(game_score_id_t game, const game_scores_t *scores)
{
    if (scores == NULL || (unsigned)game >= GAME_SCORE_COUNT) return false;
    game_scores_t previous;
    const game_score_result_t loaded = game_scores_load(game, &previous);
    if (loaded != SCORES_OK && loaded != SCORES_NOT_FOUND) return false;
    const results_record_t record = {1U, *scores};
    return game_storage_write(RESULTS_NAMESPACE, results_keys[game], &record, sizeof(record));
}

const char *game_scores_status_text(game_score_result_t result)
{
    switch (result) {
    case SCORES_OK: return "SCORES OK";
    case SCORES_NOT_FOUND: return "NO SCORES YET";
    case SCORES_UNAVAILABLE: return "STORAGE UNAVAILABLE";
    case SCORES_INVALID: return "SCORE DATA ERROR";
    default: return "SCORE IO ERROR";
    }
}