16 void draw_with_linebreaks (struct Win * win, char * text, int start_y) {
17 // Write text into window content space. Start on row start_y. Fill unused rows with whitespace.
20 int height_av = win->height - 1;
21 int width_av = win->width - 1;
24 for (y = start_y; y < height_av; y++) {
27 for (x = 0; x < width_av; x++) {
30 if ('\n' == text[z]) {
31 mvwaddch(win->curses_win, y+1, x+win->border_left, ' ');
35 mvwaddch(win->curses_win, y+1, x+win->border_left, text[z]);
36 if ('\n' == text[z+1]) {
39 else if (0 == text[z+1]) {
43 mvwaddch(win->curses_win, y+1, x+win->border_left, ' '); } } }
45 void draw_text_from_bottom (struct Win * win) {
46 // Draw text in win->data from end/bottom to the top.
47 char * text = (char *) win->data;
48 int width_av = win->width - 1;
49 int height_av = win->height - 1;
53 for (y = 0; 0 == toggle; y++) // Determine number of lines text would have in a window of available
54 for (x = 0; x < width_av; x++) { // width, but infinite height.
56 if ('\n' == text[z]) // Treat \n and \0 as control characters for incrementing y and
57 break; // stopping the loop. Make sure they don't count as cell space
58 if ('\n' == text[z+1]) { // themselves.
61 else if (0 == text[z+1]) {
66 if (y < height_av) { // Depending on what is bigger, determine start point in window or in text.
67 start_y = height_av - y;
68 for (y = 0; y < start_y; y++)
69 for (x = 0; x < width_av; x++)
70 mvwaddch(win->curses_win, y+1, x+win->border_left, ' '); }
71 else if (y > height_av) {
72 offset = y - height_av;
73 for (y = 0; y < offset; y++)
74 for (x = 0; x < width_av; x++) {
78 if ('\n' == text[z+1]) {
81 text = text + (sizeof(char) * (z + 1)); }
82 draw_with_linebreaks(win, text, start_y); }
84 void draw_map (struct Win * win) {
85 // Draw map determined by win->data Map struct into window. Respect offset.
86 int height_av = win->height - 1;
87 int width_av = win->width - 1;
88 struct Map map = * (struct Map *) win->data;
89 char * cells = map.cells;
90 int width_map_av = map.width - map.offset_x;
91 int height_map_av = map.height - map.offset_y;
93 for (y = 0; y < height_av; y++) {
94 z = map.offset_x + (map.offset_y + y) * (map.width);
95 for (x = 0; x < width_av; x++) {
96 if (y < height_map_av && x < width_map_av) {
97 if (z == (map.width * map.player_y) + map.player_x)
98 mvwaddch(win->curses_win, y+1, x+win->border_left, '@');
100 mvwaddch(win->curses_win, y+1, x+win->border_left, cells[z]);
103 mvwaddch(win->curses_win, y+1, x+win->border_left, ' '); } } }
105 void draw_info (struct Win * win) {
106 // Draw info window by appending win->data integer value to "Turn: " display.
107 int count = * (int *) win->data;
109 snprintf(text, 100, "Turn: %d", count);
110 draw_with_linebreaks(win, text, 0); }
112 void toggle_window (struct WinMeta * win_meta, struct Win * win) {
113 // Toggle display of window win.
114 if (0 != win->curses_win)
115 suspend_window(win_meta, win);
117 append_window(win_meta, win); }
119 struct Map init_map () {
120 // Initialize map with some experimental start values.
128 map.cells = malloc(map.width * map.height);
130 for (y = 0; y < map.height; y++)
131 for (x = 0; x < map.width; x++)
132 map.cells[(y * map.width) + x] = '.';
133 map.cells[(5 * map.width) + 5] = 'X';
134 map.cells[(3 * map.width) + 8] = 'X';
135 map.cells[(8 * map.width) + 3] = 'X';
138 void update_info (struct Win * win) {
139 // Update info data by incrementing turn value.
140 * (int *) win->data = * (int *) win->data + 1; }
142 void update_log (struct Win * win, char * text) {
143 // Update log with new text to be appended.
145 int len_old = strlen(win->data);
146 int len_new = strlen(text);
147 int len_whole = len_old + len_new + 1;
148 new_text = calloc(len_whole, sizeof(char));
149 memcpy(new_text, win->data, len_old);
150 memcpy(new_text + len_old, text, len_new);
152 win->data = new_text; }
155 WINDOW * screen = initscr();
158 struct WinMeta win_meta = init_win_meta(screen);
160 struct Win win_map = init_window(&win_meta, "Map");
161 win_map.draw = draw_map;
162 struct Map map = init_map();
165 struct Win win_info = init_window(&win_meta, "Info");
166 win_info.draw = draw_info;
167 win_info.data = malloc(sizeof(int));
168 * (int *) win_info.data = 0;
170 struct Win win_log = init_window(&win_meta, "Log");
171 win_log.draw = draw_text_from_bottom;
172 win_log.data = calloc(1, sizeof(char));
173 update_log (&win_log, "Start!");
178 if (key == 'Q') // quit
180 else if (key == '1') // toggle map window
181 toggle_window(&win_meta, &win_map);
182 else if (key == '2') // toggle info window
183 toggle_window(&win_meta, &win_info);
184 else if (key == '3') // toggle log window
185 toggle_window(&win_meta, &win_log);
186 else if (key == 'x') { // scroll map down
188 draw_all_windows (&win_meta); }
189 else if (key == 'w' && map.offset_y > 0) { // scroll map up
191 draw_all_windows (&win_meta); }
192 else if (key == 'd') { // scroll map right
194 draw_all_windows (&win_meta); }
195 else if (key == 'a' && map.offset_x > 0) { // scroll map left
197 draw_all_windows (&win_meta); }
198 else if (key == 'b' && map.player_y < map.height - 1) { // move player south
199 update_info (&win_info);
200 update_log (&win_log, "\nYou move south.");
202 draw_all_windows (&win_meta); }
203 else if (key == 't' && map.player_y > 0) { // move player north
204 update_info (&win_info);
205 update_log (&win_log, "\nYou move north.");
207 draw_all_windows (&win_meta); }
208 else if (key == 'h' && map.player_x < map.width - 1) { // move player east
209 update_info (&win_info);
210 update_log (&win_log, "\nYou move east.");
212 draw_all_windows (&win_meta); }
213 else if (key == 'f' && map.player_x > 0) { // move player west
214 update_info (&win_info);
215 update_log (&win_log, "\nYou move west.");
217 draw_all_windows (&win_meta); }
218 else if (key == '.') { // wait
219 update_info (&win_info);
220 update_log (&win_log, "\nYou wait.");
221 draw_all_windows(&win_meta); }
222 else if (key == '>' && win_meta.active != 0) // cycle forwards
223 cycle_active_window(&win_meta, 'n');
224 else if (key == '<' && win_meta.active != 0) // cycle backwards
225 cycle_active_window(&win_meta, 'p');
226 else if (key == 'y' && win_meta.active != 0) // shift window forwards
227 shift_window(&win_meta, 'f');
228 else if (key == 'Y' && win_meta.active != 0) // shift window backwards
229 shift_window(&win_meta, 'b');
230 else if (key == '*' && win_meta.active != 0) // grow window horizontally
231 resize_window(&win_meta, '*');
232 else if (key == '_' && win_meta.active != 0) // shrink window horizontally
233 resize_window(&win_meta, '_');
234 else if (key == '+' && win_meta.active != 0) // grow window vertically
235 resize_window(&win_meta, '+');
236 else if (key == '-' && win_meta.active != 0) // shrink window vertically
237 resize_window(&win_meta, '-'); }