GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 37 / 0 / 37
Functions: 100.0% 6 / 0 / 6
Branches: 100.0% 16 / 0 / 16

lives/src/lives.c
Line Branch Exec Source
1 /*
2 * SPDX-License-Identifier: MIT
3 *
4 * Copyright (c) 2026 Manuel Hernández Méndez
5 *
6 * Authors:
7 * Manuel Hernández Méndez <maherme.dev@gmail.com>
8 */
9
10 #include "lives.h"
11 #include "events.h"
12 #include "graph.h"
13 #include "graphGlutCallbacks.h"
14 #include <stdbool.h>
15
16 #define LIVE_WIDTH 13
17 #define LIVE_HEIGHT 8
18 #define MAX_LIVES_TO_PRINT 4
19 #define LIVE_START_COORD_Y 4
20 #define LIVE_START_COORD_X 10
21 #define LIVE_PIXELS_SPACE 4
22 #define LIVE_INITIAL_NUM 3
23
24 struct live_instance_t
25 {
26 sprite_t sprite;
27 };
28
29 static struct
30 {
31 struct live_instance_t lives[MAX_LIVES_TO_PRINT];
32 int num_lives;
33 void (*livesDepletedCallback)(void);
34 } livePool;
35
36 static const char liveImage[LIVE_HEIGHT][LIVE_WIDTH][NUM_RGBA_CHANNELS] = {
37 {B, B, B, B, B, B, G, B, B, B, B, B, B},
38 {B, B, B, B, B, G, G, G, B, B, B, B, B},
39 {B, B, B, B, B, G, G, G, B, B, B, B, B},
40 {B, G, G, G, G, G, G, G, G, G, G, G, B},
41 {G, G, G, G, G, G, G, G, G, G, G, G, G},
42 {G, G, G, G, G, G, G, G, G, G, G, G, G},
43 {B, B, G, G, B, B, B, B, B, G, G, B, B},
44 {B, G, G, G, G, B, B, B, G, G, G, G, B},
45 };
46
47 void
48 1 livesCreate(int x, int y)
49 {
50
2/2
✓ Branch 6 → 3 taken 4 times.
✓ Branch 6 → 7 taken 1 time.
5 for (int i = 0; i < MAX_LIVES_TO_PRINT; i++)
51 {
52 4 struct live_instance_t *live = &livePool.lives[i];
53 4 live->sprite.x = x + i * (LIVE_WIDTH + LIVE_PIXELS_SPACE);
54 4 live->sprite.y = y;
55 4 live->sprite.width = LIVE_WIDTH;
56 4 live->sprite.height = LIVE_HEIGHT;
57 4 live->sprite.image = (const char *)liveImage;
58 4 live->sprite.layer = LAYER_HUD;
59 4 live->sprite.visible = true;
60
61
2/2
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 5 taken 2 times.
4 if (i < LIVE_INITIAL_NUM - 1)
62 {
63 2 graphRegisterPrint(&live->sprite);
64 }
65
66 4 livePool.num_lives = LIVE_INITIAL_NUM;
67 }
68 1 }
69
70 void
71 4 livesRemove(void)
72 {
73
2/2
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 4 taken 3 times.
4 if (livePool.num_lives == 0)
74 {
75 1 return;
76 }
77
78 3 livePool.num_lives--;
79
80 3 int sprite_index = livePool.num_lives - 1;
81
82
4/4
✓ Branch 4 → 5 taken 2 times.
✓ Branch 4 → 7 taken 1 time.
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 7 taken 1 time.
3 if (sprite_index >= 0 && sprite_index < MAX_LIVES_TO_PRINT)
83 {
84 1 graphUnregisterPrint(&livePool.lives[sprite_index].sprite);
85 }
86
87
2/2
✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 9 taken 2 times.
3 if (livePool.num_lives == 0)
88 {
89 1 eventEmit(EVENT_LIVES_DEPLETED);
90 }
91 }
92
93 void
94 3 livesAdd(void)
95 {
96
2/2
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 4 taken 2 times.
3 if (livePool.num_lives == 0)
97 {
98 1 return;
99 }
100
101 2 int sprite_index = livePool.num_lives - 1;
102
103 2 livePool.num_lives++;
104
105
2/2
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 1 time.
2 if (sprite_index < MAX_LIVES_TO_PRINT)
106 {
107 1 graphRegisterPrint(&livePool.lives[sprite_index].sprite);
108 }
109 }
110
111 #ifdef UNIT_TESTING
112 int
113 8 helperUT_livesGetNumLives(void)
114 {
115 8 return livePool.num_lives;
116 }
117
118 void
119 7 helperUT_livesSetNumLives(int n)
120 {
121 7 livePool.num_lives = n;
122 7 }
123
124 sprite_t *
125 6 helperUT_livesGetSpriteByInstanceIndex(int idx)
126 {
127 6 return &livePool.lives[idx].sprite;
128 }
129 #endif /* UNIT_TESTING */
130