Skip to content

Commit d30fd50

Browse files
committed
refactor: extract menu into own module, clean up main.c
1 parent 1806969 commit d30fd50

4 files changed

Lines changed: 240 additions & 224 deletions

File tree

Comanche055-C89/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ project(comanche055 LANGUAGES C)
44

55
add_executable(comanche055
66
main.c
7+
menu.c
78
terminal.c
89
agc_math.c
910
agc_cpu.c

Comanche055-C89/main.c

Lines changed: 4 additions & 224 deletions
Original file line numberDiff line numberDiff line change
@@ -1,227 +1,19 @@
11
/*
2-
* main.c -- Entry point, backend selection, main loop.
2+
* main.c -- Entry point and main loop.
33
*
44
* Apollo 11 Command Module Guidance Computer
55
* Colossus 2A / Comanche 055
66
*
7-
* Presents a menu to select the display backend (console, Win32
8-
* GDI, or HTTP/SSE web), initializes all AGC subsystems, and runs
9-
* the 100 Hz main loop: timer tick, job dispatch, display refresh,
10-
* input poll.
11-
*
127
* Comanche055 (Apollo 11 CM) ANSI C89 port.
138
*/
149

15-
#ifdef _WIN32
16-
#ifndef _CRT_SECURE_NO_WARNINGS
17-
#define _CRT_SECURE_NO_WARNINGS
18-
#endif
19-
#endif
20-
2110
#include <stdio.h>
22-
#include <stdlib.h>
11+
#include "menu.h"
2312
#include "agc_cpu.h"
2413
#include "executive.h"
25-
#include "waitlist.h"
2614
#include "timer.h"
27-
#include "dsky.h"
28-
#include "pinball.h"
2915
#include "service.h"
30-
#include "programs.h"
3116
#include "navigation.h"
32-
#include "terminal.h"
33-
#ifdef _WIN32
34-
#define WIN32_LEAN_AND_MEAN
35-
#include <windows.h>
36-
#include "dsky_gui.h"
37-
#include "dsky_web.h"
38-
#endif
39-
40-
/* ----------------------------------------------------------------
41-
* Backend selection menu
42-
* ---------------------------------------------------------------- */
43-
44-
typedef struct {
45-
const char *label;
46-
dsky_backend_t *backend;
47-
} backend_option_t;
48-
49-
#define MENU_KEY_NONE 0
50-
#define MENU_KEY_UP 1
51-
#define MENU_KEY_DOWN 2
52-
#define MENU_KEY_ENTER 3
53-
#define MENU_KEY_SELECT 4
54-
55-
static int menu_read_key(int *selected_index)
56-
{
57-
int ch;
58-
int next;
59-
#ifndef _WIN32
60-
int third;
61-
#endif
62-
*selected_index = -1;
63-
64-
if (!hal_kbhit())
65-
return MENU_KEY_NONE;
66-
67-
ch = hal_getch();
68-
if (ch < 0)
69-
return MENU_KEY_NONE;
70-
71-
if (ch == '\r' || ch == '\n')
72-
return MENU_KEY_ENTER;
73-
if (ch >= '1' && ch <= '9') {
74-
*selected_index = ch - '1';
75-
return MENU_KEY_SELECT;
76-
}
77-
78-
#ifdef _WIN32
79-
if (ch == 0 || ch == 224) {
80-
next = hal_getch();
81-
if (next == 72) return MENU_KEY_UP;
82-
if (next == 80) return MENU_KEY_DOWN;
83-
}
84-
#else
85-
if (ch == 27) {
86-
next = hal_getch();
87-
if (next != '[') return MENU_KEY_NONE;
88-
third = hal_getch();
89-
if (third == 'A') return MENU_KEY_UP;
90-
if (third == 'B') return MENU_KEY_DOWN;
91-
}
92-
#endif
93-
94-
return MENU_KEY_NONE;
95-
}
96-
97-
static void menu_render(const backend_option_t *options, int count,
98-
int selected)
99-
{
100-
int i;
101-
static int prev_selected = -1;
102-
static int first_render = 1;
103-
char line_buffer[256];
104-
105-
if (first_render) {
106-
term_init();
107-
108-
term_set_cursor(1, 0);
109-
printf("===========================================");
110-
term_set_cursor(2, 2);
111-
printf("COMANCHE 055 -- Colossus 2A");
112-
term_set_cursor(3, 2);
113-
printf("Apollo 11 CM Guidance Computer");
114-
term_set_cursor(4, 2);
115-
printf("ANSI C89 Port");
116-
term_set_cursor(5, 0);
117-
printf("===========================================");
118-
119-
sprintf(line_buffer,
120-
"Select display mode (Up/Down + Enter, or 1-%d):",
121-
count);
122-
term_set_cursor(7, 0);
123-
printf("%s", line_buffer);
124-
125-
for (i = 0; i < count; i++) {
126-
sprintf(line_buffer, "%s [%d] %s",
127-
(i == selected) ? ">" : " ", i + 1,
128-
options[i].label);
129-
term_set_cursor(9 + i, 0);
130-
printf("%s", line_buffer);
131-
}
132-
133-
fflush(stdout);
134-
first_render = 0;
135-
prev_selected = selected;
136-
} else if (selected != prev_selected) {
137-
int menu_start_line = 9;
138-
139-
sprintf(line_buffer, " [%d] %s",
140-
prev_selected + 1, options[prev_selected].label);
141-
term_set_cursor(menu_start_line + prev_selected, 0);
142-
printf("%s", line_buffer);
143-
144-
sprintf(line_buffer, "> [%d] %s",
145-
selected + 1, options[selected].label);
146-
term_set_cursor(menu_start_line + selected, 0);
147-
printf("%s", line_buffer);
148-
149-
fflush(stdout);
150-
prev_selected = selected;
151-
}
152-
}
153-
154-
static dsky_backend_t *select_backend_interactive(void)
155-
{
156-
backend_option_t options[3];
157-
int count;
158-
int selected;
159-
int key;
160-
int direct_index;
161-
int needs_render;
162-
163-
#ifdef _WIN32
164-
options[0].label = "Console (ANSI terminal)";
165-
options[0].backend = &dsky_console_backend;
166-
options[1].label = "Graphical (Win32 GDI)";
167-
options[1].backend = &dsky_gui_backend;
168-
options[2].label = "Web (HTTP/SSE)";
169-
options[2].backend = &dsky_web_backend;
170-
count = 3;
171-
#else
172-
options[0].label = "Console (ANSI terminal)";
173-
options[0].backend = &dsky_console_backend;
174-
count = 1;
175-
#endif
176-
177-
selected = 0;
178-
needs_render = 1;
179-
hal_term_init();
180-
181-
while (1) {
182-
if (needs_render) {
183-
menu_render(options, count, selected);
184-
needs_render = 0;
185-
}
186-
187-
key = menu_read_key(&direct_index);
188-
if (key == MENU_KEY_UP) {
189-
if (selected > 0) { selected--; needs_render = 1; }
190-
} else if (key == MENU_KEY_DOWN) {
191-
if (selected < count - 1) { selected++; needs_render = 1; }
192-
} else if (key == MENU_KEY_ENTER) {
193-
break;
194-
} else if (key == MENU_KEY_SELECT) {
195-
if (direct_index >= 0 && direct_index < count) {
196-
selected = direct_index;
197-
break;
198-
}
199-
}
200-
201-
hal_sleep_ms(10);
202-
}
203-
204-
hal_term_cleanup();
205-
term_cleanup();
206-
term_clear_screen();
207-
return options[selected].backend;
208-
}
209-
210-
#ifdef _WIN32
211-
static void maybe_open_web_ui(dsky_backend_t *backend)
212-
{
213-
int rc;
214-
if (backend != &dsky_web_backend)
215-
return;
216-
217-
printf("Opening browser at http://127.0.0.1:8080/\n");
218-
rc = system("cmd /c start \"\" \"http://127.0.0.1:8080/\"");
219-
if (rc != 0) {
220-
printf("Could not open browser automatically.\n");
221-
printf("Open this URL manually: http://127.0.0.1:8080/\n");
222-
}
223-
}
224-
#endif
22517

22618
/* ----------------------------------------------------------------
22719
* Main
@@ -231,27 +23,15 @@ int main(void)
23123
{
23224
dsky_backend_t *backend;
23325

234-
backend = select_backend_interactive();
26+
backend = menu_select_backend();
23527

23628
printf("Initializing AGC...\n");
23729

23830
agc_init();
239-
exec_init();
240-
waitlist_init();
241-
timer_init();
242-
dsky_init();
243-
pinball_init();
244-
fresh_start();
24531
nav_init();
32+
fresh_start();
24633

24734
backend->init();
248-
#ifdef _WIN32
249-
maybe_open_web_ui(backend);
250-
#endif
251-
252-
pinball_show_prog(0);
253-
pinball_show_verb(0);
254-
pinball_show_noun(0);
25535

25636
/* Main loop: 100 Hz (10ms per tick) */
25737
while (1) {

0 commit comments

Comments
 (0)