8 void toggle_window (struct WinMeta * win_meta, struct Win * win) {
9 // Toggle display of window win.
11 suspend_window(win_meta, win);
13 append_window(win_meta, win); }
15 void growshrink_active_window (struct WinMeta * win_meta, char change) {
16 // Grow or shrink active window horizontally or vertically by one cell size.
17 if (0 != win_meta->active) {
18 int height = win_meta->active->height;
19 int width = win_meta->active->width;
22 else if (change == '+')
24 else if (change == '_')
26 else if (change == '*')
28 resize_active_window (win_meta, height, width); } }
30 void init_keybindings(struct World * world) {
31 // Initialize keybindings from file "keybindings".
32 FILE * file = fopen("keybindings", "r");
41 if (c_count > linemax)
42 linemax = c_count + 1;
45 struct KeyBinding * keybindings = malloc(lines * sizeof(struct KeyBinding));
46 fseek(file, 0, SEEK_SET);
47 char * command = malloc(linemax);
50 while (fgets(command, linemax, file)) {
51 keybindings[commcount].key = atoi(command);
52 cmdptr = strchr(command, ' ') + 1;
53 keybindings[commcount].name = malloc(strlen(cmdptr));
54 memcpy(keybindings[commcount].name, cmdptr, strlen(cmdptr) - 1);
55 keybindings[commcount].name[strlen(cmdptr) - 1] = '\0';
59 struct KeysWinData * keyswindata = malloc(sizeof(struct KeysWinData));
60 keyswindata->max = lines - 1;
61 keyswindata->select = 0;
62 keyswindata->edit = 0;
63 world->keybindings = keybindings;
64 world->keyswindata = keyswindata; }
66 struct Map init_map () {
67 // Initialize map with some experimental start values.
73 map.cells = malloc(map.width * map.height);
76 for (y = 0; y < map.height; y++)
77 for (x = 0; x < map.width; x++) {
80 if ( 0 == ran % ((x*x) / 3 + 1)
81 || 0 == ran % ((y*y) / 3 + 1)
82 || 0 == ran % ((map.width - x - 1) * (map.width - x - 1) / 3 + 1)
83 || 0 == ran %((map.height - y - 1) * (map.height - y - 1) / 3 + 1))
85 map.cells[(y * map.width) + x] = terrain; }
88 void map_scroll (struct Map * map, char dir) {
89 // Scroll map into direction dir if possible by changing the offset.
90 if ('n' == dir && map->offset_y > 0)
94 else if ('w' == dir && map->offset_x > 0)
99 void next_turn (struct World * world) {
100 // Increment turn and move enemy.
103 char ty = world->monster->y;
104 char tx = world->monster->x;
113 if (tx == world->player->x && ty == world->player->y)
114 update_log(world, "\nThe monster hits you.");
115 else if (is_passable(world, tx, ty)) {
116 world->monster->y = ty;
117 world->monster->x = tx; } }
119 void update_log (struct World * world, char * text) {
120 // Update log with new text to be appended.
122 int len_old = strlen(world->log);
123 int len_new = strlen(text);
124 int len_whole = len_old + len_new + 1;
125 new_text = calloc(len_whole, sizeof(char));
126 memcpy(new_text, world->log, len_old);
127 memcpy(new_text + len_old, text, len_new);
129 world->log = new_text; }
131 void save_keybindings(struct World * world) {
132 // Write keybindings to keybindings file.
133 struct KeysWinData * keyswindata = (struct KeysWinData *) world->keyswindata;
134 struct KeyBinding * keybindings = world->keybindings;
135 FILE * file = fopen("keybindings", "w");
138 for (i = 0; i <= keyswindata->max; i++)
139 if (strlen(keybindings[i].name) > linemax)
140 linemax = strlen(keybindings[i].name);
141 linemax = linemax + 6; // + 6 = + 3 digits + whitespace + newline + null byte
142 char * line = malloc(linemax);
143 for (i = 0; i <= keyswindata->max; i++) {
144 snprintf(line, linemax, "%d %s\n", keybindings[i].key, keybindings[i].name);
145 fwrite(line, sizeof(char), strlen(line), file); }
149 int get_action_key (struct KeyBinding * keybindings, char * name) {
150 // Return key matching name in keybindings.
152 while (strcmp(keybindings[i].name, name) )
154 return keybindings[i].key; }
156 char * get_keyname(int keycode) {
157 // Translate some keycodes to readable names of max 9 chars.
159 keyname = malloc(15);
160 if (32 < keycode && keycode < 127)
161 sprintf(keyname, "%c", keycode);
162 else if (keycode == 9)
163 sprintf(keyname, "TAB");
164 else if (keycode == 10)
165 sprintf(keyname, "RETURN");
166 else if (keycode == 27)
167 sprintf(keyname, "ESCAPE");
168 else if (keycode == 32)
169 sprintf(keyname, "SPACE");
170 else if (keycode == KEY_UP)
171 sprintf(keyname, "UP");
172 else if (keycode == KEY_DOWN)
173 sprintf(keyname, "DOWN");
174 else if (keycode == KEY_LEFT)
175 sprintf(keyname, "LEFT");
176 else if (keycode == KEY_RIGHT)
177 sprintf(keyname, "RIGHT");
178 else if (keycode == KEY_HOME)
179 sprintf(keyname, "HOME");
180 else if (keycode == KEY_BACKSPACE)
181 sprintf(keyname, "BACKSPACE");
182 else if (keycode >= KEY_F0 && keycode <= KEY_F(63)) {
183 int f = keycode - KEY_F0;
184 sprintf(keyname, "F%d", f); }
185 else if (keycode == KEY_DC)
186 sprintf(keyname, "DELETE");
187 else if (keycode == KEY_IC)
188 sprintf(keyname, "INSERT");
189 else if (keycode == KEY_NPAGE)
190 sprintf(keyname, "NEXT PAGE");
191 else if (keycode == KEY_PPAGE)
192 sprintf(keyname, "PREV PAGE");
193 else if (keycode == KEY_END)
194 sprintf(keyname, "END");
196 sprintf(keyname, "(unknown)");
199 void keyswin_mod_key (struct World * world, struct WinMeta * win_meta) {
200 // In keybindings window, mark selection modifiable, modify key. Ensure max of three digits in key code field.
201 world->keyswindata->edit = 1;
202 draw_all_windows (win_meta);
205 world->keybindings[world->keyswindata->select].key = key;
206 world->keyswindata->edit = 0; }
208 void keyswin_move_selection (struct World * world, char dir) {
209 // In keybindings window, move selection upwards or downwards (if within limits of list length).
210 if ('u' == dir && world->keyswindata->select > 0)
211 world->keyswindata->select--;
212 else if ('d' == dir && world->keyswindata->select < world->keyswindata->max)
213 world->keyswindata->select++; }
215 char is_passable (struct World * world, int x, int y) {
216 // Check if coordinate on (or beyond) map is accessible to movement.
218 if (0 <= x && x < world->map->width && 0 <= y && y < world->map->height)
219 if ('.' == world->map->cells[y * world->map->width + x])
223 void move_player (struct World * world, char d) {
224 // Move player in direction d, increment turn counter and update log.
225 static char prev = 0;
228 char ty = world->player->y;
229 char tx = world->player->x;
242 if (ty == world->monster->y && tx == world->monster->x)
244 else if (is_passable(world, tx, ty)) {
246 world->player->y = ty;
247 world->player->x = tx; }
248 if (success * d == prev)
249 update_log (world, ".");
252 update_log (world, "\nYou hit the monster.");
254 char * msg = calloc(25, sizeof(char));
255 char * msg_content = "You fail to move";
257 msg_content = "You move";
258 sprintf(msg, "\n%s %s.", msg_content, dir);
259 update_log (world, msg);
264 void player_wait(struct World * world) {
265 // Make player wait one turn.
267 update_log (world, "\nYou wait."); }
271 init_keybindings(&world);
273 world.log = calloc(1, sizeof(char));
274 update_log (&world, "Start!");
275 struct Map map = init_map();
277 struct Player player;
280 world.player = &player;
281 struct Monster monster;
284 world.monster = &monster;
286 WINDOW * screen = initscr();
289 keypad(screen, TRUE);
291 struct WinMeta win_meta = init_win_meta(screen);
292 struct Win win_keys = init_window(&win_meta, "Keys", &world, draw_keys_win);
293 struct Win win_map = init_window(&win_meta, "Map", &world, draw_map_win);
294 struct Win win_info = init_window(&win_meta, "Info", &world, draw_info_win);
295 struct Win win_log = init_window(&win_meta, "Log", &world, draw_log_win);
299 draw_all_windows (&win_meta);
301 if (key == get_action_key(world.keybindings, "quit"))
303 else if (key == get_action_key(world.keybindings, "scroll pad right"))
304 scroll_pad (&win_meta, '+');
305 else if (key == get_action_key(world.keybindings, "scroll pad left"))
306 scroll_pad (&win_meta, '-');
307 else if (key == get_action_key(world.keybindings, "toggle keys window"))
308 toggle_window(&win_meta, &win_keys);
309 else if (key == get_action_key(world.keybindings, "toggle map window"))
310 toggle_window(&win_meta, &win_map);
311 else if (key == get_action_key(world.keybindings, "toggle info window"))
312 toggle_window(&win_meta, &win_info);
313 else if (key == get_action_key(world.keybindings, "toggle log window"))
314 toggle_window(&win_meta, &win_log);
315 else if (key == get_action_key(world.keybindings, "cycle forwards"))
316 cycle_active_window(&win_meta, 'n');
317 else if (key == get_action_key(world.keybindings, "cycle backwards"))
318 cycle_active_window(&win_meta, 'p');
319 else if (key == get_action_key(world.keybindings, "shift forwards"))
320 shift_active_window(&win_meta, 'f');
321 else if (key == get_action_key(world.keybindings, "shift backwards"))
322 shift_active_window(&win_meta, 'b');
323 else if (key == get_action_key(world.keybindings, "grow horizontally"))
324 growshrink_active_window(&win_meta, '*');
325 else if (key == get_action_key(world.keybindings, "shrink horizontally"))
326 growshrink_active_window(&win_meta, '_');
327 else if (key == get_action_key(world.keybindings, "grow vertically"))
328 growshrink_active_window(&win_meta, '+');
329 else if (key == get_action_key(world.keybindings, "shrink vertically"))
330 growshrink_active_window(&win_meta, '-');
331 else if (key == get_action_key(world.keybindings, "save keys"))
332 save_keybindings(&world);
333 else if (key == get_action_key(world.keybindings, "keys nav up"))
334 keyswin_move_selection (&world, 'u');
335 else if (key == get_action_key(world.keybindings, "keys nav down"))
336 keyswin_move_selection (&world, 'd');
337 else if (key == get_action_key(world.keybindings, "keys mod"))
338 keyswin_mod_key (&world, &win_meta);
339 else if (key == get_action_key(world.keybindings, "map up"))
340 map_scroll (&map, 'n');
341 else if (key == get_action_key(world.keybindings, "map down"))
342 map_scroll (&map, 's');
343 else if (key == get_action_key(world.keybindings, "map right"))
344 map_scroll (&map, 'e');
345 else if (key == get_action_key(world.keybindings, "map left"))
346 map_scroll (&map, 'w');
347 else if (key == get_action_key(world.keybindings, "player down"))
348 move_player(&world, 's');
349 else if (key == get_action_key(world.keybindings, "player up"))
350 move_player(&world, 'n');
351 else if (key == get_action_key(world.keybindings, "player right"))
352 move_player(&world, 'e');
353 else if (key == get_action_key(world.keybindings, "player left"))
354 move_player(&world, 'w');
355 else if (key == get_action_key(world.keybindings, "wait") )
356 player_wait (&world); }
359 for (key = 0; key <= world.keyswindata->max; key++)
360 free(world.keybindings[key].name);
361 free(world.keybindings);
362 free(world.keyswindata);