commit 875e9d53a57e3a6e89fa6e6239220986e25281d3
parent 1fbb80b7635b1b38d38cb42a37b4007f61ef6629
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date: Mon, 30 May 2022 19:15:47 +0200
Visual selection of the cells and status bar
- In visual mode you can select the pattern to be saved
- Save/Load menu for patter as well as the whole game
- Ability to save in a new file with name selection
- Optional NO_UNICODE mode, use make NO_UNICODE
- Status bar that displays basic game information
- Status bar does not appear until the game is started
- Ability to change time between screen updates in game
- General performance and cleanup improvement
Diffstat:
9 files changed, 414 insertions(+), 158 deletions(-)
diff --git a/Makefile b/Makefile
@@ -17,7 +17,8 @@ OBJS=$(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SRCS))
all: $(BIN)
debug: CFLAGS +=-ggdb -Wall
-debug: ${BIN}
+NO_UNICODE: CFLAGS += -D NO_UNICODE
+NO_UNICODE debug: ${BIN}
$(BIN): $(OBJS)
$(CC) $^ $(CFLAGS) $(LDFLAGS) -o $@
@@ -33,4 +34,4 @@ clean:
rm -f $(BIN) $(OBJS)
endif
-.PHONY: all clean debug
+.PHONY: all clean debug NO_UNICODE
diff --git a/include/display.h b/include/display.h
@@ -1,15 +1,15 @@
#ifndef DISPLAY_H
#define DISPLAY_H
-#include "window.h"
#include "logic.h"
+#include "window.h"
extern window_T MAIN_w;
typedef int (*input_f)(int);
struct menu_T {
- void (*callback)(window_T, char *, int);
+ void (*callback)(char *, int);
char *name;
};
@@ -20,16 +20,21 @@ struct imenu_T {
char *buffer;
};
+extern int screen_offset_x, screen_offset_y;
+extern int cursor_offset_x, cursor_offset_y;
+
int input(WINDOW *win, char *buffer, int size, input_f crit);
int display_start(void);
int display_stop(void);
-void display_menu(window_T win, struct menu_T *items, int size);
+void display_menu(window_T wind, char *name, struct menu_T *items, int size);
int display_imenu(window_T wind, struct imenu_T *items, int size);
-void display_game(window_T wind, cell **mat, int w, int h, int screen_offset_y,
- int screen_offset_x, int *cursor_offset_y,
- int *cursor_offset_x);
+void display_game(window_T wind, cell **mat, int h, int w, int ph, int pw);
+void display_select(window_T wind, cell **mat, int w, int h);
+void display_status(window_T wind, unsigned long int generation, int gen_step,
+ int height, int wight, int play, int dt, int cursor_y,
+ int cursor_x);
void handle_winch(int sig);
diff --git a/include/file.h b/include/file.h
@@ -8,6 +8,9 @@ void load_files(void);
void free_files(void);
int file_select(char *ext, char ***buffer);
-void load_file(window_T win, char *pass, int index);
+void file_load_pattern(char *name, int index);
+void file_save_pattern(char *name, int index);
+void file_load(char *name, int index);
+void file_save(char *name, int index);
#endif
diff --git a/include/utils.h b/include/utils.h
@@ -15,13 +15,11 @@
{ \
resize_term(0, 0); \
handle_winch(10); \
- goto redraw; \
}
#else
#define HANDLE_RESIZE \
{ \
handle_winch(10); \
- goto redraw; \
}
#endif
#endif
diff --git a/include/window.h b/include/window.h
@@ -9,10 +9,13 @@ typedef struct T *T;
T window_new(void);
void window_free(T self);
T window_init(T self);
-T window_split(T self, int hor, int a, int b);
-T window_center(T self, int tmp, int h, int w);
+T window_split(T self, int hor, int a, int b, char *name1, char *name2);
+void window_unsplit(T self);
+T window_center(T self, int tmp, int h, int w, char *name);
void window_update_children(T self);
+WINDOW *WINDOW_new(T self);
+
T window_sibiling(T self);
int window_height(T self);
int window_wight(T self);
@@ -20,6 +23,8 @@ WINDOW *window_win(T self);
void window_settings(WINDOW *win);
void window_clear(T self);
+void window_set_title(T self, char *title);
+
void wcenter_horizontal(T window, int y, int n);
int wcenter_vertical(T window, int n);
void cursor_offset(WINDOW *win, int oy, int ox);
diff --git a/src/display.c b/src/display.c
@@ -11,10 +11,11 @@
#define center_vertical(n) wcenter_vertical(MAIN_W, n);
#define center_horizontal(y, n) wcenter_horizontal(MAIN_W, y, n);
-#define CHAR_CIRCLE L'\u26AB'
-#define CHAR_SQUARE L'\u2B1B'
-#define CHAR_SQUARED L'\u2B1C'
-#define CHAR_CIRCLE_DOT L'\u2299'
+#define CHAR_BLANK " "
+#define CHAR_CIRCLE "\u26AB"
+#define CHAR_SQUARE "\u2B1B"
+#define CHAR_SQUARED "\u2B1C"
+#define CHAR_CIRCLE_DOT "\u2299"
window_T MAIN_w = NULL;
@@ -77,7 +78,7 @@ int display_imenu(window_T wind, struct imenu_T *items, int size) {
window_clear(wind);
redraw:;
win = window_win(wind);
- y_offset = wcenter_vertical(wind, size);
+ y_offset = wcenter_vertical(wind, size * 2 - 1);
for (int i = 0; i < size; i++) {
wcenter_horizontal(wind, y_offset + 2 * i, 20);
@@ -119,7 +120,7 @@ redraw:;
curs_set(0);
}
-void display_menu(window_T wind, struct menu_T *items, int size) {
+void display_menu(window_T wind, char *name, struct menu_T *items, int size) {
WINDOW *win;
int current = 0;
@@ -128,10 +129,12 @@ void display_menu(window_T wind, struct menu_T *items, int size) {
if ((len = strlen(items[i].name)) > maxi)
maxi = len;
+ window_set_title(wind, name);
+ window_clear(wind);
redraw:;
win = window_win(wind);
int CLINES = LINES, CCOLS = COLS;
- int y_offset = wcenter_vertical(wind, size * 2);
+ int y_offset = wcenter_vertical(wind, size * 2 - 1);
while (TRUE) {
CLAMP(current, 0, size - 1);
@@ -144,17 +147,15 @@ redraw:;
while (TRUE) {
int c = getch();
- if (c == 'k' || c == KEY_UP) {
+ if (c == 'k' || c == 'w' || c == KEY_UP) {
current--;
break;
- } else if (c == 'j' || c == KEY_DOWN) {
+ } else if (c == 'j' || c == 's' || c == KEY_DOWN) {
current++;
break;
} else if (c == '\n') {
wattrset(win, COLOR_PAIR(0));
- window_clear(wind);
- items[current].callback(wind, items[current].name, current);
- /* window_clear(wind); */
+ items[current].callback(items[current].name, current);
return;
} else if (c == 27)
return;
@@ -166,51 +167,134 @@ redraw:;
}
}
-#define y_at(y) (y + screen_offset_y + h) % h + 1
-#define x_at(x) (x + screen_offset_x + w) % w + 1
+#define y_at(y) (y + screen_offset_y + h) % h + 1
+#define x_at(x) (x + screen_offset_x + w) % w + 1
+#define at(y, x) mat[y_at(y)][x_at(x)]
+#define at_offset(off) mat[y_at(off##_y)][x_at(off##_x)]
+
+#ifndef NO_UNICODE
+#define print_cell(win, k, l, blank) \
+ if (at(k, l)) \
+ waddstr(win, CHAR_CIRCLE); \
+ else \
+ waddstr(win, blank);
+#else
+#define print_cell(win, i, j, blank) waddstr(win, blank);
+#endif
-void display_game(window_T wind, cell **mat, int w, int h, int screen_offset_y,
- int screen_offset_x, int *cursor_offset_y,
- int *cursor_offset_x) {
- WINDOW *win = window_win(wind);
- wattrset(win, COLOR_PAIR(0));
+#define print_cells(win, start_i, end_i, start_j, end_j, color_offset, blank) \
+ for (int i = start_i; i < end_i; i++) { \
+ wmove(win, i + 1, 1 + start_j * 2); \
+ for (int j = start_j; j < end_j; j++) { \
+ wattrset(win, COLOR_PAIR((mat[y_at(i)][x_at(j)]) + color_offset)); \
+ print_cell(win, i, j, blank); \
+ } \
+ }
- int ph = window_height(wind), pw = window_wight(wind) / 2;
+int screen_offset_x, screen_offset_y;
+int cursor_offset_x, cursor_offset_y;
+void display_game(window_T wind, cell **mat, int h, int w, int ph, int pw) {
+ WINDOW *win = window_win(wind);
#ifdef _WIN32
window_clear(wind);
#endif
- for (int i = 0; i < ph; i++) {
- wmove(win, i + 1, 1);
- for (int j = 0; j < pw; j++) {
- wattrset(win, COLOR_PAIR((mat[y_at(i)][x_at(j)]) + 2));
-
- if (mat[y_at(i)][x_at(j)])
- waddstr(win, "\u26AB");
- else
- waddstr(win, " ");
+ print_cells(win, 0, ph, 0, pw, 2, CHAR_BLANK);
+
+ wmove(win, cursor_offset_y + 1, cursor_offset_x * 2 + 1);
+ wattrset(win, COLOR_PAIR(at_offset(cursor_offset) + 5));
+
+ print_cell(win, cursor_offset_y, cursor_offset_x, "<>");
+
+ wrefresh(win);
+}
+
+void display_select(window_T wind, cell **mat, int w, int h) {
+ int current_offset_y = cursor_offset_y;
+ int current_offset_x = cursor_offset_x;
+
+redraw:;
+ int CLINES = LINES, CCOLS = COLS;
+ WINDOW *new = WINDOW_new(wind);
+ WINDOW *win = window_win(wind);
+
+ overlay(win, new);
+ wrefresh(new);
+
+ int ph = window_height(wind), pw = window_wight(wind) / 2;
+ nodelay(stdscr, 0);
+ while (TRUE) {
+ int start_i = MIN(cursor_offset_y, current_offset_y);
+ int end_i = MAX(cursor_offset_y, current_offset_y);
+ int start_j = MIN(cursor_offset_x, current_offset_x);
+ int end_j = MAX(cursor_offset_x, current_offset_x);
+
+ print_cells(new, start_i, end_i + 1, start_j, end_j + 1, 8, CHAR_BLANK);
+ wrefresh(new);
+
+ if (is_term_resized(CLINES, CCOLS)) {
+ flushinp();
+ delwin(new);
+ HANDLE_RESIZE;
+ ph = window_height(wind), pw = window_wight(wind) / 2;
+ display_game(wind, mat, w, h, ph, pw);
+ goto redraw;
}
- }
- CLAMP(*cursor_offset_y, 0, ph - 1);
- CLAMP(*cursor_offset_x, 0, pw - 1);
+ int c = getch();
+ switch (c) {
+ // offset selection
+ case 'w':
+ case 'W':
+ current_offset_y--;
+ break;
+ case 's':
+ case 'S':
+ current_offset_y++;
+ break;
+ case 'a':
+ case 'A':
+ current_offset_x--;
+ break;
+ case 'd':
+ case 'D':
+ current_offset_x++;
+ break;
+ case '\n':
+ save_pattern();
- wmove(win, *cursor_offset_y + 1, *cursor_offset_x * 2 + 1);
- wattrset(win, COLOR_PAIR(
- (mat[y_at(*cursor_offset_y)][x_at(*cursor_offset_x)]) + 5));
+ // quit
+ case 27:
+ case 'q':
+ case 'Q':
+ nodelay(stdscr, 1);
+ delwin(new);
+ return;
+ defalut:
+ continue;
+ }
- if (mat[y_at(*cursor_offset_y)][x_at(*cursor_offset_x)])
- waddstr(win, "\u26AB");
- else
- waddstr(win, " ");
+ CLAMP(current_offset_y, 0, ph - 1);
+ CLAMP(current_offset_x, 0, pw - 1);
- wrefresh(win);
+ wclear(new);
+ overlay(win, new);
+ }
}
-#define LMAX 8
-#define LEFT 0
-#define CENTER 1
-#define RIGHT 2
+void display_status(window_T wind, unsigned long int gen, int gen_step,
+ int height, int wight, int play, int dt, int cursor_y,
+ int cursor_x) {
+ WINDOW *win = window_win(wind);
+
+ wmove(win, 1, 1);
+ wprintw(win, " | %5s | ", play ? "play" : "pause");
+ wprintw(win, "Size: %dx%d | ", height, wight);
+ wprintw(win, "Generation: %10lu(+%d) | ", gen, gen_step);
+ wprintw(win, "dt: %4dms | ", dt);
+ wprintw(win, "Cursor: %4dx%-4d | ", cursor_y, cursor_x);
+ wrefresh(win);
+}
void curses_start(void) {
initscr();
@@ -226,6 +310,7 @@ void curses_start(void) {
init_pair(0, COLOR_WHITE, -1);
init_pair(1, COLOR_RED, -1);
+#ifndef NO_UNICODE
init_pair(2, COLOR_WHITE, -1);
init_pair(3, COLOR_WHITE, -1);
init_pair(4, COLOR_RED, -1);
@@ -233,6 +318,23 @@ void curses_start(void) {
init_pair(5, COLOR_WHITE, COLOR_CYAN);
init_pair(6, COLOR_WHITE, COLOR_CYAN);
init_pair(7, COLOR_RED, COLOR_CYAN);
+
+ init_pair(8, COLOR_WHITE, COLOR_YELLOW);
+ init_pair(9, COLOR_WHITE, COLOR_YELLOW);
+ init_pair(10, COLOR_RED, COLOR_YELLOW);
+#else
+ init_pair(2, COLOR_WHITE, -1);
+ init_pair(3, COLOR_WHITE, COLOR_WHITE);
+ init_pair(4, COLOR_RED, COLOR_RED);
+
+ init_pair(5, COLOR_YELLOW, -1);
+ init_pair(6, COLOR_YELLOW, COLOR_WHITE);
+ init_pair(7, COLOR_YELLOW, COLOR_RED);
+
+ init_pair(8, COLOR_WHITE, COLOR_YELLOW);
+ init_pair(9, COLOR_WHITE, COLOR_WHITE);
+ init_pair(10, COLOR_RED, COLOR_RED);
+#endif
}
void curses_stop(void) {
diff --git a/src/file.c b/src/file.c
@@ -130,6 +130,16 @@ int file_select(char *ext, char ***buffer) {
return size;
}
-void load_files(void) { loaded_files = file_fromDirectory(); }
+void load_files(void) {
+ if (loaded_files)
+ file_free(loaded_files);
+ loaded_files = file_fromDirectory();
+}
+
void free_files(void) { file_free(loaded_files); }
-void load_file(window_T win, char *pass, int index) { (void)3; }
+
+// Comming soon...
+void file_load_pattern(char *name, int index) { return; }
+void file_save_pattern(char *name, int index) { return; }
+void file_load(char *name, int index) { return; }
+void file_save(char *name, int index) { return; }
diff --git a/src/main.c b/src/main.c
@@ -15,9 +15,9 @@
#include "window.h"
#ifdef _WIN32
-#define TIME_CONST 100
+#define TIME_MOD 1
#else
-#define TIME_CONST 100000
+#define TIME_MOD 1000
#endif
extern window_T MAIN_w;
@@ -26,49 +26,136 @@ extern char *evolution_names[];
extern int evolution_cells[];
extern int evolution_size;
-window_T status_w, screen_w, game_w;
+window_T menu_w;
int top_space = 5;
-void game(window_T wind, int w, int h, int ncells) {
- int screen_offset_y = 0, screen_offset_x = 0;
- int cursor_offset_y = 0, cursor_offset_x = 0;
- int in = 3;
- int gen_step = 1;
- int play = 0;
- int gen = 1;
+void load_pattern(void);
+void save_pattern(void);
- window_clear(wind);
- game_w = window_center(wind, 0, h, w * 2);
+#define y_at(y) (y + screen_offset_y + h) % h + 1
+#define x_at(x) (x + screen_offset_x + w) % w + 1
+
+extern int screen_offset_x, screen_offset_y;
+extern int cursor_offset_x, cursor_offset_y;
+
+void game(int h, int w, char *name, int ncells) {
+ unsigned long int gen = 0;
+ int gen_step = 1, play = 0, time_const = 100, time_step = 1;
+
+ window_T status_w, screen_w, game_w;
+
+ window_set_title(menu_w, NULL);
+ window_clear(menu_w);
+
+ status_w = window_split(menu_w, 1, 3, 0, "Status", name);
+ screen_w = window_sibiling(status_w);
+ game_w = window_center(screen_w, 0, h, w * 2, "Game");
clock_t start_t, end_t = 0, total_t;
+
redraw:;
int CLINES = LINES, CCOLS = COLS;
+ int ph = window_height(game_w), pw = window_wight(game_w) / 2;
+ window_clear(game_w);
while (TRUE) {
start_t = clock();
- display_game(game_w, mat, w, h, screen_offset_y, screen_offset_x,
- &cursor_offset_y, &cursor_offset_x);
+
+ display_status(status_w, gen, gen_step, h, w, play, time_const,
+ y_at(cursor_offset_y), x_at(cursor_offset_x));
+ display_game(game_w, mat, h, w, ph, pw);
+
if (play) {
do_evolution(gen_step);
- gen++;
+ gen += gen_step;
}
- while ((total_t = (long int)(end_t - start_t)) < TIME_CONST) {
+ while ((total_t = (long int)(end_t - start_t)) < time_const * TIME_MOD) {
refresh();
int c = getch();
switch (c) {
+
+ // toggle pause
case 'p':
case 'P':
play = !play;
break;
+
+ // lead pattern
+ case 'l':
+ case 'L':
+ load_pattern();
+ window_set_title(screen_w, name);
+ goto redraw;
+ break;
+
+ // quit
case 27:
+ case 'q':
+ case 'Q':
+ window_unsplit(menu_w);
return;
+
+ // change num of evolutions before display
case '+':
gen_step++;
break;
case '-':
gen_step--;
break;
+
+ // change refreshrate
+ case ']':
+ time_const += time_step;
+ break;
+ case '[':
+ time_const -= time_step;
+ break;
+ }
+
+ if (!play) {
+ // move cursor around
+ switch (c) {
+ case 'w':
+ case 'W':
+ cursor_offset_y--;
+ break;
+ case 's':
+ case 'S':
+ cursor_offset_y++;
+ break;
+ case 'a':
+ case 'A':
+ cursor_offset_x--;
+ break;
+ case 'd':
+ case 'D':
+ cursor_offset_x++;
+ break;
+
+ // toggle cell
+ case ' ':
+ mat[y_at(cursor_offset_y)][x_at(cursor_offset_x)] += 1;
+ mat[y_at(cursor_offset_y)][x_at(cursor_offset_x)] %= ncells;
+ break;
+
+ // visual selection
+ case 'v':
+ case 'V':
+ display_select(game_w, mat, h, h);
+
+ // clear up the screen afterwards
+ window_set_title(menu_w, NULL);
+ window_clear(menu_w);
+ window_clear(screen_w);
+ window_clear(status_w);
+ window_clear(game_w);
+ break;
+ }
+ }
+
+ // move screen around
+ switch (c) {
case KEY_A1:
case KEY_C1:
case KEY_END:
@@ -101,73 +188,47 @@ redraw:;
screen_offset_y++;
}
- if (!play) {
- switch (c) {
- case 'w':
- case 'W':
- cursor_offset_y--;
- break;
- case 's':
- case 'S':
- cursor_offset_y++;
- break;
- case 'a':
- case 'A':
- cursor_offset_x--;
- break;
- case 'd':
- case 'D':
- cursor_offset_x++;
- break;
- case ' ':
- mat[(cursor_offset_y + screen_offset_y + h) % h + 1]
- [(cursor_offset_x + screen_offset_x + w) % w + 1] =
- (mat[(cursor_offset_y + screen_offset_y + h) % h + 1]
- [(cursor_offset_x + screen_offset_x + w) % w + 1] +
- 1) %
- ncells;
- break;
- }
- }
screen_offset_x = (screen_offset_x + w) % w;
screen_offset_y = (screen_offset_y + h) % h;
+
+ CLAMP(cursor_offset_y, 0, ph - 1);
+ CLAMP(cursor_offset_x, 0, pw - 1);
+
CLAMP(gen_step, 1, 10);
+ CLAMP(time_const, 1, 1000);
- /* usleep(100000); */
if (is_term_resized(CLINES, CCOLS)) {
flushinp();
HANDLE_RESIZE;
goto redraw;
}
- end_t = clock(); // clock stopped
+ end_t = clock();
}
flushinp();
}
}
-struct imenu_T imenu_items[] = {
- {"Unesi broj redova", 4, isdigit, NULL},
- {"Unesi broj kolona", 4, isdigit, NULL},
-};
-int imenu_items_s = sizeof(imenu_items) / sizeof(struct imenu_T);
+void settings(char *pass, int index) {
+ struct imenu_T imenu_items[] = {
+ { "Number of rows", 4, isdigit, NULL},
+ {"Number of columns", 4, isdigit, NULL},
+ };
+ int imenu_items_s = sizeof(imenu_items) / sizeof(struct imenu_T);
-void settings(window_T wind, char *pass, int index) {
- while (TRUE) {
- if (display_imenu(wind, imenu_items, imenu_items_s)) {
- int row = atoi(imenu_items[0].buffer);
- int column = atoi(imenu_items[1].buffer);
+ window_set_title(menu_w, "Game settings");
+ while (display_imenu(menu_w, imenu_items, imenu_items_s)) {
+ int row = atoi(imenu_items[0].buffer);
+ int column = atoi(imenu_items[1].buffer);
- if (!row || !column)
- continue;
+ if (!row || !column)
+ continue;
- logic_init(column, row);
- evolution_init(index);
+ logic_init(column, row);
+ evolution_init(index);
- game(wind, row, column, evolution_cells[index]);
- break;
- } else {
- break;
- }
+ game(row, column, pass, evolution_cells[index]);
+ logic_free();
+ break;
}
for (int i = 0; i < imenu_items_s; i++) {
@@ -176,39 +237,83 @@ void settings(window_T wind, char *pass, int index) {
}
}
-void mode_select(window_T wind, char *pass, int index) {
+void mode_select(char *pass, int index) {
struct menu_T *mode_items = malloc(evolution_size * sizeof(struct menu_T));
for (int i = 0; i < evolution_size; i++) {
mode_items[i].name = evolution_names[i];
mode_items[i].callback = settings;
}
- display_menu(wind, mode_items, evolution_size);
+ display_menu(menu_w, "Game Mode", mode_items, evolution_size);
free(mode_items);
}
-void load(window_T wind, char *pass, int index) {
+void new_file(char *pass, int index) {
+ struct imenu_T new_file_items[] = {
+ {"Pick a name", 10, isalnum, NULL},
+ };
+ int new_file_items_s = sizeof(new_file_items) / sizeof(struct imenu_T);
+
+ window_set_title(menu_w, "New File");
+ while (display_imenu(menu_w, new_file_items, new_file_items_s)) {
+ file_save_pattern(new_file_items[0].buffer, index);
+ break;
+ }
+
+ for (int i = 0; i < new_file_items_s; i++) {
+ free(new_file_items[i].buffer);
+ new_file_items[i].buffer = NULL;
+ }
+}
+
+struct menu_T *file_menu_list(char *ext, void (*callback)(char *, int),
+ int offset, int *size) {
char **buffer;
int n;
load_files();
- n = file_select("all", &buffer);
+ n = file_select("part", &buffer);
- struct menu_T *file_items = malloc(n * sizeof(struct menu_T));
+ struct menu_T *file_items = malloc((n + offset) * sizeof(struct menu_T));
for (int i = 0; i < n; i++) {
- file_items[i].name = buffer[i];
- file_items[i].callback = load_file;
+ file_items[i + offset].name = buffer[i];
+ file_items[i + offset].callback = callback;
}
free(buffer);
- display_menu(wind, file_items, n);
- mode_select(wind, "nothing", 0);
+ *size = n + offset;
+ return file_items;
+}
+
+void save_pattern(void) {
+ int n;
+ struct menu_T *file_items = file_menu_list("part", file_save_pattern, 1, &n);
+ file_items[0].name = "NEW";
+ file_items[0].callback = new_file;
+ display_menu(menu_w, "Save Pattern", file_items, n);
free(file_items);
- free_files();
}
-void exitp(window_T wind, char *pass, int index) {
+void load_pattern(void) {
+ int n;
+ struct menu_T *file_items = file_menu_list("part", file_load_pattern, 0, &n);
+
+ display_menu(menu_w, "Load Pattern", file_items, n);
+ free(file_items);
+}
+
+void load(char *pass, int index) {
+ int n;
+ struct menu_T *file_items = file_menu_list("part", file_load, 0, &n);
+
+ display_menu(menu_w, "Load Game", file_items, n);
+ free(file_items);
+
+ mode_select("nothing", 0);
+}
+
+void exitp(char *pass, int index) {
display_stop();
exit(0);
}
@@ -226,24 +331,26 @@ int state = 0;
int main(void) {
setlocale(LC_ALL, "");
- if (!display_start()) {
- printf("Couldn't start the display!\n");
- }
-
if (!file_setup()) {
printf("File setup error\n");
+ abort();
}
- status_w = window_split(MAIN_w, 1, 3, 0);
- screen_w = window_sibiling(status_w);
+ if (!display_start()) {
+ printf("Couldn't start the display!\n");
+ abort();
+ }
+ menu_w = MAIN_w;
while (TRUE) {
- display_menu(screen_w, menu_items, menu_items_s);
- window_clear(screen_w);
+ display_menu(menu_w, "Main menu", menu_items, menu_items_s);
}
+ window_free(MAIN_w);
+
if (!display_stop()) {
printf("Couldn't stop the display!\n");
+ abort();
}
return 0;
diff --git a/src/window.c b/src/window.c
@@ -21,17 +21,24 @@ struct T {
int param[4];
int mod[3];
+
+ char *title;
};
-void WINDOW_init(WINDOW *win) {
+void WINDOW_init(WINDOW *win, char *title) {
window_settings(win);
+ wattrset(win, COLOR_PAIR(0));
box(win, ACS_VLINE, ACS_HLINE);
+ if (title) {
+ mvwprintw(win, 0, 1, "%s", title);
+ }
wrefresh(win);
}
-void WINDOW_new(T self) {
- self->win = newwin(H(self), W(self), Y(self), X(self));
- WINDOW_init(self->win);
+WINDOW *WINDOW_new(T self) {
+ WINDOW *win = newwin(H(self), W(self), Y(self), X(self));
+ WINDOW_init(win, self->title);
+ return win;
}
T window_new(void) {
@@ -40,6 +47,7 @@ T window_new(void) {
self->c1 = NULL;
self->c2 = NULL;
self->sibiling = NULL;
+ self->title = NULL;
H(self) = 0;
W(self) = 0;
Y(self) = 0;
@@ -52,11 +60,11 @@ int window_height(T self) { return H(self) - 2; }
int window_wight(T self) { return W(self) - 2; }
WINDOW *window_win(T self) { return self->win; }
-T window_init(T self) {
+void window_set_title(T self, char *title) { self->title = title; }
+T window_init(T self) {
self->win = stdscr;
- box(self->win, ACS_VLINE, ACS_HLINE);
- wrefresh(self->win);
+ WINDOW_init(stdscr, self->title);
H(self) = LINES;
W(self) = COLS;
return self;
@@ -71,6 +79,13 @@ void window_free(T self) {
free(self);
}
+void window_unsplit(T self) {
+ window_free(self->c1);
+ window_free(self->c2);
+ self->c1 = NULL;
+ self->c2 = NULL;
+}
+
void window_calc_children(T self) {
T c1, c2, f, nf;
c1 = self->c1;
@@ -129,7 +144,12 @@ void window_calc_children(T self) {
}
}
-T window_split(T self, int hor, int a, int b) {
+T window_split(T self, int hor, int a, int b, char *name1, char *name2) {
+ if (self->c1)
+ window_free(self->c1);
+ if (self->c2)
+ window_free(self->c2);
+
self->c1 = window_new();
self->c2 = window_new();
@@ -142,13 +162,16 @@ T window_split(T self, int hor, int a, int b) {
window_calc_children(self);
- WINDOW_new(self->c1);
- WINDOW_new(self->c2);
+ self->c1->title = name1;
+ self->c2->title = name2;
+
+ self->c1->win = WINDOW_new(self->c1);
+ self->c2->win = WINDOW_new(self->c2);
return self->c1;
}
-T window_center(T self, int tmp, int h, int w) {
+T window_center(T self, int tmp, int h, int w, char *name) {
self->c1 = window_new();
self->c2 = NULL;
@@ -157,7 +180,9 @@ T window_center(T self, int tmp, int h, int w) {
self->mod[2] = w;
window_calc_children(self);
- WINDOW_new(self->c1);
+
+ self->c1->title = name;
+ self->c1->win = WINDOW_new(self->c1);
return self->c1;
}
@@ -169,19 +194,19 @@ void window_update_children(T self) {
window_calc_children(self);
delwin(self->c1->win);
- WINDOW_new(self->c1);
+ self->c1->win = WINDOW_new(self->c1);
window_update_children(self->c1);
if (self->c2 != NULL) {
delwin(self->c2->win);
- WINDOW_new(self->c2);
+ self->c2->win = WINDOW_new(self->c2);
window_update_children(self->c2);
}
}
void window_clear(T self) {
wclear(self->win);
- WINDOW_init(self->win);
+ WINDOW_init(self->win, self->title);
}
void window_settings(WINDOW *win) { keypad(win, TRUE); }