-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.c
More file actions
121 lines (101 loc) · 4.02 KB
/
Copy pathmain.c
File metadata and controls
121 lines (101 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// main.c — Real-time non-blocking core loop (~60 FPS tick).
//
// Owns g_context's storage and drives the hierarchical state machine:
// each frame, service input, run any pending screen transition, then
// Update()/Draw() whichever screen is active, then service audio and
// backlight. Pacing comes entirely from systemGetTimeMs() deltas -- no
// _delay_ms() anywhere in this loop.
#include <avr/io.h>
#include <avr/interrupt.h>
#include "context.h"
#include "system.h"
#include "backlight.h"
#include "display.h"
#include "input.h"
#include "audio.h"
#include "boot.h"
#include "menu.h"
#include "snake.h"
#include "tetris.h"
#include "bricks.h"
#include "launcher.h"
#include "storage.h"
// Global user name for high scores
char g_playerName[4] = "AAA";
bool g_isContinuing = false;
// Define the global system context
SystemContext g_context; // storage for the extern declared in context.h
#define FRAME_INTERVAL_MS 16u // ~60 FPS (16.67ms rounded down)
// ----------------------------------------------------------------------------
// Screen Management
// ----------------------------------------------------------------------------
static void handleScreenTransition(void) {
if (g_context.nextScreen == g_context.screen && g_context.screenEntered) {
return;
}
g_context.screen = g_context.nextScreen;
g_context.screenEntered = true;
switch (g_context.screen) {
case SCREEN_BOOT: bootEnter(); break;
case SCREEN_MENU: menuEnter(); break;
case SCREEN_GAME_LAUNCHER: launcherEnter(); break;
case SCREEN_NAME_ENTRY: NameEntry_Enter(); break;
case SCREEN_GAME_SNAKE: snakeEnter(); break;
case SCREEN_GAME_TETRIS: tetrisEnter(); break;
case SCREEN_GAME_BRICKS: bricksEnter(); break;
case SCREEN_SETTINGS: settingsEnter(); break;
}
}
static void updateCurrentScreen(uint32_t nowMs, uint16_t deltaMs) {
switch (g_context.screen) {
case SCREEN_BOOT: bootUpdate(nowMs, deltaMs); break;
case SCREEN_MENU: menuUpdate(nowMs, deltaMs); break;
case SCREEN_GAME_LAUNCHER: launcherUpdate(nowMs, deltaMs); break;
case SCREEN_NAME_ENTRY: NameEntry_Update(nowMs, deltaMs); break;
case SCREEN_GAME_SNAKE: snakeUpdate(nowMs, deltaMs); break;
case SCREEN_GAME_TETRIS: tetrisUpdate(nowMs, deltaMs); break;
case SCREEN_GAME_BRICKS: bricksUpdate(nowMs, deltaMs); break;
case SCREEN_SETTINGS: settingsUpdate(nowMs, deltaMs); break;
}
}
static void drawCurrentScreen(void) {
switch (g_context.screen) {
case SCREEN_BOOT: bootDraw(); break;
case SCREEN_MENU: menuDraw(); break;
case SCREEN_GAME_LAUNCHER: launcherDraw(); break;
case SCREEN_NAME_ENTRY: NameEntry_Draw(); break;
case SCREEN_GAME_SNAKE: snakeDraw(); break;
case SCREEN_GAME_TETRIS: tetrisDraw(); break;
case SCREEN_GAME_BRICKS: bricksDraw(); break;
case SCREEN_SETTINGS: settingsDraw(); break;
}
}
int main(void) {
contextInit();
systemInit(); // Timer0 1ms tick
backlightInit();
inputInit();
displayInit();
audioInit(); // Timer1 audio PWM
storageInit();
sei();
g_context.lastTickMs = systemGetTimeMs();
for (;;) {
uint32_t nowMs = systemGetTimeMs();
uint32_t elapsed = nowMs - g_context.lastTickMs;
if (elapsed < FRAME_INTERVAL_MS) {
continue; // non-blocking: just re-poll the clock, no _delay_ms
}
g_context.deltaMs = (uint16_t)elapsed;
g_context.lastTickMs = nowMs;
inputUpdate(nowMs);
handleScreenTransition();
updateCurrentScreen(nowMs, g_context.deltaMs);
drawCurrentScreen();
audioUpdate(nowMs);
backlightSetBrightness(g_context.settings.brightness);
backlightUpdate(nowMs);
audioSetVolume(g_context.settings.volume);
}
return 0;
}