TTK4155 Lab Node 1
Term project in the NTNU course TTK4155 Embedded and Industrial Computer Systems Design
Loading...
Searching...
No Matches
menu.c
Go to the documentation of this file.
1#include <avr/io.h>
2
3#include "menu.h"
4#include "utils.h"
5#include "io.h"
6
7#define BIG_FONT &OLED_FONT_8x8
8#define MEDIUM_FONT &OLED_FONT_5x7
9#define SMALL_FONT &OLED_FONT_4x6
10
16int menu_init(struct menu_cfg *menu) {
17 int status = 0;
18
19 io_oled_init(menu->oled);
21
22 return status;
23}
24
31 int status = 0;
32
34
35 io_oled_home(menu->oled);
36 io_oled_print_with_font(menu->oled, MEDIUM_FONT, "Welcome");
37
38 io_oled_pos(menu->oled, 1, 0);
39 //io_oled_print_with_font(menu->oled, MEDIUM_FONT, "-------------");
40 io_oled_print_with_font(menu->oled, MEDIUM_FONT, "---------");
41
43
44 // Printing menu items
45 for (uint8_t i = 0; i < menu->length; i++) {
46 io_oled_clear_line(menu->oled, 2 + i);
47 io_oled_pos(menu->oled, 2 + i, 10);
48 io_oled_print_with_font(menu->oled, SMALL_FONT, menu->items[i].name);
49 }
50
51 return status;
52}
53
60 int status = 0;
61
63
64 io_oled_home(menu->oled);
65 io_oled_print_with_font(menu->oled, MEDIUM_FONT, "Game in progress..");
66
67 return status;
68}
69
76 int status = 0;
77
79
80 io_oled_home(menu->oled);
81 io_oled_print_with_font(menu->oled, MEDIUM_FONT, "High scores");
82
83 return status;
84}
85
92 int status = 0;
93
95
96 io_oled_home(menu->oled);
97 io_oled_print_with_font(menu->oled, MEDIUM_FONT, "Settings");
98
99 io_oled_pos(menu->oled, 1, 0);
100 io_oled_print_with_font(menu->oled, MEDIUM_FONT, "-------------");
101
103
104 // Printing menu items
105 for (uint8_t i = 0; i < menu->length; i++) {
106 io_oled_clear_line(menu->oled, 2 + i);
107 io_oled_pos(menu->oled, 2 + i, 10);
108 io_oled_print_with_font(menu->oled, SMALL_FONT, menu->items[i].name);
109 }
110
111 return status;
112}
113
115 int status = 0;
116
117 io_oled_clear_all(menu->oled);
118
119 io_oled_home(menu->oled);
120 io_oled_print_with_font(menu->oled, SMALL_FONT, "Adjusting brightness..");
121
122 return status;
123}
124
126 int status = 0;
127
128 io_oled_clear_all(menu->oled);
129
130 io_oled_home(menu->oled);
131 io_oled_print_with_font(menu->oled, SMALL_FONT, "Calibrating joystick..");
132
133 return status;
134}
135
137 int status = 0;
138
139 io_oled_clear_all(menu->oled);
140 io_oled_home(menu->oled);
141 io_oled_print_with_font(menu->oled, MEDIUM_FONT, "GAME OVER");
142
143 io_oled_pos(menu->oled, 2, 0);
144 io_oled_print_with_font(menu->oled, SMALL_FONT, "Returning to main menu...");
145
146 return status;
147}
148
155 int status = 0;
156
157 for (uint8_t i = 0; i < menu->length; i++) {
158 io_oled_pos(menu->oled, 2 + i, 0);
159 if (i == menu->cursor_pos) {
161 } else {
162 // Clearing the cursor position
163 for (uint8_t j = 0; j < 6; j++) {
164 io_oled_write_data(menu->oled, 0x00);
165 }
166 }
167 }
168
169 return status;
170}
171
178int cursor_update(struct menu_cfg *menu, struct io_avr_buttons *btn) {
179 int status = 0;
180
181 static uint8_t prev_ND = 0;
182 static uint8_t prev_NU = 0;
183
184 // TODO:
185 // Implement modulus for wrapping around the cursor position
186
187 // --- NAV DOWN ---
188 if (btn->ND && !prev_ND) {
189 menu->cursor_pos++;
190
191 if (menu->cursor_pos >= menu->length) {
192 menu->cursor_pos = 0;
193 }
194 }
195 // --- NAV UP ---
196 else if (btn->NU && !prev_NU) {
197 menu->cursor_pos--;
198
199 if (menu->cursor_pos < 0) {
200 menu->cursor_pos = menu->length - 1;
201 }
202 }
203
204 prev_ND = btn->ND;
205 prev_NU = btn->NU;
206
207 return 0;
208}
209
216int page_select(struct menu_cfg *menu, struct io_avr_buttons *btn) {
217 int status = 0;
218 static uint8_t prev_NR = 0;
219
220 if(btn->NR && !prev_NR) {
221 // Get currently selected menu item
222 // - Q: why do I need an ampersand here?
223 struct menu_item *selected_item = &menu->items[menu->cursor_pos];
224
225 // Save current menu as parent before moving anywhere
226 menu->parent_menu = menu->items;
227 menu->parent_length = menu->length;
228
229 // --- Case 1: The selected item has a submenu ---
230 if(selected_item->submenu != TRASHCAN) {
231 // Set submenu info
232 menu->items = selected_item->submenu;
233 menu->length = selected_item->submenu_length;
234 menu->cursor_pos = 0;
235
236 // Go to the requested page
237 return set_page(menu, selected_item->target_page);
238 }
239
240 // --- Case 2: Leaf page ---
241 else {
242 return set_page(menu, selected_item->target_page);
243 }
244 }
245
246 prev_NR = btn->NR;
247
248 return status;
249}
250
257int set_page(struct menu_cfg *menu, enum page_id page) {
258 int status = 0;
259
260 // Checking if the requested page is the current page. If so, do nothing.
261 if (menu->current_page == page) {
262 return status;
263 }
264
265 menu->current_page = page;
267
268 return status;
269}
270
277 int status = 0;
278
279 switch (menu->current_page) {
280 case PAGE_WELCOME:
281 return welcome_display(menu);
282 case PAGE_PLAY_GAME:
283 return play_game_display(menu);
284 case PAGE_HIGH_SCORES:
286 case PAGE_SETTINGS:
287 return settings_display(menu);
289 return brightness_display(menu);
292 case PAGE_GAME_OVER:
293 return game_over_display(menu);
294 default:
295 menu->current_page = PAGE_WELCOME;
296 return welcome_display(menu);
297 }
298
299 return status;
300}
301
302int page_back(struct menu_cfg *menu, struct io_avr_buttons *btn) {
303 int status = 0;
304 static uint8_t prev_NL = 0;
305
306 if(btn->NL && !prev_NL) {
307
308 // If we have a parent menu, go back to that
309 if(menu->parent_menu != TRASHCAN) {
310 // Restore parent
311 menu->items = menu->parent_menu;
312 menu->length = menu->parent_length;
313 menu->cursor_pos = 0;
314
315 // If we just went back to the root, clear parent pointers
316 if(menu->items == menu->root_items) {
317 menu->parent_menu = TRASHCAN;
318 menu->parent_length = 0;
319 return(set_page(menu, PAGE_WELCOME));
320 }
321
322 // Otherwise, go to parents page (e.g. Brightness -> Settings)
323 menu->parent_menu = menu->root_items;
324 menu->parent_length = menu->root_length;
325 return(set_page(menu, PAGE_SETTINGS));
326 }
327 }
328
329 prev_NL = btn->NL;
330
331 return status;
332}
333
340int menu_handler(struct menu_cfg *menu, struct io_avr_buttons *btn) {
341 int status = 0;
342 static uint16_t game_over_timer = 0;
343
344 if(menu->current_page == PAGE_GAME_OVER) {
345 if(game_over_timer == 0) {
347 }
348
349 game_over_timer++;
350
351 if(game_over_timer > 20) {
352 game_over_timer = 0;
353
354 // Reset to root menu
355 menu->items = menu->root_items;
356 menu->length = menu->root_length;
357 menu->cursor_pos = 0;
358
359 // Clear parent
360 menu->parent_menu = TRASHCAN;
361 menu->parent_length = 0;
362
363 // Move back to welcome page
364 menu->current_page = PAGE_WELCOME;
366 }
367 }
368
369 // Only allow cursor movement and page selection if we're on welcome page or settings page
370 if (menu->current_page == PAGE_WELCOME || menu->current_page == PAGE_SETTINGS) {
374 }
375
377
378 return status;
379}
380
int io_oled_clear_all(struct io_oled_device *dev)
Clears all lines on the OLED (fills entire display with black).
Definition io.c:292
int io_oled_clear_line(struct io_oled_device *dev, int line)
Clear specific line in OLED.
Definition io.c:275
int io_oled_home(struct io_oled_device *dev)
Loads homescreen to OLED.
Definition io.c:247
int io_oled_write_data(struct io_oled_device *dev, uint8_t data)
Definition io.c:471
int io_oled_pos(struct io_oled_device *dev, int row, int column)
Set specific position in OLED.
Definition io.c:306
int io_oled_print_with_font(struct io_oled_device *dev, const struct oled_font *font, char *text)
Prints an arrow at a specified postion.
Definition io.c:377
int io_oled_init(struct io_oled_device *dev)
Initialise OLED.
Definition io.c:161
int menu_init(struct menu_cfg *menu)
Initializes the menu struct and OLED display.
Definition menu.c:16
int cursor_update(struct menu_cfg *menu, struct io_avr_buttons *btn)
Updates the cursor position based on nav button from the IO board. Wraps around if going out of bound...
Definition menu.c:178
int menu_handler(struct menu_cfg *menu, struct io_avr_buttons *btn)
Handles menu logic based on current page and button inputs from the IO board.
Definition menu.c:340
int draw_cursor(struct menu_cfg *menu)
Draws the cursor (">") at the current cursor position in the menu.
Definition menu.c:154
int high_scores_display(struct menu_cfg *menu)
Displays the high scores page.
Definition menu.c:75
int welcome_display(struct menu_cfg *menu)
Displays the welcome page.
Definition menu.c:30
int game_over_display(struct menu_cfg *menu)
Definition menu.c:136
page_id
Menu page identifiers.
Definition menu.h:19
int set_page(struct menu_cfg *menu, enum page_id page)
Sets the current page field in the menu struct to a specified page and calls the page_dispatch functi...
Definition menu.c:257
int page_back(struct menu_cfg *menu, struct io_avr_buttons *btn)
Definition menu.c:302
int play_game_display(struct menu_cfg *menu)
Displays the play game page.
Definition menu.c:59
int brightness_display(struct menu_cfg *menu)
Definition menu.c:114
int page_select(struct menu_cfg *menu, struct io_avr_buttons *btn)
Selects the current menu item based on nav button from the IO board.
Definition menu.c:216
int page_dispatch(struct menu_cfg *menu)
Dispatches to the appropriate page display function based on the current page field in the menu struc...
Definition menu.c:276
int calibrate_joystick_display(struct menu_cfg *menu)
Definition menu.c:125
int settings_display(struct menu_cfg *menu)
Displays the settings page.
Definition menu.c:91
@ PAGE_PLAY_GAME
Definition menu.h:21
@ PAGE_HIGH_SCORES
Definition menu.h:22
@ PAGE_SETTINGS
Definition menu.h:23
@ PAGE_ADJUST_BRIGHTNESS
Definition menu.h:24
@ PAGE_GAME_OVER
Definition menu.h:26
@ PAGE_WELCOME
Definition menu.h:20
@ PAGE_CALIBRATE_JOYSTICK
Definition menu.h:25
#define TRASHCAN
Definition utils.h:19
Driver for joystick, buttons, and OLED.
struct io_avr_buttons btn
Definition main.c:59
struct menu_cfg menu
Definition main.c:76
#define MEDIUM_FONT
Definition menu.c:8
#define SMALL_FONT
Definition menu.c:9
Hierarchical OLED menu system with navigation and page handling.
Menu configuration and state.
Definition menu.h:49
Menu item struct.
Definition menu.h:35
uint8_t submenu_length
Definition menu.h:39
struct menu_item * submenu
Definition menu.h:38
enum page_id target_page
Definition menu.h:37
Utility and helper functions for joystick, LED debugging, and mapping.